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