Revert 290001 because it's causing test failures:
[chromium-blink-merge.git] / apps / app_window_registry.cc
blob67c836ab35a07625069f2af28b595ebe0a5fd02c
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "apps/app_window_registry.h"
7 #include <string>
8 #include <vector>
10 #include "apps/app_window.h"
11 #include "apps/ui/apps_client.h"
12 #include "apps/ui/native_app_window.h"
13 #include "components/keyed_service/content/browser_context_dependency_manager.h"
14 #include "content/public/browser/browser_context.h"
15 #include "content/public/browser/devtools_agent_host.h"
16 #include "content/public/browser/devtools_manager.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/site_instance.h"
20 #include "content/public/browser/web_contents.h"
21 #include "extensions/browser/extensions_browser_client.h"
22 #include "extensions/common/extension.h"
24 namespace {
26 // Create a key that identifies a AppWindow in a RenderViewHost across App
27 // reloads. If the window was given an id in CreateParams, the key is the
28 // extension id, a colon separator, and the AppWindow's |id|. If there is no
29 // |id|, the chrome-extension://extension-id/page.html URL will be used. If the
30 // RenderViewHost is not for a AppWindow, return an empty string.
31 std::string GetWindowKeyForRenderViewHost(
32 const apps::AppWindowRegistry* registry,
33 content::RenderViewHost* render_view_host) {
34 apps::AppWindow* app_window =
35 registry->GetAppWindowForRenderViewHost(render_view_host);
36 if (!app_window)
37 return std::string(); // Not a AppWindow.
39 if (app_window->window_key().empty())
40 return app_window->web_contents()->GetURL().possibly_invalid_spec();
42 std::string key = app_window->extension_id();
43 key += ':';
44 key += app_window->window_key();
45 return key;
48 } // namespace
50 namespace apps {
52 void AppWindowRegistry::Observer::OnAppWindowAdded(AppWindow* app_window) {
55 void AppWindowRegistry::Observer::OnAppWindowIconChanged(
56 AppWindow* app_window) {
59 void AppWindowRegistry::Observer::OnAppWindowRemoved(AppWindow* app_window) {
62 void AppWindowRegistry::Observer::OnAppWindowHidden(AppWindow* app_window) {
65 void AppWindowRegistry::Observer::OnAppWindowShown(AppWindow* app_window) {
68 AppWindowRegistry::Observer::~Observer() {
71 AppWindowRegistry::AppWindowRegistry(content::BrowserContext* context)
72 : context_(context),
73 devtools_callback_(base::Bind(&AppWindowRegistry::OnDevToolsStateChanged,
74 base::Unretained(this))) {
75 content::DevToolsManager::GetInstance()->AddAgentStateCallback(
76 devtools_callback_);
79 AppWindowRegistry::~AppWindowRegistry() {
80 content::DevToolsManager::GetInstance()->RemoveAgentStateCallback(
81 devtools_callback_);
84 // static
85 AppWindowRegistry* AppWindowRegistry::Get(content::BrowserContext* context) {
86 return Factory::GetForBrowserContext(context, true /* create */);
89 void AppWindowRegistry::AddAppWindow(AppWindow* app_window) {
90 BringToFront(app_window);
91 FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowAdded(app_window));
94 void AppWindowRegistry::AppWindowIconChanged(AppWindow* app_window) {
95 AddAppWindowToList(app_window);
96 FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowIconChanged(app_window));
99 void AppWindowRegistry::AppWindowActivated(AppWindow* app_window) {
100 BringToFront(app_window);
103 void AppWindowRegistry::AppWindowHidden(AppWindow* app_window) {
104 FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowHidden(app_window));
107 void AppWindowRegistry::AppWindowShown(AppWindow* app_window) {
108 FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowShown(app_window));
111 void AppWindowRegistry::RemoveAppWindow(AppWindow* app_window) {
112 const AppWindowList::iterator it =
113 std::find(app_windows_.begin(), app_windows_.end(), app_window);
114 if (it != app_windows_.end())
115 app_windows_.erase(it);
116 FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowRemoved(app_window));
119 void AppWindowRegistry::AddObserver(Observer* observer) {
120 observers_.AddObserver(observer);
123 void AppWindowRegistry::RemoveObserver(Observer* observer) {
124 observers_.RemoveObserver(observer);
127 AppWindowRegistry::AppWindowList AppWindowRegistry::GetAppWindowsForApp(
128 const std::string& app_id) const {
129 AppWindowList app_windows;
130 for (AppWindowList::const_iterator i = app_windows_.begin();
131 i != app_windows_.end();
132 ++i) {
133 if ((*i)->extension_id() == app_id)
134 app_windows.push_back(*i);
136 return app_windows;
139 void AppWindowRegistry::CloseAllAppWindowsForApp(const std::string& app_id) {
140 const AppWindowList windows = GetAppWindowsForApp(app_id);
141 for (AppWindowRegistry::const_iterator it = windows.begin();
142 it != windows.end();
143 ++it) {
144 (*it)->GetBaseWindow()->Close();
148 AppWindow* AppWindowRegistry::GetAppWindowForRenderViewHost(
149 content::RenderViewHost* render_view_host) const {
150 for (AppWindowList::const_iterator i = app_windows_.begin();
151 i != app_windows_.end();
152 ++i) {
153 if ((*i)->web_contents()->GetRenderViewHost() == render_view_host)
154 return *i;
157 return NULL;
160 AppWindow* AppWindowRegistry::GetAppWindowForNativeWindow(
161 gfx::NativeWindow window) const {
162 for (AppWindowList::const_iterator i = app_windows_.begin();
163 i != app_windows_.end();
164 ++i) {
165 if ((*i)->GetNativeWindow() == window)
166 return *i;
169 return NULL;
172 AppWindow* AppWindowRegistry::GetCurrentAppWindowForApp(
173 const std::string& app_id) const {
174 AppWindow* result = NULL;
175 for (AppWindowList::const_iterator i = app_windows_.begin();
176 i != app_windows_.end();
177 ++i) {
178 if ((*i)->extension_id() == app_id) {
179 result = *i;
180 if (result->GetBaseWindow()->IsActive())
181 return result;
185 return result;
188 AppWindow* AppWindowRegistry::GetAppWindowForAppAndKey(
189 const std::string& app_id,
190 const std::string& window_key) const {
191 AppWindow* result = NULL;
192 for (AppWindowList::const_iterator i = app_windows_.begin();
193 i != app_windows_.end();
194 ++i) {
195 if ((*i)->extension_id() == app_id && (*i)->window_key() == window_key) {
196 result = *i;
197 if (result->GetBaseWindow()->IsActive())
198 return result;
201 return result;
204 bool AppWindowRegistry::HadDevToolsAttached(
205 content::RenderViewHost* render_view_host) const {
206 std::string key = GetWindowKeyForRenderViewHost(this, render_view_host);
207 return key.empty() ? false : inspected_windows_.count(key) != 0;
210 // static
211 AppWindow* AppWindowRegistry::GetAppWindowForNativeWindowAnyProfile(
212 gfx::NativeWindow window) {
213 std::vector<content::BrowserContext*> contexts =
214 AppsClient::Get()->GetLoadedBrowserContexts();
215 for (std::vector<content::BrowserContext*>::const_iterator i =
216 contexts.begin();
217 i != contexts.end();
218 ++i) {
219 AppWindowRegistry* registry =
220 Factory::GetForBrowserContext(*i, false /* create */);
221 if (!registry)
222 continue;
224 AppWindow* app_window = registry->GetAppWindowForNativeWindow(window);
225 if (app_window)
226 return app_window;
229 return NULL;
232 // static
233 bool AppWindowRegistry::IsAppWindowRegisteredInAnyProfile(
234 int window_type_mask) {
235 std::vector<content::BrowserContext*> contexts =
236 AppsClient::Get()->GetLoadedBrowserContexts();
237 for (std::vector<content::BrowserContext*>::const_iterator i =
238 contexts.begin();
239 i != contexts.end();
240 ++i) {
241 AppWindowRegistry* registry =
242 Factory::GetForBrowserContext(*i, false /* create */);
243 if (!registry)
244 continue;
246 const AppWindowList& app_windows = registry->app_windows();
247 if (app_windows.empty())
248 continue;
250 if (window_type_mask == 0)
251 return true;
253 for (const_iterator j = app_windows.begin(); j != app_windows.end(); ++j) {
254 if ((*j)->window_type() & window_type_mask)
255 return true;
259 return false;
262 // static
263 void AppWindowRegistry::CloseAllAppWindows() {
264 std::vector<content::BrowserContext*> contexts =
265 AppsClient::Get()->GetLoadedBrowserContexts();
266 for (std::vector<content::BrowserContext*>::const_iterator i =
267 contexts.begin();
268 i != contexts.end();
269 ++i) {
270 AppWindowRegistry* registry =
271 Factory::GetForBrowserContext(*i, false /* create */);
272 if (!registry)
273 continue;
275 while (!registry->app_windows().empty())
276 registry->app_windows().front()->GetBaseWindow()->Close();
280 void AppWindowRegistry::OnDevToolsStateChanged(
281 content::DevToolsAgentHost* agent_host,
282 bool attached) {
283 content::WebContents* web_contents = agent_host->GetWebContents();
284 // Ignore unrelated notifications.
285 if (!web_contents || web_contents->GetBrowserContext() != context_)
286 return;
288 std::string key =
289 GetWindowKeyForRenderViewHost(this, web_contents->GetRenderViewHost());
290 if (key.empty())
291 return;
293 if (attached)
294 inspected_windows_.insert(key);
295 else
296 inspected_windows_.erase(key);
299 void AppWindowRegistry::AddAppWindowToList(AppWindow* app_window) {
300 const AppWindowList::iterator it =
301 std::find(app_windows_.begin(), app_windows_.end(), app_window);
302 if (it != app_windows_.end())
303 return;
304 app_windows_.push_back(app_window);
307 void AppWindowRegistry::BringToFront(AppWindow* app_window) {
308 const AppWindowList::iterator it =
309 std::find(app_windows_.begin(), app_windows_.end(), app_window);
310 if (it != app_windows_.end())
311 app_windows_.erase(it);
312 app_windows_.push_front(app_window);
315 ///////////////////////////////////////////////////////////////////////////////
316 // Factory boilerplate
318 // static
319 AppWindowRegistry* AppWindowRegistry::Factory::GetForBrowserContext(
320 content::BrowserContext* context,
321 bool create) {
322 return static_cast<AppWindowRegistry*>(
323 GetInstance()->GetServiceForBrowserContext(context, create));
326 AppWindowRegistry::Factory* AppWindowRegistry::Factory::GetInstance() {
327 return Singleton<AppWindowRegistry::Factory>::get();
330 AppWindowRegistry::Factory::Factory()
331 : BrowserContextKeyedServiceFactory(
332 "AppWindowRegistry",
333 BrowserContextDependencyManager::GetInstance()) {}
335 AppWindowRegistry::Factory::~Factory() {}
337 KeyedService* AppWindowRegistry::Factory::BuildServiceInstanceFor(
338 content::BrowserContext* context) const {
339 return new AppWindowRegistry(context);
342 bool AppWindowRegistry::Factory::ServiceIsCreatedWithBrowserContext() const {
343 return true;
346 bool AppWindowRegistry::Factory::ServiceIsNULLWhileTesting() const {
347 return false;
350 content::BrowserContext* AppWindowRegistry::Factory::GetBrowserContextToUse(
351 content::BrowserContext* context) const {
352 return extensions::ExtensionsBrowserClient::Get()->GetOriginalContext(
353 context);
356 } // namespace apps