• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #include "chrome/browser/extensions/file_manager_util.h"
5 
6 #include "base/json/json_writer.h"
7 #include "base/logging.h"
8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "chrome/browser/metrics/user_metrics.h"
12 #include "chrome/browser/platform_util.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_list.h"
16 #include "chrome/browser/ui/webui/mediaplayer_ui.h"
17 #include "content/browser/browser_thread.h"
18 #include "grit/generated_resources.h"
19 #include "third_party/libjingle/source/talk/base/urlencode.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "webkit/fileapi/file_system_context.h"
22 #include "webkit/fileapi/file_system_mount_point_provider.h"
23 #include "webkit/fileapi/file_system_util.h"
24 
25 // This is the "well known" url for the file manager extension from
26 // browser/resources/file_manager.  In the future we may provide a way to swap
27 // out this file manager for an aftermarket part, but not yet.
28 const char kBaseFileBrowserUrl[] =
29     "chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/main.html";
30 // List of file extension we can open in tab.
31 const char* kBrowserSupportedExtensions[] = {
32     ".jpg", ".jpeg", ".png", ".webp", ".gif", ".pdf", ".txt", ".html", ".htm"
33 };
34 // List of file extension that can be handled with the media player.
35 const char* kAVExtensions[] = {
36     ".webm", ".mp4", ".m4v", ".mov", ".ogm", ".ogv", ".ogx",
37     ".mp3", ".m4a", ".ogg", ".oga", ".wav",
38 /* TODO(zelidrag): Add unsupported ones as we enable them:
39     ".3gp", ".mkv", ".avi", ".divx", ".xvid", ".wmv", ".asf", ".mpeg", ".mpg",
40     ".wma", ".aiff",
41 */
42 };
43 
IsSupportedBrowserExtension(const char * ext)44 bool IsSupportedBrowserExtension(const char* ext) {
45   for (size_t i = 0; i < arraysize(kBrowserSupportedExtensions); i++) {
46     if (base::strcasecmp(ext, kBrowserSupportedExtensions[i]) == 0) {
47       return true;
48     }
49   }
50   return false;
51 }
52 
IsSupportedAVExtension(const char * ext)53 bool IsSupportedAVExtension(const char* ext) {
54   for (size_t i = 0; i < arraysize(kAVExtensions); i++) {
55     if (base::strcasecmp(ext, kAVExtensions[i]) == 0) {
56       return true;
57     }
58   }
59   return false;
60 }
61 
62 // static
GetFileBrowserUrl()63 GURL FileManagerUtil::GetFileBrowserUrl() {
64   return GURL(kBaseFileBrowserUrl);
65 }
66 
67 // static
ConvertFileToFileSystemUrl(Profile * profile,const FilePath & full_file_path,const GURL & origin_url,GURL * url)68 bool FileManagerUtil::ConvertFileToFileSystemUrl(
69     Profile* profile, const FilePath& full_file_path, const GURL& origin_url,
70     GURL* url) {
71   fileapi::FileSystemPathManager* path_manager =
72       profile->GetFileSystemContext()->path_manager();
73   fileapi::ExternalFileSystemMountPointProvider* provider =
74       path_manager->external_provider();
75   if (!provider)
76     return false;
77 
78   // Find if this file path is managed by the external provider.
79   std::vector<FilePath> root_dirs = provider->GetRootDirectories();
80   for (std::vector<FilePath>::iterator iter = root_dirs.begin();
81        iter != root_dirs.end();
82        ++iter) {
83     FilePath path;
84     std::vector<FilePath::StringType> components;
85     const FilePath& root_path = *iter;
86     root_path.GetComponents(&components);
87     if (!components.size()) {
88       NOTREACHED();
89       continue;
90     }
91     if (root_path.AppendRelativePath(full_file_path, &path)) {
92       GURL base_url = fileapi::GetFileSystemRootURI(origin_url,
93           fileapi::kFileSystemTypeExternal);
94       std::string final_url = base_url.spec();
95       FilePath relative_path(components[components.size() - 1]);
96       *url = GURL(base_url.spec() + relative_path.Append(path).value());
97       return true;
98     }
99   }
100   return false;
101 }
102 
103 // static
GetFileBrowserUrlWithParams(SelectFileDialog::Type type,const string16 & title,const FilePath & default_path,const SelectFileDialog::FileTypeInfo * file_types,int file_type_index,const FilePath::StringType & default_extension)104 GURL FileManagerUtil::GetFileBrowserUrlWithParams(
105     SelectFileDialog::Type type,
106     const string16& title,
107     const FilePath& default_path,
108     const SelectFileDialog::FileTypeInfo* file_types,
109     int file_type_index,
110     const FilePath::StringType& default_extension) {
111   std::string json = GetArgumentsJson(type, title, default_path, file_types,
112                                       file_type_index, default_extension);
113   return GURL(FileManagerUtil::GetFileBrowserUrl().spec() + "?" +
114               UrlEncodeStringWithoutEncodingSpaceAsPlus(json));
115 
116 }
117 // static
ShowFullTabUrl(Profile * profile,const FilePath & default_path)118 void FileManagerUtil::ShowFullTabUrl(Profile* profile,
119                                      const FilePath& default_path) {
120   std::string json = GetArgumentsJson(SelectFileDialog::SELECT_NONE, string16(),
121       default_path, NULL, 0, FilePath::StringType());
122   GURL url(std::string(kBaseFileBrowserUrl) + "?" +
123            UrlEncodeStringWithoutEncodingSpaceAsPlus(json));
124   Browser* browser = BrowserList::GetLastActive();
125   if (!browser)
126     return;
127 
128   UserMetrics::RecordAction(UserMetricsAction("ShowFileBrowserFullTab"),
129                             profile);
130   browser->ShowSingletonTab(GURL(url));
131 }
132 
133 
ViewItem(const FilePath & full_path,bool enqueue)134 void FileManagerUtil::ViewItem(const FilePath& full_path, bool enqueue) {
135   std::string ext = full_path.Extension();
136   // For things supported natively by the browser, we should open it
137   // in a tab.
138   if (IsSupportedBrowserExtension(ext.data())) {
139     std::string path;
140     path = "file://";
141     path.append(full_path.value());
142     if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
143       bool result = BrowserThread::PostTask(
144           BrowserThread::UI, FROM_HERE,
145           NewRunnableFunction(&ViewItem, full_path, enqueue));
146       DCHECK(result);
147       return;
148     }
149     Browser* browser = BrowserList::GetLastActive();
150     if (browser)
151       browser->AddSelectedTabWithURL(GURL(path), PageTransition::LINK);
152     return;
153   }
154   if (IsSupportedAVExtension(ext.data())) {
155     Browser* browser = BrowserList::GetLastActive();
156     if (!browser)
157       return;
158     MediaPlayer* mediaplayer = MediaPlayer::GetInstance();
159     if (enqueue)
160       mediaplayer->EnqueueMediaFile(browser->profile(), full_path, NULL);
161     else
162       mediaplayer->ForcePlayMediaFile(browser->profile(), full_path, NULL);
163     return;
164   }
165 
166   // Unknown file type. Show an error message.
167   BrowserThread::PostTask(
168       BrowserThread::UI, FROM_HERE,
169       NewRunnableFunction(
170           &platform_util::SimpleErrorBox,
171           static_cast<gfx::NativeWindow>(NULL),
172           l10n_util::GetStringUTF16(IDS_FILEBROWSER_ERROR_TITLE),
173           l10n_util::GetStringFUTF16(IDS_FILEBROWSER_ERROR_UNKNOWN_FILE_TYPE,
174                                      UTF8ToUTF16(full_path.BaseName().value()))
175           ));
176 }
177 
178 // static
GetArgumentsJson(SelectFileDialog::Type type,const string16 & title,const FilePath & default_path,const SelectFileDialog::FileTypeInfo * file_types,int file_type_index,const FilePath::StringType & default_extension)179 std::string FileManagerUtil::GetArgumentsJson(
180     SelectFileDialog::Type type,
181     const string16& title,
182     const FilePath& default_path,
183     const SelectFileDialog::FileTypeInfo* file_types,
184     int file_type_index,
185     const FilePath::StringType& default_extension) {
186   DictionaryValue arg_value;
187   arg_value.SetString("type", GetDialogTypeAsString(type));
188   arg_value.SetString("title", title);
189   // TODO(zelidrag): Convert local system path into virtual path for File API.
190   arg_value.SetString("defaultPath", default_path.value());
191   arg_value.SetString("defaultExtension", default_extension);
192 
193   ListValue* types_list = new ListValue();
194 
195   if (file_types) {
196     for (size_t i = 0; i < file_types->extensions.size(); ++i) {
197       ListValue* extensions_list = new ListValue();
198       for (size_t j = 0; j < file_types->extensions[i].size(); ++j) {
199         extensions_list->Set(
200             i, Value::CreateStringValue(file_types->extensions[i][j]));
201       }
202 
203       DictionaryValue* dict = new DictionaryValue();
204       dict->Set("extensions", extensions_list);
205 
206       if (i < file_types->extension_description_overrides.size()) {
207         string16 desc = file_types->extension_description_overrides[i];
208         dict->SetString("description", desc);
209       }
210 
211       dict->SetBoolean("selected",
212                        (static_cast<size_t>(file_type_index) == i));
213 
214       types_list->Set(i, dict);
215     }
216   }
217 
218   std::string rv;
219   base::JSONWriter::Write(&arg_value, false, &rv);
220 
221   return rv;
222 }
223 
224 // static
GetDialogTypeAsString(SelectFileDialog::Type dialog_type)225 std::string FileManagerUtil::GetDialogTypeAsString(
226     SelectFileDialog::Type dialog_type) {
227   std::string type_str;
228   switch (dialog_type) {
229     case SelectFileDialog::SELECT_NONE:
230       type_str = "full-page";
231       break;
232 
233     case SelectFileDialog::SELECT_FOLDER:
234       type_str = "folder";
235       break;
236 
237     case SelectFileDialog::SELECT_SAVEAS_FILE:
238       type_str = "saveas-file";
239       break;
240 
241     case SelectFileDialog::SELECT_OPEN_FILE:
242       type_str = "open-file";
243       break;
244 
245     case SelectFileDialog::SELECT_OPEN_MULTI_FILE:
246       type_str = "open-multi-file";
247       break;
248 
249     default:
250       NOTREACHED();
251   }
252 
253   return type_str;
254 }
255