summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--athena/extensions/shell/extensions_delegate_impl.cc9
-rw-r--r--athena/main/athena_main.cc2
-rw-r--r--extensions/browser/guest_view/web_view/web_view_apitest.cc5
-rw-r--r--extensions/shell/browser/default_shell_browser_main_delegate.cc25
-rw-r--r--extensions/shell/browser/desktop_controller.h3
-rw-r--r--extensions/shell/browser/shell_desktop_controller.cc25
-rw-r--r--extensions/shell/browser/shell_desktop_controller.h7
-rw-r--r--extensions/shell/browser/shell_extension_system.cc32
-rw-r--r--extensions/shell/browser/shell_extension_system.h19
-rw-r--r--extensions/shell/browser/shell_native_app_window.cc1
-rw-r--r--extensions/shell/test/shell_apitest.cc6
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();