Chromium Code Reviews| 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 b461c9d0072826e9c1127672279060c758605b97..7d792cfe6ddb94bba5b95ea6e97ee2f35d253f55 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 HasCommonTimestamp(LastUsedHandlerList* list) { |
|
benwells
2012/08/30 08:09:03
Now I understand. Can you rename this to AllHaveSa
thorogood
2012/08/31 01:27:32
Done.
|
| + 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 (HasCommonTimestamp(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,51 @@ 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()); |
| -} |
| + DCHECK(task_type == TASK_FILE |
| + || task_type == TASK_DRIVE |
| + || task_type == TASK_WEBINTENT); |
| -std::string MakeDriveTaskID(const std::string& app_id, |
| - const std::string& action_id) { |
| - return MakeTaskID(FileTaskExecutor::kDriveTaskExtensionPrefix + app_id, |
| - action_id); |
| -} |
| + std::string out = base::StringPrintf("%s|%d|%s", |
| + extension_id.c_str(), |
| + task_type, |
| + action_id.c_str()); |
| + LOG(INFO) << "Made task_id=" << out |
|
benwells
2012/08/30 08:09:03
Make this VLOG(1) (then it will only show up with
thorogood
2012/08/31 01:27:32
Removed actually. Was just for testing.
|
| + << ", ext=" << extension_id |
| + << ", type=" << task_type |
| + << ", action=" << action_id; |
| + |
| + return out; |
| +} |
| // 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]; |
| + |
| + LOG(INFO) << "Cracked task_id=" << task_id |
| + << ", ext=" << *extension_id |
| + << ", type=" << *task_type |
| + << ", action=" << *action_id; |
| + |
| return true; |
| } |
| @@ -262,8 +301,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 +347,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 +406,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 +445,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 +464,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 +476,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 +486,7 @@ FileTaskExecutor* FileTaskExecutor::Create(Profile* profile, |
| return new ExtensionTaskExecutor(profile, |
| source_url, |
| extension_id, |
| + task_type, |
| action_id); |
| } |
| } |
| @@ -640,10 +680,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) { |
| } |
| @@ -737,7 +779,6 @@ void ExtensionTaskExecutor::ExecuteFileActionsOnUIThread( |
| InitHandlerHostFileAccessPermissions( |
| file_list, |
| extension, |
| - action_id_, |
| base::Bind( |
| &ExtensionTaskExecutor::OnInitAccessForExecuteFileActionsOnUIThread, |
| this, |
| @@ -794,6 +835,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); |
| @@ -840,7 +894,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)); |
| @@ -849,9 +902,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); |