diff options
-rw-r--r-- | athena/extensions/shell/extensions_delegate_impl.cc | 9 | ||||
-rw-r--r-- | athena/main/athena_main.cc | 2 | ||||
-rw-r--r-- | extensions/browser/guest_view/web_view/web_view_apitest.cc | 5 | ||||
-rw-r--r-- | extensions/shell/browser/default_shell_browser_main_delegate.cc | 25 | ||||
-rw-r--r-- | extensions/shell/browser/desktop_controller.h | 3 | ||||
-rw-r--r-- | extensions/shell/browser/shell_desktop_controller.cc | 25 | ||||
-rw-r--r-- | extensions/shell/browser/shell_desktop_controller.h | 7 | ||||
-rw-r--r-- | extensions/shell/browser/shell_extension_system.cc | 32 | ||||
-rw-r--r-- | extensions/shell/browser/shell_extension_system.h | 19 | ||||
-rw-r--r-- | extensions/shell/browser/shell_native_app_window.cc | 1 | ||||
-rw-r--r-- | extensions/shell/test/shell_apitest.cc | 6 |
11 files changed, 83 insertions, 51 deletions
diff --git a/athena/extensions/shell/extensions_delegate_impl.cc b/athena/extensions/shell/extensions_delegate_impl.cc index 4b468ef..00af9cc 100644 --- a/athena/extensions/shell/extensions_delegate_impl.cc +++ b/athena/extensions/shell/extensions_delegate_impl.cc @@ -6,6 +6,7 @@ #include "athena/extensions/shell/athena_shell_app_window_client.h" #include "base/macros.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/install/extension_install_ui.h" #include "extensions/common/extension_set.h" #include "extensions/shell/browser/shell_extension_system.h" @@ -32,13 +33,10 @@ class ShellExtensionsDelegate : public ExtensionsDelegate { return context_; } virtual const extensions::ExtensionSet& GetInstalledExtensions() override { - shell_extensions_.Clear(); - if (extension_system_->extension().get()) - shell_extensions_.Insert(extension_system_->extension()); - return shell_extensions_; + return extensions::ExtensionRegistry::Get(context_)->enabled_extensions(); } virtual bool LaunchApp(const std::string& app_id) override { - extension_system_->LaunchApp(); + extension_system_->LaunchApp(app_id); return true; } @@ -51,7 +49,6 @@ class ShellExtensionsDelegate : public ExtensionsDelegate { content::BrowserContext* context_; extensions::ShellExtensionSystem* extension_system_; - extensions::ExtensionSet shell_extensions_; AthenaShellAppWindowClient app_window_client_; diff --git a/athena/main/athena_main.cc b/athena/main/athena_main.cc index 59f579f6..c8cc2e8 100644 --- a/athena/main/athena_main.cc +++ b/athena/main/athena_main.cc @@ -69,6 +69,8 @@ class AthenaDesktopController : public extensions::DesktopController { NOTIMPLEMENTED(); } + virtual void RemoveAppWindow(extensions::AppWindow* window) override {} + // Closes and destroys the app windows. virtual void CloseAppWindows() override {} diff --git a/extensions/browser/guest_view/web_view/web_view_apitest.cc b/extensions/browser/guest_view/web_view/web_view_apitest.cc index a30b78a..574e334 100644 --- a/extensions/browser/guest_view/web_view/web_view_apitest.cc +++ b/extensions/browser/guest_view/web_view/web_view_apitest.cc @@ -140,8 +140,9 @@ void WebViewAPITest::LaunchApp(const std::string& app_location) { embedded_test_server()->ServeFilesFromDirectory(test_data_dir); - ASSERT_TRUE(extension_system_->LoadApp(test_data_dir)); - extension_system_->LaunchApp(); + const Extension* extension = extension_system_->LoadApp(test_data_dir); + ASSERT_TRUE(extension); + extension_system_->LaunchApp(extension->id()); ExtensionTestMessageListener launch_listener("LAUNCHED", false); ASSERT_TRUE(launch_listener.WaitUntilSatisfied()); diff --git a/extensions/shell/browser/default_shell_browser_main_delegate.cc b/extensions/shell/browser/default_shell_browser_main_delegate.cc index 491fe43..7e49f52 100644 --- a/extensions/shell/browser/default_shell_browser_main_delegate.cc +++ b/extensions/shell/browser/default_shell_browser_main_delegate.cc @@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/strings/string_tokenizer.h" #include "extensions/shell/browser/shell_desktop_controller.h" #include "extensions/shell/browser/shell_extension_system.h" #include "extensions/shell/common/switches.h" @@ -23,15 +24,25 @@ void DefaultShellBrowserMainDelegate::Start( content::BrowserContext* browser_context) { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kAppShellAppPath)) { - base::FilePath app_dir( - command_line->GetSwitchValueNative(switches::kAppShellAppPath)); - base::FilePath app_absolute_dir = base::MakeAbsoluteFilePath(app_dir); - ShellExtensionSystem* extension_system = static_cast<ShellExtensionSystem*>( ExtensionSystem::Get(browser_context)); - if (!extension_system->LoadApp(app_absolute_dir)) - return; - extension_system->LaunchApp(); + extension_system->Init(); + + CommandLine::StringType path_list = + command_line->GetSwitchValueNative(switches::kAppShellAppPath); + + base::StringTokenizerT<CommandLine::StringType, + CommandLine::StringType::const_iterator> + tokenizer(path_list, FILE_PATH_LITERAL(",")); + while (tokenizer.GetNext()) { + base::FilePath app_absolute_dir = + base::MakeAbsoluteFilePath(base::FilePath(tokenizer.token())); + + const Extension* extension = extension_system->LoadApp(app_absolute_dir); + if (!extension) + continue; + extension_system->LaunchApp(extension->id()); + } } else { LOG(ERROR) << "--" << switches::kAppShellAppPath << " unset; boredom is in your future"; diff --git a/extensions/shell/browser/desktop_controller.h b/extensions/shell/browser/desktop_controller.h index 116d692..40a4e53 100644 --- a/extensions/shell/browser/desktop_controller.h +++ b/extensions/shell/browser/desktop_controller.h @@ -46,6 +46,9 @@ class DesktopController { // Attaches the window to our window hierarchy. virtual void AddAppWindow(aura::Window* window) = 0; + // Removes the window from the desktop. + virtual void RemoveAppWindow(AppWindow* window) = 0; + // Closes and destroys the app windows. virtual void CloseAppWindows() = 0; }; diff --git a/extensions/shell/browser/shell_desktop_controller.cc b/extensions/shell/browser/shell_desktop_controller.cc index 59e84a5..1ec98c8 100644 --- a/extensions/shell/browser/shell_desktop_controller.cc +++ b/extensions/shell/browser/shell_desktop_controller.cc @@ -4,6 +4,7 @@ #include "extensions/shell/browser/shell_desktop_controller.h" +#include <algorithm> #include <string> #include <vector> @@ -160,7 +161,7 @@ class AppsFocusRules : public wm::BaseFocusRules { } // namespace ShellDesktopController::ShellDesktopController() - : app_window_client_(new ShellAppWindowClient), app_window_(NULL) { + : app_window_client_(new ShellAppWindowClient) { extensions::AppWindowClient::Set(app_window_client_.get()); #if defined(OS_CHROMEOS) @@ -191,8 +192,9 @@ aura::WindowTreeHost* ShellDesktopController::GetHost() { AppWindow* ShellDesktopController::CreateAppWindow( content::BrowserContext* context, const Extension* extension) { - app_window_ = new AppWindow(context, new ShellAppDelegate, extension); - return app_window_; + app_windows_.push_back( + new AppWindow(context, new ShellAppDelegate, extension)); + return app_windows_.back(); } void ShellDesktopController::AddAppWindow(aura::Window* window) { @@ -200,11 +202,20 @@ void ShellDesktopController::AddAppWindow(aura::Window* window) { root_window->AddChild(window); } +void ShellDesktopController::RemoveAppWindow(AppWindow* window) { + auto iter = std::find(app_windows_.begin(), app_windows_.end(), window); + DCHECK(iter != app_windows_.end()); + app_windows_.erase(iter); +} + void ShellDesktopController::CloseAppWindows() { - if (app_window_) { - app_window_->GetBaseWindow()->Close(); // Close() deletes |app_window_|. - app_window_ = NULL; - } + // Create a copy of the window vector, because closing the windows will + // trigger RemoveAppWindow, which will invalidate the iterator. + // This vector should be small enough that this should not be an issue. + std::vector<AppWindow*> app_windows(app_windows_); + for (AppWindow* app_window : app_windows) + app_window->GetBaseWindow()->Close(); // Close() deletes |app_window|. + app_windows_.clear(); } aura::Window* ShellDesktopController::GetDefaultParent( diff --git a/extensions/shell/browser/shell_desktop_controller.h b/extensions/shell/browser/shell_desktop_controller.h index 14aa466..0b75e6b 100644 --- a/extensions/shell/browser/shell_desktop_controller.h +++ b/extensions/shell/browser/shell_desktop_controller.h @@ -5,6 +5,8 @@ #ifndef EXTENSIONS_SHELL_BROWSER_SHELL_DESKTOP_CONTROLLER_H_ #define EXTENSIONS_SHELL_BROWSER_SHELL_DESKTOP_CONTROLLER_H_ +#include <vector> + #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" @@ -69,6 +71,7 @@ class ShellDesktopController : public DesktopController, virtual AppWindow* CreateAppWindow(content::BrowserContext* context, const Extension* extension) override; virtual void AddAppWindow(aura::Window* window) override; + virtual void RemoveAppWindow(AppWindow* window) override; virtual void CloseAppWindows() override; // aura::client::WindowTreeClient overrides: @@ -131,8 +134,8 @@ class ShellDesktopController : public DesktopController, scoped_ptr<AppWindowClient> app_window_client_; - // The desktop supports a single app window. - AppWindow* app_window_; // NativeAppWindow::Close() deletes this. + // NativeAppWindow::Close() deletes the AppWindow. + std::vector<AppWindow*> app_windows_; DISALLOW_COPY_AND_ASSIGN(ShellDesktopController); }; diff --git a/extensions/shell/browser/shell_extension_system.cc b/extensions/shell/browser/shell_extension_system.cc index 317a410..6337108 100644 --- a/extensions/shell/browser/shell_extension_system.cc +++ b/extensions/shell/browser/shell_extension_system.cc @@ -37,21 +37,20 @@ ShellExtensionSystem::ShellExtensionSystem(BrowserContext* browser_context) ShellExtensionSystem::~ShellExtensionSystem() { } -bool ShellExtensionSystem::LoadApp(const base::FilePath& app_dir) { +const Extension* ShellExtensionSystem::LoadApp(const base::FilePath& app_dir) { // app_shell only supports unpacked extensions. // NOTE: If you add packed extension support consider removing the flag // FOLLOW_SYMLINKS_ANYWHERE below. Packed extensions should not have symlinks. CHECK(base::DirectoryExists(app_dir)) << app_dir.AsUTF8Unsafe(); int load_flags = Extension::FOLLOW_SYMLINKS_ANYWHERE; std::string load_error; - extension_ = file_util::LoadExtension( + scoped_refptr<Extension> extension = file_util::LoadExtension( app_dir, Manifest::COMMAND_LINE, load_flags, &load_error); - if (!extension_.get()) { + if (!extension.get()) { LOG(ERROR) << "Loading extension at " << app_dir.value() << " failed with: " << load_error; - return false; + return nullptr; } - app_id_ = extension_->id(); // TODO(jamescook): We may want to do some of these things here: // * Create a PermissionsUpdater. @@ -60,29 +59,36 @@ bool ShellExtensionSystem::LoadApp(const base::FilePath& app_dir) { // * Call ExtensionPrefs::OnExtensionInstalled(). // * Send NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED. - ExtensionRegistry::Get(browser_context_)->AddEnabled(extension_); + ExtensionRegistry::Get(browser_context_)->AddEnabled(extension.get()); - RegisterExtensionWithRequestContexts(extension_.get()); + RegisterExtensionWithRequestContexts(extension.get()); content::NotificationService::current()->Notify( extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, content::Source<BrowserContext>(browser_context_), - content::Details<const Extension>(extension_.get())); + content::Details<const Extension>(extension.get())); + return extension.get(); +} + +void ShellExtensionSystem::Init() { // Inform the rest of the extensions system to start. ready_.Signal(); content::NotificationService::current()->Notify( extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, content::Source<BrowserContext>(browser_context_), content::NotificationService::NoDetails()); - return true; } -void ShellExtensionSystem::LaunchApp() { +void ShellExtensionSystem::LaunchApp(const ExtensionId& extension_id) { // Send the onLaunched event. - DCHECK(extension_.get()); - AppRuntimeEventRouter::DispatchOnLaunchedEvent(browser_context_, - extension_.get()); + DCHECK(ExtensionRegistry::Get(browser_context_) + ->enabled_extensions() + .Contains(extension_id)); + const Extension* extension = ExtensionRegistry::Get(browser_context_) + ->enabled_extensions() + .GetByID(extension_id); + AppRuntimeEventRouter::DispatchOnLaunchedEvent(browser_context_, extension); } void ShellExtensionSystem::Shutdown() { diff --git a/extensions/shell/browser/shell_extension_system.h b/extensions/shell/browser/shell_extension_system.h index 08004ce..28113b7 100644 --- a/extensions/shell/browser/shell_extension_system.h +++ b/extensions/shell/browser/shell_extension_system.h @@ -38,17 +38,19 @@ class ShellExtensionSystem : public ExtensionSystem { explicit ShellExtensionSystem(content::BrowserContext* browser_context); ~ShellExtensionSystem() override; - // Loads an unpacked application from a directory. Returns true on success. - bool LoadApp(const base::FilePath& app_dir); + // Loads an unpacked application from a directory. Returns the extension on + // success, or null otherwise. + const Extension* LoadApp(const base::FilePath& app_dir); - // Launch the currently loaded app. - void LaunchApp(); + // Initializes the extension system. + void Init(); + + // Launch the app with id |extension_id|. + void LaunchApp(const std::string& extension_id); // KeyedService implementation: void Shutdown() override; - scoped_refptr<Extension> extension() { return extension_; } - // ExtensionSystem implementation: void InitForRegularProfile(bool extensions_enabled) override; ExtensionService* extension_service() override; @@ -81,11 +83,6 @@ class ShellExtensionSystem : public ExtensionSystem { private: content::BrowserContext* browser_context_; // Not owned. - // Extension ID for the app. - std::string app_id_; - - scoped_refptr<Extension> extension_; - // Data to be accessed on the IO thread. Must outlive process_manager_. scoped_refptr<InfoMap> info_map_; diff --git a/extensions/shell/browser/shell_native_app_window.cc b/extensions/shell/browser/shell_native_app_window.cc index 97968a9..1581a71 100644 --- a/extensions/shell/browser/shell_native_app_window.cc +++ b/extensions/shell/browser/shell_native_app_window.cc @@ -92,6 +92,7 @@ void ShellNativeAppWindow::ShowInactive() { } void ShellNativeAppWindow::Close() { + DesktopController::instance()->RemoveAppWindow(app_window_); app_window_->OnNativeClose(); } diff --git a/extensions/shell/test/shell_apitest.cc b/extensions/shell/test/shell_apitest.cc index b60bf5b..f1ea7a2 100644 --- a/extensions/shell/test/shell_apitest.cc +++ b/extensions/shell/test/shell_apitest.cc @@ -24,11 +24,11 @@ bool ShellApiTest::RunAppTest(const std::string& app_dir) { test_data_dir = test_data_dir.AppendASCII(app_dir); ResultCatcher catcher; - bool loaded = extension_system_->LoadApp(test_data_dir); - if (!loaded) + const Extension* extension = extension_system_->LoadApp(test_data_dir); + if (!extension) return false; - extension_system_->LaunchApp(); + extension_system_->LaunchApp(extension->id()); if (!catcher.GetNextResult()) { message_ = catcher.message(); |