diff options
Diffstat (limited to 'chrome/browser')
6 files changed, 147 insertions, 8 deletions
diff --git a/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc b/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc index ff70376..10e29f57 100644 --- a/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc +++ b/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc @@ -9,6 +9,7 @@ #include "base/strings/string_number_conversions.h" #include "base/utf_string_conversions.h" #include "base/values.h" +#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" #include "chrome/browser/extensions/event_router.h" #include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/profiles/profile.h" @@ -51,10 +52,28 @@ void AppEventRouter::DispatchOnLaunchedEvent( DispatchOnLaunchedEventImpl(extension->id(), arguments.Pass(), profile); } +DictionaryValue* DictionaryFromSavedFileEntry( + const app_file_handler_util::GrantedFileEntry& file_entry) { + DictionaryValue* result = new DictionaryValue(); + result->SetString("id", file_entry.id); + result->SetString("fileSystemId", file_entry.filesystem_id); + result->SetString("baseName", file_entry.registered_name); + return result; +} + // static. void AppEventRouter::DispatchOnRestartedEvent( - Profile* profile, const Extension* extension) { + Profile* profile, + const Extension* extension, + const std::vector<app_file_handler_util::GrantedFileEntry>& file_entries) { + ListValue* file_entries_list = new ListValue(); + for (std::vector<extensions::app_file_handler_util::GrantedFileEntry> + ::const_iterator it = file_entries.begin(); it != file_entries.end(); + ++it) { + file_entries_list->Append(DictionaryFromSavedFileEntry(*it)); + } scoped_ptr<ListValue> arguments(new ListValue()); + arguments->Append(file_entries_list); scoped_ptr<Event> event(new Event(kOnRestartedEvent, arguments.Pass())); event->restrict_to_profile = profile; extensions::ExtensionSystem::Get(profile)->event_router()-> diff --git a/chrome/browser/extensions/api/app_runtime/app_runtime_api.h b/chrome/browser/extensions/api/app_runtime/app_runtime_api.h index 84ade63..f9075b4 100644 --- a/chrome/browser/extensions/api/app_runtime/app_runtime_api.h +++ b/chrome/browser/extensions/api/app_runtime/app_runtime_api.h @@ -18,14 +18,20 @@ namespace extensions { class Extension; +namespace app_file_handler_util { +struct GrantedFileEntry; +} + class AppEventRouter { public: // Dispatches the onLaunched event to the given app, providing no launch // data. static void DispatchOnLaunchedEvent(Profile* profile, const Extension* extension); - static void DispatchOnRestartedEvent(Profile* profile, - const Extension* extension); + static void DispatchOnRestartedEvent( + Profile* profile, + const Extension* extension, + const std::vector<app_file_handler_util::GrantedFileEntry>& file_entries); // TODO(benwells): Update this comment, it is out of date. // Dispatches the onLaunched event to the given app, providing launch data of diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 38df2d4..832218d 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc @@ -32,6 +32,7 @@ #include "chrome/browser/extensions/api/app_runtime/app_runtime_api.h" #include "chrome/browser/extensions/api/declarative/rules_registry_service.h" #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" +#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" #include "chrome/browser/extensions/api/profile_keyed_api_factory.h" #include "chrome/browser/extensions/api/runtime/runtime_api.h" #include "chrome/browser/extensions/api/storage/settings_frontend.h" @@ -743,6 +744,11 @@ void ExtensionService::ReloadExtensionWithEvents( } on_load_events_[extension_id] = events; + if (events & EVENT_RESTARTED) { + extension_prefs_->GetSavedFileEntries( + extension_id, &on_restart_file_entries_[extension_id]); + } + if (delayed_updates_for_idle_.Contains(extension_id)) { FinishDelayedInstallation(extension_id); @@ -2910,9 +2916,16 @@ void ExtensionService::DoPostLoadTasks(const Extension* extension) { if (events_to_fire & EVENT_LAUNCHED) queue->AddPendingTask(profile(), extension->id(), base::Bind(&ExtensionService::LaunchApplication)); - if (events_to_fire & EVENT_RESTARTED) + if (events_to_fire & EVENT_RESTARTED) { + SavedFileEntryMap::iterator it = + on_restart_file_entries_.find(extension->id()); + if (it == on_restart_file_entries_.end()) + NOTREACHED(); queue->AddPendingTask(profile(), extension->id(), - base::Bind(&ExtensionService::RestartApplication)); + base::Bind(&ExtensionService::RestartApplication, + it->second)); + on_restart_file_entries_.erase(it); + } } on_load_events_.erase(it); @@ -2933,13 +2946,14 @@ void ExtensionService::LaunchApplication( // static void ExtensionService::RestartApplication( + std::vector<extensions::app_file_handler_util::SavedFileEntry> file_entries, extensions::ExtensionHost* extension_host) { if (!extension_host) return; #if !defined(OS_ANDROID) - extensions::AppEventRouter::DispatchOnRestartedEvent( - extension_host->profile(), extension_host->extension()); + extensions::RestartPlatformAppWithFileEntries( + extension_host->profile(), extension_host->extension(), file_entries); #endif } diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index 7fb4a13..7a4eaea 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h @@ -796,7 +796,10 @@ class ExtensionService // Dispatches a restart event to the platform app associated with // |extension_host|. - static void RestartApplication(extensions::ExtensionHost* extension_host); + static void RestartApplication( + std::vector<extensions::app_file_handler_util::SavedFileEntry> + file_entries, + extensions::ExtensionHost* extension_host); // Helper to inspect an ExtensionHost after it has been loaded. void InspectExtensionHost(extensions::ExtensionHost* host); @@ -924,6 +927,13 @@ class ExtensionService // dispatched to the extension when it is loaded. std::map<std::string, int> on_load_events_; + // Maps extension ids to vectors of saved file entries that the extension + // should be given access to on restart. + typedef std::map<std::string, + std::vector<extensions::app_file_handler_util::SavedFileEntry> > + SavedFileEntryMap; + SavedFileEntryMap on_restart_file_entries_; + content::NotificationRegistrar registrar_; PrefChangeRegistrar pref_change_registrar_; diff --git a/chrome/browser/extensions/platform_app_launcher.cc b/chrome/browser/extensions/platform_app_launcher.cc index 78548d8..0d37609 100644 --- a/chrome/browser/extensions/platform_app_launcher.cc +++ b/chrome/browser/extensions/platform_app_launcher.cc @@ -13,8 +13,11 @@ #include "base/utf_string_conversions.h" #include "chrome/browser/extensions/api/app_runtime/app_runtime_api.h" #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" +#include "chrome/browser/extensions/api/file_system/file_system_api.h" #include "chrome/browser/extensions/extension_host.h" +#include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/extensions/extension_process_manager.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" @@ -33,6 +36,9 @@ using content::BrowserThread; using extensions::app_file_handler_util::FileHandlerForId; using extensions::app_file_handler_util::FileHandlerCanHandleFileWithMimeType; using extensions::app_file_handler_util::FirstFileHandlerForMimeType; +using extensions::app_file_handler_util::CreateFileEntry; +using extensions::app_file_handler_util::GrantedFileEntry; +using extensions::app_file_handler_util::SavedFileEntry; namespace extensions { @@ -239,6 +245,70 @@ class PlatformAppPathLauncher DISALLOW_COPY_AND_ASSIGN(PlatformAppPathLauncher); }; +class SavedFileEntryLauncher + : public base::RefCountedThreadSafe<SavedFileEntryLauncher> { + public: + SavedFileEntryLauncher( + Profile* profile, + const Extension* extension, + const std::vector<SavedFileEntry>& file_entries) + : profile_(profile), + extension_(extension), + file_entries_(file_entries) {} + + void Launch() { + // Access needs to be granted to the file or filesystem for the process + // associated with the extension. To do this the ExtensionHost is needed. + // This might not be available, or it might be in the process of being + // unloaded, in which case the lazy background task queue is used to load + // he extension and then call back to us. + extensions::LazyBackgroundTaskQueue* queue = + ExtensionSystem::Get(profile_)->lazy_background_task_queue(); + if (queue->ShouldEnqueueTask(profile_, extension_)) { + queue->AddPendingTask(profile_, extension_->id(), base::Bind( + &SavedFileEntryLauncher::GrantAccessToFilesAndLaunch, + this)); + return; + } + ExtensionProcessManager* process_manager = + ExtensionSystem::Get(profile_)->process_manager(); + extensions::ExtensionHost* host = + process_manager->GetBackgroundHostForExtension(extension_->id()); + DCHECK(host); + GrantAccessToFilesAndLaunch(host); + } + + private: + friend class base::RefCountedThreadSafe<SavedFileEntryLauncher>; + ~SavedFileEntryLauncher() {} + void GrantAccessToFilesAndLaunch(ExtensionHost* host) { + int renderer_id = host->render_process_host()->GetID(); + std::vector<GrantedFileEntry> granted_file_entries; + for (std::vector<SavedFileEntry>::const_iterator it = + file_entries_.begin(); it != file_entries_.end(); ++it) { + GrantedFileEntry file_entry = CreateFileEntry( + profile_, extension_->id(), renderer_id, it->path, it->writable); + file_entry.id = it->id; + granted_file_entries.push_back(file_entry); + + // Record that we have granted this file permission. + ExtensionPrefs* extension_prefs = ExtensionSystem::Get(profile_)-> + extension_service()->extension_prefs(); + extension_prefs->AddSavedFileEntry( + host->extension()->id(), it->id, it->path, it->writable); + } + extensions::AppEventRouter::DispatchOnRestartedEvent( + profile_, extension_, granted_file_entries); + } + + // The profile the app should be run in. + Profile* profile_; + // The extension providing the app. + const Extension* extension_; + + std::vector<SavedFileEntry> file_entries_; +}; + } // namespace void LaunchPlatformApp(Profile* profile, @@ -275,4 +345,13 @@ void LaunchPlatformAppWithFileHandler(Profile* profile, launcher->LaunchWithHandler(handler_id); } +void RestartPlatformAppWithFileEntries( + Profile* profile, + const Extension* extension, + const std::vector<SavedFileEntry>& file_entries) { + scoped_refptr<SavedFileEntryLauncher> launcher = new SavedFileEntryLauncher( + profile, extension, file_entries); + launcher->Launch(); +} + } // namespace extensions diff --git a/chrome/browser/extensions/platform_app_launcher.h b/chrome/browser/extensions/platform_app_launcher.h index c301c45..fc7965a 100644 --- a/chrome/browser/extensions/platform_app_launcher.h +++ b/chrome/browser/extensions/platform_app_launcher.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_EXTENSIONS_PLATFORM_APP_LAUNCHER_H_ #include <string> +#include <vector> class CommandLine; class Profile; @@ -22,6 +23,10 @@ namespace extensions { class Extension; +namespace app_file_handler_util { +struct SavedFileEntry; +} + // Launches the platform app |extension|. Creates appropriate launch data for // the |command_line| fields present. |extension| and |profile| must not be // NULL. A NULL |command_line| means there is no launch data. If non-empty, @@ -44,6 +49,12 @@ void LaunchPlatformAppWithFileHandler(Profile* profile, const std::string& handler_id, const base::FilePath& file_path); +void RestartPlatformAppWithFileEntries( + Profile* profile, + const Extension* extension, + const std::vector<app_file_handler_util::SavedFileEntry>& + saved_file_entries); + } // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_PLATFORM_APP_LAUNCHER_H_ |