| Index: chrome/browser/chromeos/extensions/file_handler_util.cc
|
| diff --git a/chrome/browser/chromeos/extensions/file_handler_util.cc b/chrome/browser/chromeos/extensions/file_handler_util.cc
|
| index 60f7c6e92563574001d69e9ad4cdf41984c0fe0c..e16737055f452b3f9b2dec710308644d5f7c2fe0 100644
|
| --- a/chrome/browser/chromeos/extensions/file_handler_util.cc
|
| +++ b/chrome/browser/chromeos/extensions/file_handler_util.cc
|
| @@ -20,6 +20,7 @@
|
| #include "chrome/browser/extensions/extension_system.h"
|
| #include "chrome/browser/extensions/extension_tab_util.h"
|
| #include "chrome/browser/extensions/lazy_background_task_queue.h"
|
| +#include "chrome/browser/extensions/platform_app_launcher.h"
|
| #include "chrome/browser/prefs/scoped_user_pref_update.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| #include "chrome/browser/profiles/profile_manager.h"
|
| @@ -38,6 +39,7 @@
|
| #include "webkit/fileapi/file_system_context.h"
|
| #include "webkit/fileapi/file_system_url.h"
|
| #include "webkit/fileapi/file_system_util.h"
|
| +#include "webkit/fileapi/isolated_context.h"
|
|
|
| using content::BrowserContext;
|
| using content::BrowserThread;
|
| @@ -48,11 +50,6 @@ using extensions::Extension;
|
|
|
| namespace file_handler_util {
|
|
|
| -// The prefix used to differentiate drive extensions from Chrome extensions.
|
| -const char FileTaskExecutor::kDriveTaskExtensionPrefix[] = "drive-app:";
|
| -const size_t FileTaskExecutor::kDriveTaskExtensionPrefixLength =
|
| - arraysize(FileTaskExecutor::kDriveTaskExtensionPrefix) - 1;
|
| -
|
| namespace {
|
|
|
| const int kReadWriteFilePermissions = base::PLATFORM_FILE_OPEN |
|
| @@ -120,7 +117,11 @@ const FileBrowserHandler* FindFileBrowserHandler(const Extension* extension,
|
| }
|
|
|
| unsigned int GetAccessPermissionsForHandler(const Extension* extension,
|
| - const std::string& action_id) {
|
| + const std::string& action_id,
|
| + TaskType task_type) {
|
| + if (task_type == TASK_WEBINTENT)
|
| + return kReadOnlyFilePermissions;
|
| +
|
| const FileBrowserHandler* action =
|
| FindFileBrowserHandler(extension, action_id);
|
| if (!action)
|
| @@ -134,7 +135,6 @@ unsigned int GetAccessPermissionsForHandler(const Extension* extension,
|
| return result;
|
| }
|
|
|
| -
|
| std::string EscapedUtf8ToLower(const std::string& str) {
|
| string16 utf16 = UTF8ToUTF16(
|
| net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL));
|
| @@ -189,11 +189,29 @@ bool SortByTaskName(const LastUsedHandler& a, const LastUsedHandler& b) {
|
| b.handler->title().c_str()) > 0;
|
| }
|
|
|
| +// Does this LastUsedHandlerList contain entries with only a common timestamp?
|
| +bool AllHaveSameTimestamp(LastUsedHandlerList* list) {
|
| + DCHECK(!list->empty());
|
| + int common_timestamp = list->begin()->timestamp;
|
| + for (LastUsedHandlerList::const_iterator iter = list->begin() + 1;
|
| + iter != list->end(); ++iter) {
|
| + if (common_timestamp != iter->timestamp)
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| void SortLastUsedHandlerList(LastUsedHandlerList *list) {
|
| - // Sort by the last used descending.
|
| - std::sort(list->begin(), list->end(), SortByLastUsedTimestampDesc);
|
| - if (list->size() > 1) {
|
| - // Sort the rest by name.
|
| + // If we've got one element or fewer, the list is already sorted. If the
|
| + // handlers have a common timestamp (e.g., if no handlers have ever been
|
| + // invoked), just sort by name. Otherwise, bring the last used handler to
|
| + // the front and sort the rest by name.
|
| + if (list->size() <= 1) {
|
| + // do nothing
|
| + } else if (AllHaveSameTimestamp(list)) {
|
| + std::sort(list->begin(), list->end(), SortByTaskName);
|
| + } else {
|
| + std::sort(list->begin(), list->end(), SortByLastUsedTimestampDesc);
|
| std::sort(list->begin() + 1, list->end(), SortByTaskName);
|
| }
|
| }
|
| @@ -221,30 +239,38 @@ int GetReadOnlyPermissions() {
|
| }
|
|
|
| std::string MakeTaskID(const std::string& extension_id,
|
| + TaskType task_type,
|
| const std::string& action_id) {
|
| - return base::StringPrintf("%s|%s", extension_id.c_str(), action_id.c_str());
|
| -}
|
| -
|
| -std::string MakeDriveTaskID(const std::string& app_id,
|
| - const std::string& action_id) {
|
| - return MakeTaskID(FileTaskExecutor::kDriveTaskExtensionPrefix + app_id,
|
| - action_id);
|
| + DCHECK(task_type == TASK_FILE
|
| + || task_type == TASK_DRIVE
|
| + || task_type == TASK_WEBINTENT);
|
| + return base::StringPrintf("%s|%d|%s",
|
| + extension_id.c_str(),
|
| + task_type,
|
| + action_id.c_str());
|
| }
|
|
|
| -
|
| // Breaks down task_id that is used between getFileTasks() and executeTask() on
|
| // its building blocks. task_id field the following structure:
|
| -// <extension-id>|<task-action-id>
|
| +// <extension-id>|<task-type>|<task-action-id>
|
| // Currently, the only supported task-type is of 'context'.
|
| bool CrackTaskID(const std::string& task_id,
|
| std::string* extension_id,
|
| + TaskType* task_type,
|
| std::string* action_id) {
|
| std::vector<std::string> result;
|
| int count = Tokenize(task_id, std::string("|"), &result);
|
| - if (count != 2)
|
| + if (count != 3)
|
| return false;
|
| *extension_id = result[0];
|
| - *action_id = result[1];
|
| +
|
| + *task_type = file_handler_util::TaskType(atoi(result[1].c_str()));
|
| + DCHECK(*task_type == TASK_FILE
|
| + || *task_type == TASK_DRIVE
|
| + || *task_type == TASK_WEBINTENT);
|
| +
|
| + *action_id = result[2];
|
| +
|
| return true;
|
| }
|
|
|
| @@ -262,8 +288,8 @@ LastUsedHandlerList::iterator FindHandler(
|
| return iter;
|
| }
|
|
|
| -// Given the list of selected files, returns array of context menu tasks
|
| -// that are shared
|
| +// Given the list of selected files, returns array of file action tasks
|
| +// that are shared between them.
|
| bool FindCommonTasks(Profile* profile,
|
| const std::vector<GURL>& files_list,
|
| LastUsedHandlerList* named_action_list) {
|
| @@ -308,7 +334,9 @@ bool FindCommonTasks(Profile* profile,
|
| // to make sure it is the default on a fresh profile.
|
| last_used_timestamp = 1;
|
| }
|
| - prefs_tasks->GetInteger(MakeTaskID((*iter)->extension_id(), (*iter)->id()),
|
| + prefs_tasks->GetInteger(MakeTaskID((*iter)->extension_id(),
|
| + TASK_FILE,
|
| + (*iter)->id()),
|
| &last_used_timestamp);
|
| URLPatternSet matching_patterns = GetAllMatchingPatterns(*iter, files_list);
|
| named_action_list->push_back(LastUsedHandler(last_used_timestamp, *iter,
|
| @@ -365,6 +393,7 @@ class ExtensionTaskExecutor : public FileTaskExecutor {
|
| ExtensionTaskExecutor(Profile* profile,
|
| const GURL source_url,
|
| const std::string& extension_id,
|
| + TaskType task_type,
|
| const std::string& action_id);
|
| virtual ~ExtensionTaskExecutor();
|
|
|
| @@ -403,7 +432,6 @@ class ExtensionTaskExecutor : public FileTaskExecutor {
|
| void InitHandlerHostFileAccessPermissions(
|
| const FileDefinitionList& file_list,
|
| const extensions::Extension* handler_extension,
|
| - const std::string& action_id,
|
| const base::Closure& callback);
|
|
|
| // Invoked upon completion of InitHandlerHostFileAccessPermissions initiated
|
| @@ -423,6 +451,7 @@ class ExtensionTaskExecutor : public FileTaskExecutor {
|
|
|
| const GURL source_url_;
|
| const std::string extension_id_;
|
| + TaskType task_type_;
|
| const std::string action_id_;
|
| FileTaskFinishedCallback done_;
|
|
|
| @@ -434,12 +463,9 @@ class ExtensionTaskExecutor : public FileTaskExecutor {
|
| FileTaskExecutor* FileTaskExecutor::Create(Profile* profile,
|
| const GURL source_url,
|
| const std::string& extension_id,
|
| + TaskType task_type,
|
| const std::string& action_id) {
|
| - // Check out the extension ID and see if this is a drive task,
|
| - // and instantiate drive-specific executor if so.
|
| - if (StartsWithASCII(extension_id,
|
| - FileTaskExecutor::kDriveTaskExtensionPrefix,
|
| - false)) {
|
| + if (task_type == TASK_DRIVE) {
|
| return new gdata::DriveTaskExecutor(profile,
|
| extension_id, // really app_id
|
| action_id);
|
| @@ -447,6 +473,7 @@ FileTaskExecutor* FileTaskExecutor::Create(Profile* profile,
|
| return new ExtensionTaskExecutor(profile,
|
| source_url,
|
| extension_id,
|
| + task_type,
|
| action_id);
|
| }
|
| }
|
| @@ -634,10 +661,12 @@ ExtensionTaskExecutor::ExtensionTaskExecutor(
|
| Profile* profile,
|
| const GURL source_url,
|
| const std::string& extension_id,
|
| + TaskType task_type,
|
| const std::string& action_id)
|
| : FileTaskExecutor(profile),
|
| source_url_(source_url),
|
| extension_id_(extension_id),
|
| + task_type_(task_type),
|
| action_id_(action_id) {
|
| }
|
|
|
| @@ -731,7 +760,6 @@ void ExtensionTaskExecutor::ExecuteFileActionsOnUIThread(
|
| InitHandlerHostFileAccessPermissions(
|
| file_list,
|
| extension,
|
| - action_id_,
|
| base::Bind(
|
| &ExtensionTaskExecutor::OnInitAccessForExecuteFileActionsOnUIThread,
|
| this,
|
| @@ -788,6 +816,19 @@ void ExtensionTaskExecutor::SetupPermissionsAndDispatchEvent(
|
| return;
|
| }
|
|
|
| + // If we're a Web Intent action (to an extension), short-circuit and deliver
|
| + // the Web Intent via LaunchPlatformAppWithPath.
|
| + if (task_type_ == TASK_WEBINTENT) {
|
| + for (FileDefinitionList::const_iterator iter = file_list.begin();
|
| + iter != file_list.end(); ++iter) {
|
| + extensions::LaunchPlatformAppWithPath(
|
| + profile(), GetExtension(), iter->absolute_path);
|
| + }
|
| + ExecuteDoneOnUIThread(true);
|
| + return;
|
| + }
|
| + DCHECK(task_type_ == TASK_FILE);
|
| +
|
| extensions::EventRouter* event_router = profile()->GetExtensionEventRouter();
|
| if (!event_router) {
|
| ExecuteDoneOnUIThread(false);
|
| @@ -834,7 +875,6 @@ void ExtensionTaskExecutor::SetupPermissionsAndDispatchEvent(
|
| void ExtensionTaskExecutor::InitHandlerHostFileAccessPermissions(
|
| const FileDefinitionList& file_list,
|
| const Extension* handler_extension,
|
| - const std::string& action_id,
|
| const base::Closure& callback) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
|
|
| @@ -843,9 +883,10 @@ void ExtensionTaskExecutor::InitHandlerHostFileAccessPermissions(
|
| iter != file_list.end();
|
| ++iter) {
|
| // Setup permission for file's absolute file.
|
| - handler_host_permissions_.push_back(std::make_pair(
|
| - iter->absolute_path,
|
| - GetAccessPermissionsForHandler(handler_extension, action_id)));
|
| + handler_host_permissions_.push_back(std::make_pair(iter->absolute_path,
|
| + GetAccessPermissionsForHandler(handler_extension,
|
| + action_id_,
|
| + task_type_)));
|
|
|
| if (gdata::util::IsUnderGDataMountPoint(iter->absolute_path))
|
| gdata_paths->push_back(iter->virtual_path);
|
|
|