| 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" |
| 22 #include "base/utf_string_conversions.h" |
| 19 #include "base/values.h" | 23 #include "base/values.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/system/statistics_provider.h" | 33 #include "chrome/browser/chromeos/system/statistics_provider.h" |
| 30 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 34 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| 31 #include "chrome/browser/extensions/extension_process_manager.h" | 35 #include "chrome/browser/extensions/extension_process_manager.h" |
| 32 #include "chrome/browser/extensions/extension_service.h" | 36 #include "chrome/browser/extensions/extension_service.h" |
| 33 #include "chrome/browser/extensions/extension_tab_util.h" | 37 #include "chrome/browser/extensions/extension_tab_util.h" |
| 34 #include "chrome/browser/extensions/process_map.h" | 38 #include "chrome/browser/extensions/process_map.h" |
| 39 #include "chrome/browser/google_apis/operation_registry.h" |
| 35 #include "chrome/browser/google_apis/gdata_util.h" | 40 #include "chrome/browser/google_apis/gdata_util.h" |
| 36 #include "chrome/browser/google_apis/gdata_wapi_parser.h" | 41 #include "chrome/browser/google_apis/gdata_wapi_parser.h" |
| 42 #include "chrome/browser/intents/web_intents_util.h" |
| 37 #include "chrome/browser/profiles/profile.h" | 43 #include "chrome/browser/profiles/profile.h" |
| 38 #include "chrome/browser/ui/browser.h" | 44 #include "chrome/browser/ui/browser.h" |
| 39 #include "chrome/browser/ui/browser_window.h" | 45 #include "chrome/browser/ui/browser_window.h" |
| 40 #include "chrome/browser/ui/views/select_file_dialog_extension.h" | 46 #include "chrome/browser/ui/views/select_file_dialog_extension.h" |
| 41 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" | 47 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" |
| 42 #include "chrome/common/extensions/extension.h" | 48 #include "chrome/common/extensions/extension.h" |
| 43 #include "chrome/common/extensions/extension_constants.h" | 49 #include "chrome/common/extensions/extension_constants.h" |
| 44 #include "chrome/common/extensions/extension_icon_set.h" | 50 #include "chrome/common/extensions/extension_icon_set.h" |
| 45 #include "chrome/common/extensions/file_browser_handler.h" | 51 #include "chrome/common/extensions/file_browser_handler.h" |
| 46 #include "chrome/common/pref_names.h" | 52 #include "chrome/common/pref_names.h" |
| 47 #include "chromeos/disks/disk_mount_manager.h" | 53 #include "chromeos/disks/disk_mount_manager.h" |
| 48 #include "content/public/browser/child_process_security_policy.h" | 54 #include "content/public/browser/child_process_security_policy.h" |
| 49 #include "content/public/browser/render_process_host.h" | 55 #include "content/public/browser/render_process_host.h" |
| 50 #include "content/public/browser/render_view_host.h" | 56 #include "content/public/browser/render_view_host.h" |
| 51 #include "content/public/browser/storage_partition.h" | 57 #include "content/public/browser/storage_partition.h" |
| 52 #include "googleurl/src/gurl.h" | 58 #include "googleurl/src/gurl.h" |
| 53 #include "grit/generated_resources.h" | 59 #include "grit/generated_resources.h" |
| 54 #include "grit/platform_locale_settings.h" | 60 #include "grit/platform_locale_settings.h" |
| 55 #include "net/base/escape.h" | 61 #include "net/base/escape.h" |
| 62 #include "net/base/mime_util.h" |
| 56 #include "ui/base/dialogs/selected_file_info.h" | 63 #include "ui/base/dialogs/selected_file_info.h" |
| 57 #include "ui/base/l10n/l10n_util.h" | 64 #include "ui/base/l10n/l10n_util.h" |
| 58 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h" | 65 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h" |
| 59 #include "webkit/fileapi/file_system_context.h" | 66 #include "webkit/fileapi/file_system_context.h" |
| 60 #include "webkit/fileapi/file_system_file_util.h" | 67 #include "webkit/fileapi/file_system_file_util.h" |
| 61 #include "webkit/fileapi/file_system_operation_context.h" | 68 #include "webkit/fileapi/file_system_operation_context.h" |
| 62 #include "webkit/fileapi/file_system_types.h" | 69 #include "webkit/fileapi/file_system_types.h" |
| 63 #include "webkit/fileapi/file_system_url.h" | 70 #include "webkit/fileapi/file_system_url.h" |
| 64 #include "webkit/fileapi/file_system_util.h" | 71 #include "webkit/fileapi/file_system_util.h" |
| 72 #include "webkit/glue/web_intent_service_data.h" |
| 65 | 73 |
| 66 using chromeos::disks::DiskMountManager; | 74 using chromeos::disks::DiskMountManager; |
| 67 using content::BrowserContext; | 75 using content::BrowserContext; |
| 68 using content::BrowserThread; | 76 using content::BrowserThread; |
| 69 using content::ChildProcessSecurityPolicy; | 77 using content::ChildProcessSecurityPolicy; |
| 70 using content::SiteInstance; | 78 using content::SiteInstance; |
| 71 using content::WebContents; | 79 using content::WebContents; |
| 72 using extensions::Extension; | 80 using extensions::Extension; |
| 73 using file_handler_util::FileTaskExecutor; | 81 using file_handler_util::FileTaskExecutor; |
| 74 using gdata::InstalledApp; | 82 using gdata::InstalledApp; |
| 75 | 83 |
| 76 namespace { | 84 namespace { |
| 77 | 85 |
| 78 // Default icon path for drive docs. | 86 // Default icon path for drive docs. |
| 79 const char kDefaultDriveIcon[] = "images/filetype_generic.png"; | 87 const char kDefaultIcon[] = "images/filetype_generic.png"; |
| 80 const int kPreferredIconSize = 16; | 88 const int kPreferredIconSize = 16; |
| 81 | 89 |
| 82 // Error messages. | 90 // Error messages. |
| 83 const char kFileError[] = "File error %d"; | 91 const char kFileError[] = "File error %d"; |
| 84 const char kInvalidFileUrl[] = "Invalid file URL"; | 92 const char kInvalidFileUrl[] = "Invalid file URL"; |
| 85 const char kVolumeDevicePathNotFound[] = "Device path not found"; | 93 const char kVolumeDevicePathNotFound[] = "Device path not found"; |
| 86 | 94 |
| 87 // Unescape rules used for parsing query parameters. | 95 // Unescape rules used for parsing query parameters. |
| 88 const net::UnescapeRule::Type kUnescapeRuleForQueryParameters = | 96 const net::UnescapeRule::Type kUnescapeRuleForQueryParameters = |
| 89 net::UnescapeRule::SPACES | | 97 net::UnescapeRule::SPACES | |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 if (icons.empty()) | 235 if (icons.empty()) |
| 228 return result; | 236 return result; |
| 229 result = icons.rbegin()->second; | 237 result = icons.rbegin()->second; |
| 230 for (InstalledApp::IconList::const_reverse_iterator iter = icons.rbegin(); | 238 for (InstalledApp::IconList::const_reverse_iterator iter = icons.rbegin(); |
| 231 iter != icons.rend() && iter->first >= preferred_size; ++iter) { | 239 iter != icons.rend() && iter->first >= preferred_size; ++iter) { |
| 232 result = iter->second; | 240 result = iter->second; |
| 233 } | 241 } |
| 234 return result; | 242 return result; |
| 235 } | 243 } |
| 236 | 244 |
| 245 // Finds the title of the given Web Intents |action|, if the passed extension |
| 246 // supports this action for all specified |mime_types|. Returns true and |
| 247 // provides the |title| as output on success. |
| 248 bool FindTitleForActionWithTypes( |
| 249 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 data = |
| 258 extension->intents_services().begin(); |
| 259 data != extension->intents_services().end(); ++data) { |
| 260 if (pending.empty()) |
| 261 break; |
| 262 |
| 263 if (UTF16ToUTF8(data->action) != action) |
| 264 continue; |
| 265 |
| 266 std::set<std::string>::iterator pending_iter = pending.begin(); |
| 267 while (pending_iter != pending.end()) { |
| 268 std::set<std::string>::iterator current = pending_iter++; |
| 269 if (net::MatchesMimeType(UTF16ToUTF8(data->type), *current)) |
| 270 pending.erase(current); |
| 271 } |
| 272 if (found_title.empty()) |
| 273 found_title = UTF16ToUTF8(data->title); |
| 274 } |
| 275 |
| 276 // Not all mime-types have been found. |
| 277 if (!pending.empty()) |
| 278 return false; |
| 279 |
| 280 *title = found_title; |
| 281 return true; |
| 282 } |
| 283 |
| 237 // Retrieves total and remaining available size on |mount_path|. | 284 // Retrieves total and remaining available size on |mount_path|. |
| 238 void GetSizeStatsOnFileThread(const std::string& mount_path, | 285 void GetSizeStatsOnFileThread(const std::string& mount_path, |
| 239 size_t* total_size_kb, | 286 size_t* total_size_kb, |
| 240 size_t* remaining_size_kb) { | 287 size_t* remaining_size_kb) { |
| 241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 242 | 289 |
| 243 uint64_t total_size_in_bytes = 0; | 290 uint64_t total_size_in_bytes = 0; |
| 244 uint64_t remaining_size_in_bytes = 0; | 291 uint64_t remaining_size_in_bytes = 0; |
| 245 | 292 |
| 246 struct statvfs stat = {}; // Zero-clear | 293 struct statvfs stat = {}; // Zero-clear |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 file_iter->mime_type, &info); | 642 file_iter->mime_type, &info); |
| 596 std::vector<gdata::DriveWebAppInfo*> info_ptrs; | 643 std::vector<gdata::DriveWebAppInfo*> info_ptrs; |
| 597 info.release(&info_ptrs); // so they don't go away prematurely. | 644 info.release(&info_ptrs); // so they don't go away prematurely. |
| 598 std::set<std::string> tasks_for_this_file; | 645 std::set<std::string> tasks_for_this_file; |
| 599 for (std::vector<gdata::DriveWebAppInfo*>::iterator | 646 for (std::vector<gdata::DriveWebAppInfo*>::iterator |
| 600 apps = info_ptrs.begin(); apps != info_ptrs.end(); ++apps) { | 647 apps = info_ptrs.begin(); apps != info_ptrs.end(); ++apps) { |
| 601 std::pair<WebAppInfoMap::iterator, bool> insert_result = | 648 std::pair<WebAppInfoMap::iterator, bool> insert_result = |
| 602 app_info->insert(std::make_pair((*apps)->app_id, *apps)); | 649 app_info->insert(std::make_pair((*apps)->app_id, *apps)); |
| 603 // TODO(gspencer): For now, the action id is always "open-with", but we | 650 // TODO(gspencer): For now, the action id is always "open-with", but we |
| 604 // could add any actions that the drive app supports. | 651 // could add any actions that the drive app supports. |
| 605 std::string task_id = | 652 std::string task_id = file_handler_util::MakeTaskID( |
| 606 file_handler_util::MakeDriveTaskID((*apps)->app_id, "open-with"); | 653 (*apps)->app_id, file_handler_util::kTaskDrive, "open-with"); |
| 607 tasks_for_this_file.insert(task_id); | 654 tasks_for_this_file.insert(task_id); |
| 608 // If we failed to insert a task_id because there was a duplicate, then we | 655 // If we failed to insert a task_id because there was a duplicate, then we |
| 609 // must delete it (since we own it). | 656 // must delete it (since we own it). |
| 610 if (!insert_result.second) | 657 if (!insert_result.second) |
| 611 delete *apps; | 658 delete *apps; |
| 612 } | 659 } |
| 613 if (file_iter == file_info_list.begin()) { | 660 if (file_iter == file_info_list.begin()) { |
| 614 *available_tasks = tasks_for_this_file; | 661 *available_tasks = tasks_for_this_file; |
| 615 } else { | 662 } else { |
| 616 std::set<std::string> intersection; | 663 std::set<std::string> intersection; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 const std::set<std::string>& available_tasks, | 696 const std::set<std::string>& available_tasks, |
| 650 const std::set<std::string>& default_tasks, | 697 const std::set<std::string>& default_tasks, |
| 651 ListValue* result_list, | 698 ListValue* result_list, |
| 652 bool* default_already_set) { | 699 bool* default_already_set) { |
| 653 *default_already_set = false; | 700 *default_already_set = false; |
| 654 // OK, now we traverse the intersection of available applications for this | 701 // OK, now we traverse the intersection of available applications for this |
| 655 // list of files, adding a task for each one that is found. | 702 // list of files, adding a task for each one that is found. |
| 656 for (std::set<std::string>::const_iterator app_iter = available_tasks.begin(); | 703 for (std::set<std::string>::const_iterator app_iter = available_tasks.begin(); |
| 657 app_iter != available_tasks.end(); ++app_iter) { | 704 app_iter != available_tasks.end(); ++app_iter) { |
| 658 std::string app_id; | 705 std::string app_id; |
| 659 bool result = file_handler_util::CrackDriveTaskID(*app_iter, &app_id, NULL); | 706 std::string task_type; |
| 707 bool result = file_handler_util::CrackTaskID( |
| 708 *app_iter, &app_id, &task_type, NULL); |
| 660 DCHECK(result) << "Unable to parse Drive task id: " << *app_iter; | 709 DCHECK(result) << "Unable to parse Drive task id: " << *app_iter; |
| 661 if (!result) | 710 DCHECK_EQ(task_type, file_handler_util::kTaskDrive); |
| 662 continue; | 711 |
| 663 WebAppInfoMap::const_iterator info_iter = app_info.find(app_id); | 712 WebAppInfoMap::const_iterator info_iter = app_info.find(app_id); |
| 664 DCHECK(info_iter != app_info.end()); | 713 DCHECK(info_iter != app_info.end()); |
| 665 gdata::DriveWebAppInfo* info = info_iter->second; | 714 gdata::DriveWebAppInfo* info = info_iter->second; |
| 666 DictionaryValue* task = new DictionaryValue; | 715 DictionaryValue* task = new DictionaryValue; |
| 667 | 716 |
| 668 task->SetString("taskId", *app_iter); | 717 task->SetString("taskId", *app_iter); |
| 669 task->SetString("title", info->app_name); | 718 task->SetString("title", info->app_name); |
| 670 | 719 |
| 671 GURL best_icon = FindPreferredIcon(info->app_icons, | 720 GURL best_icon = FindPreferredIcon(info->app_icons, |
| 672 kPreferredIconSize); | 721 kPreferredIconSize); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 700 return true; | 749 return true; |
| 701 | 750 |
| 702 gdata::DriveSystemService* system_service = | 751 gdata::DriveSystemService* system_service = |
| 703 gdata::DriveSystemServiceFactory::GetForProfile(profile_); | 752 gdata::DriveSystemServiceFactory::GetForProfile(profile_); |
| 704 // |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 |
| 705 // 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 |
| 706 // have any to add. | 755 // have any to add. |
| 707 if (!system_service || !system_service->webapps_registry()) | 756 if (!system_service || !system_service->webapps_registry()) |
| 708 return true; | 757 return true; |
| 709 | 758 |
| 710 | |
| 711 gdata::DriveWebAppsRegistry* registry = system_service->webapps_registry(); | 759 gdata::DriveWebAppsRegistry* registry = system_service->webapps_registry(); |
| 712 | 760 |
| 713 // 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 |
| 714 // after taking the intersection of available apps. | 762 // after taking the intersection of available apps. |
| 715 std::map<std::string, gdata::DriveWebAppInfo*> app_info; | 763 std::map<std::string, gdata::DriveWebAppInfo*> app_info; |
| 716 // 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 |
| 717 // application IDs that apply to the paths in |file_paths|. | 765 // application IDs that apply to the paths in |file_paths|. |
| 718 std::set<std::string> available_tasks; | 766 std::set<std::string> available_tasks; |
| 719 | 767 |
| 720 IntersectAvailableDriveTasks(registry, file_info_list, | 768 IntersectAvailableDriveTasks(registry, file_info_list, |
| 721 &app_info, &available_tasks); | 769 &app_info, &available_tasks); |
| 722 std::set<std::string> default_tasks; | 770 std::set<std::string> default_tasks; |
| 723 FindDefaultDriveTasks(file_info_list, available_tasks, &default_tasks); | 771 FindDefaultDriveTasks(file_info_list, available_tasks, &default_tasks); |
| 724 CreateDriveTasks(registry, app_info, available_tasks, default_tasks, | 772 CreateDriveTasks(registry, app_info, available_tasks, default_tasks, |
| 725 result_list, default_already_set); | 773 result_list, default_already_set); |
| 726 | 774 |
| 727 // 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. |
| 728 STLDeleteContainerPairSecondPointers(app_info.begin(), app_info.end()); | 776 STLDeleteContainerPairSecondPointers(app_info.begin(), app_info.end()); |
| 729 return true; | 777 return true; |
| 730 } | 778 } |
| 731 | 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 kTaskWebIntent. |
| 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 // If the file doesn't have an extension or its mime-type cannot be |
| 804 // determined, then indicate that it has the empty mime-type. This will |
| 805 // only be matched if the Web Intents accepts "*" or "*/*". |
| 806 mime_types.insert(""); |
| 807 } else { |
| 808 mime_types.insert(mime_type); |
| 809 } |
| 810 } |
| 811 |
| 812 for (ExtensionSet::const_iterator iter = service->extensions()->begin(); |
| 813 iter != service->extensions()->end(); |
| 814 ++iter) { |
| 815 const Extension* extension = *iter; |
| 816 |
| 817 // We don't support using hosted apps to open files. |
| 818 if (!extension->is_platform_app()) |
| 819 continue; |
| 820 |
| 821 if (profile_->IsOffTheRecord() && |
| 822 !service->IsIncognitoEnabled(extension->id())) |
| 823 continue; |
| 824 |
| 825 std::string title; |
| 826 if (!FindTitleForActionWithTypes( |
| 827 extension, web_intents::kActionView, mime_types, &title)) |
| 828 continue; |
| 829 |
| 830 DictionaryValue* task = new DictionaryValue; |
| 831 std::string task_id = file_handler_util::MakeTaskID(extension->id(), |
| 832 file_handler_util::kTaskWebIntent, web_intents::kActionView); |
| 833 task->SetString("taskId", task_id); |
| 834 task->SetString("title", title); |
| 835 task->SetBoolean("isDefault", false); |
| 836 |
| 837 GURL best_icon = extension->GetIconURL(kPreferredIconSize, |
| 838 ExtensionIconSet::MATCH_BIGGER); |
| 839 if (!best_icon.is_empty()) |
| 840 task->SetString("iconUrl", best_icon.spec()); |
| 841 else |
| 842 task->SetString("iconUrl", kDefaultIcon); |
| 843 |
| 844 task->SetBoolean("driveApp", false); |
| 845 result_list->Append(task); |
| 846 } |
| 847 |
| 848 return true; |
| 849 } |
| 850 |
| 732 bool GetFileTasksFileBrowserFunction::RunImpl() { | 851 bool GetFileTasksFileBrowserFunction::RunImpl() { |
| 733 // First argument is the list of files to get tasks for. | 852 // First argument is the list of files to get tasks for. |
| 734 ListValue* files_list = NULL; | 853 ListValue* files_list = NULL; |
| 735 if (!args_->GetList(0, &files_list)) | 854 if (!args_->GetList(0, &files_list)) |
| 736 return false; | 855 return false; |
| 737 | 856 |
| 738 // Second argument is the list of mime types of each of the files in the list. | 857 // Second argument is the list of mime types of each of the files in the list. |
| 739 ListValue* mime_types_list = NULL; | 858 ListValue* mime_types_list = NULL; |
| 740 if (!args_->GetList(1, &mime_types_list)) | 859 if (!args_->GetList(1, &mime_types_list)) |
| 741 return false; | 860 return false; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 ExtensionService* service = profile_->GetExtensionService(); | 910 ExtensionService* service = profile_->GetExtensionService(); |
| 792 for (std::set<const FileBrowserHandler*>::const_iterator iter = | 911 for (std::set<const FileBrowserHandler*>::const_iterator iter = |
| 793 common_tasks.begin(); | 912 common_tasks.begin(); |
| 794 iter != common_tasks.end(); | 913 iter != common_tasks.end(); |
| 795 ++iter) { | 914 ++iter) { |
| 796 const FileBrowserHandler* handler = *iter; | 915 const FileBrowserHandler* handler = *iter; |
| 797 const std::string extension_id = handler->extension_id(); | 916 const std::string extension_id = handler->extension_id(); |
| 798 const Extension* extension = service->GetExtensionById(extension_id, false); | 917 const Extension* extension = service->GetExtensionById(extension_id, false); |
| 799 CHECK(extension); | 918 CHECK(extension); |
| 800 DictionaryValue* task = new DictionaryValue; | 919 DictionaryValue* task = new DictionaryValue; |
| 801 task->SetString("taskId", | 920 task->SetString("taskId", file_handler_util::MakeTaskID( |
| 802 file_handler_util::MakeTaskID(extension_id, handler->id())); | 921 extension_id, file_handler_util::kTaskFile, handler->id())); |
| 803 task->SetString("title", handler->title()); | 922 task->SetString("title", handler->title()); |
| 804 // TODO(zelidrag): Figure out how to expose icon URL that task defined in | 923 // TODO(zelidrag): Figure out how to expose icon URL that task defined in |
| 805 // manifest instead of the default extension icon. | 924 // manifest instead of the default extension icon. |
| 806 GURL icon = | 925 GURL icon = |
| 807 ExtensionIconSource::GetIconURL(extension, | 926 ExtensionIconSource::GetIconURL(extension, |
| 808 extension_misc::EXTENSION_ICON_BITTY, | 927 extension_misc::EXTENSION_ICON_BITTY, |
| 809 ExtensionIconSet::MATCH_BIGGER, | 928 ExtensionIconSet::MATCH_BIGGER, |
| 810 false, NULL); // grayscale | 929 false, NULL); // grayscale |
| 811 task->SetString("iconUrl", icon.spec()); | 930 task->SetString("iconUrl", icon.spec()); |
| 812 task->SetBoolean("driveApp", false); | 931 task->SetBoolean("driveApp", false); |
| 813 | 932 |
| 814 // Only set the default if there isn't already a default set. | 933 // Only set the default if there isn't already a default set. |
| 815 if (!default_already_set && | 934 if (!default_already_set && |
| 816 default_tasks.find(*iter) != default_tasks.end()) { | 935 default_tasks.find(*iter) != default_tasks.end()) { |
| 817 task->SetBoolean("isDefault", true); | 936 task->SetBoolean("isDefault", true); |
| 818 default_already_set = true; | 937 default_already_set = true; |
| 819 } else { | 938 } else { |
| 820 task->SetBoolean("isDefault", false); | 939 task->SetBoolean("isDefault", false); |
| 821 } | 940 } |
| 822 | 941 |
| 823 result_list->Append(task); | 942 result_list->Append(task); |
| 824 } | 943 } |
| 825 | 944 |
| 945 // Take the union of Web Intents (that platform apps may accept) and all |
| 946 // previous Drive and extension tasks. As above, we know there aren't |
| 947 // duplicates because they're entirely different kinds of tasks. |
| 948 if (!FindWebIntentTasks(file_urls, result_list)) |
| 949 return false; |
| 950 |
| 826 if (VLOG_IS_ON(1)) { | 951 if (VLOG_IS_ON(1)) { |
| 827 std::string result_json; | 952 std::string result_json; |
| 828 base::JSONWriter::WriteWithOptions( | 953 base::JSONWriter::WriteWithOptions( |
| 829 result_list, | 954 result_list, |
| 830 base::JSONWriter::OPTIONS_DO_NOT_ESCAPE | | 955 base::JSONWriter::OPTIONS_DO_NOT_ESCAPE | |
| 831 base::JSONWriter::OPTIONS_PRETTY_PRINT, | 956 base::JSONWriter::OPTIONS_PRETTY_PRINT, |
| 832 &result_json); | 957 &result_json); |
| 833 VLOG(1) << "GetFileTasks result:\n" << result_json; | 958 VLOG(1) << "GetFileTasks result:\n" << result_json; |
| 834 } | 959 } |
| 835 | 960 |
| 836 // TODO(zelidrag, serya): Add intent content tasks to result_list once we | |
| 837 // implement that API. | |
| 838 SendResponse(true); | 961 SendResponse(true); |
| 839 return true; | 962 return true; |
| 840 } | 963 } |
| 841 | 964 |
| 842 ExecuteTasksFileBrowserFunction::ExecuteTasksFileBrowserFunction() {} | 965 ExecuteTasksFileBrowserFunction::ExecuteTasksFileBrowserFunction() {} |
| 843 | 966 |
| 844 void ExecuteTasksFileBrowserFunction::OnTaskExecuted(bool success) { | 967 void ExecuteTasksFileBrowserFunction::OnTaskExecuted(bool success) { |
| 845 SendResponse(success); | 968 SendResponse(success); |
| 846 } | 969 } |
| 847 | 970 |
| 848 ExecuteTasksFileBrowserFunction::~ExecuteTasksFileBrowserFunction() {} | 971 ExecuteTasksFileBrowserFunction::~ExecuteTasksFileBrowserFunction() {} |
| 849 | 972 |
| 850 bool ExecuteTasksFileBrowserFunction::RunImpl() { | 973 bool ExecuteTasksFileBrowserFunction::RunImpl() { |
| 851 // First param is task id that was to the extension with getFileTasks call. | 974 // First param is task id that was to the extension with getFileTasks call. |
| 852 std::string task_id; | 975 std::string task_id; |
| 853 if (!args_->GetString(0, &task_id) || !task_id.size()) | 976 if (!args_->GetString(0, &task_id) || !task_id.size()) |
| 854 return false; | 977 return false; |
| 855 | 978 |
| 856 // TODO(kaznacheev): Crack the task_id here, store it in the Executor | 979 // TODO(kaznacheev): Crack the task_id here, store it in the Executor |
| 857 // and avoid passing it around. | 980 // and avoid passing it around. |
| 858 | 981 |
| 859 // The second param is the list of files that need to be executed with this | 982 // The second param is the list of files that need to be executed with this |
| 860 // task. | 983 // task. |
| 861 ListValue* files_list = NULL; | 984 ListValue* files_list = NULL; |
| 862 if (!args_->GetList(1, &files_list)) | 985 if (!args_->GetList(1, &files_list)) |
| 863 return false; | 986 return false; |
| 864 | 987 |
| 865 std::string extension_id; | 988 std::string extension_id; |
| 989 std::string task_type; |
| 866 std::string action_id; | 990 std::string action_id; |
| 867 if (!file_handler_util::CrackTaskID(task_id, &extension_id, &action_id)) { | 991 if (!file_handler_util::CrackTaskID( |
| 992 task_id, &extension_id, &task_type, &action_id)) { |
| 868 LOG(WARNING) << "Invalid task " << task_id; | 993 LOG(WARNING) << "Invalid task " << task_id; |
| 869 return false; | 994 return false; |
| 870 } | 995 } |
| 871 | 996 |
| 872 if (!files_list->GetSize()) | 997 if (!files_list->GetSize()) |
| 873 return true; | 998 return true; |
| 874 | 999 |
| 875 std::vector<GURL> file_urls; | 1000 std::vector<GURL> file_urls; |
| 876 for (size_t i = 0; i < files_list->GetSize(); i++) { | 1001 for (size_t i = 0; i < files_list->GetSize(); i++) { |
| 877 std::string origin_file_url; | 1002 std::string origin_file_url; |
| 878 if (!files_list->GetString(i, &origin_file_url)) { | 1003 if (!files_list->GetString(i, &origin_file_url)) { |
| 879 error_ = kInvalidFileUrl; | 1004 error_ = kInvalidFileUrl; |
| 880 return false; | 1005 return false; |
| 881 } | 1006 } |
| 882 file_urls.push_back(GURL(origin_file_url)); | 1007 file_urls.push_back(GURL(origin_file_url)); |
| 883 } | 1008 } |
| 884 | 1009 |
| 885 scoped_refptr<FileTaskExecutor> executor( | 1010 scoped_refptr<FileTaskExecutor> executor( |
| 886 FileTaskExecutor::Create(profile(), | 1011 FileTaskExecutor::Create(profile(), |
| 887 source_url(), | 1012 source_url(), |
| 888 extension_id, | 1013 extension_id, |
| 1014 task_type, |
| 889 action_id)); | 1015 action_id)); |
| 890 | 1016 |
| 891 if (!executor->ExecuteAndNotify( | 1017 if (!executor->ExecuteAndNotify( |
| 892 file_urls, | 1018 file_urls, |
| 893 base::Bind(&ExecuteTasksFileBrowserFunction::OnTaskExecuted, this))) | 1019 base::Bind(&ExecuteTasksFileBrowserFunction::OnTaskExecuted, this))) |
| 894 return false; | 1020 return false; |
| 895 | 1021 |
| 896 SetResult(new base::FundamentalValue(true)); | 1022 SetResult(new base::FundamentalValue(true)); |
| 897 return true; | 1023 return true; |
| 898 } | 1024 } |
| (...skipping 1129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2028 // Get drive WebApps that can accept this file. | 2154 // Get drive WebApps that can accept this file. |
| 2029 ScopedVector<gdata::DriveWebAppInfo> web_apps; | 2155 ScopedVector<gdata::DriveWebAppInfo> web_apps; |
| 2030 system_service->webapps_registry()->GetWebAppsForFile( | 2156 system_service->webapps_registry()->GetWebAppsForFile( |
| 2031 file_path, file_specific_info.content_mime_type(), &web_apps); | 2157 file_path, file_specific_info.content_mime_type(), &web_apps); |
| 2032 if (!web_apps.empty()) { | 2158 if (!web_apps.empty()) { |
| 2033 std::string default_task_id = file_handler_util::GetDefaultTaskIdFromPrefs( | 2159 std::string default_task_id = file_handler_util::GetDefaultTaskIdFromPrefs( |
| 2034 profile_, | 2160 profile_, |
| 2035 file_specific_info.content_mime_type(), | 2161 file_specific_info.content_mime_type(), |
| 2036 file_path.Extension()); | 2162 file_path.Extension()); |
| 2037 std::string default_app_id; | 2163 std::string default_app_id; |
| 2038 file_handler_util::CrackDriveTaskID(default_task_id, &default_app_id, NULL); | 2164 file_handler_util::CrackTaskID( |
| 2165 default_task_id, &default_app_id, NULL, NULL); |
| 2039 | 2166 |
| 2040 ListValue* apps = new ListValue(); | 2167 ListValue* apps = new ListValue(); |
| 2041 property_dict->Set("driveApps", apps); | 2168 property_dict->Set("driveApps", apps); |
| 2042 for (ScopedVector<gdata::DriveWebAppInfo>::const_iterator it = | 2169 for (ScopedVector<gdata::DriveWebAppInfo>::const_iterator it = |
| 2043 web_apps.begin(); | 2170 web_apps.begin(); |
| 2044 it != web_apps.end(); ++it) { | 2171 it != web_apps.end(); ++it) { |
| 2045 const gdata::DriveWebAppInfo* webapp_info = *it; | 2172 const gdata::DriveWebAppInfo* webapp_info = *it; |
| 2046 DictionaryValue* app = new DictionaryValue(); | 2173 DictionaryValue* app = new DictionaryValue(); |
| 2047 app->SetString("appId", webapp_info->app_id); | 2174 app->SetString("appId", webapp_info->app_id); |
| 2048 app->SetString("appName", webapp_info->app_name); | 2175 app->SetString("appName", webapp_info->app_name); |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2613 gdata::DriveSystemService* system_service = | 2740 gdata::DriveSystemService* system_service = |
| 2614 gdata::DriveSystemServiceFactory::GetForProfile(profile_); | 2741 gdata::DriveSystemServiceFactory::GetForProfile(profile_); |
| 2615 if (!system_service || !system_service->file_system()) | 2742 if (!system_service || !system_service->file_system()) |
| 2616 return false; | 2743 return false; |
| 2617 | 2744 |
| 2618 FilePath directory_path = GetVirtualPathFromURL(GURL(file_url_as_string)); | 2745 FilePath directory_path = GetVirtualPathFromURL(GURL(file_url_as_string)); |
| 2619 system_service->file_system()->RequestDirectoryRefresh(directory_path); | 2746 system_service->file_system()->RequestDirectoryRefresh(directory_path); |
| 2620 | 2747 |
| 2621 return true; | 2748 return true; |
| 2622 } | 2749 } |
| OLD | NEW |