OLD | NEW |
---|---|
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 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h" | 4 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h" |
5 | 5 |
6 #include "ash/shell.h" | 6 #include "ash/shell.h" |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/json/json_file_value_serializer.h" | 10 #include "base/json/json_file_value_serializer.h" |
11 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
17 #include "base/values.h" | 17 #include "base/values.h" |
18 #include "chrome/browser/chromeos/drive/drive.pb.h" | 18 #include "chrome/browser/chromeos/drive/drive.pb.h" |
19 #include "chrome/browser/chromeos/drive/drive_system_service.h" | 19 #include "chrome/browser/chromeos/drive/drive_system_service.h" |
20 #include "chrome/browser/chromeos/drive/file_system.h" | 20 #include "chrome/browser/chromeos/drive/file_system.h" |
21 #include "chrome/browser/chromeos/drive/file_system_util.h" | 21 #include "chrome/browser/chromeos/drive/file_system_util.h" |
22 #include "chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h " | 22 #include "chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h " |
23 #include "chrome/browser/chromeos/extensions/file_manager/file_handler_util.h" | 23 #include "chrome/browser/chromeos/extensions/file_manager/file_handler_util.h" |
24 #include "chrome/browser/chromeos/media/media_player.h" | 24 #include "chrome/browser/chromeos/media/media_player.h" |
25 #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/crx_installer.h" |
26 #include "chrome/browser/extensions/extension_install_prompt.h" | 27 #include "chrome/browser/extensions/extension_install_prompt.h" |
27 #include "chrome/browser/extensions/extension_service.h" | 28 #include "chrome/browser/extensions/extension_service.h" |
28 #include "chrome/browser/extensions/extension_system.h" | 29 #include "chrome/browser/extensions/extension_system.h" |
29 #include "chrome/browser/google_apis/task_util.h" | 30 #include "chrome/browser/google_apis/task_util.h" |
30 #include "chrome/browser/plugins/plugin_prefs.h" | 31 #include "chrome/browser/plugins/plugin_prefs.h" |
31 #include "chrome/browser/profiles/profile.h" | 32 #include "chrome/browser/profiles/profile.h" |
32 #include "chrome/browser/profiles/profile_manager.h" | 33 #include "chrome/browser/profiles/profile_manager.h" |
33 #include "chrome/browser/ui/browser.h" | 34 #include "chrome/browser/ui/browser.h" |
34 #include "chrome/browser/ui/browser_finder.h" | 35 #include "chrome/browser/ui/browser_finder.h" |
35 #include "chrome/browser/ui/browser_iterator.h" | 36 #include "chrome/browser/ui/browser_iterator.h" |
36 #include "chrome/browser/ui/browser_tabstrip.h" | 37 #include "chrome/browser/ui/browser_tabstrip.h" |
37 #include "chrome/browser/ui/browser_window.h" | 38 #include "chrome/browser/ui/browser_window.h" |
38 #include "chrome/browser/ui/extensions/application_launch.h" | 39 #include "chrome/browser/ui/extensions/application_launch.h" |
39 #include "chrome/browser/ui/host_desktop.h" | 40 #include "chrome/browser/ui/host_desktop.h" |
40 #include "chrome/browser/ui/simple_message_box.h" | 41 #include "chrome/browser/ui/simple_message_box.h" |
41 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 42 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
42 #include "chrome/common/chrome_paths.h" | 43 #include "chrome/common/chrome_paths.h" |
43 #include "chrome/common/chrome_switches.h" | 44 #include "chrome/common/chrome_switches.h" |
44 #include "chrome/common/url_constants.h" | 45 #include "chrome/common/url_constants.h" |
45 #include "content/public/browser/browser_thread.h" | 46 #include "content/public/browser/browser_thread.h" |
46 #include "content/public/browser/plugin_service.h" | 47 #include "content/public/browser/plugin_service.h" |
47 #include "content/public/browser/storage_partition.h" | 48 #include "content/public/browser/storage_partition.h" |
48 #include "content/public/browser/user_metrics.h" | 49 #include "content/public/browser/user_metrics.h" |
49 #include "content/public/browser/web_contents.h" | 50 #include "content/public/browser/web_contents.h" |
50 #include "content/public/common/pepper_plugin_info.h" | 51 #include "content/public/common/pepper_plugin_info.h" |
51 #include "grit/generated_resources.h" | 52 #include "grit/generated_resources.h" |
52 #include "net/base/escape.h" | 53 #include "net/base/escape.h" |
54 #include "net/base/mime_util.h" | |
53 #include "net/base/net_util.h" | 55 #include "net/base/net_util.h" |
54 #include "ui/base/l10n/l10n_util.h" | 56 #include "ui/base/l10n/l10n_util.h" |
55 #include "ui/gfx/screen.h" | 57 #include "ui/gfx/screen.h" |
56 #include "webkit/fileapi/file_system_context.h" | 58 #include "webkit/fileapi/file_system_context.h" |
57 #include "webkit/fileapi/file_system_mount_point_provider.h" | 59 #include "webkit/fileapi/file_system_mount_point_provider.h" |
58 #include "webkit/fileapi/file_system_operation.h" | 60 #include "webkit/fileapi/file_system_operation.h" |
59 #include "webkit/fileapi/file_system_url.h" | 61 #include "webkit/fileapi/file_system_url.h" |
60 #include "webkit/fileapi/file_system_util.h" | 62 #include "webkit/fileapi/file_system_util.h" |
61 #include "webkit/plugins/webplugininfo.h" | 63 #include "webkit/plugins/webplugininfo.h" |
62 | 64 |
63 using base::DictionaryValue; | 65 using base::DictionaryValue; |
64 using base::ListValue; | 66 using base::ListValue; |
65 using content::BrowserContext; | 67 using content::BrowserContext; |
66 using content::BrowserThread; | 68 using content::BrowserThread; |
67 using content::PluginService; | 69 using content::PluginService; |
68 using content::UserMetricsAction; | 70 using content::UserMetricsAction; |
71 using extensions::app_file_handler_util::FindFileHandlersForFiles; | |
72 using extensions::app_file_handler_util::PathAndMimeTypeSet; | |
69 using extensions::Extension; | 73 using extensions::Extension; |
70 using file_handler_util::FileTaskExecutor; | 74 using file_handler_util::FileTaskExecutor; |
71 using fileapi::FileSystemURL; | 75 using fileapi::FileSystemURL; |
72 | 76 |
73 #define FILEBROWSER_EXTENSON_ID "hhaomjibdihmijegdhdafkllkbggdgoj" | 77 #define FILEBROWSER_EXTENSON_ID "hhaomjibdihmijegdhdafkllkbggdgoj" |
74 const char kFileBrowserDomain[] = FILEBROWSER_EXTENSON_ID; | 78 const char kFileBrowserDomain[] = FILEBROWSER_EXTENSON_ID; |
75 | 79 |
76 const char kFileBrowserGalleryTaskId[] = "gallery"; | 80 const char kFileBrowserGalleryTaskId[] = "gallery"; |
77 const char kFileBrowserMountArchiveTaskId[] = "mount-archive"; | 81 const char kFileBrowserMountArchiveTaskId[] = "mount-archive"; |
78 const char kFileBrowserWatchTaskId[] = "watch"; | 82 const char kFileBrowserWatchTaskId[] = "watch"; |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 if (!external_provider) | 333 if (!external_provider) |
330 return false; | 334 return false; |
331 external_provider->GrantFullAccessToExtension(GetFileBrowserUrl().host()); | 335 external_provider->GrantFullAccessToExtension(GetFileBrowserUrl().host()); |
332 return true; | 336 return true; |
333 } | 337 } |
334 | 338 |
335 // Executes handler specifed with |extension_id| and |action_id| for |url|. | 339 // Executes handler specifed with |extension_id| and |action_id| for |url|. |
336 void ExecuteHandler(Profile* profile, | 340 void ExecuteHandler(Profile* profile, |
337 std::string extension_id, | 341 std::string extension_id, |
338 std::string action_id, | 342 std::string action_id, |
339 const GURL& url) { | 343 const GURL& url, |
344 const std::string& task_type) { | |
340 // If File Browser has not been open yet then it did not request access | 345 // If File Browser has not been open yet then it did not request access |
341 // to the file system. Do it now. | 346 // to the file system. Do it now. |
342 if (!GrantFileSystemAccessToFileBrowser(profile)) | 347 if (!GrantFileSystemAccessToFileBrowser(profile)) |
343 return; | 348 return; |
344 | 349 |
345 GURL site = extensions::ExtensionSystem::Get(profile)->extension_service()-> | 350 GURL site = extensions::ExtensionSystem::Get(profile)->extension_service()-> |
346 GetSiteForExtensionId(kFileBrowserDomain); | 351 GetSiteForExtensionId(kFileBrowserDomain); |
347 fileapi::FileSystemContext* file_system_context = | 352 fileapi::FileSystemContext* file_system_context = |
348 BrowserContext::GetStoragePartitionForSite(profile, site)-> | 353 BrowserContext::GetStoragePartitionForSite(profile, site)-> |
349 GetFileSystemContext(); | 354 GetFileSystemContext(); |
350 | 355 |
351 // We are executing the task on behalf of File Browser extension. | 356 // We are executing the task on behalf of File Browser extension. |
352 const GURL source_url = GetFileBrowserUrl(); | 357 const GURL source_url = GetFileBrowserUrl(); |
353 std::vector<FileSystemURL> urls; | 358 std::vector<FileSystemURL> urls; |
354 urls.push_back(file_system_context->CrackURL(url)); | 359 urls.push_back(file_system_context->CrackURL(url)); |
355 scoped_refptr<FileTaskExecutor> executor = FileTaskExecutor::Create(profile, | 360 scoped_refptr<FileTaskExecutor> executor = FileTaskExecutor::Create(profile, |
356 source_url, kFileBrowserDomain, 0 /* no tab id */, extension_id, | 361 source_url, kFileBrowserDomain, 0 /* no tab id */, extension_id, |
357 file_handler_util::kTaskFile, action_id); | 362 task_type, action_id); |
358 executor->Execute(urls); | 363 executor->Execute(urls); |
359 } | 364 } |
360 | 365 |
361 void OpenFileBrowserImpl(const base::FilePath& path, | 366 void OpenFileBrowserImpl(const base::FilePath& path, |
362 TAB_REUSE_MODE mode, | 367 TAB_REUSE_MODE mode, |
363 const std::string& action_id) { | 368 const std::string& action_id) { |
364 content::RecordAction(UserMetricsAction("ShowFileBrowserFullTab")); | 369 content::RecordAction(UserMetricsAction("ShowFileBrowserFullTab")); |
365 | 370 |
366 if (FileManageTabExists(path, mode)) | 371 if (FileManageTabExists(path, mode)) |
367 return; | 372 return; |
368 | 373 |
369 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); | 374 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); |
370 | 375 |
371 if (IsFileManagerPackaged() && !path.value().empty()) { | 376 if (IsFileManagerPackaged() && !path.value().empty()) { |
372 GURL url; | 377 GURL url; |
373 if (!ConvertFileToFileSystemUrl(profile, path, kFileBrowserDomain, &url)) | 378 if (!ConvertFileToFileSystemUrl(profile, path, kFileBrowserDomain, &url)) |
374 return; | 379 return; |
375 | 380 |
376 // Some values of |action_id| are not listed in the manifest and are used | 381 // Some values of |action_id| are not listed in the manifest and are used |
377 // to parametrize the behavior when opening the Files app window. | 382 // to parametrize the behavior when opening the Files app window. |
378 ExecuteHandler(profile, kFileBrowserDomain, action_id, url); | 383 ExecuteHandler(profile, kFileBrowserDomain, action_id, url, |
384 file_handler_util::kTaskFile); | |
379 return; | 385 return; |
380 } | 386 } |
381 | 387 |
382 std::string url = chrome::kChromeUIFileManagerURL; | 388 std::string url = chrome::kChromeUIFileManagerURL; |
383 if (action_id.size()) { | 389 if (action_id.size()) { |
384 DictionaryValue arg_value; | 390 DictionaryValue arg_value; |
385 arg_value.SetString("action", action_id); | 391 arg_value.SetString("action", action_id); |
386 std::string query; | 392 std::string query; |
387 base::JSONWriter::Write(&arg_value, &query); | 393 base::JSONWriter::Write(&arg_value, &query); |
388 url += "?" + | 394 url += "?" + |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 for (int idx = 0; idx < tab_strip->count(); idx++) { | 429 for (int idx = 0; idx < tab_strip->count(); idx++) { |
424 content::WebContents* web_contents = tab_strip->GetWebContentsAt(idx); | 430 content::WebContents* web_contents = tab_strip->GetWebContentsAt(idx); |
425 const GURL& url = web_contents->GetURL(); | 431 const GURL& url = web_contents->GetURL(); |
426 if (url == target_url) | 432 if (url == target_url) |
427 return browser; | 433 return browser; |
428 } | 434 } |
429 } | 435 } |
430 return NULL; | 436 return NULL; |
431 } | 437 } |
432 | 438 |
439 bool ExecuteDefaultAppHandler(Profile* profile, | |
440 const base::FilePath& path, | |
441 const GURL& url, | |
442 const std::string& mime_type, | |
443 const std::string& default_task_id) { | |
444 ExtensionService* service = profile->GetExtensionService(); | |
445 if (!service) | |
446 return false; | |
447 | |
448 PathAndMimeTypeSet files; | |
449 files.insert(std::make_pair(path, mime_type)); | |
450 const extensions::FileHandlerInfo* first_handler = NULL; | |
451 const extensions::Extension* extension_for_first_handler = NULL; | |
452 | |
453 for (ExtensionSet::const_iterator iter = service->extensions()->begin(); | |
Matt Giuca
2013/05/09 04:58:22
Explain the algorithm overall.
// If we find the
Sam McNally
2013/05/09 07:31:35
Done.
| |
454 iter != service->extensions()->end(); | |
455 ++iter) { | |
456 const Extension* extension = *iter; | |
457 | |
458 // We don't support using hosted apps to open files. | |
459 if (!extension->is_platform_app()) | |
460 continue; | |
461 | |
462 if (profile->IsOffTheRecord() && | |
Matt Giuca
2013/05/09 04:58:22
What does this mean? Can you add a comment?
Sam McNally
2013/05/09 07:31:35
Done.
Matt Giuca
2013/05/09 08:56:58
Can you put quotes around "incognito: split". It's
Sam McNally
2013/05/09 23:27:44
Done.
| |
463 !service->IsIncognitoEnabled(extension->id())) | |
464 continue; | |
465 | |
466 typedef std::vector<const extensions::FileHandlerInfo*> FileHandlerList; | |
467 FileHandlerList file_handlers = FindFileHandlersForFiles(*extension, files); | |
468 for (FileHandlerList::iterator i = file_handlers.begin(); | |
469 i != file_handlers.end(); ++i) { | |
470 const extensions::FileHandlerInfo* handler = *i; | |
471 std::string task_id = file_handler_util::MakeTaskID(extension->id(), | |
472 file_handler_util::kTaskApp, handler->id); | |
473 if (task_id == default_task_id) { | |
474 ExecuteHandler(profile, extension->id(), handler->id, url, | |
475 file_handler_util::kTaskApp); | |
476 return true; | |
477 | |
478 } else if (!first_handler) { | |
479 first_handler = handler; | |
480 extension_for_first_handler = extension; | |
481 } | |
482 } | |
483 } | |
484 if (first_handler) { | |
485 ExecuteHandler(profile, extension_for_first_handler->id(), | |
486 first_handler->id, url, file_handler_util::kTaskApp); | |
487 return true; | |
488 } | |
489 return false; | |
490 } | |
491 | |
433 bool ExecuteDefaultHandler(Profile* profile, const base::FilePath& path) { | 492 bool ExecuteDefaultHandler(Profile* profile, const base::FilePath& path) { |
434 GURL url; | 493 GURL url; |
435 if (!ConvertFileToFileSystemUrl(profile, path, kFileBrowserDomain, &url)) | 494 if (!ConvertFileToFileSystemUrl(profile, path, kFileBrowserDomain, &url)) |
436 return false; | 495 return false; |
437 | 496 |
497 std::string mime_type = GetMimeTypeForPath(path); | |
Matt Giuca
2013/05/09 04:58:22
Explain the approach you are taking in comments he
Sam McNally
2013/05/09 07:31:35
Done.
| |
498 std::string default_task_id = file_handler_util::GetDefaultTaskIdFromPrefs( | |
499 profile, mime_type, path.Extension()); | |
438 const FileBrowserHandler* handler; | 500 const FileBrowserHandler* handler; |
439 if (!file_handler_util::GetTaskForURLAndPath(profile, url, path, &handler)) | 501 if (!file_handler_util::GetTaskForURLAndPath(profile, url, path, &handler)) { |
Matt Giuca
2013/05/09 04:58:22
I think this could be clearer. It seems as though
Sam McNally
2013/05/09 07:31:35
Done.
| |
440 return false; | 502 return ExecuteDefaultAppHandler( |
503 profile, path, url, mime_type, default_task_id); | |
504 } | |
505 | |
506 std::string handler_task_id = file_handler_util::MakeTaskID( | |
507 handler->extension_id(), file_handler_util::kTaskFile, handler->id()); | |
508 if (handler_task_id != default_task_id && ExecuteDefaultAppHandler( | |
509 profile, path, url, mime_type, default_task_id)) { | |
510 return true; | |
511 } | |
441 | 512 |
442 std::string extension_id = handler->extension_id(); | 513 std::string extension_id = handler->extension_id(); |
443 std::string action_id = handler->id(); | 514 std::string action_id = handler->id(); |
444 Browser* browser = chrome::FindLastActiveWithProfile(profile, | 515 Browser* browser = chrome::FindLastActiveWithProfile(profile, |
445 chrome::HOST_DESKTOP_TYPE_ASH); | 516 chrome::HOST_DESKTOP_TYPE_ASH); |
446 | 517 |
447 // If there is no browsers for the profile, bail out. Return true so warning | 518 // If there is no browsers for the profile, bail out. Return true so warning |
448 // about file type not being supported is not displayed. | 519 // about file type not being supported is not displayed. |
449 if (!browser) | 520 if (!browser) |
450 return true; | 521 return true; |
451 | 522 |
452 if (extension_id == kFileBrowserDomain) { | 523 if (extension_id == kFileBrowserDomain) { |
453 if (IsFileManagerPackaged()) { | 524 if (IsFileManagerPackaged()) { |
454 if (action_id == kFileBrowserGalleryTaskId || | 525 if (action_id == kFileBrowserGalleryTaskId || |
455 action_id == kFileBrowserMountArchiveTaskId || | 526 action_id == kFileBrowserMountArchiveTaskId || |
456 action_id == kFileBrowserPlayTaskId || | 527 action_id == kFileBrowserPlayTaskId || |
457 action_id == kFileBrowserWatchTaskId) { | 528 action_id == kFileBrowserWatchTaskId) { |
458 ExecuteHandler(profile, extension_id, action_id, url); | 529 ExecuteHandler(profile, extension_id, action_id, url, |
530 file_handler_util::kTaskFile); | |
459 return true; | 531 return true; |
460 } | 532 } |
461 return ExecuteBuiltinHandler(browser, path, action_id); | 533 return ExecuteBuiltinHandler(browser, path, action_id); |
462 } | 534 } |
463 | 535 |
464 // Only two of the built-in File Browser tasks require opening the File | 536 // Only two of the built-in File Browser tasks require opening the File |
465 // Browser tab. | 537 // Browser tab. |
466 if (action_id == kFileBrowserGalleryTaskId || | 538 if (action_id == kFileBrowserGalleryTaskId || |
467 action_id == kFileBrowserMountArchiveTaskId) { | 539 action_id == kFileBrowserMountArchiveTaskId) { |
468 // Tab reuse currently does not work for these two tasks. | 540 // Tab reuse currently does not work for these two tasks. |
469 // |gallery| tries to put the file url into the tab url but it does not | 541 // |gallery| tries to put the file url into the tab url but it does not |
470 // work on Chrome OS. | 542 // work on Chrome OS. |
471 // |mount-archive| does not even try. | 543 // |mount-archive| does not even try. |
472 OpenFileBrowserImpl(path, REUSE_SAME_PATH, ""); | 544 OpenFileBrowserImpl(path, REUSE_SAME_PATH, ""); |
473 return true; | 545 return true; |
474 } | 546 } |
475 return ExecuteBuiltinHandler(browser, path, action_id); | 547 return ExecuteBuiltinHandler(browser, path, action_id); |
476 } | 548 } |
477 | 549 |
478 ExecuteHandler(profile, extension_id, action_id, url); | 550 ExecuteHandler(profile, extension_id, action_id, url, |
551 file_handler_util::kTaskFile); | |
479 return true; | 552 return true; |
480 } | 553 } |
481 | 554 |
482 // Reads JSON from a Google Docs file and extracts a document url. When the file | 555 // Reads JSON from a Google Docs file and extracts a document url. When the file |
483 // is not in GDoc format, returns a file URL for |file_path| as fallback. | 556 // is not in GDoc format, returns a file URL for |file_path| as fallback. |
484 GURL ReadUrlFromGDocOnBlockingPool(const base::FilePath& file_path) { | 557 GURL ReadUrlFromGDocOnBlockingPool(const base::FilePath& file_path) { |
485 const int64 kMaxGDocSize = 4096; | 558 const int64 kMaxGDocSize = 4096; |
486 int64 file_size = 0; | 559 int64 file_size = 0; |
487 if (!file_util::GetFileSize(file_path, &file_size) || | 560 if (!file_util::GetFileSize(file_path, &file_size) || |
488 file_size > kMaxGDocSize) { | 561 file_size > kMaxGDocSize) { |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
918 | 991 |
919 // If a bundled plugin is enabled, we should open pdf/swf files in a tab. | 992 // If a bundled plugin is enabled, we should open pdf/swf files in a tab. |
920 bool ShouldBeOpenedWithPlugin(Profile* profile, const char* file_extension) { | 993 bool ShouldBeOpenedWithPlugin(Profile* profile, const char* file_extension) { |
921 if (LowerCaseEqualsASCII(file_extension, kPdfExtension)) | 994 if (LowerCaseEqualsASCII(file_extension, kPdfExtension)) |
922 return IsPdfPluginEnabled(profile); | 995 return IsPdfPluginEnabled(profile); |
923 if (LowerCaseEqualsASCII(file_extension, kSwfExtension)) | 996 if (LowerCaseEqualsASCII(file_extension, kSwfExtension)) |
924 return IsFlashPluginEnabled(profile); | 997 return IsFlashPluginEnabled(profile); |
925 return false; | 998 return false; |
926 } | 999 } |
927 | 1000 |
1001 std::string GetMimeTypeForPath(const base::FilePath& file_path) { | |
1002 const base::FilePath::StringType file_extension = | |
1003 StringToLowerASCII(file_path.Extension()); | |
1004 | |
1005 // TODO(thorogood): Rearchitect this call so it can run on the File thread; | |
1006 // GetMimeTypeFromFile requires this on Linux. Right now, we use | |
1007 // Chrome-level knowledge only. | |
1008 std::string mime_type; | |
1009 if (file_extension.empty() || | |
1010 !net::GetWellKnownMimeTypeFromExtension(file_extension.substr(1), | |
1011 &mime_type)) { | |
1012 // If the file doesn't have an extension or its mime-type cannot be | |
1013 // determined, then indicate that it has the empty mime-type. This will | |
1014 // only be matched if the Web Intents accepts "*" or "*/*". | |
1015 return ""; | |
1016 } else { | |
1017 return mime_type; | |
1018 } | |
1019 } | |
1020 | |
928 } // namespace file_manager_util | 1021 } // namespace file_manager_util |
OLD | NEW |