| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 // | |
| 5 // This file provides utility functions for "file tasks". | |
| 6 // | |
| 7 // WHAT ARE FILE TASKS? | |
| 8 // | |
| 9 // File tasks are representatiosn of actions that can be performed over the | |
| 10 // currently selected files from Files.app. A task can be either of: | |
| 11 // | |
| 12 // 1) Chrome extension or app, registered via "file_handlers" or | |
| 13 // "file_browser_handlers" in manifest.json (ex. Text.app). This information | |
| 14 // comes from FileBrowserHandler::GetHandlers() | |
| 15 // | |
| 16 // See also: | |
| 17 // https://developer.chrome.com/extensions/manifest.html#file_handlers | |
| 18 // https://developer.chrome.com/extensions/fileBrowserHandler.html | |
| 19 // | |
| 20 // 2) Built-in handlers provided from Files.app. Files.app provides lots of | |
| 21 // file_browser_handlers, such as "play", "watch", "mount-archive". These | |
| 22 // built-in handlers are often handled in special manners inside Files.app. | |
| 23 // This information also comes from FileBrowserHandler::GetHandlers(). | |
| 24 // | |
| 25 // See also: | |
| 26 // chrome/browser/resources/file_manager/manifest.json | |
| 27 // | |
| 28 // 3) Drive app, which is a hosted app (i.e. just web site), that can work | |
| 29 // with Drive (ex. Pixlr Editor). This information comes from | |
| 30 // drive::DriveAppRegistry. | |
| 31 // | |
| 32 // See also: | |
| 33 // https://chrome.google.com/webstore/category/collection/drive_apps | |
| 34 // | |
| 35 // For example, if the user is now selecting a JPEG file, Files.app will | |
| 36 // receive file tasks represented as a JSON object via | |
| 37 // chrome.fileBrowserPrivate.getFileTasks() API, which look like: | |
| 38 // | |
| 39 // [ | |
| 40 // { | |
| 41 // "driveApp": true, | |
| 42 // "iconUrl": "<app_icon_url>", | |
| 43 // "isDefault": false, | |
| 44 // "taskId": "<drive_app_id>|drive|open-with", | |
| 45 // "title": "Drive App Name (ex. Pixlr Editor)" | |
| 46 // }, | |
| 47 // { | |
| 48 // "driveApp": false, | |
| 49 // "iconUrl": "chrome://extension-icon/hhaomjibdihmijegdhdafkllkbggdgoj/16/1
", | |
| 50 // "isDefault": true, | |
| 51 // "taskId": "hhaomjibdihmijegdhdafkllkbggdgoj|file|gallery", | |
| 52 // "title": "__MSG_OPEN_ACTION__" | |
| 53 // } | |
| 54 // ] | |
| 55 // | |
| 56 // The first file task is a Drive app. The second file task is a built-in | |
| 57 // handler from Files.app. | |
| 58 // | |
| 59 // WHAT ARE TASK IDS? | |
| 60 // | |
| 61 // You may have noticed that "taskId" fields in the above example look | |
| 62 // awakard. Apparently "taskId" encodes three types of information delimited | |
| 63 // by "|". This is a weird format for something called as an ID. | |
| 64 // | |
| 65 // 1) Why are the three types information encoded in this way? | |
| 66 // | |
| 67 // It's just a historical reason. The reason is that a simple string can be | |
| 68 // easily stored in user's preferences. We should stop doing this, by storing | |
| 69 // this information in chrome.storage instead. crbug.com/267359. | |
| 70 // | |
| 71 // 2) OK, then what are the three types of information encoded here? | |
| 72 // | |
| 73 // The task ID encodes the folloing structure: | |
| 74 // | |
| 75 // <app-id>|<task-type>|<task-action-id> | |
| 76 // | |
| 77 // <app-id> is either of Chrome Extension/App ID or Drive App ID. For some | |
| 78 // reason, Chrome Extension/App IDs and Drive App IDs look differently. As of | |
| 79 // writing, the fomer looks like "hhaomjibdihmijegdhdafkllkbggdgoj" | |
| 80 // (Files.app) and the latter looks like "419782477519" (Pixlr Editor). | |
| 81 // | |
| 82 // <task-type> is either of | |
| 83 // - "file" - File browser handler - app/extension declaring | |
| 84 // "file_browser_handlers" in manifest. | |
| 85 // - "app" - File handler - app declaring "file_handlers" in manifest.json. | |
| 86 // - "drive" - Drive App | |
| 87 // | |
| 88 // <task-action-id> is an ID string used for identifying actions provided | |
| 89 // from a single Chrome Extension/App. In other words, a single | |
| 90 // Chrome/Extension can provide multiple file handlers hence each of them | |
| 91 // needs to have a unique action ID. For Drive apps, <task-action-id> is | |
| 92 // always "open-with". | |
| 93 // | |
| 94 // HOW TASKS ARE EXECUTED? | |
| 95 // | |
| 96 // chrome.fileBrowserPrivate.viewFiles() is used to open a file in a browser, | |
| 97 // without any handler. Browser will take care of handling the file (ex. PDF). | |
| 98 // | |
| 99 // chrome.fileBrowserPrivate.executeTasks() is used to open a file with a | |
| 100 // handler (Chrome Extension/App or Drive App). | |
| 101 // | |
| 102 // Some built-in handlers such as "play" and "watch" are handled internally | |
| 103 // in Files.app. "mount-archive" is handled very differently. The task | |
| 104 // execution business should be simplified: crbug.com/267313 | |
| 105 // | |
| 106 // See also: | |
| 107 // chrome/browser/resources/file_manager/js/file_tasks.js | |
| 108 // | |
| 109 | |
| 110 #ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_TASKS_H_ | |
| 111 #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_TASKS_H_ | |
| 112 | |
| 113 #include <set> | |
| 114 #include <string> | |
| 115 #include <vector> | |
| 116 | |
| 117 #include "base/basictypes.h" | |
| 118 #include "base/callback_forward.h" | |
| 119 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" | |
| 120 #include "url/gurl.h" | |
| 121 | |
| 122 class PrefService; | |
| 123 class Profile; | |
| 124 | |
| 125 namespace drive { | |
| 126 class DriveAppRegistry; | |
| 127 } | |
| 128 | |
| 129 namespace fileapi { | |
| 130 class FileSystemURL; | |
| 131 } | |
| 132 | |
| 133 namespace file_manager { | |
| 134 namespace file_tasks { | |
| 135 | |
| 136 // Task types as explained in the comment above. Search for <task-type>. | |
| 137 enum TaskType { | |
| 138 TASK_TYPE_FILE_BROWSER_HANDLER, | |
| 139 TASK_TYPE_FILE_HANDLER, | |
| 140 TASK_TYPE_DRIVE_APP, | |
| 141 TASK_TYPE_UNKNOWN, // Used only for handling errors. | |
| 142 }; | |
| 143 | |
| 144 // Describes a task. | |
| 145 // See the comment above for <app-id>, <task-type>, and <action-id>. | |
| 146 struct TaskDescriptor { | |
| 147 TaskDescriptor(const std::string& in_app_id, | |
| 148 TaskType in_task_type, | |
| 149 const std::string& in_action_id) | |
| 150 : app_id(in_app_id), | |
| 151 task_type(in_task_type), | |
| 152 action_id(in_action_id) { | |
| 153 } | |
| 154 TaskDescriptor() { | |
| 155 } | |
| 156 | |
| 157 std::string app_id; | |
| 158 TaskType task_type; | |
| 159 std::string action_id; | |
| 160 }; | |
| 161 | |
| 162 // Describes a task with extra information such as icon URL. | |
| 163 class FullTaskDescriptor { | |
| 164 public: | |
| 165 FullTaskDescriptor(const TaskDescriptor& task_descriptor, | |
| 166 const std::string& task_title, | |
| 167 const GURL& icon_url, | |
| 168 bool is_default); | |
| 169 const TaskDescriptor& task_descriptor() const { return task_descriptor_; } | |
| 170 | |
| 171 // The title of the task. | |
| 172 const std::string& task_title() { return task_title_; } | |
| 173 // The icon URL for the task (ex. app icon) | |
| 174 const GURL& icon_url() const { return icon_url_; } | |
| 175 | |
| 176 // True if this task is set as default. | |
| 177 bool is_default() const { return is_default_; } | |
| 178 void set_is_default(bool is_default) { is_default_ = is_default; } | |
| 179 | |
| 180 // Returns a DictionaryValue representation, which looks like: | |
| 181 // | |
| 182 // { | |
| 183 // "iconUrl": "<app_icon_url>", | |
| 184 // "isDefault": false, | |
| 185 // "taskId": "<drive_app_id>|drive|open-with", | |
| 186 // "title": "Drive App Name (ex. Pixlr Editor)" | |
| 187 // }, | |
| 188 // | |
| 189 // "iconUrl" is omitted if icon_url_ is empty. | |
| 190 // | |
| 191 // This representation will be used to send task info to the JavaScript. | |
| 192 scoped_ptr<base::DictionaryValue> AsDictionaryValue() const; | |
| 193 | |
| 194 private: | |
| 195 TaskDescriptor task_descriptor_; | |
| 196 std::string task_title_; | |
| 197 GURL icon_url_; | |
| 198 bool is_default_; | |
| 199 }; | |
| 200 | |
| 201 // Update the default file handler for the given sets of suffixes and MIME | |
| 202 // types. | |
| 203 void UpdateDefaultTask(PrefService* pref_service, | |
| 204 const std::string& task_id, | |
| 205 const std::set<std::string>& suffixes, | |
| 206 const std::set<std::string>& mime_types); | |
| 207 | |
| 208 // Returns the task ID of the default task for the given |mime_type|/|suffix| | |
| 209 // combination. If it finds a MIME type match, then it prefers that over a | |
| 210 // suffix match. If it a default can't be found, then it returns the empty | |
| 211 // string. | |
| 212 std::string GetDefaultTaskIdFromPrefs(const PrefService& pref_service, | |
| 213 const std::string& mime_type, | |
| 214 const std::string& suffix); | |
| 215 | |
| 216 // Generates task id for the task specified by |app_id|, |task_type| and | |
| 217 // |action_id|. | |
| 218 // | |
| 219 // |app_id| is either of Chrome Extension/App ID or Drive App ID. | |
| 220 // |action_id| is a free-form string ID for the action. | |
| 221 std::string MakeTaskID(const std::string& app_id, | |
| 222 TaskType task_type, | |
| 223 const std::string& action_id); | |
| 224 | |
| 225 // Returns a task id for the Drive app with |app_id|. | |
| 226 // TODO(gspencer): For now, the action id is always "open-with", but we | |
| 227 // could add any actions that the drive app supports. | |
| 228 std::string MakeDriveAppTaskId(const std::string& app_id); | |
| 229 | |
| 230 // Converts |task_descriptor| to a task ID. | |
| 231 std::string TaskDescriptorToId(const TaskDescriptor& task_descriptor); | |
| 232 | |
| 233 // Parses the task ID and extracts app ID, task type, and action ID into | |
| 234 // |task|. On failure, returns false, and the contents of |task| are | |
| 235 // undefined. | |
| 236 // | |
| 237 // See also the comment at the beginning of the file for details for how | |
| 238 // "task_id" looks like. | |
| 239 bool ParseTaskID(const std::string& task_id, TaskDescriptor* task); | |
| 240 | |
| 241 // The callback is used for ExecuteFileTask(). Will be called with true if | |
| 242 // the file task execution is successful, or false if unsuccessful. | |
| 243 typedef base::Callback<void(bool success)> FileTaskFinishedCallback; | |
| 244 | |
| 245 // Executes file handler task for each element of |file_urls|. | |
| 246 // Returns |false| if the execution cannot be initiated. Otherwise returns | |
| 247 // |true| and then eventually calls |done| when all the files have been handled. | |
| 248 // |done| can be a null callback. | |
| 249 // | |
| 250 // Parameters: | |
| 251 // profile - The profile used for making this function call. | |
| 252 // app_id - The ID of the app requesting the file task execution. | |
| 253 // source_url - The source URL which originates this function call. | |
| 254 // tab_id - The ID of the tab which originates this function call. | |
| 255 // This can be 0 if no tab is associated. | |
| 256 // task - See the comment at TaskDescriptor struct. | |
| 257 // file_urls - URLs of the target files. | |
| 258 // done - The callback which will be called on completion. | |
| 259 // The callback won't be called if the function returns | |
| 260 // false. | |
| 261 bool ExecuteFileTask(Profile* profile, | |
| 262 const GURL& source_url, | |
| 263 const std::string& app_id, | |
| 264 int32 tab_id, | |
| 265 const TaskDescriptor& task, | |
| 266 const std::vector<fileapi::FileSystemURL>& file_urls, | |
| 267 const FileTaskFinishedCallback& done); | |
| 268 | |
| 269 typedef extensions::app_file_handler_util::PathAndMimeTypeSet | |
| 270 PathAndMimeTypeSet; | |
| 271 | |
| 272 // Finds the Drive app tasks that can be used with the given |path_mime_set| | |
| 273 // from |drive_app_registry|, and append them to the |result_list|. | |
| 274 // Drive app tasks will be found only if all of the files are on Drive. | |
| 275 void FindDriveAppTasks(const drive::DriveAppRegistry& drive_app_registry, | |
| 276 const PathAndMimeTypeSet& path_mime_set, | |
| 277 std::vector<FullTaskDescriptor>* result_list); | |
| 278 | |
| 279 // Finds the file handler tasks (apps declaring "file_handlers" in | |
| 280 // manifest.json) that can be used with the given files, appending them to | |
| 281 // the |result_list|. | |
| 282 void FindFileHandlerTasks(Profile* profile, | |
| 283 const PathAndMimeTypeSet& path_mime_set, | |
| 284 std::vector<FullTaskDescriptor>* result_list); | |
| 285 | |
| 286 // Finds the file browser handler tasks (app/extensions declaring | |
| 287 // "file_browser_handlers" in manifest.json) that can be used with the | |
| 288 // given files, appending them to the |result_list|. | |
| 289 void FindFileBrowserHandlerTasks( | |
| 290 Profile* profile, | |
| 291 const std::vector<GURL>& file_urls, | |
| 292 std::vector<FullTaskDescriptor>* result_list); | |
| 293 | |
| 294 // Finds all types (drive, file handlers, file browser handlers) of | |
| 295 // tasks. See the comment at FindDriveAppTasks() about |result_list|. | |
| 296 // Drive app tasks will be found only if all of the files are on Drive. | |
| 297 void FindAllTypesOfTasks( | |
| 298 Profile* profile, | |
| 299 const PathAndMimeTypeSet& path_mime_set, | |
| 300 const std::vector<GURL>& file_urls, | |
| 301 std::vector<FullTaskDescriptor>* result_list); | |
| 302 | |
| 303 // Chooses the default task in |tasks| and sets it as default, if the default | |
| 304 // task is found (i.e. the default task may not exist in |tasks|). No tasks | |
| 305 // should be set as default before calling this function. | |
| 306 void ChooseAndSetDefaultTask(const PrefService& pref_service, | |
| 307 const PathAndMimeTypeSet& path_mime_set, | |
| 308 std::vector<FullTaskDescriptor>* tasks); | |
| 309 | |
| 310 } // namespace file_tasks | |
| 311 } // namespace file_manager | |
| 312 | |
| 313 #endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_FILE_TASKS_H_ | |
| OLD | NEW |