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

Unified Diff: apps/launcher.cc

Issue 300063006: Files.app: Let Files.app pass mutliple files to file handlers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased. Created 6 years, 7 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: apps/launcher.cc
diff --git a/apps/launcher.cc b/apps/launcher.cc
index 1c8c57fd072b15653598af2b7c9971c4e8ea9a15..4765c84e30de8caf40ec97268f7f1bbf20078c7f 100644
--- a/apps/launcher.cc
+++ b/apps/launcher.cc
@@ -89,7 +89,7 @@ void LaunchPlatformAppWithNoData(Profile* profile, const Extension* extension) {
AppEventRouter::DispatchOnLaunchedEvent(profile, extension);
}
-// Class to handle launching of platform apps to open a specific path.
+// Class to handle launching of platform apps to open specific paths.
// An instance of this class is created for each launch. The lifetime of these
// instances is managed by reference counted pointers. As long as an instance
// has outstanding tasks on a message queue it will be retained; once all
@@ -99,23 +99,31 @@ class PlatformAppPathLauncher
public:
PlatformAppPathLauncher(Profile* profile,
const Extension* extension,
+ const std::vector<base::FilePath>& file_paths)
+ : profile_(profile), extension_(extension), file_paths_(file_paths) {}
+
+ PlatformAppPathLauncher(Profile* profile,
+ const Extension* extension,
const base::FilePath& file_path)
- : profile_(profile), extension_(extension), file_path_(file_path) {}
+ : profile_(profile), extension_(extension) {
+ if (!file_path.empty())
+ file_paths_.push_back(file_path);
+ }
void Launch() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (file_path_.empty()) {
+ if (file_paths_.empty()) {
LaunchPlatformAppWithNoData(profile_, extension_);
return;
}
- DCHECK(file_path_.IsAbsolute());
+ for (size_t i = 0; i < file_paths_.size(); ++i) {
+ DCHECK(file_paths_[i].IsAbsolute());
+ }
if (HasFileSystemWritePermission(extension_)) {
- std::vector<base::FilePath> paths;
- paths.push_back(file_path_);
CheckWritableFiles(
- paths,
+ file_paths_,
profile_,
false,
base::Bind(&PlatformAppPathLauncher::OnFileValid, this),
@@ -148,9 +156,14 @@ class PlatformAppPathLauncher
void MakePathAbsolute(const base::FilePath& current_directory) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
- if (!DoMakePathAbsolute(current_directory, &file_path_)) {
- LOG(WARNING) << "Cannot make absolute path from " << file_path_.value();
- file_path_ = base::FilePath();
+ for (std::vector<base::FilePath>::iterator it = file_paths_.begin();
+ it != file_paths_.end();) {
+ if (!DoMakePathAbsolute(current_directory, &*it)) {
+ LOG(WARNING) << "Cannot make absolute path from " << it->value();
+ file_paths_.erase(it);
benwells 2014/05/28 22:46:14 should this be it = file_path_.erase(it)? I'd be
hirono 2014/05/29 04:08:03 Done.
+ } else {
+ ++it;
+ }
}
BrowserThread::PostTask(BrowserThread::UI,
@@ -158,12 +171,27 @@ class PlatformAppPathLauncher
base::Bind(&PlatformAppPathLauncher::Launch, this));
}
- void OnFileValid() {
+ void OnFileValid() { StepToFillMimeTypes(); }
+
+ void OnFileInvalid(const base::FilePath& /* error_path */) {
+ LaunchWithNoLaunchData();
+ }
+
+ void StepToFillMimeTypes() {
benwells 2014/05/28 22:46:14 This logic is more complicated than it needs to be
hirono 2014/05/29 04:08:03 Done.
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(file_paths_.size() >= mime_types_.size());
+
+ if (file_paths_.size() == mime_types_.size()) {
+ LaunchWithMimeType();
+ return;
+ }
+
#if defined(OS_CHROMEOS)
- if (file_manager::util::IsUnderSpecialPath(profile_, file_path_)) {
+ if (file_manager::util::IsUnderSpecialPath(
+ profile_, file_paths_[mime_types_.size()])) {
file_manager::util::GetSpecialPathMimeType(
profile_,
- file_path_,
+ file_paths_[mime_types_.size()],
base::Bind(&PlatformAppPathLauncher::OnGotMimeType, this));
return;
}
@@ -172,44 +200,45 @@ class PlatformAppPathLauncher
BrowserThread::PostTask(
BrowserThread::FILE,
FROM_HERE,
- base::Bind(&PlatformAppPathLauncher::GetMimeTypeAndLaunch, this));
- }
-
- void OnFileInvalid(const base::FilePath& /* error_path */) {
- LaunchWithNoLaunchData();
+ base::Bind(&PlatformAppPathLauncher::GetMimeTypeAndStep, this));
}
- void GetMimeTypeAndLaunch() {
+ void GetMimeTypeAndStep() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+ const base::FilePath& file_path = file_paths_[mime_types_.size()];
+
// If the file doesn't exist, or is a directory, launch with no launch data.
- if (!base::PathExists(file_path_) ||
- base::DirectoryExists(file_path_)) {
- LOG(WARNING) << "No file exists with path " << file_path_.value();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
- &PlatformAppPathLauncher::LaunchWithNoLaunchData, this));
+ if (!base::PathExists(file_path) || base::DirectoryExists(file_path)) {
+ LOG(WARNING) << "No file exists with path " << file_path.value();
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&PlatformAppPathLauncher::LaunchWithNoLaunchData, this));
return;
}
std::string mime_type;
- if (!net::GetMimeTypeFromFile(file_path_, &mime_type)) {
+ if (!net::GetMimeTypeFromFile(file_path, &mime_type)) {
// If MIME type of the file can't be determined by its path,
// try to sniff it by its content.
std::vector<char> content(net::kMaxBytesToSniff);
- int bytes_read = base::ReadFile(file_path_, &content[0], content.size());
+ int bytes_read = base::ReadFile(file_path, &content[0], content.size());
if (bytes_read >= 0) {
net::SniffMimeType(&content[0],
bytes_read,
- net::FilePathToFileURL(file_path_),
+ net::FilePathToFileURL(file_path),
std::string(), // type_hint (passes no hint)
&mime_type);
}
if (mime_type.empty())
mime_type = kFallbackMimeType;
}
-
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
- &PlatformAppPathLauncher::LaunchWithMimeType, this, mime_type));
+ mime_types_.push_back(mime_type);
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&PlatformAppPathLauncher::StepToFillMimeTypes, this));
}
#if defined(OS_CHROMEOS)
@@ -218,7 +247,8 @@ class PlatformAppPathLauncher
LaunchWithNoLaunchData();
return;
}
- LaunchWithMimeType(mime_type.empty() ? kFallbackMimeType : mime_type);
+ mime_types_.push_back(mime_type.empty() ? kFallbackMimeType : mime_type);
+ StepToFillMimeTypes();
}
#endif
@@ -227,25 +257,42 @@ class PlatformAppPathLauncher
LaunchPlatformAppWithNoData(profile_, extension_);
}
- void LaunchWithMimeType(const std::string& mime_type) {
+ void LaunchWithMimeType() {
+ DCHECK(file_paths_.size() == mime_types_.size());
+
// Find file handler from the platform app for the file being opened.
const extensions::FileHandlerInfo* handler = NULL;
- if (!handler_id_.empty())
+ if (!handler_id_.empty()) {
handler = FileHandlerForId(*extension_, handler_id_);
- else
- handler = FirstFileHandlerForFile(*extension_, mime_type, file_path_);
- if (handler && !FileHandlerCanHandleFile(*handler, mime_type, file_path_)) {
- LOG(WARNING) << "Extension does not provide a valid file handler for "
- << file_path_.value();
- LaunchWithNoLaunchData();
- return;
+ if (handler) {
+ for (size_t i = 0; i < file_paths_.size(); ++i) {
+ if (!FileHandlerCanHandleFile(
+ *handler, mime_types_[i], file_paths_[i])) {
+ LOG(WARNING)
+ << "Extension does not provide a valid file handler for "
+ << file_paths_[i].value();
+ handler = NULL;
+ break;
+ }
+ }
+ }
+ } else {
+ std::set<std::pair<base::FilePath, std::string> > path_and_file_type_set;
+ for (size_t i = 0; i < file_paths_.size(); ++i) {
+ path_and_file_type_set.insert(
+ std::make_pair(file_paths_[i], mime_types_[i]));
+ }
+ const std::vector<const extensions::FileHandlerInfo*>& handlers =
+ extensions::app_file_handler_util::FindFileHandlersForFiles(
+ *extension_, path_and_file_type_set);
+ if (!handlers.empty())
+ handler = handlers[0];
}
// If this app doesn't have a file handler that supports the file, launch
// with no launch data.
if (!handler) {
- LOG(WARNING) << "Extension does not provide a valid file handler for "
- << file_path_.value();
+ LOG(WARNING) << "Extension does not provide a valid file handler.";
LaunchWithNoLaunchData();
return;
}
@@ -258,39 +305,44 @@ class PlatformAppPathLauncher
// available, or it might be in the process of being unloaded, in which case
// the lazy background task queue is used to load the extension and then
// call back to us.
- extensions::LazyBackgroundTaskQueue* queue =
+ extensions::LazyBackgroundTaskQueue* const queue =
ExtensionSystem::Get(profile_)->lazy_background_task_queue();
if (queue->ShouldEnqueueTask(profile_, extension_)) {
- queue->AddPendingTask(profile_, extension_->id(), base::Bind(
- &PlatformAppPathLauncher::GrantAccessToFileAndLaunch,
- this, mime_type));
+ queue->AddPendingTask(
+ profile_,
+ extension_->id(),
+ base::Bind(&PlatformAppPathLauncher::GrantAccessToFileAndLaunch,
+ this));
return;
}
- extensions::ProcessManager* process_manager =
+ extensions::ProcessManager* const process_manager =
ExtensionSystem::Get(profile_)->process_manager();
- ExtensionHost* host =
+ ExtensionHost* const host =
process_manager->GetBackgroundHostForExtension(extension_->id());
DCHECK(host);
- GrantAccessToFileAndLaunch(mime_type, host);
+ GrantAccessToFileAndLaunch(host);
}
- void GrantAccessToFileAndLaunch(const std::string& mime_type,
- ExtensionHost* host) {
+ void GrantAccessToFileAndLaunch(ExtensionHost* host) {
benwells 2014/05/28 22:46:14 Nit should be GrantAccessToFilesAndLaunch
hirono 2014/05/29 04:08:03 Done.
// If there was an error loading the app page, |host| will be NULL.
if (!host) {
LOG(ERROR) << "Could not load app page for " << extension_->id();
return;
}
- GrantedFileEntry file_entry =
- CreateFileEntry(profile_,
- extension_,
- host->render_process_host()->GetID(),
- file_path_,
- false);
- AppEventRouter::DispatchOnLaunchedEventWithFileEntry(
- profile_, extension_, handler_id_, mime_type, file_entry);
+ std::vector<GrantedFileEntry> file_entries;
+ for (size_t i = 0; i < file_paths_.size(); ++i) {
+ file_entries.push_back(
+ CreateFileEntry(profile_,
+ extension_,
+ host->render_process_host()->GetID(),
+ file_paths_[i],
+ false));
+ }
+
+ AppEventRouter::DispatchOnLaunchedEventWithFileEntries(
+ profile_, extension_, handler_id_, mime_types_, file_entries);
}
// The profile the app should be run in.
@@ -301,7 +353,8 @@ class PlatformAppPathLauncher
// See http://crbug.com/372270 for details.
const Extension* extension_;
// The path to be passed through to the app.
- base::FilePath file_path_;
+ std::vector<base::FilePath> file_paths_;
+ std::vector<std::string> mime_types_;
// The ID of the file handler used to launch the app.
std::string handler_id_;
@@ -369,12 +422,13 @@ void LaunchPlatformApp(Profile* profile, const Extension* extension) {
base::FilePath());
}
-void LaunchPlatformAppWithFileHandler(Profile* profile,
- const Extension* extension,
- const std::string& handler_id,
- const base::FilePath& file_path) {
+void LaunchPlatformAppWithFileHandler(
+ Profile* profile,
+ const Extension* extension,
+ const std::string& handler_id,
+ const std::vector<base::FilePath>& file_paths) {
scoped_refptr<PlatformAppPathLauncher> launcher =
- new PlatformAppPathLauncher(profile, extension, file_path);
+ new PlatformAppPathLauncher(profile, extension, file_paths);
launcher->LaunchWithHandler(handler_id);
}

Powered by Google App Engine
This is Rietveld 408576698