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

Side by Side Diff: chrome/browser/chromeos/extensions/file_browser_private_api.cc

Issue 10834383: Chrome OS "open with" picker allowing Web Intents (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: enum => string Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/extensions/file_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"
tbarzic 2012/09/19 15:45:13 this goes before base/values.h
thorogood 2012/09/20 00:48:17 Done, I think this was me being lazy with a merge.
tbarzic 2012/09/20 00:52:24 yeah, I know the feeling :)
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/intents/web_intents_util.h"
40 #include "chrome/browser/google_apis/operation_registry.h"
tbarzic 2012/09/19 15:45:13 nit: not in alphabetical order
thorogood 2012/09/20 00:48:17 ditto, merge.
35 #include "chrome/browser/google_apis/gdata_util.h" 41 #include "chrome/browser/google_apis/gdata_util.h"
36 #include "chrome/browser/google_apis/gdata_wapi_parser.h" 42 #include "chrome/browser/google_apis/gdata_wapi_parser.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
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
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
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
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)) {
tbarzic 2012/09/19 15:45:13 indent +=2
thorogood 2012/09/20 00:48:17 Done.
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))
tbarzic 2012/09/19 15:45:13 nit: indent
thorogood 2012/09/20 00:48:17 Done.
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698