Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(612)

Unified Diff: chrome/browser/chromeos/extensions/file_browser_private_api.cc

Issue 10834383: Chrome OS "open with" picker allowing Web Intents (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: address tbarzic comments Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/extensions/file_browser_private_api.cc
diff --git a/chrome/browser/chromeos/extensions/file_browser_private_api.cc b/chrome/browser/chromeos/extensions/file_browser_private_api.cc
index f5714bf1b713be741bd4a137857093853a7005d8..0b511124698664f8bcbc0a0fb0aa73dbef2cb5a8 100644
--- a/chrome/browser/chromeos/extensions/file_browser_private_api.cc
+++ b/chrome/browser/chromeos/extensions/file_browser_private_api.cc
@@ -9,6 +9,9 @@
#include "base/base64.h"
#include "base/bind.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/i18n/case_conversion.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/scoped_vector.h"
@@ -17,6 +20,7 @@
#include "base/stringprintf.h"
#include "base/time.h"
#include "base/values.h"
+#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/network_library.h"
#include "chrome/browser/chromeos/extensions/file_handler_util.h"
@@ -34,6 +38,7 @@
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/process_map.h"
+#include "chrome/browser/intents/web_intents_util.h"
#include "chrome/browser/google_apis/operation_registry.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
@@ -54,6 +59,7 @@
#include "grit/generated_resources.h"
#include "grit/platform_locale_settings.h"
#include "net/base/escape.h"
+#include "net/base/mime_util.h"
#include "ui/base/dialogs/selected_file_info.h"
#include "ui/base/l10n/l10n_util.h"
#include "webkit/chromeos/fileapi/cros_mount_point_provider.h"
@@ -63,6 +69,7 @@
#include "webkit/fileapi/file_system_types.h"
#include "webkit/fileapi/file_system_url.h"
#include "webkit/fileapi/file_system_util.h"
+#include "webkit/glue/web_intent_service_data.h"
using chromeos::disks::DiskMountManager;
using content::BrowserContext;
@@ -78,7 +85,7 @@ using gdata::OperationRegistry;
namespace {
// Default icon path for drive docs.
-const char kDefaultDriveIcon[] = "images/filetype_generic.png";
+const char kDefaultIcon[] = "images/filetype_generic.png";
const int kPreferredIconSize = 16;
// Error messages.
@@ -235,6 +242,44 @@ GURL FindPreferredIcon(const InstalledApp::IconList& icons,
return result;
}
+// Given an extension, a Web Intents |action|, and a set of |mime_types|,
+// determines whether this extension supports this action for all specified
+// mime-types.
+// If this method returns true, also returns the |title| of this action.
+bool ExtensionSupportsAction(const Extension* extension,
tbarzic 2012/09/13 18:44:45 nit: const Extension* extension should got to the
thorogood 2012/09/16 03:41:19 Done.
+ const std::string& action,
+ const std::set<std::string>& mime_types,
+ std::string* title) {
+ DCHECK(!mime_types.empty());
+ std::set<std::string> pending(mime_types.begin(), mime_types.end());
+ std::string found_title;
+
+ for (std::vector<webkit_glue::WebIntentServiceData>::const_iterator data =
+ extension->intents_services().begin();
+ data != extension->intents_services().end(); ++data) {
+ if (pending.empty())
+ break;
+
+ if (UTF16ToUTF8(data->action) != action)
+ continue;
+
+ std::set<std::string>::iterator pending_iter = pending.begin();
+ while (pending_iter != pending.end()) {
+ std::set<std::string>::iterator current = pending_iter++;
+ if (net::MatchesMimeType(UTF16ToUTF8(data->type), *pending_iter))
+ pending.erase(current);
+ }
+ if (found_title.empty())
+ found_title = UTF16ToUTF8(data->title);
+ }
+
+ if (!pending.empty())
+ return false; // we haven't found all mime-types
+
+ *title = found_title;
+ return true;
+}
+
// Retrieves total and remaining available size on |mount_path|.
void GetSizeStatsOnFileThread(const std::string& mount_path,
size_t* total_size_kb,
@@ -601,8 +646,8 @@ void GetFileTasksFileBrowserFunction::IntersectAvailableDriveTasks(
app_info->insert(std::make_pair((*apps)->app_id, *apps));
// TODO(gspencer): For now, the action id is always "open-with", but we
// could add any actions that the drive app supports.
- std::string task_id =
- file_handler_util::MakeDriveTaskID((*apps)->app_id, "open-with");
+ std::string task_id = file_handler_util::MakeTaskID(
+ (*apps)->app_id, file_handler_util::TASK_DRIVE, "open-with");
tasks_for_this_file.insert(task_id);
// If we failed to insert a task_id because there was a duplicate, then we
// must delete it (since we own it).
@@ -655,9 +700,12 @@ void GetFileTasksFileBrowserFunction::CreateDriveTasks(
for (std::set<std::string>::const_iterator app_iter = available_tasks.begin();
app_iter != available_tasks.end(); ++app_iter) {
std::string app_id;
- bool result = file_handler_util::CrackDriveTaskID(*app_iter, &app_id, NULL);
+ file_handler_util::TaskType task_type;
+ bool result = file_handler_util::CrackTaskID(
+ *app_iter, &app_id, &task_type, NULL);
DCHECK(result) << "Unable to parse Drive task id: " << *app_iter;
- if (!result)
+ DCHECK_EQ(task_type, file_handler_util::TASK_DRIVE);
+ if (!result || task_type != file_handler_util::TASK_DRIVE)
continue;
WebAppInfoMap::const_iterator info_iter = app_info.find(app_id);
DCHECK(info_iter != app_info.end());
@@ -706,7 +754,6 @@ bool GetFileTasksFileBrowserFunction::FindDriveAppTasks(
if (!system_service || !system_service->webapps_registry())
return true;
-
gdata::DriveWebAppsRegistry* registry = system_service->webapps_registry();
// Map of app_id to DriveWebAppInfo so we can look up the apps we've found
@@ -728,6 +775,73 @@ bool GetFileTasksFileBrowserFunction::FindDriveAppTasks(
return true;
}
+// Find Web Intent platform apps that support the View task, and add them to
+// the |result_list|. These will be marked as TASK_WEBINTENT.
+bool GetFileTasksFileBrowserFunction::FindWebIntentTasks(
+ const std::vector<GURL>& file_urls,
+ ListValue* result_list) {
+ DCHECK(!file_urls.empty());
+ ExtensionService* service = profile_->GetExtensionService();
+ if (!service)
+ return false;
+
+ std::set<std::string> mime_types;
+ for (std::vector<GURL>::const_iterator iter = file_urls.begin();
+ iter != file_urls.end(); ++iter) {
+ const FilePath file = FilePath(GURL(iter->spec()).ExtractFileName());
+ const FilePath::StringType file_extension =
+ StringToLowerASCII(file.Extension());
+
+ // TODO(thorogood): Rearchitect this call so it can run on the File thread;
+ // GetMimeTypeFromFile requires this on Linux. Right now, we use
+ // Chrome-level knowledge only.
+ std::string mime_type;
+ if (!file_extension.empty() && !net::GetWellKnownMimeTypeFromExtension(
+ file_extension.substr(1), &mime_type))
+ mime_type = std::string(); // There was no mime-type available from this
+ // file, but we'll still match "*".
+ mime_types.insert(mime_type);
+ }
+
+ for (ExtensionSet::const_iterator iter = service->extensions()->begin();
+ iter != service->extensions()->end();
+ ++iter) {
+ const Extension* extension = *iter;
+ std::string title;
+
+ // We don't support using hosted apps to open files.
+ if (!extension->is_platform_app())
+ continue;
+
+ if (profile_->IsOffTheRecord() &&
+ !service->IsIncognitoEnabled(extension->id()))
+ continue;
+
+ if (!ExtensionSupportsAction(
+ extension, web_intents::kActionView, mime_types, &title))
+ continue;
+
+ DictionaryValue* task = new DictionaryValue;
+ std::string task_id = file_handler_util::MakeTaskID(extension->id(),
+ file_handler_util::TASK_WEBINTENT, web_intents::kActionView);
+ task->SetString("taskId", task_id);
+ task->SetString("title", title);
+ task->SetBoolean("isDefault", false);
+
+ GURL best_icon = extension->GetIconURL(kPreferredIconSize,
+ ExtensionIconSet::MATCH_BIGGER);
+ if (!best_icon.is_empty())
+ task->SetString("iconUrl", best_icon.spec());
+ else
+ task->SetString("iconUrl", kDefaultIcon);
+
+ task->SetBoolean("driveApp", false);
+ result_list->Append(task);
+ }
+
+ return true;
+}
+
bool GetFileTasksFileBrowserFunction::RunImpl() {
// First argument is the list of files to get tasks for.
ListValue* files_list = NULL;
@@ -797,8 +911,8 @@ bool GetFileTasksFileBrowserFunction::RunImpl() {
const Extension* extension = service->GetExtensionById(extension_id, false);
CHECK(extension);
DictionaryValue* task = new DictionaryValue;
- task->SetString("taskId",
- file_handler_util::MakeTaskID(extension_id, handler->id()));
+ task->SetString("taskId", file_handler_util::MakeTaskID(
+ extension_id, file_handler_util::TASK_FILE, handler->id()));
task->SetString("title", handler->title());
// TODO(zelidrag): Figure out how to expose icon URL that task defined in
// manifest instead of the default extension icon.
@@ -822,6 +936,12 @@ bool GetFileTasksFileBrowserFunction::RunImpl() {
result_list->Append(task);
}
+ // Take the union of Web Intents (that platform apps may accept) and all
+ // previous Drive and extension tasks. As above, we know there aren't
+ // duplicates because they're entirely different kinds of tasks.
+ if (!FindWebIntentTasks(file_urls, result_list))
+ return false;
+
if (VLOG_IS_ON(1)) {
std::string result_json;
base::JSONWriter::WriteWithOptions(
@@ -832,8 +952,6 @@ bool GetFileTasksFileBrowserFunction::RunImpl() {
VLOG(1) << "GetFileTasks result:\n" << result_json;
}
- // TODO(zelidrag, serya): Add intent content tasks to result_list once we
- // implement that API.
SendResponse(true);
return true;
}
@@ -862,8 +980,10 @@ bool ExecuteTasksFileBrowserFunction::RunImpl() {
return false;
std::string extension_id;
+ file_handler_util::TaskType task_type;
std::string action_id;
- if (!file_handler_util::CrackTaskID(task_id, &extension_id, &action_id)) {
+ if (!file_handler_util::CrackTaskID(
+ task_id, &extension_id, &task_type, &action_id)) {
LOG(WARNING) << "Invalid task " << task_id;
return false;
}
@@ -885,6 +1005,7 @@ bool ExecuteTasksFileBrowserFunction::RunImpl() {
FileTaskExecutor::Create(profile(),
source_url(),
extension_id,
+ task_type,
action_id));
if (!executor->ExecuteAndNotify(
@@ -2017,7 +2138,8 @@ void GetDriveFilePropertiesFunction::OnOperationComplete(
file_specific_info.content_mime_type(),
file_path.Extension());
std::string default_app_id;
- file_handler_util::CrackDriveTaskID(default_task_id, &default_app_id, NULL);
+ file_handler_util::CrackTaskID(
+ default_task_id, &default_app_id, NULL, NULL);
ListValue* apps = new ListValue();
property_dict->Set("driveApps", apps);
« no previous file with comments | « chrome/browser/chromeos/extensions/file_browser_private_api.h ('k') | chrome/browser/chromeos/extensions/file_handler_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698