summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorbenwells@chromium.org <benwells@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-09 11:03:20 +0000
committerbenwells@chromium.org <benwells@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-09 11:03:20 +0000
commitf6d9b28c0c05bb27e4d1f4e9d554929eb4d47218 (patch)
tree5ad0daca2f34da5cae31f7da4aaf3eb62d85b77d /apps
parent40febbe53d32b6c3f4b23a0b4c6da7cc2017c62d (diff)
downloadchromium_src-f6d9b28c0c05bb27e4d1f4e9d554929eb4d47218.zip
chromium_src-f6d9b28c0c05bb27e4d1f4e9d554929eb4d47218.tar.gz
chromium_src-f6d9b28c0c05bb27e4d1f4e9d554929eb4d47218.tar.bz2
Move ShellWindowRegistry to apps
TBR=sky BUG=159366 Review URL: https://chromiumcodereview.appspot.com/22642008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216658 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'apps')
-rw-r--r--apps/app_lifetime_monitor.cc1
-rw-r--r--apps/app_lifetime_monitor.h6
-rw-r--r--apps/app_lifetime_monitor_factory.cc4
-rw-r--r--apps/app_load_service.cc4
-rw-r--r--apps/app_load_service_factory.cc4
-rw-r--r--apps/app_restore_service.h2
-rw-r--r--apps/app_shim/extension_app_shim_handler_mac.cc13
-rw-r--r--apps/app_shim/extension_app_shim_handler_mac.h4
-rw-r--r--apps/app_shim/extension_app_shim_handler_mac_unittest.cc2
-rw-r--r--apps/apps.gypi2
-rw-r--r--apps/shell_window.cc10
-rw-r--r--apps/shell_window_registry.cc304
-rw-r--r--apps/shell_window_registry.h151
13 files changed, 481 insertions, 26 deletions
diff --git a/apps/app_lifetime_monitor.cc b/apps/app_lifetime_monitor.cc
index 8e4819a..8547be9 100644
--- a/apps/app_lifetime_monitor.cc
+++ b/apps/app_lifetime_monitor.cc
@@ -15,7 +15,6 @@ namespace apps {
using extensions::Extension;
using extensions::ExtensionHost;
-using extensions::ShellWindowRegistry;
AppLifetimeMonitor::AppLifetimeMonitor(Profile* profile)
: profile_(profile) {
diff --git a/apps/app_lifetime_monitor.h b/apps/app_lifetime_monitor.h
index f18a97d..2da6550 100644
--- a/apps/app_lifetime_monitor.h
+++ b/apps/app_lifetime_monitor.h
@@ -8,8 +8,8 @@
#include <string>
#include <vector>
+#include "apps/shell_window_registry.h"
#include "base/observer_list.h"
-#include "chrome/browser/extensions/shell_window_registry.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
@@ -26,7 +26,7 @@ namespace apps {
// events.
class AppLifetimeMonitor : public BrowserContextKeyedService,
public content::NotificationObserver,
- public extensions::ShellWindowRegistry::Observer {
+ public ShellWindowRegistry::Observer {
public:
class Observer {
public:
@@ -61,7 +61,7 @@ class AppLifetimeMonitor : public BrowserContextKeyedService,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
- // extensions::ShellWindowRegistry::Observer overrides:
+ // ShellWindowRegistry::Observer overrides:
virtual void OnShellWindowAdded(ShellWindow* shell_window) OVERRIDE;
virtual void OnShellWindowIconChanged(ShellWindow* shell_window) OVERRIDE;
virtual void OnShellWindowRemoved(ShellWindow* shell_window) OVERRIDE;
diff --git a/apps/app_lifetime_monitor_factory.cc b/apps/app_lifetime_monitor_factory.cc
index 4d828b0..1fb7994 100644
--- a/apps/app_lifetime_monitor_factory.cc
+++ b/apps/app_lifetime_monitor_factory.cc
@@ -5,7 +5,7 @@
#include "apps/app_lifetime_monitor_factory.h"
#include "apps/app_lifetime_monitor.h"
-#include "chrome/browser/extensions/shell_window_registry.h"
+#include "apps/shell_window_registry.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
@@ -26,7 +26,7 @@ AppLifetimeMonitorFactory::AppLifetimeMonitorFactory()
: BrowserContextKeyedServiceFactory(
"AppLifetimeMonitor",
BrowserContextDependencyManager::GetInstance()) {
- DependsOn(extensions::ShellWindowRegistry::Factory::GetInstance());
+ DependsOn(ShellWindowRegistry::Factory::GetInstance());
}
AppLifetimeMonitorFactory::~AppLifetimeMonitorFactory() {}
diff --git a/apps/app_load_service.cc b/apps/app_load_service.cc
index d2423c0..a0a6a66 100644
--- a/apps/app_load_service.cc
+++ b/apps/app_load_service.cc
@@ -6,12 +6,12 @@
#include "apps/app_load_service_factory.h"
#include "apps/launcher.h"
+#include "apps/shell_window_registry.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/shell_window_registry.h"
#include "chrome/browser/extensions/unpacked_installer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/extension.h"
@@ -125,7 +125,7 @@ void AppLoadService::Observe(int type,
}
bool AppLoadService::HasShellWindows(const std::string& extension_id) {
- return !extensions::ShellWindowRegistry::Get(profile_)->
+ return !ShellWindowRegistry::Get(profile_)->
GetShellWindowsForApp(extension_id).empty();
}
diff --git a/apps/app_load_service_factory.cc b/apps/app_load_service_factory.cc
index 37c2d45..a68cf94 100644
--- a/apps/app_load_service_factory.cc
+++ b/apps/app_load_service_factory.cc
@@ -5,9 +5,9 @@
#include "apps/app_load_service_factory.h"
#include "apps/app_load_service.h"
+#include "apps/shell_window_registry.h"
#include "chrome/browser/extensions/extension_prefs_factory.h"
#include "chrome/browser/extensions/extension_system_factory.h"
-#include "chrome/browser/extensions/shell_window_registry.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
@@ -30,7 +30,7 @@ AppLoadServiceFactory::AppLoadServiceFactory()
BrowserContextDependencyManager::GetInstance()) {
DependsOn(extensions::ExtensionPrefsFactory::GetInstance());
DependsOn(extensions::ExtensionSystemFactory::GetInstance());
- DependsOn(extensions::ShellWindowRegistry::Factory::GetInstance());
+ DependsOn(ShellWindowRegistry::Factory::GetInstance());
}
AppLoadServiceFactory::~AppLoadServiceFactory() {
diff --git a/apps/app_restore_service.h b/apps/app_restore_service.h
index 5a66005..425364e 100644
--- a/apps/app_restore_service.h
+++ b/apps/app_restore_service.h
@@ -9,7 +9,7 @@
#include <vector>
#include "apps/app_lifetime_monitor.h"
-#include "chrome/browser/extensions/shell_window_registry.h"
+#include "apps/shell_window_registry.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
namespace extensions {
diff --git a/apps/app_shim/extension_app_shim_handler_mac.cc b/apps/app_shim/extension_app_shim_handler_mac.cc
index 9173767..130c7f1 100644
--- a/apps/app_shim/extension_app_shim_handler_mac.cc
+++ b/apps/app_shim/extension_app_shim_handler_mac.cc
@@ -9,6 +9,7 @@
#include "apps/app_shim/app_shim_messages.h"
#include "apps/native_app_window.h"
#include "apps/shell_window.h"
+#include "apps/shell_window_registry.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "chrome/browser/browser_process.h"
@@ -16,7 +17,6 @@
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/shell_window_registry.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
@@ -44,7 +44,7 @@ void ProfileLoadedCallback(base::Callback<void(Profile*)> callback,
void TerminateIfNoShellWindows() {
bool shell_windows_left =
- extensions::ShellWindowRegistry::IsShellWindowRegisteredInAnyProfile(0);
+ apps::ShellWindowRegistry::IsShellWindowRegisteredInAnyProfile(0);
if (!shell_windows_left)
chrome::AttemptExit();
}
@@ -53,7 +53,7 @@ void TerminateIfNoShellWindows() {
namespace apps {
-typedef extensions::ShellWindowRegistry::ShellWindowList ShellWindowList;
+typedef ShellWindowRegistry::ShellWindowList ShellWindowList;
bool ExtensionAppShimHandler::Delegate::ProfileExistsForPath(
const base::FilePath& path) {
@@ -89,8 +89,7 @@ void ExtensionAppShimHandler::Delegate::LoadProfileAsync(
ShellWindowList ExtensionAppShimHandler::Delegate::GetWindows(
Profile* profile,
const std::string& extension_id) {
- return extensions::ShellWindowRegistry::Get(profile)->
- GetShellWindowsForApp(extension_id);
+ return ShellWindowRegistry::Get(profile)->GetShellWindowsForApp(extension_id);
}
const extensions::Extension*
@@ -167,7 +166,7 @@ void ExtensionAppShimHandler::QuitAppForWindow(ShellWindow* shell_window) {
handler->OnShimQuit(host);
} else {
// App shims might be disabled or the shim is still starting up.
- extensions::ShellWindowRegistry::Get(shell_window->profile())->
+ ShellWindowRegistry::Get(shell_window->profile())->
CloseAllShellWindowsForApp(shell_window->extension_id());
}
}
@@ -305,7 +304,7 @@ void ExtensionAppShimHandler::OnShimQuit(Host* host) {
const std::string& app_id = host->GetAppId();
const ShellWindowList windows =
delegate_->GetWindows(profile, app_id);
- for (extensions::ShellWindowRegistry::const_iterator it = windows.begin();
+ for (ShellWindowRegistry::const_iterator it = windows.begin();
it != windows.end(); ++it) {
(*it)->GetBaseWindow()->Close();
}
diff --git a/apps/app_shim/extension_app_shim_handler_mac.h b/apps/app_shim/extension_app_shim_handler_mac.h
index 616fd78..8a9f64e 100644
--- a/apps/app_shim/extension_app_shim_handler_mac.h
+++ b/apps/app_shim/extension_app_shim_handler_mac.h
@@ -10,9 +10,9 @@
#include "apps/app_lifetime_monitor.h"
#include "apps/app_shim/app_shim_handler_mac.h"
+#include "apps/shell_window_registry.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "chrome/browser/extensions/shell_window_registry.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
@@ -47,7 +47,7 @@ class ExtensionAppShimHandler : public AppShimHandler,
virtual void LoadProfileAsync(const base::FilePath& path,
base::Callback<void(Profile*)> callback);
- virtual extensions::ShellWindowRegistry::ShellWindowList GetWindows(
+ virtual ShellWindowRegistry::ShellWindowList GetWindows(
Profile* profile, const std::string& extension_id);
virtual const extensions::Extension* GetAppExtension(
diff --git a/apps/app_shim/extension_app_shim_handler_mac_unittest.cc b/apps/app_shim/extension_app_shim_handler_mac_unittest.cc
index 33941de7..636ba1b 100644
--- a/apps/app_shim/extension_app_shim_handler_mac_unittest.cc
+++ b/apps/app_shim/extension_app_shim_handler_mac_unittest.cc
@@ -16,7 +16,7 @@
namespace apps {
using extensions::Extension;
-typedef extensions::ShellWindowRegistry::ShellWindowList ShellWindowList;
+typedef ShellWindowRegistry::ShellWindowList ShellWindowList;
using ::testing::_;
using ::testing::Invoke;
diff --git a/apps/apps.gypi b/apps/apps.gypi
index 59f4c75..7e2c179 100644
--- a/apps/apps.gypi
+++ b/apps/apps.gypi
@@ -70,6 +70,8 @@
'shell_window.h',
'shell_window_geometry_cache.cc',
'shell_window_geometry_cache.h',
+ 'shell_window_registry.cc',
+ 'shell_window_registry.h',
'switches.cc',
'switches.h',
],
diff --git a/apps/shell_window.cc b/apps/shell_window.cc
index 12585aa..10ab851 100644
--- a/apps/shell_window.cc
+++ b/apps/shell_window.cc
@@ -6,13 +6,13 @@
#include "apps/native_app_window.h"
#include "apps/shell_window_geometry_cache.h"
+#include "apps/shell_window_registry.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/shell_window_registry.h"
#include "chrome/browser/extensions/suggest_permission_util.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
@@ -194,7 +194,7 @@ void ShellWindow::Init(const GURL& url,
UpdateExtensionAppIcon();
- extensions::ShellWindowRegistry::Get(profile_)->AddShellWindow(this);
+ ShellWindowRegistry::Get(profile_)->AddShellWindow(this);
}
ShellWindow::~ShellWindow() {
@@ -280,7 +280,7 @@ void ShellWindow::RequestToLockMouse(WebContents* web_contents,
}
void ShellWindow::OnNativeClose() {
- extensions::ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this);
+ ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this);
if (shell_window_contents_)
shell_window_contents_->NativeWindowClosed();
delete this;
@@ -293,7 +293,7 @@ void ShellWindow::OnNativeWindowChanged() {
}
void ShellWindow::OnNativeWindowActivated() {
- extensions::ShellWindowRegistry::Get(profile_)->ShellWindowActivated(this);
+ ShellWindowRegistry::Get(profile_)->ShellWindowActivated(this);
}
scoped_ptr<gfx::Image> ShellWindow::GetAppListIcon() {
@@ -374,7 +374,7 @@ void ShellWindow::UpdateAppIcon(const gfx::Image& image) {
return;
app_icon_ = image;
native_app_window_->UpdateWindowIcon();
- extensions::ShellWindowRegistry::Get(profile_)->ShellWindowIconChanged(this);
+ ShellWindowRegistry::Get(profile_)->ShellWindowIconChanged(this);
}
void ShellWindow::Fullscreen() {
diff --git a/apps/shell_window_registry.cc b/apps/shell_window_registry.cc
new file mode 100644
index 0000000..301bcf1
--- /dev/null
+++ b/apps/shell_window_registry.cc
@@ -0,0 +1,304 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "apps/native_app_window.h"
+#include "apps/shell_window.h"
+#include "apps/shell_window_registry.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/extensions/extension.h"
+#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
+#include "content/public/browser/devtools_agent_host.h"
+#include "content/public/browser/devtools_manager.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/site_instance.h"
+#include "content/public/browser/web_contents.h"
+
+namespace {
+
+// Create a key that identifies a ShellWindow in a RenderViewHost across App
+// reloads. If the window was given an id in CreateParams, the key is the
+// extension id, a colon separator, and the ShellWindow's |id|. If there is no
+// |id|, the chrome-extension://extension-id/page.html URL will be used. If the
+// RenderViewHost is not for a ShellWindow, return an empty string.
+std::string GetWindowKeyForRenderViewHost(
+ const apps::ShellWindowRegistry* registry,
+ content::RenderViewHost* render_view_host) {
+ apps::ShellWindow* shell_window =
+ registry->GetShellWindowForRenderViewHost(render_view_host);
+ if (!shell_window)
+ return std::string(); // Not a ShellWindow.
+
+ if (shell_window->window_key().empty())
+ return shell_window->web_contents()->GetURL().possibly_invalid_spec();
+
+ std::string key = shell_window->extension()->id();
+ key += ':';
+ key += shell_window->window_key();
+ return key;
+}
+
+} // namespace
+
+namespace apps {
+
+ShellWindowRegistry::ShellWindowRegistry(Profile* profile)
+ : profile_(profile),
+ devtools_callback_(base::Bind(
+ &ShellWindowRegistry::OnDevToolsStateChanged,
+ base::Unretained(this))) {
+ content::DevToolsManager::GetInstance()->AddAgentStateCallback(
+ devtools_callback_);
+}
+
+ShellWindowRegistry::~ShellWindowRegistry() {
+ content::DevToolsManager::GetInstance()->RemoveAgentStateCallback(
+ devtools_callback_);
+}
+
+// static
+ShellWindowRegistry* ShellWindowRegistry::Get(Profile* profile) {
+ return Factory::GetForProfile(profile, true /* create */);
+}
+
+void ShellWindowRegistry::AddShellWindow(ShellWindow* shell_window) {
+ BringToFront(shell_window);
+ FOR_EACH_OBSERVER(Observer, observers_, OnShellWindowAdded(shell_window));
+}
+
+void ShellWindowRegistry::ShellWindowIconChanged(ShellWindow* shell_window) {
+ AddShellWindowToList(shell_window);
+ FOR_EACH_OBSERVER(Observer, observers_,
+ OnShellWindowIconChanged(shell_window));
+}
+
+void ShellWindowRegistry::ShellWindowActivated(ShellWindow* shell_window) {
+ BringToFront(shell_window);
+}
+
+void ShellWindowRegistry::RemoveShellWindow(ShellWindow* shell_window) {
+ const ShellWindowList::iterator it = std::find(shell_windows_.begin(),
+ shell_windows_.end(),
+ shell_window);
+ if (it != shell_windows_.end())
+ shell_windows_.erase(it);
+ FOR_EACH_OBSERVER(Observer, observers_, OnShellWindowRemoved(shell_window));
+}
+
+void ShellWindowRegistry::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void ShellWindowRegistry::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+ShellWindowRegistry::ShellWindowList ShellWindowRegistry::GetShellWindowsForApp(
+ const std::string& app_id) const {
+ ShellWindowList app_windows;
+ for (ShellWindowList::const_iterator i = shell_windows_.begin();
+ i != shell_windows_.end(); ++i) {
+ if ((*i)->extension_id() == app_id)
+ app_windows.push_back(*i);
+ }
+ return app_windows;
+}
+
+void ShellWindowRegistry::CloseAllShellWindowsForApp(
+ const std::string& app_id) {
+ for (ShellWindowList::const_iterator i = shell_windows_.begin();
+ i != shell_windows_.end(); ) {
+ ShellWindow* shell_window = *(i++);
+ if (shell_window->extension_id() == app_id)
+ shell_window->GetBaseWindow()->Close();
+ }
+}
+
+ShellWindow* ShellWindowRegistry::GetShellWindowForRenderViewHost(
+ content::RenderViewHost* render_view_host) const {
+ for (ShellWindowList::const_iterator i = shell_windows_.begin();
+ i != shell_windows_.end(); ++i) {
+ if ((*i)->web_contents()->GetRenderViewHost() == render_view_host)
+ return *i;
+ }
+
+ return NULL;
+}
+
+ShellWindow* ShellWindowRegistry::GetShellWindowForNativeWindow(
+ gfx::NativeWindow window) const {
+ for (ShellWindowList::const_iterator i = shell_windows_.begin();
+ i != shell_windows_.end(); ++i) {
+ if ((*i)->GetNativeWindow() == window)
+ return *i;
+ }
+
+ return NULL;
+}
+
+ShellWindow* ShellWindowRegistry::GetCurrentShellWindowForApp(
+ const std::string& app_id) const {
+ ShellWindow* result = NULL;
+ for (ShellWindowList::const_iterator i = shell_windows_.begin();
+ i != shell_windows_.end(); ++i) {
+ if ((*i)->extension()->id() == app_id) {
+ result = *i;
+ if (result->GetBaseWindow()->IsActive())
+ return result;
+ }
+ }
+
+ return result;
+}
+
+ShellWindow* ShellWindowRegistry::GetShellWindowForAppAndKey(
+ const std::string& app_id,
+ const std::string& window_key) const {
+ ShellWindow* result = NULL;
+ for (ShellWindowList::const_iterator i = shell_windows_.begin();
+ i != shell_windows_.end(); ++i) {
+ if ((*i)->extension()->id() == app_id && (*i)->window_key() == window_key) {
+ result = *i;
+ if (result->GetBaseWindow()->IsActive())
+ return result;
+ }
+ }
+ return result;
+}
+
+bool ShellWindowRegistry::HadDevToolsAttached(
+ content::RenderViewHost* render_view_host) const {
+ std::string key = GetWindowKeyForRenderViewHost(this, render_view_host);
+ return key.empty() ? false : inspected_windows_.count(key) != 0;
+}
+
+// static
+ShellWindow* ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile(
+ gfx::NativeWindow window) {
+ std::vector<Profile*> profiles =
+ g_browser_process->profile_manager()->GetLoadedProfiles();
+ for (std::vector<Profile*>::const_iterator i = profiles.begin();
+ i != profiles.end(); ++i) {
+ ShellWindowRegistry* registry = Factory::GetForProfile(*i,
+ false /* create */);
+ if (!registry)
+ continue;
+
+ ShellWindow* shell_window = registry->GetShellWindowForNativeWindow(window);
+ if (shell_window)
+ return shell_window;
+ }
+
+ return NULL;
+}
+
+// static
+bool ShellWindowRegistry::IsShellWindowRegisteredInAnyProfile(
+ int window_type_mask) {
+ std::vector<Profile*> profiles =
+ g_browser_process->profile_manager()->GetLoadedProfiles();
+ for (std::vector<Profile*>::const_iterator i = profiles.begin();
+ i != profiles.end(); ++i) {
+ ShellWindowRegistry* registry = Factory::GetForProfile(*i,
+ false /* create */);
+ if (!registry)
+ continue;
+
+ const ShellWindowList& shell_windows = registry->shell_windows();
+ if (shell_windows.empty())
+ continue;
+
+ if (window_type_mask == 0)
+ return true;
+
+ for (const_iterator j = shell_windows.begin(); j != shell_windows.end();
+ ++j) {
+ if ((*j)->window_type() & window_type_mask)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void ShellWindowRegistry::OnDevToolsStateChanged(
+ content::DevToolsAgentHost* agent_host, bool attached) {
+ content::RenderViewHost* rvh = agent_host->GetRenderViewHost();
+ // Ignore unrelated notifications.
+ if (!rvh ||
+ rvh->GetSiteInstance()->GetProcess()->GetBrowserContext() != profile_)
+ return;
+ std::string key = GetWindowKeyForRenderViewHost(this, rvh);
+ if (key.empty())
+ return;
+
+ if (attached)
+ inspected_windows_.insert(key);
+ else
+ inspected_windows_.erase(key);
+}
+
+void ShellWindowRegistry::AddShellWindowToList(ShellWindow* shell_window) {
+ const ShellWindowList::iterator it = std::find(shell_windows_.begin(),
+ shell_windows_.end(),
+ shell_window);
+ if (it != shell_windows_.end())
+ return;
+ shell_windows_.push_back(shell_window);
+}
+
+void ShellWindowRegistry::BringToFront(ShellWindow* shell_window) {
+ const ShellWindowList::iterator it = std::find(shell_windows_.begin(),
+ shell_windows_.end(),
+ shell_window);
+ if (it != shell_windows_.end())
+ shell_windows_.erase(it);
+ shell_windows_.push_front(shell_window);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Factory boilerplate
+
+// static
+ShellWindowRegistry* ShellWindowRegistry::Factory::GetForProfile(
+ Profile* profile, bool create) {
+ return static_cast<ShellWindowRegistry*>(
+ GetInstance()->GetServiceForBrowserContext(profile, create));
+}
+
+ShellWindowRegistry::Factory* ShellWindowRegistry::Factory::GetInstance() {
+ return Singleton<ShellWindowRegistry::Factory>::get();
+}
+
+ShellWindowRegistry::Factory::Factory()
+ : BrowserContextKeyedServiceFactory(
+ "ShellWindowRegistry",
+ BrowserContextDependencyManager::GetInstance()) {
+}
+
+ShellWindowRegistry::Factory::~Factory() {
+}
+
+BrowserContextKeyedService*
+ShellWindowRegistry::Factory::BuildServiceInstanceFor(
+ content::BrowserContext* profile) const {
+ return new ShellWindowRegistry(static_cast<Profile*>(profile));
+}
+
+bool ShellWindowRegistry::Factory::ServiceIsCreatedWithBrowserContext() const {
+ return true;
+}
+
+bool ShellWindowRegistry::Factory::ServiceIsNULLWhileTesting() const {
+ return false;
+}
+
+content::BrowserContext* ShellWindowRegistry::Factory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ return chrome::GetBrowserContextRedirectedInIncognito(context);
+}
+
+} // namespace extensions
diff --git a/apps/shell_window_registry.h b/apps/shell_window_registry.h
new file mode 100644
index 0000000..e23c5e9
--- /dev/null
+++ b/apps/shell_window_registry.h
@@ -0,0 +1,151 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef APPS_SHELL_WINDOW_REGISTRY_H_
+#define APPS_SHELL_WINDOW_REGISTRY_H_
+
+#include <list>
+
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/memory/singleton.h"
+#include "base/observer_list.h"
+#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
+#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
+#include "ui/gfx/native_widget_types.h"
+
+class Profile;
+
+namespace content {
+class DevToolsAgentHost;
+class RenderViewHost;
+}
+
+namespace apps {
+
+class ShellWindow;
+
+// The ShellWindowRegistry tracks the ShellWindows for all platform apps for a
+// particular profile.
+// This class is planned to evolve into tracking all PlatformApps for a
+// particular profile, with a PlatformApp encapsulating all views (background
+// page, shell windows, tray view, panels etc.) and other app level behaviour
+// (e.g. notifications the app is interested in, lifetime of the background
+// page).
+class ShellWindowRegistry : public BrowserContextKeyedService {
+ public:
+ class Observer {
+ public:
+ // Called just after a shell window was added.
+ virtual void OnShellWindowAdded(apps::ShellWindow* shell_window) = 0;
+ // Called when the window icon changes.
+ virtual void OnShellWindowIconChanged(apps::ShellWindow* shell_window) = 0;
+ // Called just after a shell window was removed.
+ virtual void OnShellWindowRemoved(apps::ShellWindow* shell_window) = 0;
+
+ protected:
+ virtual ~Observer() {}
+ };
+
+ typedef std::list<apps::ShellWindow*> ShellWindowList;
+ typedef ShellWindowList::const_iterator const_iterator;
+ typedef std::set<std::string> InspectedWindowSet;
+
+ explicit ShellWindowRegistry(Profile* profile);
+ virtual ~ShellWindowRegistry();
+
+ // Returns the instance for the given profile, or NULL if none. This is
+ // a convenience wrapper around ShellWindowRegistry::Factory::GetForProfile.
+ static ShellWindowRegistry* Get(Profile* profile);
+
+ void AddShellWindow(apps::ShellWindow* shell_window);
+ void ShellWindowIconChanged(apps::ShellWindow* shell_window);
+ // Called by |shell_window| when it is activated.
+ void ShellWindowActivated(apps::ShellWindow* shell_window);
+ void RemoveShellWindow(apps::ShellWindow* shell_window);
+
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
+ // Returns a set of windows owned by the application identified by app_id.
+ ShellWindowList GetShellWindowsForApp(const std::string& app_id) const;
+ const ShellWindowList& shell_windows() const { return shell_windows_; }
+
+ // Close all shell windows associated with an app.
+ void CloseAllShellWindowsForApp(const std::string& app_id);
+
+ // Helper functions to find shell windows with particular attributes.
+ apps::ShellWindow* GetShellWindowForRenderViewHost(
+ content::RenderViewHost* render_view_host) const;
+ apps::ShellWindow* GetShellWindowForNativeWindow(
+ gfx::NativeWindow window) const;
+ // Returns an app window for the given app, or NULL if no shell windows are
+ // open. If there is a window for the given app that is active, that one will
+ // be returned, otherwise an arbitrary window will be returned.
+ apps::ShellWindow* GetCurrentShellWindowForApp(
+ const std::string& app_id) const;
+ // Returns an app window for the given app and window key, or NULL if no shell
+ // window with the key are open. If there is a window for the given app and
+ // key that is active, that one will be returned, otherwise an arbitrary
+ // window will be returned.
+ apps::ShellWindow* GetShellWindowForAppAndKey(
+ const std::string& app_id,
+ const std::string& window_key) const;
+
+ // Returns whether a ShellWindow's ID was last known to have a DevToolsAgent
+ // attached to it, which should be restored during a reload of a corresponding
+ // newly created |render_view_host|.
+ bool HadDevToolsAttached(content::RenderViewHost* render_view_host) const;
+
+ // Returns the shell window for |window|, looking in all profiles.
+ static apps::ShellWindow* GetShellWindowForNativeWindowAnyProfile(
+ gfx::NativeWindow window);
+
+ // Returns true if the number of shell windows registered across all profiles
+ // is non-zero. |window_type_mask| is a bitwise OR filter of
+ // ShellWindow::WindowType, or 0 for any window type.
+ static bool IsShellWindowRegisteredInAnyProfile(int window_type_mask);
+
+ class Factory : public BrowserContextKeyedServiceFactory {
+ public:
+ static ShellWindowRegistry* GetForProfile(Profile* profile, bool create);
+
+ static Factory* GetInstance();
+ private:
+ friend struct DefaultSingletonTraits<Factory>;
+
+ Factory();
+ virtual ~Factory();
+
+ // BrowserContextKeyedServiceFactory
+ virtual BrowserContextKeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* profile) const OVERRIDE;
+ virtual bool ServiceIsCreatedWithBrowserContext() const OVERRIDE;
+ virtual bool ServiceIsNULLWhileTesting() const OVERRIDE;
+ virtual content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const OVERRIDE;
+ };
+
+ protected:
+ void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached);
+
+ private:
+ // Ensures the specified |shell_window| is included in |shell_windows_|.
+ // Otherwise adds |shell_window| to the back of |shell_windows_|.
+ void AddShellWindowToList(apps::ShellWindow* shell_window);
+
+ // Bring |shell_window| to the front of |shell_windows_|. If it is not in the
+ // list, add it first.
+ void BringToFront(apps::ShellWindow* shell_window);
+
+ Profile* profile_;
+ ShellWindowList shell_windows_;
+ InspectedWindowSet inspected_windows_;
+ ObserverList<Observer> observers_;
+ base::Callback<void(content::DevToolsAgentHost*, bool)> devtools_callback_;
+};
+
+} // namespace extensions
+
+#endif // APPS_SHELL_WINDOW_REGISTRY_H_