Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(430)

Side by Side Diff: chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc

Issue 22893048: file_manager: Split the open with browser stuff into a set of separate files (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address comments Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h" 5 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/logging.h" 8 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/path_service.h"
12 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "chrome/browser/chromeos/drive/drive.pb.h"
16 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
17 #include "chrome/browser/chromeos/drive/file_system.h"
18 #include "chrome/browser/chromeos/drive/file_system_util.h"
19 #include "chrome/browser/chromeos/extensions/file_manager/app_id.h" 11 #include "chrome/browser/chromeos/extensions/file_manager/app_id.h"
20 #include "chrome/browser/chromeos/extensions/file_manager/file_browser_handlers. h" 12 #include "chrome/browser/chromeos/extensions/file_manager/file_browser_handlers. h"
21 #include "chrome/browser/chromeos/extensions/file_manager/file_tasks.h" 13 #include "chrome/browser/chromeos/extensions/file_manager/file_tasks.h"
22 #include "chrome/browser/chromeos/extensions/file_manager/fileapi_util.h" 14 #include "chrome/browser/chromeos/extensions/file_manager/fileapi_util.h"
23 #include "chrome/browser/chromeos/extensions/file_manager/url_util.h" 15 #include "chrome/browser/chromeos/extensions/file_manager/url_util.h"
24 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" 16 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
25 #include "chrome/browser/extensions/crx_installer.h"
26 #include "chrome/browser/extensions/extension_install_prompt.h"
27 #include "chrome/browser/extensions/extension_service.h" 17 #include "chrome/browser/extensions/extension_service.h"
28 #include "chrome/browser/extensions/extension_system.h" 18 #include "chrome/browser/extensions/extension_system.h"
29 #include "chrome/browser/google_apis/task_util.h" 19 #include "chrome/browser/google_apis/task_util.h"
30 #include "chrome/browser/plugins/plugin_prefs.h"
31 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
32 #include "chrome/browser/profiles/profile_manager.h" 21 #include "chrome/browser/profiles/profile_manager.h"
33 #include "chrome/browser/ui/browser.h" 22 #include "chrome/browser/ui/browser.h"
34 #include "chrome/browser/ui/browser_finder.h" 23 #include "chrome/browser/ui/browser_finder.h"
35 #include "chrome/browser/ui/browser_tabstrip.h" 24 #include "chrome/browser/ui/browser_tabstrip.h"
36 #include "chrome/browser/ui/browser_window.h" 25 #include "chrome/browser/ui/browser_window.h"
37 #include "chrome/browser/ui/extensions/application_launch.h" 26 #include "chrome/browser/ui/extensions/application_launch.h"
38 #include "chrome/browser/ui/simple_message_box.h" 27 #include "chrome/browser/ui/simple_message_box.h"
39 #include "chrome/common/chrome_paths.h"
40 #include "chrome/common/chrome_switches.h"
41 #include "chrome/common/extensions/api/file_browser_handlers/file_browser_handle r.h" 28 #include "chrome/common/extensions/api/file_browser_handlers/file_browser_handle r.h"
42 #include "chrome/common/url_constants.h"
43 #include "chromeos/chromeos_switches.h"
44 #include "content/public/browser/browser_thread.h" 29 #include "content/public/browser/browser_thread.h"
45 #include "content/public/browser/plugin_service.h"
46 #include "content/public/browser/storage_partition.h" 30 #include "content/public/browser/storage_partition.h"
47 #include "content/public/browser/user_metrics.h" 31 #include "content/public/browser/user_metrics.h"
48 #include "content/public/common/pepper_plugin_info.h"
49 #include "content/public/common/webplugininfo.h"
50 #include "grit/generated_resources.h" 32 #include "grit/generated_resources.h"
51 #include "net/base/escape.h"
52 #include "net/base/mime_util.h" 33 #include "net/base/mime_util.h"
53 #include "net/base/net_util.h"
54 #include "ui/base/l10n/l10n_util.h" 34 #include "ui/base/l10n/l10n_util.h"
55 #include "webkit/browser/fileapi/file_system_backend.h" 35 #include "webkit/browser/fileapi/file_system_backend.h"
56 #include "webkit/browser/fileapi/file_system_context.h" 36 #include "webkit/browser/fileapi/file_system_context.h"
57 #include "webkit/browser/fileapi/file_system_operation_runner.h" 37 #include "webkit/browser/fileapi/file_system_operation_runner.h"
58 #include "webkit/browser/fileapi/file_system_url.h" 38 #include "webkit/browser/fileapi/file_system_url.h"
59 39
60 using content::BrowserContext; 40 using content::BrowserContext;
61 using content::BrowserThread; 41 using content::BrowserThread;
62 using content::PluginService;
63 using content::UserMetricsAction; 42 using content::UserMetricsAction;
64 using extensions::Extension; 43 using extensions::Extension;
65 using extensions::app_file_handler_util::FindFileHandlersForFiles; 44 using extensions::app_file_handler_util::FindFileHandlersForFiles;
66 using extensions::app_file_handler_util::PathAndMimeTypeSet; 45 using extensions::app_file_handler_util::PathAndMimeTypeSet;
67 using fileapi::FileSystemURL; 46 using fileapi::FileSystemURL;
68 47
69 namespace file_manager { 48 namespace file_manager {
70 namespace util { 49 namespace util {
71 namespace { 50 namespace {
72 51
73 const base::FilePath::CharType kCRXExtension[] = FILE_PATH_LITERAL(".crx");
74 const base::FilePath::CharType kPdfExtension[] = FILE_PATH_LITERAL(".pdf");
75 const base::FilePath::CharType kSwfExtension[] = FILE_PATH_LITERAL(".swf");
76
77 // List of file extensions viewable in the browser.
78 const base::FilePath::CharType* kFileExtensionsViewableInBrowser[] = {
79 #if defined(GOOGLE_CHROME_BUILD)
80 FILE_PATH_LITERAL(".pdf"),
81 FILE_PATH_LITERAL(".swf"),
82 #endif
83 FILE_PATH_LITERAL(".bmp"),
84 FILE_PATH_LITERAL(".jpg"),
85 FILE_PATH_LITERAL(".jpeg"),
86 FILE_PATH_LITERAL(".png"),
87 FILE_PATH_LITERAL(".webp"),
88 FILE_PATH_LITERAL(".gif"),
89 FILE_PATH_LITERAL(".txt"),
90 FILE_PATH_LITERAL(".html"),
91 FILE_PATH_LITERAL(".htm"),
92 FILE_PATH_LITERAL(".mhtml"),
93 FILE_PATH_LITERAL(".mht"),
94 FILE_PATH_LITERAL(".svg"),
95 };
96
97 // Returns true if |file_path| is viewable in the browser (ex. HTML file).
98 bool IsViewableInBrowser(const base::FilePath& file_path) {
99 for (size_t i = 0; i < arraysize(kFileExtensionsViewableInBrowser); i++) {
100 if (file_path.MatchesExtension(kFileExtensionsViewableInBrowser[i]))
101 return true;
102 }
103 return false;
104 }
105
106 bool IsPepperPluginEnabled(Profile* profile,
107 const base::FilePath& plugin_path) {
108 content::PepperPluginInfo* pepper_info =
109 PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(plugin_path);
110 if (!pepper_info)
111 return false;
112
113 scoped_refptr<PluginPrefs> plugin_prefs = PluginPrefs::GetForProfile(profile);
114 if (!plugin_prefs.get())
115 return false;
116
117 return plugin_prefs->IsPluginEnabled(pepper_info->ToWebPluginInfo());
118 }
119
120 bool IsPdfPluginEnabled(Profile* profile) {
121 base::FilePath plugin_path;
122 PathService::Get(chrome::FILE_PDF_PLUGIN, &plugin_path);
123 return IsPepperPluginEnabled(profile, plugin_path);
124 }
125
126 bool IsFlashPluginEnabled(Profile* profile) {
127 base::FilePath plugin_path(
128 CommandLine::ForCurrentProcess()->GetSwitchValueNative(
129 switches::kPpapiFlashPath));
130 if (plugin_path.empty())
131 PathService::Get(chrome::FILE_PEPPER_FLASH_PLUGIN, &plugin_path);
132 return IsPepperPluginEnabled(profile, plugin_path);
133 }
134
135 void OpenNewTab(Profile* profile, const GURL& url) {
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
137 Browser* browser = chrome::FindOrCreateTabbedBrowser(
138 profile ? profile : ProfileManager::GetDefaultProfileOrOffTheRecord(),
139 chrome::HOST_DESKTOP_TYPE_ASH);
140 chrome::AddSelectedTabWithURL(browser, url, content::PAGE_TRANSITION_LINK);
141 // If the current browser is not tabbed then the new tab will be created
142 // in a different browser. Make sure it is visible.
143 browser->window()->Show();
144 }
145
146 // Shows a warning message box saying that the file could not be opened. 52 // Shows a warning message box saying that the file could not be opened.
147 void ShowWarningMessageBox(Profile* profile, const base::FilePath& file_path) { 53 void ShowWarningMessageBox(Profile* profile, const base::FilePath& file_path) {
148 // TODO: if FindOrCreateTabbedBrowser creates a new browser the returned 54 // TODO: if FindOrCreateTabbedBrowser creates a new browser the returned
149 // browser is leaked. 55 // browser is leaked.
150 Browser* browser = 56 Browser* browser =
151 chrome::FindOrCreateTabbedBrowser(profile, 57 chrome::FindOrCreateTabbedBrowser(profile,
152 chrome::HOST_DESKTOP_TYPE_ASH); 58 chrome::HOST_DESKTOP_TYPE_ASH);
153 chrome::ShowMessageBox( 59 chrome::ShowMessageBox(
154 browser->window()->GetNativeWindow(), 60 browser->window()->GetNativeWindow(),
155 l10n_util::GetStringFUTF16( 61 l10n_util::GetStringFUTF16(
156 IDS_FILE_BROWSER_ERROR_VIEWING_FILE_TITLE, 62 IDS_FILE_BROWSER_ERROR_VIEWING_FILE_TITLE,
157 UTF8ToUTF16(file_path.BaseName().value())), 63 UTF8ToUTF16(file_path.BaseName().value())),
158 l10n_util::GetStringUTF16(IDS_FILE_BROWSER_ERROR_VIEWING_FILE), 64 l10n_util::GetStringUTF16(IDS_FILE_BROWSER_ERROR_VIEWING_FILE),
159 chrome::MESSAGE_BOX_TYPE_WARNING); 65 chrome::MESSAGE_BOX_TYPE_WARNING);
160 } 66 }
161 67
162 void InstallCRX(Browser* browser, const base::FilePath& file_path) {
163 ExtensionService* service =
164 extensions::ExtensionSystem::Get(browser->profile())->extension_service();
165 CHECK(service);
166
167 scoped_refptr<extensions::CrxInstaller> installer(
168 extensions::CrxInstaller::Create(
169 service,
170 scoped_ptr<ExtensionInstallPrompt>(new ExtensionInstallPrompt(
171 browser->profile(), NULL, NULL))));
172 installer->set_error_on_unsupported_requirements(true);
173 installer->set_is_gallery_install(false);
174 installer->set_allow_silent_install(false);
175 installer->InstallCrx(file_path);
176 }
177
178 // Called when a crx file on Drive was downloaded.
179 void OnCRXDownloadCallback(Browser* browser,
180 drive::FileError error,
181 const base::FilePath& file,
182 scoped_ptr<drive::ResourceEntry> entry) {
183 if (error != drive::FILE_ERROR_OK)
184 return;
185 InstallCRX(browser, file);
186 }
187
188 // Grants file system access to the file manager. 68 // Grants file system access to the file manager.
189 bool GrantFileSystemAccessToFileBrowser(Profile* profile) { 69 bool GrantFileSystemAccessToFileBrowser(Profile* profile) {
190 // The file manager always runs in the site for its extension id, so that 70 // The file manager always runs in the site for its extension id, so that
191 // is the site for which file access permissions should be granted. 71 // is the site for which file access permissions should be granted.
192 GURL site = extensions::ExtensionSystem::Get(profile)->extension_service()-> 72 GURL site = extensions::ExtensionSystem::Get(profile)->extension_service()->
193 GetSiteForExtensionId(kFileManagerAppId); 73 GetSiteForExtensionId(kFileManagerAppId);
194 fileapi::ExternalFileSystemBackend* backend = 74 fileapi::ExternalFileSystemBackend* backend =
195 BrowserContext::GetStoragePartitionForSite(profile, site)-> 75 BrowserContext::GetStoragePartitionForSite(profile, site)->
196 GetFileSystemContext()->external_backend(); 76 GetFileSystemContext()->external_backend();
197 if (!backend) 77 if (!backend)
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 handler->id()); 252 handler->id());
373 if (handler_task_id != default_task_id && 253 if (handler_task_id != default_task_id &&
374 !file_browser_handlers::IsFallbackFileBrowserHandler(handler) && 254 !file_browser_handlers::IsFallbackFileBrowserHandler(handler) &&
375 OpenFileWithFileHandler( 255 OpenFileWithFileHandler(
376 profile, file_path, url, mime_type, default_task_id)) { 256 profile, file_path, url, mime_type, default_task_id)) {
377 return true; 257 return true;
378 } 258 }
379 return OpenFileWithFileBrowserHandler(profile, file_path, *handler, url); 259 return OpenFileWithFileBrowserHandler(profile, file_path, *handler, url);
380 } 260 }
381 261
382 // Reads the alternate URL from a GDoc file. When it fails, returns a file URL
383 // for |file_path| as fallback.
384 // Note that an alternate url is a URL to open a hosted document.
385 GURL ReadUrlFromGDocOnBlockingPool(const base::FilePath& file_path) {
386 GURL url = drive::util::ReadUrlFromGDocFile(file_path);
387 if (url.is_empty())
388 url = net::FilePathToFileURL(file_path);
389 return url;
390 }
391
392 // Used to implement OpenItem(). 262 // Used to implement OpenItem().
393 void ContinueOpenItem(Profile* profile, 263 void ContinueOpenItem(Profile* profile,
394 const base::FilePath& file_path, 264 const base::FilePath& file_path,
395 base::PlatformFileError error) { 265 base::PlatformFileError error) {
396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
397 267
398 if (error == base::PLATFORM_FILE_OK) { 268 if (error == base::PLATFORM_FILE_OK) {
399 // A directory exists at |file_path|. Open it with the file manager. 269 // A directory exists at |file_path|. Open it with the file manager.
400 OpenFileManagerWithInternalActionId(file_path, "open"); 270 OpenFileManagerWithInternalActionId(file_path, "open");
401 } else { 271 } else {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 365
496 CheckIfDirectoryExists(file_system_context, url, 366 CheckIfDirectoryExists(file_system_context, url,
497 base::Bind(&ContinueOpenItem, profile, file_path)); 367 base::Bind(&ContinueOpenItem, profile, file_path));
498 } 368 }
499 369
500 void ShowItemInFolder(const base::FilePath& file_path) { 370 void ShowItemInFolder(const base::FilePath& file_path) {
501 // This action changes the selection so we do not reuse existing tabs. 371 // This action changes the selection so we do not reuse existing tabs.
502 OpenFileManagerWithInternalActionId(file_path, "select"); 372 OpenFileManagerWithInternalActionId(file_path, "select");
503 } 373 }
504 374
505 bool OpenFileWithBrowser(Browser* browser, const base::FilePath& file_path) {
506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
507
508 Profile* profile = browser->profile();
509 // For things supported natively by the browser, we should open it
510 // in a tab.
511 if (IsViewableInBrowser(file_path) ||
512 ShouldBeOpenedWithPlugin(profile, file_path.Extension())) {
513 GURL page_url = net::FilePathToFileURL(file_path);
514 // Override drive resource to point to internal handler instead of file URL.
515 if (drive::util::IsUnderDriveMountPoint(file_path)) {
516 page_url = drive::util::FilePathToDriveURL(
517 drive::util::ExtractDrivePath(file_path));
518 }
519 OpenNewTab(profile, page_url);
520 return true;
521 }
522
523 if (drive::util::HasGDocFileExtension(file_path)) {
524 if (drive::util::IsUnderDriveMountPoint(file_path)) {
525 // The file is on Google Docs. Open with drive URL.
526 GURL url = drive::util::FilePathToDriveURL(
527 drive::util::ExtractDrivePath(file_path));
528 OpenNewTab(profile, url);
529 } else {
530 // The file is local (downloaded from an attachment or otherwise copied).
531 // Parse the file to extract the Docs url and open this url.
532 base::PostTaskAndReplyWithResult(
533 BrowserThread::GetBlockingPool(),
534 FROM_HERE,
535 base::Bind(&ReadUrlFromGDocOnBlockingPool, file_path),
536 base::Bind(&OpenNewTab, static_cast<Profile*>(NULL)));
537 }
538 return true;
539 }
540
541 if (file_path.MatchesExtension(kCRXExtension)) {
542 if (drive::util::IsUnderDriveMountPoint(file_path)) {
543 drive::DriveIntegrationService* integration_service =
544 drive::DriveIntegrationServiceFactory::GetForProfile(profile);
545 if (!integration_service)
546 return false;
547 integration_service->file_system()->GetFileByPath(
548 drive::util::ExtractDrivePath(file_path),
549 base::Bind(&OnCRXDownloadCallback, browser));
550 } else {
551 InstallCRX(browser, file_path);
552 }
553 return true;
554 }
555
556 // Failed to open the file of unknown type.
557 LOG(WARNING) << "Unknown file type: " << file_path.value();
558 return false;
559 }
560
561 // If a bundled plugin is enabled, we should open pdf/swf files in a tab.
562 bool ShouldBeOpenedWithPlugin(
563 Profile* profile,
564 const base::FilePath::StringType& file_extension) {
565 const base::FilePath file_path =
566 base::FilePath::FromUTF8Unsafe("dummy").AddExtension(file_extension);
567 if (file_path.MatchesExtension(kPdfExtension))
568 return IsPdfPluginEnabled(profile);
569 if (file_path.MatchesExtension(kSwfExtension))
570 return IsFlashPluginEnabled(profile);
571 return false;
572 }
573
574 std::string GetMimeTypeForPath(const base::FilePath& file_path) { 375 std::string GetMimeTypeForPath(const base::FilePath& file_path) {
575 const base::FilePath::StringType file_extension = 376 const base::FilePath::StringType file_extension =
576 StringToLowerASCII(file_path.Extension()); 377 StringToLowerASCII(file_path.Extension());
577 378
578 // TODO(thorogood): Rearchitect this call so it can run on the File thread; 379 // TODO(thorogood): Rearchitect this call so it can run on the File thread;
579 // GetMimeTypeFromFile requires this on Linux. Right now, we use 380 // GetMimeTypeFromFile requires this on Linux. Right now, we use
580 // Chrome-level knowledge only. 381 // Chrome-level knowledge only.
581 std::string mime_type; 382 std::string mime_type;
582 if (file_extension.empty() || 383 if (file_extension.empty() ||
583 !net::GetWellKnownMimeTypeFromExtension(file_extension.substr(1), 384 !net::GetWellKnownMimeTypeFromExtension(file_extension.substr(1),
584 &mime_type)) { 385 &mime_type)) {
585 // If the file doesn't have an extension or its mime-type cannot be 386 // If the file doesn't have an extension or its mime-type cannot be
586 // determined, then indicate that it has the empty mime-type. This will 387 // determined, then indicate that it has the empty mime-type. This will
587 // only be matched if the Web Intents accepts "*" or "*/*". 388 // only be matched if the Web Intents accepts "*" or "*/*".
588 return ""; 389 return "";
589 } else { 390 } else {
590 return mime_type; 391 return mime_type;
591 } 392 }
592 } 393 }
593 394
594 } // namespace util 395 } // namespace util
595 } // namespace file_manager 396 } // namespace file_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698