1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file. 4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_file_browser_private_api.h" 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base64.h" 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/command_line.h" 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/json/json_writer.h" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/logging.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/stringprintf.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_util.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/task.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/time.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/values.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/profiles/profile.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_event_router.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_function_dispatcher.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_process_manager.h" 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_service.h" 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_tabs_module.h" 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/file_manager_util.h" 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/prefs/pref_service.h" 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/prefs/scoped_user_pref_update.h" 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser.h" 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/html_dialog_view.h" 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/webui/extension_icon_source.h" 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/chrome_switches.h" 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/extensions/extension.h" 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/extensions/file_browser_handler.h" 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/pref_names.h" 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/browser_thread.h" 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/child_process_security_policy.h" 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/render_process_host.h" 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/render_view_host.h" 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/tab_contents/tab_contents.h" 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "googleurl/src/gurl.h" 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "grit/generated_resources.h" 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/fileapi/file_system_context.h" 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/fileapi/file_system_mount_point_provider.h" 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/fileapi/file_system_operation.h" 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/fileapi/file_system_operation_context.h" 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/fileapi/file_system_path_manager.h" 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/fileapi/file_system_types.h" 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/fileapi/file_system_util.h" 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/fileapi/file_system_file_util.h" 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/fileapi/local_file_system_file_util.h" 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/l10n/l10n_util.h" 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Error messages. 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kFileError[] = "File error %d"; 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kInvalidFileUrl[] = "Invalid file URL"; 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Internal task ids. 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kEnqueueTaskId[] = "enqueue"; 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kReadOnlyFilePermissions = base::PLATFORM_FILE_OPEN | 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_READ | 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_EXCLUSIVE_READ | 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_ASYNC; 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kReadWriteFilePermissions = base::PLATFORM_FILE_OPEN | 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_CREATE | 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_OPEN_ALWAYS | 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_CREATE_ALWAYS | 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_READ | 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_WRITE | 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_EXCLUSIVE_READ | 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_EXCLUSIVE_WRITE | 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_ASYNC | 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_TRUNCATE | 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PLATFORM_FILE_WRITE_ATTRIBUTES; 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsentypedef std::pair<int, const FileBrowserHandler* > LastUsedHandler; 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsentypedef std::vector<LastUsedHandler> LastUsedHandlerList; 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsentypedef std::vector<const FileBrowserHandler*> ActionList; 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Breaks down task_id that is used between getFileTasks() and executeTask() on 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// its building blocks. task_id field the following structure: 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// <extension-id>|<task-action-id> 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Currently, the only supported task-type is of 'context'. 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool CrackTaskIdentifier(const std::string& task_id, 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string* target_extension_id, 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string* action_id) { 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<std::string> result; 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int count = Tokenize(task_id, std::string("|"), &result); 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (count != 2) 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *target_extension_id = result[0]; 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *action_id = result[1]; 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::string MakeTaskID(const char* extension_id, 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char* action_id) { 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return base::StringPrintf("%s|%s", extension_id, action_id); 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool GetFileBrowserHandlers(Profile* profile, 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& selected_file_url, 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ActionList* results) { 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionService* service = profile->GetExtensionService(); 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!service) 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; // In unit-tests, we may not have an ExtensionService. 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (ExtensionList::const_iterator iter = service->extensions()->begin(); 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != service->extensions()->end(); 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++iter) { 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const Extension* extension = iter->get(); 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!extension->file_browser_handlers()) 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (Extension::FileBrowserHandlerList::const_iterator action_iter = 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen extension->file_browser_handlers()->begin(); 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen action_iter != extension->file_browser_handlers()->end(); 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++action_iter) { 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const FileBrowserHandler* action = action_iter->get(); 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!action->MatchesURL(selected_file_url)) 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen results->push_back(action_iter->get()); 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool SortByLastUsedTimestampDesc(const LastUsedHandler& a, 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const LastUsedHandler& b) { 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return a.first > b.first; 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(zelidrag): Wire this with ICU to make this sort I18N happy. 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool SortByTaskName(const LastUsedHandler& a, const LastUsedHandler& b) { 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return base::strcasecmp(a.second->title().data(), 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen b.second->title().data()) > 0; 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Given the list of selected files, returns array of context menu tasks 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// that are shared 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool FindCommonTasks(Profile* profile, 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* files_list, 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LastUsedHandlerList* named_action_list) { 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen named_action_list->clear(); 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ActionList common_tasks; 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < files_list->GetSize(); ++i) { 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string file_url; 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!files_list->GetString(i, &file_url)) 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ActionList file_actions; 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!GetFileBrowserHandlers(profile, GURL(file_url), &file_actions)) 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If there is nothing to do for one file, the intersection of tasks for all 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // files will be empty at the end. 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!file_actions.size()) { 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen common_tasks.clear(); 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // For the very first file, just copy elements. 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (i == 0) { 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen common_tasks.insert(common_tasks.begin(), 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_actions.begin(), 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_actions.end()); 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::sort(common_tasks.begin(), common_tasks.end()); 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (common_tasks.size()) { 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // For all additional files, find intersection between the accumulated 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // and file specific set. 171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::sort(file_actions.begin(), file_actions.end()); 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ActionList intersection(common_tasks.size()); 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ActionList::iterator intersection_end = 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::set_intersection(common_tasks.begin(), 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen common_tasks.end(), 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_actions.begin(), 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_actions.end(), 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen intersection.begin()); 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen common_tasks.clear(); 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen common_tasks.insert(common_tasks.begin(), 181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen intersection.begin(), 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen intersection_end); 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::sort(common_tasks.begin(), common_tasks.end()); 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const DictionaryValue* prefs_tasks = 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile->GetPrefs()->GetDictionary(prefs::kLastUsedFileBrowserHandlers); 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (ActionList::const_iterator iter = common_tasks.begin(); 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != common_tasks.end(); ++iter) { 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Get timestamp of when this task was used last time. 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int last_used_timestamp = 0; 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs_tasks->GetInteger(MakeTaskID((*iter)->extension_id().data(), 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (*iter)->id().data()), 195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &last_used_timestamp); 196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen named_action_list->push_back(LastUsedHandler(last_used_timestamp, *iter)); 197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Sort by the last used descending. 199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::sort(named_action_list->begin(), named_action_list->end(), 200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SortByLastUsedTimestampDesc); 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (named_action_list->size() > 1) { 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Sort the rest by name. 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::sort(named_action_list->begin() + 1, named_action_list->end(), 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SortByTaskName); 205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Update file handler usage stats. 210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid UpdateFileHandlerUsageStats(Profile* profile, const std::string& task_id) { 211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!profile || !profile->GetPrefs()) 212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryPrefUpdate prefs_usage_update(profile->GetPrefs(), 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kLastUsedFileBrowserHandlers); 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs_usage_update->SetWithoutPathExpansion(task_id, 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new FundamentalValue( 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static_cast<int>(base::Time::Now().ToInternalValue()/ 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::Time::kMicrosecondsPerSecond))); 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass LocalFileSystemCallbackDispatcher 223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : public fileapi::FileSystemCallbackDispatcher { 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public: 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen explicit LocalFileSystemCallbackDispatcher( 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RequestLocalFileSystemFunction* function, 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Profile* profile, 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int child_id, 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<const Extension> extension) 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : function_(function), 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile_(profile), 232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen child_id_(child_id), 233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen extension_(extension) { 234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(function_); 235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // fileapi::FileSystemCallbackDispatcher overrides. 238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidSucceed() OVERRIDE { 239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidGetLocalPath(const FilePath& local_path) { 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidReadMetadata(const base::PlatformFileInfo& info, 247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const FilePath& unused) OVERRIDE { 248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidReadDirectory( 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<base::FileUtilProxy::Entry>& entries, 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool has_more) OVERRIDE { 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidWrite(int64 bytes, bool complete) OVERRIDE { 258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidOpenFileSystem(const std::string& name, 262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& root_path) OVERRIDE { 263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Set up file permission access. 265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!SetupFileSystemAccessPermissions()) { 266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DidFail(base::PLATFORM_FILE_ERROR_SECURITY); 267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::UI, FROM_HERE, 272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(function_, 273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &RequestLocalFileSystemFunction::RespondSuccessOnUIThread, 274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen name, 275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen root_path)); 276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidFail(base::PlatformFileError error_code) OVERRIDE { 279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::UI, FROM_HERE, 281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(function_, 282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &RequestLocalFileSystemFunction::RespondFailedOnUIThread, 283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen error_code)); 284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private: 287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Grants file system access permissions to file browser component. 289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool SetupFileSystemAccessPermissions() { 290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!extension_.get()) 291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Make sure that only component extension can access the entire 294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // local file system. 295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (extension_->location() != Extension::COMPONENT 296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifndef NDEBUG 297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen && !CommandLine::ForCurrentProcess()->HasSwitch( 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switches::kExposePrivateExtensionApi) 299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ) { 301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED() << "Private method access by non-component extension " 302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen << extension_->id(); 303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::FileSystemPathManager* path_manager = 307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile_->GetFileSystemContext()->path_manager(); 308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::ExternalFileSystemMountPointProvider* provider = 309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen path_manager->external_provider(); 310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!provider) 311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Grant full access to File API from this component extension. 314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen provider->GrantFullAccessToExtension(extension_->id()); 315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Grant R/W file permissions to the renderer hosting component 317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // extension for all paths exposed by our local file system provider. 318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<FilePath> root_dirs = provider->GetRootDirectories(); 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (std::vector<FilePath>::iterator iter = root_dirs.begin(); 320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != root_dirs.end(); 321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++iter) { 322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( 323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen child_id_, *iter, kReadWriteFilePermissions); 324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RequestLocalFileSystemFunction* function_; 329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Profile* profile_; 330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Renderer process id. 331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int child_id_; 332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Extension source URL. 333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<const Extension> extension_; 334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DISALLOW_COPY_AND_ASSIGN(LocalFileSystemCallbackDispatcher); 335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid RequestLocalFileSystemFunction::RequestOnFileThread( 338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& source_url, int child_id) { 339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::FileSystemOperation* operation = 340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new fileapi::FileSystemOperation( 341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new LocalFileSystemCallbackDispatcher( 342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this, 343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile(), 344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen child_id, 345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GetExtension()), 346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), 347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile()->GetFileSystemContext(), 348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL); 349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL origin_url = source_url.GetOrigin(); 350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen operation->OpenFileSystem(origin_url, fileapi::kFileSystemTypeExternal, 351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen false); // create 352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool RequestLocalFileSystemFunction::RunImpl() { 355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!dispatcher() || !dispatcher()->render_view_host() || 356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !dispatcher()->render_view_host()->process()) 357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::FILE, FROM_HERE, 361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(this, 362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &RequestLocalFileSystemFunction::RequestOnFileThread, 363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen source_url_, 364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dispatcher()->render_view_host()->process()->id())); 365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Will finish asynchronously. 366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid RequestLocalFileSystemFunction::RespondSuccessOnUIThread( 370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& name, const GURL& root_path) { 371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result_.reset(new DictionaryValue()); 373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* dict = reinterpret_cast<DictionaryValue*>(result_.get()); 374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dict->SetString("name", name); 375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dict->SetString("path", root_path.spec()); 376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dict->SetInteger("error", base::PLATFORM_FILE_OK); 377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(true); 378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid RequestLocalFileSystemFunction::RespondFailedOnUIThread( 381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PlatformFileError error_code) { 382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen error_ = base::StringPrintf(kFileError, static_cast<int>(error_code)); 384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(false); 385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool GetFileTasksFileBrowserFunction::RunImpl() { 388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* files_list = NULL; 389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!args_->GetList(0, &files_list)) 390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* result_list = new ListValue(); 393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result_.reset(result_list); 394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LastUsedHandlerList common_tasks; 396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!FindCommonTasks(profile_, files_list, &common_tasks)) 397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionService* service = profile_->GetExtensionService(); 400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (LastUsedHandlerList::const_iterator iter = common_tasks.begin(); 401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != common_tasks.end(); 402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++iter) { 403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string extension_id = iter->second->extension_id(); 404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const Extension* extension = service->GetExtensionById(extension_id, false); 405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CHECK(extension); 406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* task = new DictionaryValue(); 407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen task->SetString("taskId", MakeTaskID(extension_id.data(), 408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter->second->id().data())); 409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen task->SetString("title", iter->second->title()); 410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(zelidrag): Figure out how to expose icon URL that task defined in 411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // manifest instead of the default extension icon. 412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL icon = 413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionIconSource::GetIconURL(extension, 414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Extension::EXTENSION_ICON_BITTY, 415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionIconSet::MATCH_BIGGER, 416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen false); // grayscale 417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen task->SetString("iconUrl", icon.spec()); 418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result_list->Append(task); 419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(zelidrag, serya): Add intent content tasks to result_list once we 422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // implement that API. 423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(true); 424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass ExecuteTasksFileSystemCallbackDispatcher 428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : public fileapi::FileSystemCallbackDispatcher { 429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public: 430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen explicit ExecuteTasksFileSystemCallbackDispatcher( 431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExecuteTasksFileBrowserFunction* function, 432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Profile* profile, 433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int child_id, 434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& source_url, 435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<const Extension> extension, 436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string task_id, 437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<GURL>& file_urls) 438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : function_(function), 439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile_(profile), 440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen source_url_(source_url), 441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen extension_(extension), 442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen task_id_(task_id), 443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen origin_file_urls_(file_urls) { 444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(function_); 445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // fileapi::FileSystemCallbackDispatcher overrides. 448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidSucceed() OVERRIDE { 449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidGetLocalPath(const FilePath& local_path) { 453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidReadMetadata(const base::PlatformFileInfo& info, 457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const FilePath& unused) OVERRIDE { 458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidReadDirectory( 462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<base::FileUtilProxy::Entry>& entries, 463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool has_more) OVERRIDE { 464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidWrite(int64 bytes, bool complete) OVERRIDE { 468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidOpenFileSystem(const std::string& file_system_name, 472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& file_system_root) OVERRIDE { 473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExecuteTasksFileBrowserFunction::FileDefinitionList file_list; 475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (std::vector<GURL>::iterator iter = origin_file_urls_.begin(); 476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != origin_file_urls_.end(); 477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++iter) { 478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Set up file permission access. 479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExecuteTasksFileBrowserFunction::FileDefinition file; 480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!SetupFileAccessPermissions(*iter, &file.target_file_url, 481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &file.virtual_path, &file.is_directory)) { 482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_list.push_back(file); 485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (file_list.empty()) { 487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::UI, FROM_HERE, 489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(function_, 490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &ExecuteTasksFileBrowserFunction::ExecuteFailedOnUIThread)); 491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::UI, FROM_HERE, 496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(function_, 497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &ExecuteTasksFileBrowserFunction::ExecuteFileActionsOnUIThread, 498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen task_id_, 499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_system_name, 500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_system_root, 501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_list)); 502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual void DidFail(base::PlatformFileError error_code) OVERRIDE { 505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(WARNING) << "Local file system cant be resolved"; 506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::UI, FROM_HERE, 508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(function_, 509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &ExecuteTasksFileBrowserFunction::ExecuteFailedOnUIThread)); 510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private: 513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Checks legitimacy of file url and grants file RO access permissions from 514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // handler (target) extension and its renderer process. 515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool SetupFileAccessPermissions(const GURL& origin_file_url, 516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL* target_file_url, FilePath* file_path, bool* is_directory) { 517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!extension_.get()) 519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL file_origin_url; 522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath virtual_path; 523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::FileSystemType type; 524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!CrackFileSystemURL(origin_file_url, &file_origin_url, &type, 525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &virtual_path)) { 526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 528ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (type != fileapi::kFileSystemTypeExternal) 530ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::FileSystemPathManager* path_manager = 533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile_->GetFileSystemContext()->path_manager(); 534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!path_manager->IsAccessAllowed(file_origin_url, 535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen type, 536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual_path)) { 537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Make sure this url really being used by the right caller extension. 541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (source_url_.GetOrigin() != file_origin_url) { 542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DidFail(base::PLATFORM_FILE_ERROR_SECURITY); 543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath root_path = 547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen path_manager->ValidateFileSystemRootAndGetPathOnFileThread( 548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_origin_url, 549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::kFileSystemTypeExternal, 550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual_path, 551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen false); // create 552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath final_file_path = root_path.Append(virtual_path); 553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Check if this file system entry exists first. 555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::PlatformFileInfo file_info; 556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath platform_path; 557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::FileSystemOperationContext file_system_operation_context( 558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile_->GetFileSystemContext(), 559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::LocalFileSystemFileUtil::GetInstance()); 560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (base::PLATFORM_FILE_OK != 561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::FileSystemFileUtil::GetInstance()->GetFileInfo( 562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &file_system_operation_context, final_file_path, &file_info, 563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &platform_path)) { 564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::ExternalFileSystemMountPointProvider* external_provider = 568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen path_manager->external_provider(); 569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!external_provider) 570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(zelidrag): Let's just prevent all symlinks for now. We don't want a 573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // USB drive content to point to something in the rest of the file system. 574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Ideally, we should permit symlinks within the boundary of the same 575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // virtual mount point. 576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (file_info.is_symbolic_link) 577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Get task details. 580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string target_extension_id; 581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string action_id; 582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!CrackTaskIdentifier(task_id_, &target_extension_id, 583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &action_id)) { 584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(zelidrag): Add explicit R/W + R/O permissions for non-component 588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // extensions. 589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Get target extension's process. 591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RenderProcessHost* target_host = 592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile_->GetExtensionProcessManager()->GetExtensionProcess( 593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen target_extension_id); 594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!target_host) 595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Grant R/O access permission to non-component extension and R/W to 598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // component extensions. 599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( 600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen target_host->id(), final_file_path, 601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen extension_->location() != Extension::COMPONENT ? 602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kReadOnlyFilePermissions : kReadWriteFilePermissions); 603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Grant access to this particular file to target extension. This will 605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // ensure that the target extension can access only this FS entry and 606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // prevent from traversing FS hierarchy upward. 607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen external_provider->GrantFileAccessToExtension(target_extension_id, 608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual_path); 609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Output values. 611ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL target_origin_url(Extension::GetBaseURLFromExtensionId( 612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen target_extension_id)); 613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL base_url = fileapi::GetFileSystemRootURI(target_origin_url, 614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::kFileSystemTypeExternal); 615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *target_file_url = GURL(base_url.spec() + virtual_path.value()); 616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath root(FILE_PATH_LITERAL("/")); 617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *file_path = root.Append(virtual_path); 618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *is_directory = file_info.is_directory; 619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExecuteTasksFileBrowserFunction* function_; 623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Profile* profile_; 624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Extension source URL. 625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL source_url_; 626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<const Extension> extension_; 627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string task_id_; 628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<GURL> origin_file_urls_; 629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DISALLOW_COPY_AND_ASSIGN(ExecuteTasksFileSystemCallbackDispatcher); 630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ExecuteTasksFileBrowserFunction::RunImpl() { 633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // First param is task id that was to the extension with getFileTasks call. 634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string task_id; 635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!args_->GetString(0, &task_id) || !task_id.size()) 636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The second param is the list of files that need to be executed with this 639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // task. 640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* files_list = NULL; 641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!args_->GetList(1, &files_list)) 642ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 643ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!files_list->GetSize()) 645ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return InitiateFileTaskExecution(task_id, files_list); 648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ExecuteTasksFileBrowserFunction::InitiateFileTaskExecution( 651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& task_id, ListValue* files_list) { 652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<GURL> file_urls; 653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < files_list->GetSize(); i++) { 654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string origin_file_url; 655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!files_list->GetString(i, &origin_file_url)) { 656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen error_ = kInvalidFileUrl; 657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_urls.push_back(GURL(origin_file_url)); 660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Get local file system instance on file thread. 662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::FILE, FROM_HERE, 664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(this, 665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &ExecuteTasksFileBrowserFunction::RequestFileEntryOnFileThread, 666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen source_url_, 667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen task_id, 668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_urls)); 669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result_.reset(new FundamentalValue(true)); 670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ExecuteTasksFileBrowserFunction::RequestFileEntryOnFileThread( 674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& source_url, const std::string& task_id, 675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<GURL>& file_urls) { 676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::FileSystemOperation* operation = 678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new fileapi::FileSystemOperation( 679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new ExecuteTasksFileSystemCallbackDispatcher( 680ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen this, 681ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile(), 682ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dispatcher()->render_view_host()->process()->id(), 683ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen source_url, 684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GetExtension(), 685ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen task_id, 686ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_urls), 687ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), 688ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile()->GetFileSystemContext(), 689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL); 690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL origin_url = source_url.GetOrigin(); 691ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen operation->OpenFileSystem(origin_url, fileapi::kFileSystemTypeExternal, 692ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen false); // create 693ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 694ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 695ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ExecuteTasksFileBrowserFunction::ExecuteFailedOnUIThread() { 696ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(false); 697ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ExecuteTasksFileBrowserFunction::ExecuteFileActionsOnUIThread( 701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& task_id, 702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& file_system_name, 703ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& file_system_root, 704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const FileDefinitionList& file_list) { 705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionService* service = profile_->GetExtensionService(); 707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!service) 708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Get task details. 710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string handler_extension_id; 711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string action_id; 712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!CrackTaskIdentifier(task_id, &handler_extension_id, 713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &action_id)) { 714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(WARNING) << "Invalid task " << task_id; 715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(false); 716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const Extension* extension = service->GetExtensionById(handler_extension_id, 720ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen false); 721ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!extension) { 722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(false); 723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionEventRouter* event_router = profile_->GetExtensionEventRouter(); 727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!event_router) { 728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(false); 729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<ListValue> event_args(new ListValue()); 733ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen event_args->Append(Value::CreateStringValue(action_id)); 734ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* details = new DictionaryValue(); 735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen event_args->Append(details); 736ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Get file definitions. These will be replaced with Entry instances by 737ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // chromeHidden.Event.dispatchJSON() method from even_binding.js. 738ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* files_urls = new ListValue(); 739ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen details->Set("entries", files_urls); 740ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (FileDefinitionList::const_iterator iter = file_list.begin(); 741ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != file_list.end(); 742ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++iter) { 743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* file_def = new DictionaryValue(); 744ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen files_urls->Append(file_def); 745ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_def->SetString("fileSystemName", file_system_name); 746ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_def->SetString("fileSystemRoot", file_system_root.spec()); 747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_def->SetString("fileFullPath", iter->virtual_path.value()); 748ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_def->SetBoolean("fileIsDirectory", iter->is_directory); 749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Get tab id. 751ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Browser* browser = GetCurrentBrowser(); 752ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (browser) { 753ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TabContents* contents = browser->GetSelectedTabContents(); 754ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (contents) 755ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen details->SetInteger("tab_id", ExtensionTabUtil::GetTabId(contents)); 756ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 758ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateFileHandlerUsageStats(profile_, task_id); 759ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 760ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string json_args; 761ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::JSONWriter::Write(event_args.get(), false, &json_args); 762ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen event_router->DispatchEventToExtension( 763ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen handler_extension_id, std::string("fileBrowserHandler.onExecute"), 764ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen json_args, profile_, 765ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL()); 766ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(true); 767ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 768ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 769ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFileDialogFunction::FileDialogFunction() { 770ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 771ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 772ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFileDialogFunction::~FileDialogFunction() { 773ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 774ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 775ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 776ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFileDialogFunction::Callback 777ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFileDialogFunction::Callback::null_(NULL, NULL, NULL); 778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 779ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 780ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFileDialogFunction::Callback::Map FileDialogFunction::Callback::map_; 781ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 782ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 783ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid FileDialogFunction::Callback::Add(int32 tab_id, 784ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SelectFileDialog::Listener* listener, 785ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HtmlDialogView* dialog, 786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void* params) { 787ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (map_.find(tab_id) == map_.end()) { 788ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen map_.insert(std::make_pair(tab_id, Callback(listener, dialog, params))); 789ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 790ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DLOG_ASSERT("FileDialogFunction::AddCallback tab_id already present"); 791ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 792ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 793ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 794ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 795ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid FileDialogFunction::Callback::Remove(int32 tab_id) { 796ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen map_.erase(tab_id); 797ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 798ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 799ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 800ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst FileDialogFunction::Callback& 801ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFileDialogFunction::Callback::Find(int32 tab_id) { 802ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Callback::Map::const_iterator it = map_.find(tab_id); 803ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (it == map_.end()) ? null_ : it->second; 804ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 805ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 806ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 807ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint32 FileDialogFunction::GetTabId() const { 808ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return dispatcher()->delegate()->associated_tab_contents()-> 809ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen controller().session_id().id(); 810ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 811ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 812ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst FileDialogFunction::Callback& FileDialogFunction::GetCallback() const { 813ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!dispatcher() || !dispatcher()->delegate() || 814ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !dispatcher()->delegate()->associated_tab_contents()) { 815ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return Callback::null(); 816ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 817ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return Callback::Find(GetTabId()); 818ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 819ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 820ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid FileDialogFunction::CloseDialog(HtmlDialogView* dialog) { 821ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(dialog); 822ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TabContents* contents = dispatcher()->delegate()->associated_tab_contents(); 823ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (contents) 824ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dialog->CloseContents(contents); 825ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 826ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 827ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// GetFileSystemRootPathOnFileThread can only be called from the file thread, 828ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// so here we are. This function takes a vector of virtual paths, converts 829ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// them to local paths and calls GetLocalPathsResponseOnUIThread with the 830ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// result vector, on the UI thread. 831ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid FileDialogFunction::GetLocalPathsOnFileThread(const UrlList& file_urls, 832ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& task_id) { 833ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 834ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePathList selected_files; 835ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 836ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // FilePath(virtual_path) doesn't work on win, so limit this to ChromeOS. 837ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS) 838ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL origin_url = source_url().GetOrigin(); 839ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::FileSystemPathManager* path_manager = 840ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen profile()->GetFileSystemContext()->path_manager(); 841ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 842ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t len = file_urls.size(); 843ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen selected_files.reserve(len); 844ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < len; ++i) { 845ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& file_url = file_urls[i]; 846ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL file_origin_url; 847ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath virtual_path; 848ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::FileSystemType type; 849ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!CrackFileSystemURL(file_url, &file_origin_url, &type, 850ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &virtual_path)) { 851ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 852ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 853ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (type != fileapi::kFileSystemTypeExternal) { 854ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 855ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 856ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 857ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath root = path_manager->ValidateFileSystemRootAndGetPathOnFileThread( 858ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen origin_url, 859ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen fileapi::kFileSystemTypeExternal, 860ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath(virtual_path), 861ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen false); 862ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!root.empty()) { 863ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen selected_files.push_back(root.Append(virtual_path)); 864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(WARNING) << "GetLocalPathsOnFileThread failed " 866ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen << file_url.spec(); 867ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 868ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 869ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 870ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 871ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!selected_files.empty()) { 872ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 873ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::UI, FROM_HERE, 874ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(this, 875ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &FileDialogFunction::GetLocalPathsResponseOnUIThread, 876ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen selected_files, task_id)); 877ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 878ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool SelectFileFunction::RunImpl() { 881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (args_->GetSize() != 2) { 882ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 884ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string file_url; 885ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen args_->GetString(0, &file_url); 886ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UrlList file_paths; 887ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_paths.push_back(GURL(file_url)); 888ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 889ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 890ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::FILE, FROM_HERE, 891ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(this, 892ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &SelectFileFunction::GetLocalPathsOnFileThread, 893ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_paths, std::string())); 894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 895ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 896ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 897ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 898ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SelectFileFunction::GetLocalPathsResponseOnUIThread( 899ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const FilePathList& files, const std::string& task_id) { 900ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 901ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (files.size() != 1) { 902ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(false); 903ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 904ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 905ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int index; 906ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen args_->GetInteger(1, &index); 907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const Callback& callback = GetCallback(); 908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!callback.IsNull()); 909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!callback.IsNull()) { 910ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Must do this before callback, as the callback may delete listeners 911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // waiting for window close. 912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CloseDialog(callback.dialog()); 913ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen callback.listener()->FileSelected(files[0], 914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen index, 915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen callback.params()); 916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 917ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(true); 918ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 919ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenViewFilesFunction::ViewFilesFunction() { 922ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenViewFilesFunction::~ViewFilesFunction() { 925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ViewFilesFunction::RunImpl() { 928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (args_->GetSize() < 1) { 929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 932ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* path_list = NULL; 933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen args_->GetList(0, &path_list); 934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(path_list); 935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string internal_task_id; 937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen args_->GetString(1, &internal_task_id); 938ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 939ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string virtual_path; 940ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t len = path_list->GetSize(); 941ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UrlList file_urls; 942ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_urls.reserve(len); 943ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < len; ++i) { 944ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen path_list->GetString(i, &virtual_path); 945ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_urls.push_back(GURL(virtual_path)); 946ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 947ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 948ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 949ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::FILE, FROM_HERE, 950ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(this, 951ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &ViewFilesFunction::GetLocalPathsOnFileThread, 952ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_urls, internal_task_id)); 953ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 954ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 955ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 956ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 957ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ViewFilesFunction::GetLocalPathsResponseOnUIThread( 958ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const FilePathList& files, const std::string& internal_task_id) { 959ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 960ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (FilePathList::const_iterator iter = files.begin(); 961ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != files.end(); 962ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++iter) { 963ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FileManagerUtil::ViewItem(*iter, internal_task_id == kEnqueueTaskId); 964ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 965ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateFileHandlerUsageStats(profile_, internal_task_id); 966ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(true); 967ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 968ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 969ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSelectFilesFunction::SelectFilesFunction() { 970ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 971ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 972ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSelectFilesFunction::~SelectFilesFunction() { 973ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 974ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 975ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool SelectFilesFunction::RunImpl() { 976ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (args_->GetSize() != 1) { 977ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 978ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 979ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 980ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* path_list = NULL; 981ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen args_->GetList(0, &path_list); 982ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(path_list); 983ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 984ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string virtual_path; 985ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t len = path_list->GetSize(); 986ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UrlList file_urls; 987ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_urls.reserve(len); 988ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < len; ++i) { 989ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen path_list->GetString(i, &virtual_path); 990ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_urls.push_back(GURL(virtual_path)); 991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 992ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 993ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::PostTask( 994ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserThread::FILE, FROM_HERE, 995ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NewRunnableMethod(this, 996ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &SelectFilesFunction::GetLocalPathsOnFileThread, 997ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_urls, std::string())); 998ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 999ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 1000ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1001ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SelectFilesFunction::GetLocalPathsResponseOnUIThread( 1003ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const FilePathList& files, const std::string& internal_task_id) { 1004ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1005ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1006ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const Callback& callback = GetCallback(); 1007ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!callback.IsNull()); 1008ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!callback.IsNull()) { 1009ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Must do this before callback, as the callback may delete listeners 1010ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // waiting for window close. 1011ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CloseDialog(callback.dialog()); 1012ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen callback.listener()->MultiFilesSelected(files, callback.params()); 1013ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1014ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(true); 1015ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1016ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1017ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool CancelFileDialogFunction::RunImpl() { 1018ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const Callback& callback = GetCallback(); 1019ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!callback.IsNull()); 1020ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!callback.IsNull()) { 1021ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Must do this before callback, as the callback may delete listeners 1022ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // waiting for window close. 1023ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CloseDialog(callback.dialog()); 1024ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen callback.listener()->FileSelectionCanceled(callback.params()); 1025ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1026ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SendResponse(true); 1027ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 1028ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1029ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1030ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool FileDialogStringsFunction::RunImpl() { 1031ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result_.reset(new DictionaryValue()); 1032ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* dict = reinterpret_cast<DictionaryValue*>(result_.get()); 1033ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1034ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SET_STRING(ns, id) \ 1035ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dict->SetString(#id, l10n_util::GetStringUTF16(ns##_##id)) 1036ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1037ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS, LOCALE_FMT_DATE_SHORT); 1038ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS, LOCALE_MONTHS_SHORT); 1039ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS, LOCALE_DAYS_SHORT); 1040ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1041ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, BODY_FONT_FAMILY); 1042ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, BODY_FONT_SIZE); 1043ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1044ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, ROOT_DIRECTORY_LABEL); 1045ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, DOWNLOADS_DIRECTORY_LABEL); 1046ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, MEDIA_DIRECTORY_LABEL); 1047ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, NAME_COLUMN_LABEL); 1048ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, SIZE_COLUMN_LABEL); 1049ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, DATE_COLUMN_LABEL); 1050ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, PREVIEW_COLUMN_LABEL); 1051ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1052ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, ERROR_CREATING_FOLDER); 1053ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, ERROR_INVALID_FOLDER_CHARACTER); 1054ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, ERROR_INVALID_FILE_CHARACTER); 1055ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, NEW_FOLDER_PROMPT); 1056ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, NEW_FOLDER_BUTTON_LABEL); 1057ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, FILENAME_LABEL); 1058ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1059ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, EJECT_BUTTON); 1060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, IMAGE_DIMENSIONS); 1061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, VOLUME_LABEL); 1062ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, READ_ONLY); 1063ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1064ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, ERROR_RENAMING); 1065ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, RENAME_PROMPT); 1066ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, RENAME_BUTTON_LABEL); 1067ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1068ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, ERROR_DELETING); 1069ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, DELETE_BUTTON_LABEL); 1070ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1071ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, ERROR_MOVING); 1072ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, MOVE_BUTTON_LABEL); 1073ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1074ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, ERROR_PASTING); 1075ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, PASTE_BUTTON_LABEL); 1076ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1077ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, COPY_BUTTON_LABEL); 1078ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, CUT_BUTTON_LABEL); 1079ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1080ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, DEVICE_TYPE_FLASH); 1081ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, DEVICE_TYPE_HDD); 1082ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, DEVICE_TYPE_OPTICAL); 1083ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, DEVICE_TYPE_UNDEFINED); 1084ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1085ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, CANCEL_LABEL); 1086ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, OPEN_LABEL); 1087ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, SAVE_LABEL); 1088ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1089ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, SELECT_FOLDER_TITLE); 1090ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, SELECT_OPEN_FILE_TITLE); 1091ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, SELECT_OPEN_MULTI_FILE_TITLE); 1092ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, SELECT_SAVEAS_FILE_TITLE); 1093ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1094ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, COMPUTING_SELECTION); 1095ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, NOTHING_SELECTED); 1096ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, ONE_FILE_SELECTED); 1097ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILE_BROWSER, MANY_FILES_SELECTED); 1098ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1099ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // FILEBROWSER, without the underscore, is from the old school codebase. 1100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(rginda): Move these into IDS_FILE_BROWSER post M12. 1101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILEBROWSER, CONFIRM_DELETE); 1102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SET_STRING(IDS_FILEBROWSER, ENQUEUE); 1104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef SET_STRING 1105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(serya): Create a new string in .grd file for this one in M13. 1107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dict->SetString("PREVIEW_IMAGE", 1108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen l10n_util::GetStringUTF16(IDS_CERT_MANAGER_VIEW_CERT_BUTTON)); 1109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dict->SetString("PLAY_MEDIA", 1110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLAY)); 1111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 1113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1114