| 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 | 4 |
| 5 #include "chrome/browser/chromeos/extensions/file_browser_private_api.h" | 5 #include "chrome/browser/chromeos/extensions/file_browser_private_api.h" |
| 6 | 6 |
| 7 #include <sys/statvfs.h> | 7 #include <sys/statvfs.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/file_path.h" |
| 13 #include "base/file_util.h" |
| 14 #include "base/i18n/case_conversion.h" |
| 12 #include "base/json/json_writer.h" | 15 #include "base/json/json_writer.h" |
| 13 #include "base/logging.h" | 16 #include "base/logging.h" |
| 14 #include "base/memory/scoped_vector.h" | 17 #include "base/memory/scoped_vector.h" |
| 15 #include "base/memory/singleton.h" | 18 #include "base/memory/singleton.h" |
| 16 #include "base/string_split.h" | 19 #include "base/string_split.h" |
| 17 #include "base/stringprintf.h" | 20 #include "base/stringprintf.h" |
| 18 #include "base/time.h" | 21 #include "base/time.h" |
| 19 #include "base/values.h" | 22 #include "base/values.h" |
| 23 #include "base/utf_string_conversions.h" |
| 20 #include "chrome/browser/chromeos/cros/cros_library.h" | 24 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 21 #include "chrome/browser/chromeos/cros/network_library.h" | 25 #include "chrome/browser/chromeos/cros/network_library.h" |
| 22 #include "chrome/browser/chromeos/extensions/file_handler_util.h" | 26 #include "chrome/browser/chromeos/extensions/file_handler_util.h" |
| 23 #include "chrome/browser/chromeos/extensions/file_manager_util.h" | 27 #include "chrome/browser/chromeos/extensions/file_manager_util.h" |
| 24 #include "chrome/browser/chromeos/gdata/drive.pb.h" | 28 #include "chrome/browser/chromeos/gdata/drive.pb.h" |
| 25 #include "chrome/browser/chromeos/gdata/drive_file_system_util.h" | 29 #include "chrome/browser/chromeos/gdata/drive_file_system_util.h" |
| 26 #include "chrome/browser/chromeos/gdata/drive_service_interface.h" | 30 #include "chrome/browser/chromeos/gdata/drive_service_interface.h" |
| 27 #include "chrome/browser/chromeos/gdata/drive_system_service.h" | 31 #include "chrome/browser/chromeos/gdata/drive_system_service.h" |
| 28 #include "chrome/browser/chromeos/gdata/drive_webapps_registry.h" | 32 #include "chrome/browser/chromeos/gdata/drive_webapps_registry.h" |
| 29 #include "chrome/browser/chromeos/gdata/gdata_util.h" | 33 #include "chrome/browser/chromeos/gdata/gdata_util.h" |
| 30 #include "chrome/browser/chromeos/gdata/gdata_wapi_parser.h" | 34 #include "chrome/browser/chromeos/gdata/gdata_wapi_parser.h" |
| 31 #include "chrome/browser/chromeos/gdata/operation_registry.h" | 35 #include "chrome/browser/chromeos/gdata/operation_registry.h" |
| 32 #include "chrome/browser/chromeos/system/statistics_provider.h" | 36 #include "chrome/browser/chromeos/system/statistics_provider.h" |
| 33 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 37 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| 34 #include "chrome/browser/extensions/extension_process_manager.h" | 38 #include "chrome/browser/extensions/extension_process_manager.h" |
| 35 #include "chrome/browser/extensions/extension_service.h" | 39 #include "chrome/browser/extensions/extension_service.h" |
| 36 #include "chrome/browser/extensions/extension_tab_util.h" | 40 #include "chrome/browser/extensions/extension_tab_util.h" |
| 37 #include "chrome/browser/extensions/process_map.h" | 41 #include "chrome/browser/extensions/process_map.h" |
| 42 #include "chrome/browser/intents/web_intents_util.h" |
| 38 #include "chrome/browser/profiles/profile.h" | 43 #include "chrome/browser/profiles/profile.h" |
| 39 #include "chrome/browser/ui/browser.h" | 44 #include "chrome/browser/ui/browser.h" |
| 40 #include "chrome/browser/ui/browser_window.h" | 45 #include "chrome/browser/ui/browser_window.h" |
| 41 #include "chrome/browser/ui/views/select_file_dialog_extension.h" | 46 #include "chrome/browser/ui/views/select_file_dialog_extension.h" |
| 42 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" | 47 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" |
| 43 #include "chrome/common/chrome_version_info.h" | 48 #include "chrome/common/chrome_version_info.h" |
| 44 #include "chrome/common/extensions/extension.h" | 49 #include "chrome/common/extensions/extension.h" |
| 45 #include "chrome/common/extensions/extension_constants.h" | 50 #include "chrome/common/extensions/extension_constants.h" |
| 46 #include "chrome/common/extensions/extension_icon_set.h" | 51 #include "chrome/common/extensions/extension_icon_set.h" |
| 47 #include "chrome/common/extensions/file_browser_handler.h" | 52 #include "chrome/common/extensions/file_browser_handler.h" |
| 48 #include "chrome/common/pref_names.h" | 53 #include "chrome/common/pref_names.h" |
| 49 #include "chromeos/disks/disk_mount_manager.h" | 54 #include "chromeos/disks/disk_mount_manager.h" |
| 50 #include "content/public/browser/child_process_security_policy.h" | 55 #include "content/public/browser/child_process_security_policy.h" |
| 51 #include "content/public/browser/render_process_host.h" | 56 #include "content/public/browser/render_process_host.h" |
| 52 #include "content/public/browser/render_view_host.h" | 57 #include "content/public/browser/render_view_host.h" |
| 53 #include "googleurl/src/gurl.h" | 58 #include "googleurl/src/gurl.h" |
| 54 #include "grit/generated_resources.h" | 59 #include "grit/generated_resources.h" |
| 55 #include "grit/platform_locale_settings.h" | 60 #include "grit/platform_locale_settings.h" |
| 56 #include "net/base/escape.h" | 61 #include "net/base/escape.h" |
| 62 #include "net/base/mime_util.h" |
| 57 #include "ui/base/dialogs/selected_file_info.h" | 63 #include "ui/base/dialogs/selected_file_info.h" |
| 58 #include "ui/base/l10n/l10n_util.h" | 64 #include "ui/base/l10n/l10n_util.h" |
| 59 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h" | 65 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h" |
| 60 #include "webkit/fileapi/file_system_context.h" | 66 #include "webkit/fileapi/file_system_context.h" |
| 61 #include "webkit/fileapi/file_system_file_util.h" | 67 #include "webkit/fileapi/file_system_file_util.h" |
| 62 #include "webkit/fileapi/file_system_operation_context.h" | 68 #include "webkit/fileapi/file_system_operation_context.h" |
| 63 #include "webkit/fileapi/file_system_types.h" | 69 #include "webkit/fileapi/file_system_types.h" |
| 64 #include "webkit/fileapi/file_system_url.h" | 70 #include "webkit/fileapi/file_system_url.h" |
| 65 #include "webkit/fileapi/file_system_util.h" | 71 #include "webkit/fileapi/file_system_util.h" |
| 72 #include "webkit/glue/web_intent_service_data.h" |
| 66 | 73 |
| 67 using chromeos::disks::DiskMountManager; | 74 using chromeos::disks::DiskMountManager; |
| 68 using content::BrowserContext; | 75 using content::BrowserContext; |
| 69 using content::BrowserThread; | 76 using content::BrowserThread; |
| 70 using content::ChildProcessSecurityPolicy; | 77 using content::ChildProcessSecurityPolicy; |
| 71 using content::SiteInstance; | 78 using content::SiteInstance; |
| 72 using content::WebContents; | 79 using content::WebContents; |
| 73 using extensions::Extension; | 80 using extensions::Extension; |
| 74 using file_handler_util::FileTaskExecutor; | 81 using file_handler_util::FileTaskExecutor; |
| 75 using gdata::InstalledApp; | 82 using gdata::InstalledApp; |
| 76 using gdata::OperationRegistry; | 83 using gdata::OperationRegistry; |
| 77 | 84 |
| 78 namespace { | 85 namespace { |
| 79 | 86 |
| 80 // Default icon path for drive docs. | 87 // Default icon path for drive docs. |
| 81 const char kDefaultDriveIcon[] = "images/filetype_generic.png"; | 88 const char kDefaultIcon[] = "images/filetype_generic.png"; |
| 82 const int kPreferredIconSize = 16; | 89 const int kPreferredIconSize = 16; |
| 83 | 90 |
| 84 // Error messages. | 91 // Error messages. |
| 85 const char kFileError[] = "File error %d"; | 92 const char kFileError[] = "File error %d"; |
| 86 const char kInvalidFileUrl[] = "Invalid file URL"; | 93 const char kInvalidFileUrl[] = "Invalid file URL"; |
| 87 const char kVolumeDevicePathNotFound[] = "Device path not found"; | 94 const char kVolumeDevicePathNotFound[] = "Device path not found"; |
| 88 | 95 |
| 89 // Unescape rules used for parsing query parameters. | 96 // Unescape rules used for parsing query parameters. |
| 90 const net::UnescapeRule::Type kUnescapeRuleForQueryParameters = | 97 const net::UnescapeRule::Type kUnescapeRuleForQueryParameters = |
| 91 net::UnescapeRule::SPACES | | 98 net::UnescapeRule::SPACES | |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 if (icons.empty()) | 235 if (icons.empty()) |
| 229 return result; | 236 return result; |
| 230 result = icons.rbegin()->second; | 237 result = icons.rbegin()->second; |
| 231 for (InstalledApp::IconList::const_reverse_iterator iter = icons.rbegin(); | 238 for (InstalledApp::IconList::const_reverse_iterator iter = icons.rbegin(); |
| 232 iter != icons.rend() && iter->first >= preferred_size; ++iter) { | 239 iter != icons.rend() && iter->first >= preferred_size; ++iter) { |
| 233 result = iter->second; | 240 result = iter->second; |
| 234 } | 241 } |
| 235 return result; | 242 return result; |
| 236 } | 243 } |
| 237 | 244 |
| 245 // Given an extension, a Web Intents |action|, and a set of |mime_types|, |
| 246 // determines whether this extension supports this action for all specified |
| 247 // mime-types. |
| 248 // If this method returns true, also returns the |title| of this action. |
| 249 bool ExtensionSupportsAction(const Extension* extension, |
| 250 const std::string& action, |
| 251 const std::set<std::string>& mime_types, |
| 252 std::string* title) { |
| 253 DCHECK(!mime_types.empty()); |
| 254 std::set<std::string> pending(mime_types.begin(), mime_types.end()); |
| 255 std::string found_title; |
| 256 |
| 257 for (std::vector<webkit_glue::WebIntentServiceData>::const_iterator i = |
| 258 extension->intents_services().begin(); |
| 259 i != extension->intents_services().end(); ++i) { |
| 260 if (pending.empty()) |
| 261 break; |
| 262 |
| 263 if (UTF16ToUTF8(i->action) != action) |
| 264 continue; |
| 265 |
| 266 std::set<std::string>::iterator pi = pending.begin(); |
| 267 while (pi != pending.end()) { |
| 268 if (net::MatchesMimeType(UTF16ToUTF8(i->type), *pi)) |
| 269 pending.erase(pi++); |
| 270 else |
| 271 ++pi; |
| 272 } |
| 273 if (found_title.empty()) |
| 274 found_title = UTF16ToUTF8(i->title); |
| 275 } |
| 276 |
| 277 if (!pending.empty()) |
| 278 return false; // we haven't found all mime-types |
| 279 |
| 280 *title = found_title; |
| 281 return true; |
| 282 } |
| 283 |
| 238 // Retrieves total and remaining available size on |mount_path|. | 284 // Retrieves total and remaining available size on |mount_path|. |
| 239 void GetSizeStatsOnFileThread(const std::string& mount_path, | 285 void GetSizeStatsOnFileThread(const std::string& mount_path, |
| 240 size_t* total_size_kb, | 286 size_t* total_size_kb, |
| 241 size_t* remaining_size_kb) { | 287 size_t* remaining_size_kb) { |
| 242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 243 | 289 |
| 244 uint64_t total_size_in_bytes = 0; | 290 uint64_t total_size_in_bytes = 0; |
| 245 uint64_t remaining_size_in_bytes = 0; | 291 uint64_t remaining_size_in_bytes = 0; |
| 246 | 292 |
| 247 struct statvfs stat = {}; // Zero-clear | 293 struct statvfs stat = {}; // Zero-clear |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 file_iter->mime_type, &info); | 640 file_iter->mime_type, &info); |
| 595 std::vector<gdata::DriveWebAppInfo*> info_ptrs; | 641 std::vector<gdata::DriveWebAppInfo*> info_ptrs; |
| 596 info.release(&info_ptrs); // so they don't go away prematurely. | 642 info.release(&info_ptrs); // so they don't go away prematurely. |
| 597 std::set<std::string> tasks_for_this_file; | 643 std::set<std::string> tasks_for_this_file; |
| 598 for (std::vector<gdata::DriveWebAppInfo*>::iterator | 644 for (std::vector<gdata::DriveWebAppInfo*>::iterator |
| 599 apps = info_ptrs.begin(); apps != info_ptrs.end(); ++apps) { | 645 apps = info_ptrs.begin(); apps != info_ptrs.end(); ++apps) { |
| 600 std::pair<WebAppInfoMap::iterator, bool> insert_result = | 646 std::pair<WebAppInfoMap::iterator, bool> insert_result = |
| 601 app_info->insert(std::make_pair((*apps)->app_id, *apps)); | 647 app_info->insert(std::make_pair((*apps)->app_id, *apps)); |
| 602 // TODO(gspencer): For now, the action id is always "open-with", but we | 648 // TODO(gspencer): For now, the action id is always "open-with", but we |
| 603 // could add any actions that the drive app supports. | 649 // could add any actions that the drive app supports. |
| 604 std::string task_id = | 650 std::string task_id = file_handler_util::MakeTaskID( |
| 605 file_handler_util::MakeDriveTaskID((*apps)->app_id, "open-with"); | 651 (*apps)->app_id, file_handler_util::TASK_DRIVE, "open-with"); |
| 606 tasks_for_this_file.insert(task_id); | 652 tasks_for_this_file.insert(task_id); |
| 607 // If we failed to insert a task_id because there was a duplicate, then we | 653 // If we failed to insert a task_id because there was a duplicate, then we |
| 608 // must delete it (since we own it). | 654 // must delete it (since we own it). |
| 609 if (!insert_result.second) | 655 if (!insert_result.second) |
| 610 delete *apps; | 656 delete *apps; |
| 611 } | 657 } |
| 612 if (file_iter == file_info_list.begin()) { | 658 if (file_iter == file_info_list.begin()) { |
| 613 *available_tasks = tasks_for_this_file; | 659 *available_tasks = tasks_for_this_file; |
| 614 } else { | 660 } else { |
| 615 std::set<std::string> intersection; | 661 std::set<std::string> intersection; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 const std::set<std::string>& available_tasks, | 694 const std::set<std::string>& available_tasks, |
| 649 const std::set<std::string>& default_tasks, | 695 const std::set<std::string>& default_tasks, |
| 650 ListValue* result_list, | 696 ListValue* result_list, |
| 651 bool* default_already_set) { | 697 bool* default_already_set) { |
| 652 *default_already_set = false; | 698 *default_already_set = false; |
| 653 // OK, now we traverse the intersection of available applications for this | 699 // OK, now we traverse the intersection of available applications for this |
| 654 // list of files, adding a task for each one that is found. | 700 // list of files, adding a task for each one that is found. |
| 655 for (std::set<std::string>::const_iterator app_iter = available_tasks.begin(); | 701 for (std::set<std::string>::const_iterator app_iter = available_tasks.begin(); |
| 656 app_iter != available_tasks.end(); ++app_iter) { | 702 app_iter != available_tasks.end(); ++app_iter) { |
| 657 std::string app_id; | 703 std::string app_id; |
| 658 bool result = file_handler_util::CrackDriveTaskID(*app_iter, &app_id, NULL); | 704 file_handler_util::TaskType task_type; |
| 705 bool result = file_handler_util::CrackTaskID( |
| 706 *app_iter, &app_id, &task_type, NULL); |
| 659 DCHECK(result) << "Unable to parse Drive task id: " << *app_iter; | 707 DCHECK(result) << "Unable to parse Drive task id: " << *app_iter; |
| 660 if (!result) | 708 DCHECK_EQ(task_type, file_handler_util::TASK_DRIVE) |
| 709 << "Expected Drive task type"; |
| 710 if (!result || task_type != file_handler_util::TASK_DRIVE) |
| 661 continue; | 711 continue; |
| 662 WebAppInfoMap::const_iterator info_iter = app_info.find(app_id); | 712 WebAppInfoMap::const_iterator info_iter = app_info.find(app_id); |
| 663 DCHECK(info_iter != app_info.end()); | 713 DCHECK(info_iter != app_info.end()); |
| 664 gdata::DriveWebAppInfo* info = info_iter->second; | 714 gdata::DriveWebAppInfo* info = info_iter->second; |
| 665 DictionaryValue* task = new DictionaryValue; | 715 DictionaryValue* task = new DictionaryValue; |
| 666 | 716 |
| 667 task->SetString("taskId", *app_iter); | 717 task->SetString("taskId", *app_iter); |
| 668 task->SetString("title", info->app_name); | 718 task->SetString("title", info->app_name); |
| 669 | 719 |
| 670 GURL best_icon = FindPreferredIcon(info->app_icons, | 720 GURL best_icon = FindPreferredIcon(info->app_icons, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 699 return true; | 749 return true; |
| 700 | 750 |
| 701 gdata::DriveSystemService* system_service = | 751 gdata::DriveSystemService* system_service = |
| 702 gdata::DriveSystemServiceFactory::GetForProfile(profile_); | 752 gdata::DriveSystemServiceFactory::GetForProfile(profile_); |
| 703 // |system_service| is NULL if incognito window / guest login. We return true | 753 // |system_service| is NULL if incognito window / guest login. We return true |
| 704 // in this case because there might be other extension tasks, even if we don't | 754 // in this case because there might be other extension tasks, even if we don't |
| 705 // have any to add. | 755 // have any to add. |
| 706 if (!system_service || !system_service->webapps_registry()) | 756 if (!system_service || !system_service->webapps_registry()) |
| 707 return true; | 757 return true; |
| 708 | 758 |
| 709 | |
| 710 gdata::DriveWebAppsRegistry* registry = system_service->webapps_registry(); | 759 gdata::DriveWebAppsRegistry* registry = system_service->webapps_registry(); |
| 711 | 760 |
| 712 // Map of app_id to DriveWebAppInfo so we can look up the apps we've found | 761 // Map of app_id to DriveWebAppInfo so we can look up the apps we've found |
| 713 // after taking the intersection of available apps. | 762 // after taking the intersection of available apps. |
| 714 std::map<std::string, gdata::DriveWebAppInfo*> app_info; | 763 std::map<std::string, gdata::DriveWebAppInfo*> app_info; |
| 715 // Set of application IDs. This will end up with the intersection of the | 764 // Set of application IDs. This will end up with the intersection of the |
| 716 // application IDs that apply to the paths in |file_paths|. | 765 // application IDs that apply to the paths in |file_paths|. |
| 717 std::set<std::string> available_tasks; | 766 std::set<std::string> available_tasks; |
| 718 | 767 |
| 719 IntersectAvailableDriveTasks(registry, file_info_list, | 768 IntersectAvailableDriveTasks(registry, file_info_list, |
| 720 &app_info, &available_tasks); | 769 &app_info, &available_tasks); |
| 721 std::set<std::string> default_tasks; | 770 std::set<std::string> default_tasks; |
| 722 FindDefaultDriveTasks(file_info_list, available_tasks, &default_tasks); | 771 FindDefaultDriveTasks(file_info_list, available_tasks, &default_tasks); |
| 723 CreateDriveTasks(registry, app_info, available_tasks, default_tasks, | 772 CreateDriveTasks(registry, app_info, available_tasks, default_tasks, |
| 724 result_list, default_already_set); | 773 result_list, default_already_set); |
| 725 | 774 |
| 726 // We own the pointers in |app_info|, so we need to delete them. | 775 // We own the pointers in |app_info|, so we need to delete them. |
| 727 STLDeleteContainerPairSecondPointers(app_info.begin(), app_info.end()); | 776 STLDeleteContainerPairSecondPointers(app_info.begin(), app_info.end()); |
| 728 return true; | 777 return true; |
| 729 } | 778 } |
| 730 | 779 |
| 780 // Find Web Intent platform apps that support the View task, and add them to |
| 781 // the |result_list|. These will be marked as TASK_WEBINTENT. |
| 782 bool GetFileTasksFileBrowserFunction::FindWebIntentTasks( |
| 783 const std::vector<GURL>& file_urls, |
| 784 ListValue* result_list) { |
| 785 DCHECK(!file_urls.empty()); |
| 786 ExtensionService* service = profile_->GetExtensionService(); |
| 787 if (!service) |
| 788 return false; |
| 789 |
| 790 std::set<std::string> mime_types; |
| 791 for (std::vector<GURL>::const_iterator iter = file_urls.begin(); |
| 792 iter != file_urls.end(); ++iter) { |
| 793 const FilePath file = FilePath(GURL(iter->spec()).ExtractFileName()); |
| 794 const FilePath::StringType file_extension = |
| 795 StringToLowerASCII(file.Extension()); |
| 796 |
| 797 // TODO(thorogood): Rearchitect this call so it can run on the File thread; |
| 798 // GetMimeTypeFromFile requires this on Linux. Right now, we use |
| 799 // Chrome-level knowledge only. |
| 800 std::string mime_type; |
| 801 if (!file_extension.empty() && !net::GetWellKnownMimeTypeFromExtension( |
| 802 file_extension.substr(1), &mime_type)) |
| 803 mime_type = std::string(); // There was no mime-type available from this |
| 804 // file, but we'll still match "*". |
| 805 mime_types.insert(mime_type); |
| 806 } |
| 807 |
| 808 for (ExtensionSet::const_iterator iter = service->extensions()->begin(); |
| 809 iter != service->extensions()->end(); |
| 810 ++iter) { |
| 811 const Extension* extension = *iter; |
| 812 std::string title; |
| 813 |
| 814 // We don't support using hosted apps to open files. |
| 815 if (!extension->is_platform_app()) |
| 816 continue; |
| 817 |
| 818 if (profile_->IsOffTheRecord() && |
| 819 !service->IsIncognitoEnabled(extension->id())) |
| 820 continue; |
| 821 |
| 822 if (!ExtensionSupportsAction( |
| 823 extension, web_intents::kActionView, mime_types, &title)) |
| 824 continue; |
| 825 |
| 826 DictionaryValue* task = new DictionaryValue; |
| 827 std::string task_id = file_handler_util::MakeTaskID(extension->id(), |
| 828 file_handler_util::TASK_WEBINTENT, web_intents::kActionView); |
| 829 task->SetString("taskId", task_id); |
| 830 task->SetString("title", title); |
| 831 task->SetBoolean("isDefault", false); |
| 832 |
| 833 GURL best_icon = extension->GetIconURL(kPreferredIconSize, |
| 834 ExtensionIconSet::MATCH_BIGGER); |
| 835 if (!best_icon.is_empty()) |
| 836 task->SetString("iconUrl", best_icon.spec()); |
| 837 else |
| 838 task->SetString("iconUrl", kDefaultIcon); |
| 839 |
| 840 task->SetBoolean("driveApp", false); |
| 841 result_list->Append(task); |
| 842 } |
| 843 |
| 844 return true; |
| 845 } |
| 846 |
| 731 bool GetFileTasksFileBrowserFunction::RunImpl() { | 847 bool GetFileTasksFileBrowserFunction::RunImpl() { |
| 732 // First argument is the list of files to get tasks for. | 848 // First argument is the list of files to get tasks for. |
| 733 ListValue* files_list = NULL; | 849 ListValue* files_list = NULL; |
| 734 if (!args_->GetList(0, &files_list)) | 850 if (!args_->GetList(0, &files_list)) |
| 735 return false; | 851 return false; |
| 736 | 852 |
| 737 // Second argument is the list of mime types of each of the files in the list. | 853 // Second argument is the list of mime types of each of the files in the list. |
| 738 ListValue* mime_types_list = NULL; | 854 ListValue* mime_types_list = NULL; |
| 739 if (!args_->GetList(1, &mime_types_list)) | 855 if (!args_->GetList(1, &mime_types_list)) |
| 740 return false; | 856 return false; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 790 ExtensionService* service = profile_->GetExtensionService(); | 906 ExtensionService* service = profile_->GetExtensionService(); |
| 791 for (std::set<const FileBrowserHandler*>::const_iterator iter = | 907 for (std::set<const FileBrowserHandler*>::const_iterator iter = |
| 792 common_tasks.begin(); | 908 common_tasks.begin(); |
| 793 iter != common_tasks.end(); | 909 iter != common_tasks.end(); |
| 794 ++iter) { | 910 ++iter) { |
| 795 const FileBrowserHandler* handler = *iter; | 911 const FileBrowserHandler* handler = *iter; |
| 796 const std::string extension_id = handler->extension_id(); | 912 const std::string extension_id = handler->extension_id(); |
| 797 const Extension* extension = service->GetExtensionById(extension_id, false); | 913 const Extension* extension = service->GetExtensionById(extension_id, false); |
| 798 CHECK(extension); | 914 CHECK(extension); |
| 799 DictionaryValue* task = new DictionaryValue; | 915 DictionaryValue* task = new DictionaryValue; |
| 800 task->SetString("taskId", | 916 task->SetString("taskId", file_handler_util::MakeTaskID( |
| 801 file_handler_util::MakeTaskID(extension_id, handler->id())); | 917 extension_id, file_handler_util::TASK_FILE, handler->id())); |
| 802 task->SetString("title", handler->title()); | 918 task->SetString("title", handler->title()); |
| 803 // TODO(zelidrag): Figure out how to expose icon URL that task defined in | 919 // TODO(zelidrag): Figure out how to expose icon URL that task defined in |
| 804 // manifest instead of the default extension icon. | 920 // manifest instead of the default extension icon. |
| 805 GURL icon = | 921 GURL icon = |
| 806 ExtensionIconSource::GetIconURL(extension, | 922 ExtensionIconSource::GetIconURL(extension, |
| 807 extension_misc::EXTENSION_ICON_BITTY, | 923 extension_misc::EXTENSION_ICON_BITTY, |
| 808 ExtensionIconSet::MATCH_BIGGER, | 924 ExtensionIconSet::MATCH_BIGGER, |
| 809 false, NULL); // grayscale | 925 false, NULL); // grayscale |
| 810 task->SetString("iconUrl", icon.spec()); | 926 task->SetString("iconUrl", icon.spec()); |
| 811 task->SetBoolean("driveApp", false); | 927 task->SetBoolean("driveApp", false); |
| 812 | 928 |
| 813 // Only set the default if there isn't already a default set. | 929 // Only set the default if there isn't already a default set. |
| 814 if (!default_already_set && | 930 if (!default_already_set && |
| 815 default_tasks.find(*iter) != default_tasks.end()) { | 931 default_tasks.find(*iter) != default_tasks.end()) { |
| 816 task->SetBoolean("isDefault", true); | 932 task->SetBoolean("isDefault", true); |
| 817 default_already_set = true; | 933 default_already_set = true; |
| 818 } else { | 934 } else { |
| 819 task->SetBoolean("isDefault", false); | 935 task->SetBoolean("isDefault", false); |
| 820 } | 936 } |
| 821 | 937 |
| 822 result_list->Append(task); | 938 result_list->Append(task); |
| 823 } | 939 } |
| 824 | 940 |
| 941 // Take the union of Web Intents (that platform apps may accept) and all |
| 942 // previous Drive and extension tasks. As above, we know there aren't |
| 943 // duplicates because they're entirely different kinds of tasks. |
| 944 if (!FindWebIntentTasks(file_urls, result_list)) |
| 945 return false; |
| 946 |
| 825 if (VLOG_IS_ON(1)) { | 947 if (VLOG_IS_ON(1)) { |
| 826 std::string result_json; | 948 std::string result_json; |
| 827 base::JSONWriter::WriteWithOptions( | 949 base::JSONWriter::WriteWithOptions( |
| 828 result_list, | 950 result_list, |
| 829 base::JSONWriter::OPTIONS_DO_NOT_ESCAPE | | 951 base::JSONWriter::OPTIONS_DO_NOT_ESCAPE | |
| 830 base::JSONWriter::OPTIONS_PRETTY_PRINT, | 952 base::JSONWriter::OPTIONS_PRETTY_PRINT, |
| 831 &result_json); | 953 &result_json); |
| 832 VLOG(1) << "GetFileTasks result:\n" << result_json; | 954 VLOG(1) << "GetFileTasks result:\n" << result_json; |
| 833 } | 955 } |
| 834 | 956 |
| 835 // TODO(zelidrag, serya): Add intent content tasks to result_list once we | |
| 836 // implement that API. | |
| 837 SendResponse(true); | 957 SendResponse(true); |
| 838 return true; | 958 return true; |
| 839 } | 959 } |
| 840 | 960 |
| 841 ExecuteTasksFileBrowserFunction::ExecuteTasksFileBrowserFunction() {} | 961 ExecuteTasksFileBrowserFunction::ExecuteTasksFileBrowserFunction() {} |
| 842 | 962 |
| 843 void ExecuteTasksFileBrowserFunction::OnTaskExecuted(bool success) { | 963 void ExecuteTasksFileBrowserFunction::OnTaskExecuted(bool success) { |
| 844 SendResponse(success); | 964 SendResponse(success); |
| 845 } | 965 } |
| 846 | 966 |
| 847 ExecuteTasksFileBrowserFunction::~ExecuteTasksFileBrowserFunction() {} | 967 ExecuteTasksFileBrowserFunction::~ExecuteTasksFileBrowserFunction() {} |
| 848 | 968 |
| 849 bool ExecuteTasksFileBrowserFunction::RunImpl() { | 969 bool ExecuteTasksFileBrowserFunction::RunImpl() { |
| 850 // First param is task id that was to the extension with getFileTasks call. | 970 // First param is task id that was to the extension with getFileTasks call. |
| 851 std::string task_id; | 971 std::string task_id; |
| 852 if (!args_->GetString(0, &task_id) || !task_id.size()) | 972 if (!args_->GetString(0, &task_id) || !task_id.size()) |
| 853 return false; | 973 return false; |
| 854 | 974 |
| 855 // TODO(kaznacheev): Crack the task_id here, store it in the Executor | 975 // TODO(kaznacheev): Crack the task_id here, store it in the Executor |
| 856 // and avoid passing it around. | 976 // and avoid passing it around. |
| 857 | 977 |
| 858 // The second param is the list of files that need to be executed with this | 978 // The second param is the list of files that need to be executed with this |
| 859 // task. | 979 // task. |
| 860 ListValue* files_list = NULL; | 980 ListValue* files_list = NULL; |
| 861 if (!args_->GetList(1, &files_list)) | 981 if (!args_->GetList(1, &files_list)) |
| 862 return false; | 982 return false; |
| 863 | 983 |
| 864 std::string extension_id; | 984 std::string extension_id; |
| 985 file_handler_util::TaskType task_type; |
| 865 std::string action_id; | 986 std::string action_id; |
| 866 if (!file_handler_util::CrackTaskID(task_id, &extension_id, &action_id)) { | 987 if (!file_handler_util::CrackTaskID( |
| 988 task_id, &extension_id, &task_type, &action_id)) { |
| 867 LOG(WARNING) << "Invalid task " << task_id; | 989 LOG(WARNING) << "Invalid task " << task_id; |
| 868 return false; | 990 return false; |
| 869 } | 991 } |
| 870 | 992 |
| 871 if (!files_list->GetSize()) | 993 if (!files_list->GetSize()) |
| 872 return true; | 994 return true; |
| 873 | 995 |
| 874 std::vector<GURL> file_urls; | 996 std::vector<GURL> file_urls; |
| 875 for (size_t i = 0; i < files_list->GetSize(); i++) { | 997 for (size_t i = 0; i < files_list->GetSize(); i++) { |
| 876 std::string origin_file_url; | 998 std::string origin_file_url; |
| 877 if (!files_list->GetString(i, &origin_file_url)) { | 999 if (!files_list->GetString(i, &origin_file_url)) { |
| 878 error_ = kInvalidFileUrl; | 1000 error_ = kInvalidFileUrl; |
| 879 return false; | 1001 return false; |
| 880 } | 1002 } |
| 881 file_urls.push_back(GURL(origin_file_url)); | 1003 file_urls.push_back(GURL(origin_file_url)); |
| 882 } | 1004 } |
| 883 | 1005 |
| 884 scoped_refptr<FileTaskExecutor> executor( | 1006 scoped_refptr<FileTaskExecutor> executor( |
| 885 FileTaskExecutor::Create(profile(), | 1007 FileTaskExecutor::Create(profile(), |
| 886 source_url(), | 1008 source_url(), |
| 887 extension_id, | 1009 extension_id, |
| 1010 task_type, |
| 888 action_id)); | 1011 action_id)); |
| 889 | 1012 |
| 890 if (!executor->ExecuteAndNotify( | 1013 if (!executor->ExecuteAndNotify( |
| 891 file_urls, | 1014 file_urls, |
| 892 base::Bind(&ExecuteTasksFileBrowserFunction::OnTaskExecuted, this))) | 1015 base::Bind(&ExecuteTasksFileBrowserFunction::OnTaskExecuted, this))) |
| 893 return false; | 1016 return false; |
| 894 | 1017 |
| 895 SetResult(new base::FundamentalValue(true)); | 1018 SetResult(new base::FundamentalValue(true)); |
| 896 return true; | 1019 return true; |
| 897 } | 1020 } |
| (...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1998 // Get drive WebApps that can accept this file. | 2121 // Get drive WebApps that can accept this file. |
| 1999 ScopedVector<gdata::DriveWebAppInfo> web_apps; | 2122 ScopedVector<gdata::DriveWebAppInfo> web_apps; |
| 2000 system_service->webapps_registry()->GetWebAppsForFile( | 2123 system_service->webapps_registry()->GetWebAppsForFile( |
| 2001 file_path, file_specific_info.content_mime_type(), &web_apps); | 2124 file_path, file_specific_info.content_mime_type(), &web_apps); |
| 2002 if (!web_apps.empty()) { | 2125 if (!web_apps.empty()) { |
| 2003 std::string default_task_id = file_handler_util::GetDefaultTaskIdFromPrefs( | 2126 std::string default_task_id = file_handler_util::GetDefaultTaskIdFromPrefs( |
| 2004 profile_, | 2127 profile_, |
| 2005 file_specific_info.content_mime_type(), | 2128 file_specific_info.content_mime_type(), |
| 2006 file_path.Extension()); | 2129 file_path.Extension()); |
| 2007 std::string default_app_id; | 2130 std::string default_app_id; |
| 2008 file_handler_util::CrackDriveTaskID(default_task_id, &default_app_id, NULL); | 2131 file_handler_util::CrackTaskID( |
| 2132 default_task_id, &default_app_id, NULL, NULL); |
| 2009 | 2133 |
| 2010 ListValue* apps = new ListValue(); | 2134 ListValue* apps = new ListValue(); |
| 2011 property_dict->Set("driveApps", apps); | 2135 property_dict->Set("driveApps", apps); |
| 2012 for (ScopedVector<gdata::DriveWebAppInfo>::const_iterator it = | 2136 for (ScopedVector<gdata::DriveWebAppInfo>::const_iterator it = |
| 2013 web_apps.begin(); | 2137 web_apps.begin(); |
| 2014 it != web_apps.end(); ++it) { | 2138 it != web_apps.end(); ++it) { |
| 2015 const gdata::DriveWebAppInfo* webapp_info = *it; | 2139 const gdata::DriveWebAppInfo* webapp_info = *it; |
| 2016 DictionaryValue* app = new DictionaryValue(); | 2140 DictionaryValue* app = new DictionaryValue(); |
| 2017 app->SetString("appId", webapp_info->app_id); | 2141 app->SetString("appId", webapp_info->app_id); |
| 2018 app->SetString("appName", webapp_info->app_name); | 2142 app->SetString("appName", webapp_info->app_name); |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2586 gdata::DriveSystemService* system_service = | 2710 gdata::DriveSystemService* system_service = |
| 2587 gdata::DriveSystemServiceFactory::GetForProfile(profile_); | 2711 gdata::DriveSystemServiceFactory::GetForProfile(profile_); |
| 2588 if (!system_service || !system_service->file_system()) | 2712 if (!system_service || !system_service->file_system()) |
| 2589 return false; | 2713 return false; |
| 2590 | 2714 |
| 2591 FilePath directory_path = GetVirtualPathFromURL(GURL(file_url_as_string)); | 2715 FilePath directory_path = GetVirtualPathFromURL(GURL(file_url_as_string)); |
| 2592 system_service->file_system()->RequestDirectoryRefresh(directory_path); | 2716 system_service->file_system()->RequestDirectoryRefresh(directory_path); |
| 2593 | 2717 |
| 2594 return true; | 2718 return true; |
| 2595 } | 2719 } |
| OLD | NEW |