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

Unified Diff: chrome/browser/chromeos/extensions/file_manager/file_browser_handlers.cc

Issue 23945002: file_manager: Move non-binding code to c/b/chromeos/file_manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 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_manager/file_browser_handlers.cc
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_handlers.cc b/chrome/browser/chromeos/extensions/file_manager/file_browser_handlers.cc
deleted file mode 100644
index 789536d50c5af6557431370e43734e5306bb8d2b..0000000000000000000000000000000000000000
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_handlers.cc
+++ /dev/null
@@ -1,660 +0,0 @@
-// 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.
-
-#include "chrome/browser/chromeos/extensions/file_manager/file_browser_handlers.h"
-
-#include "base/bind.h"
-#include "base/file_util.h"
-#include "base/i18n/case_conversion.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/chromeos/drive/file_system_util.h"
-#include "chrome/browser/chromeos/extensions/file_manager/app_id.h"
-#include "chrome/browser/chromeos/extensions/file_manager/fileapi_util.h"
-#include "chrome/browser/chromeos/extensions/file_manager/open_with_browser.h"
-#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
-#include "chrome/browser/extensions/event_router.h"
-#include "chrome/browser/extensions/extension_host.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/lazy_background_task_queue.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/common/extensions/api/file_browser_handlers/file_browser_handler.h"
-#include "chrome/common/extensions/background_info.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/child_process_security_policy.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/site_instance.h"
-#include "content/public/browser/web_contents.h"
-#include "net/base/escape.h"
-#include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/file_system_url.h"
-
-using content::BrowserThread;
-using content::ChildProcessSecurityPolicy;
-using content::SiteInstance;
-using content::WebContents;
-using extensions::Extension;
-using fileapi::FileSystemURL;
-
-namespace file_manager {
-namespace file_browser_handlers {
-namespace {
-
-// Returns process id of the process the extension is running in.
-int ExtractProcessFromExtensionId(Profile* profile,
- const std::string& extension_id) {
- GURL extension_url =
- Extension::GetBaseURLFromExtensionId(extension_id);
- ExtensionProcessManager* manager =
- extensions::ExtensionSystem::Get(profile)->process_manager();
-
- SiteInstance* site_instance = manager->GetSiteInstanceForURL(extension_url);
- if (!site_instance || !site_instance->HasProcess())
- return -1;
- content::RenderProcessHost* process = site_instance->GetProcess();
-
- return process->GetID();
-}
-
-// Finds a file browser handler that matches |action_id|. Returns NULL if not
-// found.
-const FileBrowserHandler* FindFileBrowserHandlerForActionId(
- const Extension* extension,
- const std::string& action_id) {
- FileBrowserHandler::List* handler_list =
- FileBrowserHandler::GetHandlers(extension);
- for (FileBrowserHandler::List::const_iterator handler_iter =
- handler_list->begin();
- handler_iter != handler_list->end();
- ++handler_iter) {
- if (handler_iter->get()->id() == action_id)
- return handler_iter->get();
- }
- return NULL;
-}
-
-std::string EscapedUtf8ToLower(const std::string& str) {
- string16 utf16 = UTF8ToUTF16(
- net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL));
- return net::EscapeUrlEncodedData(
- UTF16ToUTF8(base::i18n::ToLower(utf16)),
- false /* do not replace space with plus */);
-}
-
-// Finds file browser handlers that can handle the |selected_file_url|.
-FileBrowserHandlerList FindFileBrowserHandlersForURL(
- Profile* profile,
- const GURL& selected_file_url) {
- ExtensionService* service =
- extensions::ExtensionSystem::Get(profile)->extension_service();
- // In unit-tests, we may not have an ExtensionService.
- if (!service)
- return FileBrowserHandlerList();
-
- // We need case-insensitive matching, and pattern in the handler is already
- // in lower case.
- const GURL lowercase_url(EscapedUtf8ToLower(selected_file_url.spec()));
-
- FileBrowserHandlerList results;
- for (ExtensionSet::const_iterator iter = service->extensions()->begin();
- iter != service->extensions()->end();
- ++iter) {
- const Extension* extension = iter->get();
- if (profile->IsOffTheRecord() &&
- !service->IsIncognitoEnabled(extension->id()))
- continue;
-
- FileBrowserHandler::List* handler_list =
- FileBrowserHandler::GetHandlers(extension);
- if (!handler_list)
- continue;
- for (FileBrowserHandler::List::const_iterator handler_iter =
- handler_list->begin();
- handler_iter != handler_list->end();
- ++handler_iter) {
- const FileBrowserHandler* handler = handler_iter->get();
- if (!handler->MatchesURL(lowercase_url))
- continue;
-
- results.push_back(handler_iter->get());
- }
- }
- return results;
-}
-
-// Finds a file browser handler that matches |extension_id| and |action_id|
-// from |handler_list|. Returns a mutable iterator to the handler if
-// found. Returns handler_list->end() if not found.
-FileBrowserHandlerList::iterator
-FindFileBrowserHandlerForExtensionIdAndActionId(
- FileBrowserHandlerList* handler_list,
- const std::string& extension_id,
- const std::string& action_id) {
- DCHECK(handler_list);
-
- FileBrowserHandlerList::iterator iter = handler_list->begin();
- while (iter != handler_list->end() &&
- !((*iter)->extension_id() == extension_id &&
- (*iter)->id() == action_id)) {
- ++iter;
- }
- return iter;
-}
-
-// This class is used to execute a file browser handler task. Here's how this
-// works:
-//
-// 1) Open the "external" file system
-// 2) Set up permissions for the target files on the external file system.
-// 3) Raise onExecute event with the action ID and entries of the target
-// files. The event will launch the file browser handler if not active.
-// 4) In the file browser handler, onExecute event is handled and executes the
-// task in JavaScript.
-//
-// That said, the class itself does not execute a task. The task will be
-// executed in JavaScript.
-class FileBrowserHandlerExecutor {
- public:
- FileBrowserHandlerExecutor(Profile* profile,
- const Extension* extension,
- int32 tab_id,
- const std::string& action_id);
-
- // Executes the task for each file. |done| will be run with the result.
- void Execute(const std::vector<FileSystemURL>& file_urls,
- const file_tasks::FileTaskFinishedCallback& done);
-
- private:
- // This object is responsible to delete itself.
- virtual ~FileBrowserHandlerExecutor();
-
- struct FileDefinition {
- FileDefinition();
- ~FileDefinition();
-
- base::FilePath virtual_path;
- base::FilePath absolute_path;
- bool is_directory;
- };
-
- typedef std::vector<FileDefinition> FileDefinitionList;
-
- // Checks legitimacy of file url and grants file RO access permissions from
- // handler (target) extension and its renderer process.
- static FileDefinitionList SetupFileAccessPermissions(
- scoped_refptr<fileapi::FileSystemContext> file_system_context_handler,
- const scoped_refptr<const Extension>& handler_extension,
- const std::vector<FileSystemURL>& file_urls);
-
- void DidOpenFileSystem(const std::vector<FileSystemURL>& file_urls,
- base::PlatformFileError result,
- const std::string& file_system_name,
- const GURL& file_system_root);
-
- void ExecuteDoneOnUIThread(bool success);
- void ExecuteFileActionsOnUIThread(const std::string& file_system_name,
- const GURL& file_system_root,
- const FileDefinitionList& file_list);
- void SetupPermissionsAndDispatchEvent(const std::string& file_system_name,
- const GURL& file_system_root,
- const FileDefinitionList& file_list,
- int handler_pid_in,
- extensions::ExtensionHost* host);
-
- // Registers file permissions from |handler_host_permissions_| with
- // ChildProcessSecurityPolicy for process with id |handler_pid|.
- void SetupHandlerHostFileAccessPermissions(
- const FileDefinitionList& file_list,
- const Extension* extension,
- int handler_pid);
-
- Profile* profile_;
- scoped_refptr<const Extension> extension_;
- int32 tab_id_;
- const std::string action_id_;
- file_tasks::FileTaskFinishedCallback done_;
- base::WeakPtrFactory<FileBrowserHandlerExecutor> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(FileBrowserHandlerExecutor);
-};
-
-FileBrowserHandlerExecutor::FileDefinition::FileDefinition()
- : is_directory(false) {
-}
-
-FileBrowserHandlerExecutor::FileDefinition::~FileDefinition() {
-}
-
-// static
-FileBrowserHandlerExecutor::FileDefinitionList
-FileBrowserHandlerExecutor::SetupFileAccessPermissions(
- scoped_refptr<fileapi::FileSystemContext> file_system_context_handler,
- const scoped_refptr<const Extension>& handler_extension,
- const std::vector<FileSystemURL>& file_urls) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(handler_extension.get());
-
- fileapi::ExternalFileSystemBackend* backend =
- file_system_context_handler->external_backend();
-
- FileDefinitionList file_list;
- for (size_t i = 0; i < file_urls.size(); ++i) {
- const FileSystemURL& url = file_urls[i];
-
- // Check if this file system entry exists first.
- base::PlatformFileInfo file_info;
-
- base::FilePath local_path = url.path();
- base::FilePath virtual_path = url.virtual_path();
-
- bool is_drive_file = url.type() == fileapi::kFileSystemTypeDrive;
- DCHECK(!is_drive_file || drive::util::IsUnderDriveMountPoint(local_path));
-
- // If the file is under drive mount point, there is no actual file to be
- // found on the url.path().
- if (!is_drive_file) {
- if (!base::PathExists(local_path) ||
- file_util::IsLink(local_path) ||
- !file_util::GetFileInfo(local_path, &file_info)) {
- continue;
- }
- }
-
- // Grant access to this particular file to target extension. This will
- // ensure that the target extension can access only this FS entry and
- // prevent from traversing FS hierarchy upward.
- backend->GrantFileAccessToExtension(
- handler_extension->id(), virtual_path);
-
- // Output values.
- FileDefinition file;
- file.virtual_path = virtual_path;
- file.is_directory = file_info.is_directory;
- file.absolute_path = local_path;
- file_list.push_back(file);
- }
- return file_list;
-}
-
-FileBrowserHandlerExecutor::FileBrowserHandlerExecutor(
- Profile* profile,
- const Extension* extension,
- int32 tab_id,
- const std::string& action_id)
- : profile_(profile),
- extension_(extension),
- tab_id_(tab_id),
- action_id_(action_id),
- weak_ptr_factory_(this) {
-}
-
-FileBrowserHandlerExecutor::~FileBrowserHandlerExecutor() {}
-
-void FileBrowserHandlerExecutor::Execute(
- const std::vector<FileSystemURL>& file_urls,
- const file_tasks::FileTaskFinishedCallback& done) {
- done_ = done;
-
- // Get file system context for the extension to which onExecute event will be
- // sent. The file access permissions will be granted to the extension in the
- // file system context for the files in |file_urls|.
- util::GetFileSystemContextForExtensionId(
- profile_, extension_->id())->OpenFileSystem(
- Extension::GetBaseURLFromExtensionId(extension_->id()).GetOrigin(),
- fileapi::kFileSystemTypeExternal,
- fileapi::OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT,
- base::Bind(&FileBrowserHandlerExecutor::DidOpenFileSystem,
- weak_ptr_factory_.GetWeakPtr(),
- file_urls));
-}
-
-void FileBrowserHandlerExecutor::DidOpenFileSystem(
- const std::vector<FileSystemURL>& file_urls,
- base::PlatformFileError result,
- const std::string& file_system_name,
- const GURL& file_system_root) {
- if (result != base::PLATFORM_FILE_OK) {
- ExecuteDoneOnUIThread(false);
- return;
- }
-
- scoped_refptr<fileapi::FileSystemContext> file_system_context(
- util::GetFileSystemContextForExtensionId(
- profile_, extension_->id()));
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::FILE,
- FROM_HERE,
- base::Bind(&SetupFileAccessPermissions,
- file_system_context,
- extension_,
- file_urls),
- base::Bind(&FileBrowserHandlerExecutor::ExecuteFileActionsOnUIThread,
- weak_ptr_factory_.GetWeakPtr(),
- file_system_name,
- file_system_root));
-}
-
-void FileBrowserHandlerExecutor::ExecuteDoneOnUIThread(bool success) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (!done_.is_null())
- done_.Run(success);
- delete this;
-}
-
-void FileBrowserHandlerExecutor::ExecuteFileActionsOnUIThread(
- const std::string& file_system_name,
- const GURL& file_system_root,
- const FileDefinitionList& file_list) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (file_list.empty()) {
- ExecuteDoneOnUIThread(false);
- return;
- }
-
- int handler_pid = ExtractProcessFromExtensionId(profile_, extension_->id());
- if (handler_pid <= 0 &&
- !extensions::BackgroundInfo::HasLazyBackgroundPage(extension_.get())) {
- ExecuteDoneOnUIThread(false);
- return;
- }
-
- if (handler_pid > 0) {
- SetupPermissionsAndDispatchEvent(file_system_name, file_system_root,
- file_list, handler_pid, NULL);
- } else {
- // We have to wake the handler background page before we proceed.
- extensions::LazyBackgroundTaskQueue* queue =
- extensions::ExtensionSystem::Get(profile_)->
- lazy_background_task_queue();
- if (!queue->ShouldEnqueueTask(profile_, extension_.get())) {
- ExecuteDoneOnUIThread(false);
- return;
- }
- queue->AddPendingTask(
- profile_, extension_->id(),
- base::Bind(
- &FileBrowserHandlerExecutor::SetupPermissionsAndDispatchEvent,
- weak_ptr_factory_.GetWeakPtr(),
- file_system_name,
- file_system_root,
- file_list,
- handler_pid));
- }
-}
-
-void FileBrowserHandlerExecutor::SetupPermissionsAndDispatchEvent(
- const std::string& file_system_name,
- const GURL& file_system_root,
- const FileDefinitionList& file_list,
- int handler_pid_in,
- extensions::ExtensionHost* host) {
- int handler_pid = host ? host->render_process_host()->GetID() :
- handler_pid_in;
-
- if (handler_pid <= 0) {
- ExecuteDoneOnUIThread(false);
- return;
- }
-
- extensions::EventRouter* event_router =
- extensions::ExtensionSystem::Get(profile_)->event_router();
- if (!event_router) {
- ExecuteDoneOnUIThread(false);
- return;
- }
-
- SetupHandlerHostFileAccessPermissions(
- file_list, extension_.get(), handler_pid);
-
- scoped_ptr<ListValue> event_args(new ListValue());
- event_args->Append(new base::StringValue(action_id_));
- DictionaryValue* details = new DictionaryValue();
- event_args->Append(details);
- // Get file definitions. These will be replaced with Entry instances by
- // dispatchEvent() method from event_binding.js.
- ListValue* file_entries = new ListValue();
- details->Set("entries", file_entries);
- for (FileDefinitionList::const_iterator iter = file_list.begin();
- iter != file_list.end();
- ++iter) {
- DictionaryValue* file_def = new DictionaryValue();
- file_entries->Append(file_def);
- file_def->SetString("fileSystemName", file_system_name);
- file_def->SetString("fileSystemRoot", file_system_root.spec());
- base::FilePath root(FILE_PATH_LITERAL("/"));
- base::FilePath full_path = root.Append(iter->virtual_path);
- file_def->SetString("fileFullPath", full_path.value());
- file_def->SetBoolean("fileIsDirectory", iter->is_directory);
- }
-
- details->SetInteger("tab_id", tab_id_);
-
- scoped_ptr<extensions::Event> event(new extensions::Event(
- "fileBrowserHandler.onExecute", event_args.Pass()));
- event->restrict_to_profile = profile_;
- event_router->DispatchEventToExtension(extension_->id(), event.Pass());
-
- ExecuteDoneOnUIThread(true);
-}
-
-void FileBrowserHandlerExecutor::SetupHandlerHostFileAccessPermissions(
- const FileDefinitionList& file_list,
- const Extension* extension,
- int handler_pid) {
- const FileBrowserHandler* action = FindFileBrowserHandlerForActionId(
- extension_, action_id_);
- for (FileDefinitionList::const_iterator iter = file_list.begin();
- iter != file_list.end();
- ++iter) {
- if (!action)
- continue;
- if (action->CanRead()) {
- content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(
- handler_pid, iter->absolute_path);
- }
- if (action->CanWrite()) {
- content::ChildProcessSecurityPolicy::GetInstance()->
- GrantCreateReadWriteFile(handler_pid, iter->absolute_path);
- }
- }
-}
-
-// Returns true if |extension_id| and |action_id| indicate that the file
-// currently being handled should be opened with the browser. This function
-// is used to handle certain action IDs of the file manager.
-bool ShouldBeOpenedWithBrowser(const std::string& extension_id,
- const std::string& action_id) {
-
- return (extension_id == kFileManagerAppId &&
- (action_id == "view-pdf" ||
- action_id == "view-swf" ||
- action_id == "view-in-browser" ||
- action_id == "install-crx" ||
- action_id == "open-hosted-generic" ||
- action_id == "open-hosted-gdoc" ||
- action_id == "open-hosted-gsheet" ||
- action_id == "open-hosted-gslides"));
-}
-
-// Opens the files specified by |file_urls| with the browser for |profile|.
-// Returns true on success. It's a failure if no files are opened.
-bool OpenFilesWithBrowser(Profile* profile,
- const std::vector<FileSystemURL>& file_urls) {
- int num_opened = 0;
- for (size_t i = 0; i < file_urls.size(); ++i) {
- const FileSystemURL& file_url = file_urls[i];
- if (chromeos::FileSystemBackend::CanHandleURL(file_url)) {
- const base::FilePath& file_path = file_url.path();
- num_opened += util::OpenFileWithBrowser(profile, file_path);
- }
- }
- return num_opened > 0;
-}
-
-} // namespace
-
-bool ExecuteFileBrowserHandler(
- Profile* profile,
- const Extension* extension,
- int32 tab_id,
- const std::string& action_id,
- const std::vector<FileSystemURL>& file_urls,
- const file_tasks::FileTaskFinishedCallback& done) {
- // Forbid calling undeclared handlers.
- if (!FindFileBrowserHandlerForActionId(extension, action_id))
- return false;
-
- // Some action IDs of the file manager's file browser handlers require the
- // files to be directly opened with the browser.
- if (ShouldBeOpenedWithBrowser(extension->id(), action_id)) {
- return OpenFilesWithBrowser(profile, file_urls);
- }
-
- // The executor object will be self deleted on completion.
- (new FileBrowserHandlerExecutor(
- profile, extension, tab_id, action_id))->Execute(file_urls, done);
- return true;
-}
-
-bool IsFallbackFileBrowserHandler(const file_tasks::TaskDescriptor& task) {
- return (task.task_type == file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER &&
- (task.app_id == kFileManagerAppId ||
- task.app_id == extension_misc::kQuickOfficeComponentExtensionId ||
- task.app_id == extension_misc::kQuickOfficeDevExtensionId ||
- task.app_id == extension_misc::kQuickOfficeExtensionId));
-}
-
-FileBrowserHandlerList FindDefaultFileBrowserHandlers(
- const PrefService& pref_service,
- const std::vector<base::FilePath>& file_list,
- const FileBrowserHandlerList& common_handlers) {
- FileBrowserHandlerList default_handlers;
-
- std::set<std::string> default_ids;
- for (std::vector<base::FilePath>::const_iterator it = file_list.begin();
- it != file_list.end(); ++it) {
- std::string task_id = file_tasks::GetDefaultTaskIdFromPrefs(
- pref_service, "", it->Extension());
- if (!task_id.empty())
- default_ids.insert(task_id);
- }
-
- const FileBrowserHandler* fallback_handler = NULL;
- // Convert the default task IDs collected above to one of the handler pointers
- // from common_handlers.
- for (size_t i = 0; i < common_handlers.size(); ++i) {
- const FileBrowserHandler* handler = common_handlers[i];
- const file_tasks::TaskDescriptor task_descriptor(
- handler->extension_id(),
- file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER,
- handler->id());
- const std::string task_id =
- file_tasks::TaskDescriptorToId(task_descriptor);
- std::set<std::string>::iterator default_iter = default_ids.find(task_id);
- if (default_iter != default_ids.end()) {
- default_handlers.push_back(handler);
- continue;
- }
-
- // Remember the first fallback handler.
- if (!fallback_handler && IsFallbackFileBrowserHandler(task_descriptor))
- fallback_handler = handler;
- }
-
- // If there are no default handlers found, use fallback as default.
- if (fallback_handler && default_handlers.empty())
- default_handlers.push_back(fallback_handler);
-
- return default_handlers;
-}
-
-FileBrowserHandlerList FindCommonFileBrowserHandlers(
- Profile* profile,
- const std::vector<GURL>& file_list) {
- FileBrowserHandlerList common_handlers;
- for (std::vector<GURL>::const_iterator it = file_list.begin();
- it != file_list.end(); ++it) {
- FileBrowserHandlerList handlers =
- FindFileBrowserHandlersForURL(profile, *it);
- // If there is nothing to do for one file, the intersection of handlers
- // for all files will be empty at the end, so no need to check further.
- if (handlers.empty())
- return FileBrowserHandlerList();
-
- // For the very first file, just copy all the elements.
- if (it == file_list.begin()) {
- common_handlers = handlers;
- } else {
- // For all additional files, find intersection between the accumulated and
- // file specific set.
- FileBrowserHandlerList intersection;
- std::set_intersection(common_handlers.begin(), common_handlers.end(),
- handlers.begin(), handlers.end(),
- std::back_inserter(intersection));
- common_handlers = intersection;
- if (common_handlers.empty())
- return FileBrowserHandlerList();
- }
- }
-
- // "watch" and "gallery" are defined in the file manager's manifest.json.
- FileBrowserHandlerList::iterator watch_iter =
- FindFileBrowserHandlerForExtensionIdAndActionId(
- &common_handlers, kFileManagerAppId, "watch");
- FileBrowserHandlerList::iterator gallery_iter =
- FindFileBrowserHandlerForExtensionIdAndActionId(
- &common_handlers, kFileManagerAppId, "gallery");
- if (watch_iter != common_handlers.end() &&
- gallery_iter != common_handlers.end()) {
- // Both "watch" and "gallery" actions are applicable which means that the
- // selection is all videos. Showing them both is confusing, so we only keep
- // the one that makes more sense ("watch" for single selection, "gallery"
- // for multiple selection).
- if (file_list.size() == 1)
- common_handlers.erase(gallery_iter);
- else
- common_handlers.erase(watch_iter);
- }
-
- return common_handlers;
-}
-
-const FileBrowserHandler* FindFileBrowserHandlerForURLAndPath(
- Profile* profile,
- const GURL& url,
- const base::FilePath& file_path) {
- std::vector<GURL> file_urls;
- file_urls.push_back(url);
-
- FileBrowserHandlerList common_handlers =
- FindCommonFileBrowserHandlers(profile, file_urls);
- if (common_handlers.empty())
- return NULL;
-
- std::vector<base::FilePath> file_paths;
- file_paths.push_back(file_path);
-
- FileBrowserHandlerList default_handlers =
- FindDefaultFileBrowserHandlers(*profile->GetPrefs(),
- file_paths,
- common_handlers);
-
- // If there's none, or more than one, then we don't have a canonical default.
- if (!default_handlers.empty()) {
- // There should not be multiple default handlers for a single URL.
- DCHECK_EQ(1u, default_handlers.size());
-
- return *default_handlers.begin();
- }
-
- // If there are no default handlers, use first handler in the list (file
- // manager does the same in this situation). TODO(tbarzic): This is not so
- // optimal behaviour.
- return *common_handlers.begin();
-}
-
-} // namespace file_browser_handlers
-} // namespace file_manager

Powered by Google App Engine
This is Rietveld 408576698