This source file includes following definitions.
- TaskTypeToString
- StringToTaskType
- ContainsGoogleDocument
- KeepOnlyFileManagerInternalTasks
- FindTaskForAppIdAndActionId
- ChooseSuitableVideoHandler
- is_default_
- UpdateDefaultTask
- GetDefaultTaskIdFromPrefs
- MakeTaskID
- MakeDriveAppTaskId
- TaskDescriptorToId
- ParseTaskID
- ExecuteFileTask
- FindDriveAppTasks
- FindFileHandlerTasks
- FindFileBrowserHandlerTasks
- FindAllTypesOfTasks
- ChooseAndSetDefaultTask
#include "chrome/browser/chromeos/file_manager/file_tasks.h"
#include "apps/launcher.h"
#include "base/bind.h"
#include "base/prefs/pref_service.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/drive/file_task_executor.h"
#include "chrome/browser/chromeos/file_manager/app_id.h"
#include "chrome/browser/chromeos/file_manager/file_browser_handlers.h"
#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
#include "chrome/browser/chromeos/file_manager/open_util.h"
#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
#include "chrome/browser/drive/drive_app_registry.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
#include "chrome/common/extensions/api/file_browser_handlers/file_browser_handler.h"
#include "chrome/common/extensions/api/file_browser_private.h"
#include "chrome/common/pref_names.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension_set.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_url.h"
using extensions::Extension;
using extensions::app_file_handler_util::FindFileHandlersForFiles;
using fileapi::FileSystemURL;
namespace file_manager {
namespace file_tasks {
namespace {
const char kFileBrowserHandlerTaskType[] = "file";
const char kFileHandlerTaskType[] = "app";
const char kDriveAppTaskType[] = "drive";
const char kDriveAppActionID[] = "open-with";
std::string TaskTypeToString(TaskType task_type) {
switch (task_type) {
case TASK_TYPE_FILE_BROWSER_HANDLER:
return kFileBrowserHandlerTaskType;
case TASK_TYPE_FILE_HANDLER:
return kFileHandlerTaskType;
case TASK_TYPE_DRIVE_APP:
return kDriveAppTaskType;
case TASK_TYPE_UNKNOWN:
break;
}
NOTREACHED();
return "";
}
TaskType StringToTaskType(const std::string& str) {
if (str == kFileBrowserHandlerTaskType)
return TASK_TYPE_FILE_BROWSER_HANDLER;
if (str == kFileHandlerTaskType)
return TASK_TYPE_FILE_HANDLER;
if (str == kDriveAppTaskType)
return TASK_TYPE_DRIVE_APP;
return TASK_TYPE_UNKNOWN;
}
const char kDriveTaskExtensionPrefix[] = "drive-app:";
const size_t kDriveTaskExtensionPrefixLength =
arraysize(kDriveTaskExtensionPrefix) - 1;
bool ContainsGoogleDocument(const PathAndMimeTypeSet& path_mime_set) {
for (PathAndMimeTypeSet::const_iterator iter = path_mime_set.begin();
iter != path_mime_set.end(); ++iter) {
if (google_apis::ResourceEntry::ClassifyEntryKindByFileExtension(
iter->first) &
google_apis::ResourceEntry::KIND_OF_GOOGLE_DOCUMENT) {
return true;
}
}
return false;
}
void KeepOnlyFileManagerInternalTasks(std::vector<FullTaskDescriptor>* tasks) {
std::vector<FullTaskDescriptor> filtered;
for (size_t i = 0; i < tasks->size(); ++i) {
if ((*tasks)[i].task_descriptor().app_id == kFileManagerAppId)
filtered.push_back((*tasks)[i]);
}
tasks->swap(filtered);
}
std::vector<FullTaskDescriptor>::iterator
FindTaskForAppIdAndActionId(
std::vector<FullTaskDescriptor>* task_list,
const std::string& app_id,
const std::string& action_id) {
DCHECK(task_list);
std::vector<FullTaskDescriptor>::iterator iter = task_list->begin();
while (iter != task_list->end() &&
!(iter->task_descriptor().app_id == app_id &&
iter->task_descriptor().action_id == action_id)) {
++iter;
}
return iter;
}
void ChooseSuitableVideoHandler(
const std::vector<GURL>& file_urls,
std::vector<FullTaskDescriptor>* task_list) {
std::vector<FullTaskDescriptor>::iterator video_player_iter =
FindTaskForAppIdAndActionId(task_list, kVideoPlayerAppId, "video");
std::vector<FullTaskDescriptor>::iterator gallery_video_iter =
FindTaskForAppIdAndActionId(
task_list, kFileManagerAppId, "gallery-video");
if (video_player_iter != task_list->end() &&
gallery_video_iter != task_list->end()) {
if (file_urls.size() == 1)
task_list->erase(gallery_video_iter);
else
task_list->erase(video_player_iter);
}
}
}
FullTaskDescriptor::FullTaskDescriptor(
const TaskDescriptor& task_descriptor,
const std::string& task_title,
const GURL& icon_url,
bool is_default)
: task_descriptor_(task_descriptor),
task_title_(task_title),
icon_url_(icon_url),
is_default_(is_default){
}
void UpdateDefaultTask(PrefService* pref_service,
const std::string& task_id,
const std::set<std::string>& suffixes,
const std::set<std::string>& mime_types) {
if (!pref_service)
return;
if (!mime_types.empty()) {
DictionaryPrefUpdate mime_type_pref(pref_service,
prefs::kDefaultTasksByMimeType);
for (std::set<std::string>::const_iterator iter = mime_types.begin();
iter != mime_types.end(); ++iter) {
base::StringValue* value = new base::StringValue(task_id);
mime_type_pref->SetWithoutPathExpansion(*iter, value);
}
}
if (!suffixes.empty()) {
DictionaryPrefUpdate mime_type_pref(pref_service,
prefs::kDefaultTasksBySuffix);
for (std::set<std::string>::const_iterator iter = suffixes.begin();
iter != suffixes.end(); ++iter) {
base::StringValue* value = new base::StringValue(task_id);
std::string lower_suffix = StringToLowerASCII(*iter);
mime_type_pref->SetWithoutPathExpansion(lower_suffix, value);
}
}
}
std::string GetDefaultTaskIdFromPrefs(const PrefService& pref_service,
const std::string& mime_type,
const std::string& suffix) {
VLOG(1) << "Looking for default for MIME type: " << mime_type
<< " and suffix: " << suffix;
std::string task_id;
if (!mime_type.empty()) {
const base::DictionaryValue* mime_task_prefs =
pref_service.GetDictionary(prefs::kDefaultTasksByMimeType);
DCHECK(mime_task_prefs);
LOG_IF(ERROR, !mime_task_prefs) << "Unable to open MIME type prefs";
if (mime_task_prefs &&
mime_task_prefs->GetStringWithoutPathExpansion(mime_type, &task_id)) {
VLOG(1) << "Found MIME default handler: " << task_id;
return task_id;
}
}
const base::DictionaryValue* suffix_task_prefs =
pref_service.GetDictionary(prefs::kDefaultTasksBySuffix);
DCHECK(suffix_task_prefs);
LOG_IF(ERROR, !suffix_task_prefs) << "Unable to open suffix prefs";
std::string lower_suffix = StringToLowerASCII(suffix);
if (suffix_task_prefs)
suffix_task_prefs->GetStringWithoutPathExpansion(lower_suffix, &task_id);
VLOG_IF(1, !task_id.empty()) << "Found suffix default handler: " << task_id;
return task_id;
}
std::string MakeTaskID(const std::string& app_id,
TaskType task_type,
const std::string& action_id) {
return base::StringPrintf("%s|%s|%s",
app_id.c_str(),
TaskTypeToString(task_type).c_str(),
action_id.c_str());
}
std::string MakeDriveAppTaskId(const std::string& app_id) {
return MakeTaskID(app_id, TASK_TYPE_DRIVE_APP, kDriveAppActionID);
}
std::string TaskDescriptorToId(const TaskDescriptor& task_descriptor) {
return MakeTaskID(task_descriptor.app_id,
task_descriptor.task_type,
task_descriptor.action_id);
}
bool ParseTaskID(const std::string& task_id, TaskDescriptor* task) {
DCHECK(task);
std::vector<std::string> result;
int count = Tokenize(task_id, std::string("|"), &result);
if (count == 2) {
if (StartsWithASCII(result[0], kDriveTaskExtensionPrefix, true)) {
task->task_type = TASK_TYPE_DRIVE_APP;
task->app_id = result[0].substr(kDriveTaskExtensionPrefixLength);
} else {
task->task_type = TASK_TYPE_FILE_BROWSER_HANDLER;
task->app_id = result[0];
}
task->action_id = result[1];
return true;
}
if (count != 3)
return false;
TaskType task_type = StringToTaskType(result[1]);
if (task_type == TASK_TYPE_UNKNOWN)
return false;
task->app_id = result[0];
task->task_type = task_type;
task->action_id = result[2];
return true;
}
bool ExecuteFileTask(Profile* profile,
const GURL& source_url,
const TaskDescriptor& task,
const std::vector<FileSystemURL>& file_urls,
const FileTaskFinishedCallback& done) {
if (task.task_type == TASK_TYPE_DRIVE_APP) {
DCHECK_EQ(kDriveAppActionID, task.action_id);
drive::FileTaskExecutor* executor =
new drive::FileTaskExecutor(profile, task.app_id);
executor->Execute(file_urls, done);
return true;
}
ExtensionService* service =
extensions::ExtensionSystem::Get(profile)->extension_service();
const Extension* extension = service ?
service->GetExtensionById(task.app_id, false) : NULL;
if (!extension)
return false;
if (task.task_type == TASK_TYPE_FILE_BROWSER_HANDLER) {
return file_browser_handlers::ExecuteFileBrowserHandler(
profile,
extension,
task.action_id,
file_urls,
done);
} else if (task.task_type == TASK_TYPE_FILE_HANDLER) {
for (size_t i = 0; i != file_urls.size(); ++i) {
apps::LaunchPlatformAppWithFileHandler(
profile, extension, task.action_id, file_urls[i].path());
}
if (!done.is_null())
done.Run(extensions::api::file_browser_private::TASK_RESULT_MESSAGE_SENT);
return true;
}
NOTREACHED();
return false;
}
void FindDriveAppTasks(
const drive::DriveAppRegistry& drive_app_registry,
const PathAndMimeTypeSet& path_mime_set,
std::vector<FullTaskDescriptor>* result_list) {
DCHECK(result_list);
bool is_first = true;
typedef std::map<std::string, drive::DriveAppInfo> DriveAppInfoMap;
DriveAppInfoMap drive_app_map;
for (PathAndMimeTypeSet::const_iterator it = path_mime_set.begin();
it != path_mime_set.end(); ++it) {
const base::FilePath& file_path = it->first;
const std::string& mime_type = it->second;
if (!drive::util::IsUnderDriveMountPoint(file_path))
return;
std::vector<drive::DriveAppInfo> app_info_list;
drive_app_registry.GetAppsForFile(file_path.Extension(),
mime_type,
&app_info_list);
if (is_first) {
for (size_t j = 0; j < app_info_list.size(); ++j)
drive_app_map[app_info_list[j].app_id] = app_info_list[j];
} else {
std::set<std::string> app_id_set;
for (size_t j = 0; j < app_info_list.size(); ++j)
app_id_set.insert(app_info_list[j].app_id);
for (DriveAppInfoMap::iterator iter = drive_app_map.begin();
iter != drive_app_map.end();) {
if (app_id_set.count(iter->first) == 0) {
drive_app_map.erase(iter++);
} else {
++iter;
}
}
}
is_first = false;
}
for (DriveAppInfoMap::const_iterator iter = drive_app_map.begin();
iter != drive_app_map.end(); ++iter) {
const drive::DriveAppInfo& app_info = iter->second;
TaskDescriptor descriptor(app_info.app_id,
TASK_TYPE_DRIVE_APP,
kDriveAppActionID);
GURL icon_url = drive::util::FindPreferredIcon(
app_info.app_icons,
drive::util::kPreferredIconSize);
result_list->push_back(
FullTaskDescriptor(descriptor,
app_info.app_name,
icon_url,
false ));
}
}
void FindFileHandlerTasks(
Profile* profile,
const PathAndMimeTypeSet& path_mime_set,
std::vector<FullTaskDescriptor>* result_list) {
DCHECK(!path_mime_set.empty());
DCHECK(result_list);
ExtensionService* service = profile->GetExtensionService();
if (!service)
return;
for (extensions::ExtensionSet::const_iterator iter =
service->extensions()->begin();
iter != service->extensions()->end();
++iter) {
const Extension* extension = iter->get();
if (!extension->is_platform_app())
continue;
if (profile->IsOffTheRecord() &&
!extensions::util::IsIncognitoEnabled(extension->id(), profile))
continue;
typedef std::vector<const extensions::FileHandlerInfo*> FileHandlerList;
FileHandlerList file_handlers =
FindFileHandlersForFiles(*extension, path_mime_set);
if (file_handlers.empty())
continue;
for (FileHandlerList::iterator i = file_handlers.begin();
i != file_handlers.end(); ++i) {
std::string task_id = file_tasks::MakeTaskID(
extension->id(), file_tasks::TASK_TYPE_FILE_HANDLER, (*i)->id);
GURL best_icon = extensions::ExtensionIconSource::GetIconURL(
extension,
drive::util::kPreferredIconSize,
ExtensionIconSet::MATCH_BIGGER,
false,
NULL);
result_list->push_back(FullTaskDescriptor(
TaskDescriptor(extension->id(),
file_tasks::TASK_TYPE_FILE_HANDLER,
(*i)->id),
(*i)->title,
best_icon,
false ));
}
}
}
void FindFileBrowserHandlerTasks(
Profile* profile,
const std::vector<GURL>& file_urls,
std::vector<FullTaskDescriptor>* result_list) {
DCHECK(!file_urls.empty());
DCHECK(result_list);
file_browser_handlers::FileBrowserHandlerList common_tasks =
file_browser_handlers::FindFileBrowserHandlers(profile, file_urls);
if (common_tasks.empty())
return;
ExtensionService* service =
extensions::ExtensionSystem::Get(profile)->extension_service();
for (file_browser_handlers::FileBrowserHandlerList::const_iterator iter =
common_tasks.begin();
iter != common_tasks.end();
++iter) {
const FileBrowserHandler* handler = *iter;
const std::string extension_id = handler->extension_id();
const Extension* extension = service->GetExtensionById(extension_id, false);
DCHECK(extension);
const GURL icon_url = extensions::ExtensionIconSource::GetIconURL(
extension,
extension_misc::EXTENSION_ICON_BITTY,
ExtensionIconSet::MATCH_BIGGER,
false,
NULL);
result_list->push_back(FullTaskDescriptor(
TaskDescriptor(extension_id,
file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER,
handler->id()),
handler->title(),
icon_url,
false ));
}
}
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) {
DCHECK(profile);
DCHECK(result_list);
if (drive_app_registry)
FindDriveAppTasks(*drive_app_registry, path_mime_set, result_list);
FindFileHandlerTasks(profile, path_mime_set, result_list);
FindFileBrowserHandlerTasks(profile, file_urls, result_list);
if (ContainsGoogleDocument(path_mime_set))
KeepOnlyFileManagerInternalTasks(result_list);
ChooseSuitableVideoHandler(file_urls, result_list);
ChooseAndSetDefaultTask(*profile->GetPrefs(), path_mime_set, result_list);
}
void ChooseAndSetDefaultTask(const PrefService& pref_service,
const PathAndMimeTypeSet& path_mime_set,
std::vector<FullTaskDescriptor>* tasks) {
std::set<std::string> default_task_ids;
for (PathAndMimeTypeSet::const_iterator it = path_mime_set.begin();
it != path_mime_set.end(); ++it) {
const base::FilePath& file_path = it->first;
const std::string& mime_type = it->second;
std::string task_id = file_tasks::GetDefaultTaskIdFromPrefs(
pref_service, mime_type, file_path.Extension());
default_task_ids.insert(task_id);
}
for (size_t i = 0; i < tasks->size(); ++i) {
FullTaskDescriptor* task = &tasks->at(i);
DCHECK(!task->is_default());
const std::string task_id = TaskDescriptorToId(task->task_descriptor());
if (ContainsKey(default_task_ids, task_id)) {
task->set_is_default(true);
return;
}
}
for (size_t i = 0; i < tasks->size(); ++i) {
FullTaskDescriptor* task = &tasks->at(i);
DCHECK(!task->is_default());
if (file_browser_handlers::IsFallbackFileBrowserHandler(
task->task_descriptor())) {
task->set_is_default(true);
return;
}
}
}
}
}