| Index: apps/launcher.cc
|
| diff --git a/apps/launcher.cc b/apps/launcher.cc
|
| index 25c3a5f2bd14e4de31ab50dfba264101792a4054..cda74ac144969d99de88c801dd690c761403e488 100644
|
| --- a/apps/launcher.cc
|
| +++ b/apps/launcher.cc
|
| @@ -27,6 +27,7 @@
|
| #include "extensions/browser/event_router.h"
|
| #include "extensions/browser/extension_host.h"
|
| #include "extensions/browser/extension_prefs.h"
|
| +#include "extensions/browser/extension_registry.h"
|
| #include "extensions/browser/extension_system.h"
|
| #include "extensions/browser/granted_file_entry.h"
|
| #include "extensions/browser/lazy_background_task_queue.h"
|
| @@ -97,20 +98,25 @@ class PlatformAppPathLauncher
|
| const Extension* extension,
|
| const std::vector<base::FilePath>& file_paths)
|
| : profile_(profile),
|
| - extension_(extension),
|
| + extension_id(extension->id()),
|
| file_paths_(file_paths),
|
| collector_(profile) {}
|
|
|
| PlatformAppPathLauncher(Profile* profile,
|
| const Extension* extension,
|
| const base::FilePath& file_path)
|
| - : profile_(profile), extension_(extension), collector_(profile) {
|
| + : profile_(profile), extension_id(extension->id()), collector_(profile) {
|
| if (!file_path.empty())
|
| file_paths_.push_back(file_path);
|
| }
|
|
|
| void Launch() {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| +
|
| + const Extension* extension = GetExtension();
|
| + if (!extension)
|
| + return;
|
| +
|
| if (file_paths_.empty()) {
|
| LaunchWithNoLaunchData();
|
| return;
|
| @@ -120,7 +126,7 @@ class PlatformAppPathLauncher
|
| DCHECK(file_paths_[i].IsAbsolute());
|
| }
|
|
|
| - if (HasFileSystemWritePermission(extension_)) {
|
| + if (HasFileSystemWritePermission(extension)) {
|
| PrepareFilesForWritableApp(
|
| file_paths_,
|
| profile_,
|
| @@ -186,13 +192,22 @@ class PlatformAppPathLauncher
|
| void LaunchWithNoLaunchData() {
|
| // This method is required as an entry point on the UI thread.
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| +
|
| + const Extension* extension = GetExtension();
|
| + if (!extension)
|
| + return;
|
| +
|
| AppRuntimeEventRouter::DispatchOnLaunchedEvent(
|
| - profile_, extension_, extensions::SOURCE_FILE_HANDLER);
|
| + profile_, extension, extensions::SOURCE_FILE_HANDLER);
|
| }
|
|
|
| void OnMimeTypesCollected(scoped_ptr<std::vector<std::string> > mime_types) {
|
| DCHECK(file_paths_.size() == mime_types->size());
|
|
|
| + const Extension* extension = GetExtension();
|
| + if (!extension)
|
| + return;
|
| +
|
| // If fetching a mime type failed, then use a fallback one.
|
| for (size_t i = 0; i < mime_types->size(); ++i) {
|
| const std::string mime_type =
|
| @@ -203,7 +218,7 @@ class PlatformAppPathLauncher
|
| // Find file handler from the platform app for the file being opened.
|
| const extensions::FileHandlerInfo* handler = NULL;
|
| if (!handler_id_.empty()) {
|
| - handler = FileHandlerForId(*extension_, handler_id_);
|
| + handler = FileHandlerForId(*extension, handler_id_);
|
| if (handler) {
|
| for (size_t i = 0; i < file_paths_.size(); ++i) {
|
| if (!FileHandlerCanHandleFile(
|
| @@ -224,7 +239,7 @@ class PlatformAppPathLauncher
|
| }
|
| const std::vector<const extensions::FileHandlerInfo*>& handlers =
|
| extensions::app_file_handler_util::FindFileHandlersForFiles(
|
| - *extension_, path_and_file_type_set);
|
| + *extension, path_and_file_type_set);
|
| if (!handlers.empty())
|
| handler = handlers[0];
|
| }
|
| @@ -247,10 +262,9 @@ class PlatformAppPathLauncher
|
| // call back to us.
|
| extensions::LazyBackgroundTaskQueue* const queue =
|
| ExtensionSystem::Get(profile_)->lazy_background_task_queue();
|
| - if (queue->ShouldEnqueueTask(profile_, extension_)) {
|
| + if (queue->ShouldEnqueueTask(profile_, extension)) {
|
| queue->AddPendingTask(
|
| - profile_,
|
| - extension_->id(),
|
| + profile_, extension_id,
|
| base::Bind(&PlatformAppPathLauncher::GrantAccessToFilesAndLaunch,
|
| this));
|
| return;
|
| @@ -259,39 +273,44 @@ class PlatformAppPathLauncher
|
| extensions::ProcessManager* const process_manager =
|
| extensions::ProcessManager::Get(profile_);
|
| ExtensionHost* const host =
|
| - process_manager->GetBackgroundHostForExtension(extension_->id());
|
| + process_manager->GetBackgroundHostForExtension(extension_id);
|
| DCHECK(host);
|
| GrantAccessToFilesAndLaunch(host);
|
| }
|
|
|
| void GrantAccessToFilesAndLaunch(ExtensionHost* host) {
|
| + const Extension* extension = GetExtension();
|
| + if (!extension)
|
| + return;
|
| +
|
| // 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();
|
| + LOG(ERROR) << "Could not load app page for " << extension_id;
|
| return;
|
| }
|
|
|
| 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));
|
| + file_entries.push_back(CreateFileEntry(
|
| + profile_, extension, host->render_process_host()->GetID(),
|
| + file_paths_[i], false));
|
| }
|
|
|
| AppRuntimeEventRouter::DispatchOnLaunchedEventWithFileEntries(
|
| - profile_, extension_, handler_id_, mime_types_, file_entries);
|
| + profile_, extension, handler_id_, mime_types_, file_entries);
|
| + }
|
| +
|
| + const Extension* GetExtension() const {
|
| + return extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
|
| + extension_id, extensions::ExtensionRegistry::EVERYTHING);
|
| }
|
|
|
| // The profile the app should be run in.
|
| Profile* profile_;
|
| - // The extension providing the app.
|
| - // TODO(benwells): Hold onto the extension ID instead of a pointer as it
|
| - // is possible the extension will be unloaded while we're doing our thing.
|
| - // See http://crbug.com/372270 for details.
|
| - const Extension* extension_;
|
| + // The id of the extension providing the app. A pointer to the extension is
|
| + // not kept as the extension may be unloaded and deleted during the course of
|
| + // the launch.
|
| + const std::string extension_id;
|
| // The path to be passed through to the app.
|
| std::vector<base::FilePath> file_paths_;
|
| std::vector<std::string> mime_types_;
|
|
|