Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media_galleries / fileapi / media_path_filter.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
6
7 #if defined(OS_WIN)
8 #include <windows.h>
9 #endif
10
11 #include <algorithm>
12 #include <string>
13
14 #include "base/strings/string_util.h"
15 #include "net/base/mime_util.h"
16
17 namespace {
18
19 const base::FilePath::CharType* const kExtraSupportedImageExtensions[] = {
20   // RAW picture file types.
21   // Some of which are just image/tiff.
22   FILE_PATH_LITERAL("3fr"),  // (Hasselblad)
23   FILE_PATH_LITERAL("arw"),  // (Sony)
24   FILE_PATH_LITERAL("dcr"),  // (Kodak)
25   FILE_PATH_LITERAL("dng"),  // (Adobe, Leica, Ricoh, Samsung)
26   FILE_PATH_LITERAL("erf"),  // (Epson)
27   FILE_PATH_LITERAL("k25"),  // (Kodak)
28   FILE_PATH_LITERAL("kdc"),  // (Kodak)
29   FILE_PATH_LITERAL("mef"),  // (Mamiya)
30   FILE_PATH_LITERAL("mos"),  // (Leaf)
31   FILE_PATH_LITERAL("nef"),  // (Nikon)
32   FILE_PATH_LITERAL("pef"),  // (Pentax)
33   FILE_PATH_LITERAL("sr2"),  // (Sony)
34   FILE_PATH_LITERAL("srf"),  // (Sony)
35
36   // More RAW picture file types.
37   FILE_PATH_LITERAL("cr2"),  // (Canon - image/x-canon-cr2)
38   // Note, some .crw files are just TIFFs.
39   FILE_PATH_LITERAL("crw"),  // (Canon - image/x-canon-crw)
40   FILE_PATH_LITERAL("mrw"),  // (Minolta - image/x-minolta-mrw)
41   FILE_PATH_LITERAL("orf"),  // (Olympus - image/x-olympus-orf)
42   FILE_PATH_LITERAL("raf"),  // (Fuji)
43   FILE_PATH_LITERAL("rw2"),  // (Panasonic - image/x-panasonic-raw)
44   FILE_PATH_LITERAL("x3f"),  // (Sigma - image/x-x3f)
45
46   // There exists many file formats all with the .raw extension. For now, only
47   // the following types are supported:
48   // - TIFF files with .raw extension - image/tiff
49   // - Leica / Panasonic RAW files - image/x-panasonic-raw
50   // - Phase One RAW files - image/x-phaseone-raw
51   FILE_PATH_LITERAL("raw"),
52 };
53
54 const base::FilePath::CharType* const kExtraSupportedVideoExtensions[] = {
55   FILE_PATH_LITERAL("3gp"),
56   FILE_PATH_LITERAL("3gpp"),
57   FILE_PATH_LITERAL("avi"),
58   FILE_PATH_LITERAL("flv"),
59   FILE_PATH_LITERAL("mkv"),
60   FILE_PATH_LITERAL("mov"),
61   FILE_PATH_LITERAL("mpeg"),
62   FILE_PATH_LITERAL("mpeg4"),
63   FILE_PATH_LITERAL("mpegps"),
64   FILE_PATH_LITERAL("mpg"),
65   FILE_PATH_LITERAL("wmv"),
66 };
67
68 const base::FilePath::CharType* const kExtraSupportedAudioExtensions[] = {
69   // Many of these file types are audio files in the same containers that the
70   // MIME sniffer already detects as video/subtype.
71   FILE_PATH_LITERAL("aac"),   // audio/mpeg
72   FILE_PATH_LITERAL("alac"),  // video/mp4
73   FILE_PATH_LITERAL("flac"),  // audio/x-flac
74   FILE_PATH_LITERAL("m4b"),   // video/mp4
75   FILE_PATH_LITERAL("m4p"),   // video/mp4
76   FILE_PATH_LITERAL("wma"),   // video/x-ms-asf
77 };
78
79 bool IsUnsupportedExtension(const base::FilePath::StringType& extension) {
80   std::string mime_type;
81   return !net::GetMimeTypeFromExtension(extension, &mime_type) ||
82       !net::IsSupportedMimeType(mime_type);
83 }
84
85 std::vector<base::FilePath::StringType> GetMediaExtensionList(
86     const std::string& mime_type) {
87   std::vector<base::FilePath::StringType> extensions;
88   net::GetExtensionsForMimeType(mime_type, &extensions);
89   std::vector<base::FilePath::StringType>::iterator new_end =
90       std::remove_if(extensions.begin(),
91                      extensions.end(),
92                      &IsUnsupportedExtension);
93   extensions.erase(new_end, extensions.end());
94   return extensions;
95 }
96
97 }  // namespace
98
99 // static
100 bool MediaPathFilter::ShouldSkip(const base::FilePath& path) {
101   const base::FilePath::StringType base_name = path.BaseName().value();
102   if (base_name.empty())
103     return false;
104
105   // Dot files (aka hidden files)
106   if (base_name[0] == '.')
107     return true;
108
109   // Mac OS X file.
110   if (base_name == FILE_PATH_LITERAL("__MACOSX"))
111     return true;
112
113 #if defined(OS_WIN)
114   DWORD file_attributes = ::GetFileAttributes(path.value().c_str());
115   if ((file_attributes != INVALID_FILE_ATTRIBUTES) &&
116       ((file_attributes & FILE_ATTRIBUTE_HIDDEN) != 0))
117     return true;
118 #else
119   // Windows always creates a recycle bin folder in the attached device to store
120   // all the deleted contents. On non-windows operating systems, there is no way
121   // to get the hidden attribute of windows recycle bin folders that are present
122   // on the attached device. Therefore, compare the file path name to the
123   // recycle bin name and exclude those folders. For more details, please refer
124   // to http://support.microsoft.com/kb/171694.
125   const char win_98_recycle_bin_name[] = "RECYCLED";
126   const char win_xp_recycle_bin_name[] = "RECYCLER";
127   const char win_vista_recycle_bin_name[] = "$Recycle.bin";
128   if ((base::strncasecmp(base_name.c_str(),
129                          win_98_recycle_bin_name,
130                          strlen(win_98_recycle_bin_name)) == 0) ||
131       (base::strncasecmp(base_name.c_str(),
132                          win_xp_recycle_bin_name,
133                          strlen(win_xp_recycle_bin_name)) == 0) ||
134       (base::strncasecmp(base_name.c_str(),
135                          win_vista_recycle_bin_name,
136                          strlen(win_vista_recycle_bin_name)) == 0))
137     return true;
138 #endif  // defined(OS_WIN)
139   return false;
140 }
141
142 MediaPathFilter::MediaPathFilter()
143     : initialized_(false) {
144   sequence_checker_.DetachFromSequence();
145 }
146
147 MediaPathFilter::~MediaPathFilter() {
148 }
149
150 bool MediaPathFilter::Match(const base::FilePath& path) {
151   return GetType(path) != MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN;
152 }
153
154 MediaGalleryScanFileType MediaPathFilter::GetType(const base::FilePath& path) {
155   EnsureInitialized();
156   MediaFileExtensionMap::const_iterator it =
157       media_file_extensions_map_.find(StringToLowerASCII(path.Extension()));
158   if (it == media_file_extensions_map_.end())
159     return MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN;
160   return static_cast<MediaGalleryScanFileType>(it->second);
161 }
162
163 void MediaPathFilter::EnsureInitialized() {
164   DCHECK(sequence_checker_.CalledOnValidSequencedThread());
165   if (initialized_)
166     return;
167
168   // This may require I/O when it calls net::GetExtensionsForMimeType(), so
169   // doing this in the ctor and removing |initialized_| would result in a
170   // ThreadRestrictions failure.
171   AddExtensionsToMediaFileExtensionMap(GetMediaExtensionList("image/*"),
172                                        MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE);
173   AddExtensionsToMediaFileExtensionMap(GetMediaExtensionList("audio/*"),
174                                        MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO);
175   AddExtensionsToMediaFileExtensionMap(GetMediaExtensionList("video/*"),
176                                        MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO);
177   AddAdditionalExtensionsToMediaFileExtensionMap(
178       kExtraSupportedImageExtensions,
179       arraysize(kExtraSupportedImageExtensions),
180       MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE);
181   AddAdditionalExtensionsToMediaFileExtensionMap(
182       kExtraSupportedAudioExtensions,
183       arraysize(kExtraSupportedAudioExtensions),
184       MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO);
185   AddAdditionalExtensionsToMediaFileExtensionMap(
186       kExtraSupportedVideoExtensions,
187       arraysize(kExtraSupportedVideoExtensions),
188       MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO);
189
190   initialized_ = true;
191 }
192
193 void MediaPathFilter::AddExtensionsToMediaFileExtensionMap(
194     const MediaFileExtensionList& extensions_list,
195     MediaGalleryScanFileType type) {
196   for (size_t i = 0; i < extensions_list.size(); ++i)
197     AddExtensionToMediaFileExtensionMap(extensions_list[i].c_str(), type);
198 }
199
200 void MediaPathFilter::AddAdditionalExtensionsToMediaFileExtensionMap(
201     const base::FilePath::CharType* const* extensions_list,
202     size_t extensions_list_size,
203     MediaGalleryScanFileType type) {
204   for (size_t i = 0; i < extensions_list_size; ++i)
205     AddExtensionToMediaFileExtensionMap(extensions_list[i], type);
206 }
207
208 void MediaPathFilter::AddExtensionToMediaFileExtensionMap(
209     const base::FilePath::CharType* extension,
210     MediaGalleryScanFileType type) {
211   base::FilePath::StringType extension_with_sep =
212       base::FilePath::kExtensionSeparator +
213       base::FilePath::StringType(extension);
214   media_file_extensions_map_[extension_with_sep] |= type;
215 }