OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "apps/app_window_registry.h" | |
6 | |
7 #include <string> | |
8 #include <vector> | |
9 | |
10 #include "apps/app_window.h" | |
11 #include "apps/ui/apps_client.h" | |
12 #include "components/keyed_service/content/browser_context_dependency_manager.h" | |
13 #include "content/public/browser/browser_context.h" | |
14 #include "content/public/browser/devtools_agent_host.h" | |
15 #include "content/public/browser/render_process_host.h" | |
16 #include "content/public/browser/render_view_host.h" | |
17 #include "content/public/browser/site_instance.h" | |
18 #include "content/public/browser/web_contents.h" | |
19 #include "extensions/browser/app_window/native_app_window.h" | |
20 #include "extensions/browser/extensions_browser_client.h" | |
21 #include "extensions/common/extension.h" | |
22 | |
23 namespace { | |
24 | |
25 // Create a key that identifies a AppWindow in a RenderViewHost across App | |
26 // reloads. If the window was given an id in CreateParams, the key is the | |
27 // extension id, a colon separator, and the AppWindow's |id|. If there is no | |
28 // |id|, the chrome-extension://extension-id/page.html URL will be used. If the | |
29 // RenderViewHost is not for a AppWindow, return an empty string. | |
30 std::string GetWindowKeyForRenderViewHost( | |
31 const apps::AppWindowRegistry* registry, | |
32 content::RenderViewHost* render_view_host) { | |
33 apps::AppWindow* app_window = | |
34 registry->GetAppWindowForRenderViewHost(render_view_host); | |
35 if (!app_window) | |
36 return std::string(); // Not a AppWindow. | |
37 | |
38 if (app_window->window_key().empty()) | |
39 return app_window->web_contents()->GetURL().possibly_invalid_spec(); | |
40 | |
41 std::string key = app_window->extension_id(); | |
42 key += ':'; | |
43 key += app_window->window_key(); | |
44 return key; | |
45 } | |
46 | |
47 } // namespace | |
48 | |
49 namespace apps { | |
50 | |
51 void AppWindowRegistry::Observer::OnAppWindowAdded(AppWindow* app_window) { | |
52 } | |
53 | |
54 void AppWindowRegistry::Observer::OnAppWindowIconChanged( | |
55 AppWindow* app_window) { | |
56 } | |
57 | |
58 void AppWindowRegistry::Observer::OnAppWindowRemoved(AppWindow* app_window) { | |
59 } | |
60 | |
61 void AppWindowRegistry::Observer::OnAppWindowHidden(AppWindow* app_window) { | |
62 } | |
63 | |
64 void AppWindowRegistry::Observer::OnAppWindowShown(AppWindow* app_window) { | |
65 } | |
66 | |
67 AppWindowRegistry::Observer::~Observer() { | |
68 } | |
69 | |
70 AppWindowRegistry::AppWindowRegistry(content::BrowserContext* context) | |
71 : context_(context), | |
72 devtools_callback_(base::Bind(&AppWindowRegistry::OnDevToolsStateChanged, | |
73 base::Unretained(this))) { | |
74 content::DevToolsAgentHost::AddAgentStateCallback(devtools_callback_); | |
75 } | |
76 | |
77 AppWindowRegistry::~AppWindowRegistry() { | |
78 content::DevToolsAgentHost::RemoveAgentStateCallback(devtools_callback_); | |
79 } | |
80 | |
81 // static | |
82 AppWindowRegistry* AppWindowRegistry::Get(content::BrowserContext* context) { | |
83 return Factory::GetForBrowserContext(context, true /* create */); | |
84 } | |
85 | |
86 void AppWindowRegistry::AddAppWindow(AppWindow* app_window) { | |
87 BringToFront(app_window); | |
88 FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowAdded(app_window)); | |
89 } | |
90 | |
91 void AppWindowRegistry::AppWindowIconChanged(AppWindow* app_window) { | |
92 AddAppWindowToList(app_window); | |
93 FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowIconChanged(app_window)); | |
94 } | |
95 | |
96 void AppWindowRegistry::AppWindowActivated(AppWindow* app_window) { | |
97 BringToFront(app_window); | |
98 } | |
99 | |
100 void AppWindowRegistry::AppWindowHidden(AppWindow* app_window) { | |
101 FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowHidden(app_window)); | |
102 } | |
103 | |
104 void AppWindowRegistry::AppWindowShown(AppWindow* app_window) { | |
105 FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowShown(app_window)); | |
106 } | |
107 | |
108 void AppWindowRegistry::RemoveAppWindow(AppWindow* app_window) { | |
109 const AppWindowList::iterator it = | |
110 std::find(app_windows_.begin(), app_windows_.end(), app_window); | |
111 if (it != app_windows_.end()) | |
112 app_windows_.erase(it); | |
113 FOR_EACH_OBSERVER(Observer, observers_, OnAppWindowRemoved(app_window)); | |
114 } | |
115 | |
116 void AppWindowRegistry::AddObserver(Observer* observer) { | |
117 observers_.AddObserver(observer); | |
118 } | |
119 | |
120 void AppWindowRegistry::RemoveObserver(Observer* observer) { | |
121 observers_.RemoveObserver(observer); | |
122 } | |
123 | |
124 AppWindowRegistry::AppWindowList AppWindowRegistry::GetAppWindowsForApp( | |
125 const std::string& app_id) const { | |
126 AppWindowList app_windows; | |
127 for (AppWindowList::const_iterator i = app_windows_.begin(); | |
128 i != app_windows_.end(); | |
129 ++i) { | |
130 if ((*i)->extension_id() == app_id) | |
131 app_windows.push_back(*i); | |
132 } | |
133 return app_windows; | |
134 } | |
135 | |
136 void AppWindowRegistry::CloseAllAppWindowsForApp(const std::string& app_id) { | |
137 const AppWindowList windows = GetAppWindowsForApp(app_id); | |
138 for (AppWindowRegistry::const_iterator it = windows.begin(); | |
139 it != windows.end(); | |
140 ++it) { | |
141 (*it)->GetBaseWindow()->Close(); | |
142 } | |
143 } | |
144 | |
145 AppWindow* AppWindowRegistry::GetAppWindowForRenderViewHost( | |
146 content::RenderViewHost* render_view_host) const { | |
147 for (AppWindowList::const_iterator i = app_windows_.begin(); | |
148 i != app_windows_.end(); | |
149 ++i) { | |
150 if ((*i)->web_contents()->GetRenderViewHost() == render_view_host) | |
151 return *i; | |
152 } | |
153 | |
154 return NULL; | |
155 } | |
156 | |
157 AppWindow* AppWindowRegistry::GetAppWindowForNativeWindow( | |
158 gfx::NativeWindow window) const { | |
159 for (AppWindowList::const_iterator i = app_windows_.begin(); | |
160 i != app_windows_.end(); | |
161 ++i) { | |
162 if ((*i)->GetNativeWindow() == window) | |
163 return *i; | |
164 } | |
165 | |
166 return NULL; | |
167 } | |
168 | |
169 AppWindow* AppWindowRegistry::GetCurrentAppWindowForApp( | |
170 const std::string& app_id) const { | |
171 AppWindow* result = NULL; | |
172 for (AppWindowList::const_iterator i = app_windows_.begin(); | |
173 i != app_windows_.end(); | |
174 ++i) { | |
175 if ((*i)->extension_id() == app_id) { | |
176 result = *i; | |
177 if (result->GetBaseWindow()->IsActive()) | |
178 return result; | |
179 } | |
180 } | |
181 | |
182 return result; | |
183 } | |
184 | |
185 AppWindow* AppWindowRegistry::GetAppWindowForAppAndKey( | |
186 const std::string& app_id, | |
187 const std::string& window_key) const { | |
188 AppWindow* result = NULL; | |
189 for (AppWindowList::const_iterator i = app_windows_.begin(); | |
190 i != app_windows_.end(); | |
191 ++i) { | |
192 if ((*i)->extension_id() == app_id && (*i)->window_key() == window_key) { | |
193 result = *i; | |
194 if (result->GetBaseWindow()->IsActive()) | |
195 return result; | |
196 } | |
197 } | |
198 return result; | |
199 } | |
200 | |
201 bool AppWindowRegistry::HadDevToolsAttached( | |
202 content::RenderViewHost* render_view_host) const { | |
203 std::string key = GetWindowKeyForRenderViewHost(this, render_view_host); | |
204 return key.empty() ? false : inspected_windows_.count(key) != 0; | |
205 } | |
206 | |
207 // static | |
208 AppWindow* AppWindowRegistry::GetAppWindowForNativeWindowAnyProfile( | |
209 gfx::NativeWindow window) { | |
210 std::vector<content::BrowserContext*> contexts = | |
211 AppsClient::Get()->GetLoadedBrowserContexts(); | |
212 for (std::vector<content::BrowserContext*>::const_iterator i = | |
213 contexts.begin(); | |
214 i != contexts.end(); | |
215 ++i) { | |
216 AppWindowRegistry* registry = | |
217 Factory::GetForBrowserContext(*i, false /* create */); | |
218 if (!registry) | |
219 continue; | |
220 | |
221 AppWindow* app_window = registry->GetAppWindowForNativeWindow(window); | |
222 if (app_window) | |
223 return app_window; | |
224 } | |
225 | |
226 return NULL; | |
227 } | |
228 | |
229 // static | |
230 bool AppWindowRegistry::IsAppWindowRegisteredInAnyProfile( | |
231 int window_type_mask) { | |
232 std::vector<content::BrowserContext*> contexts = | |
233 AppsClient::Get()->GetLoadedBrowserContexts(); | |
234 for (std::vector<content::BrowserContext*>::const_iterator i = | |
235 contexts.begin(); | |
236 i != contexts.end(); | |
237 ++i) { | |
238 AppWindowRegistry* registry = | |
239 Factory::GetForBrowserContext(*i, false /* create */); | |
240 if (!registry) | |
241 continue; | |
242 | |
243 const AppWindowList& app_windows = registry->app_windows(); | |
244 if (app_windows.empty()) | |
245 continue; | |
246 | |
247 if (window_type_mask == 0) | |
248 return true; | |
249 | |
250 for (const_iterator j = app_windows.begin(); j != app_windows.end(); ++j) { | |
251 if ((*j)->window_type() & window_type_mask) | |
252 return true; | |
253 } | |
254 } | |
255 | |
256 return false; | |
257 } | |
258 | |
259 // static | |
260 void AppWindowRegistry::CloseAllAppWindows() { | |
261 std::vector<content::BrowserContext*> contexts = | |
262 AppsClient::Get()->GetLoadedBrowserContexts(); | |
263 for (std::vector<content::BrowserContext*>::const_iterator i = | |
264 contexts.begin(); | |
265 i != contexts.end(); | |
266 ++i) { | |
267 AppWindowRegistry* registry = | |
268 Factory::GetForBrowserContext(*i, false /* create */); | |
269 if (!registry) | |
270 continue; | |
271 | |
272 while (!registry->app_windows().empty()) | |
273 registry->app_windows().front()->GetBaseWindow()->Close(); | |
274 } | |
275 } | |
276 | |
277 void AppWindowRegistry::OnDevToolsStateChanged( | |
278 content::DevToolsAgentHost* agent_host, | |
279 bool attached) { | |
280 content::WebContents* web_contents = agent_host->GetWebContents(); | |
281 // Ignore unrelated notifications. | |
282 if (!web_contents || web_contents->GetBrowserContext() != context_) | |
283 return; | |
284 | |
285 std::string key = | |
286 GetWindowKeyForRenderViewHost(this, web_contents->GetRenderViewHost()); | |
287 if (key.empty()) | |
288 return; | |
289 | |
290 if (attached) | |
291 inspected_windows_.insert(key); | |
292 else | |
293 inspected_windows_.erase(key); | |
294 } | |
295 | |
296 void AppWindowRegistry::AddAppWindowToList(AppWindow* app_window) { | |
297 const AppWindowList::iterator it = | |
298 std::find(app_windows_.begin(), app_windows_.end(), app_window); | |
299 if (it != app_windows_.end()) | |
300 return; | |
301 app_windows_.push_back(app_window); | |
302 } | |
303 | |
304 void AppWindowRegistry::BringToFront(AppWindow* app_window) { | |
305 const AppWindowList::iterator it = | |
306 std::find(app_windows_.begin(), app_windows_.end(), app_window); | |
307 if (it != app_windows_.end()) | |
308 app_windows_.erase(it); | |
309 app_windows_.push_front(app_window); | |
310 } | |
311 | |
312 /////////////////////////////////////////////////////////////////////////////// | |
313 // Factory boilerplate | |
314 | |
315 // static | |
316 AppWindowRegistry* AppWindowRegistry::Factory::GetForBrowserContext( | |
317 content::BrowserContext* context, | |
318 bool create) { | |
319 return static_cast<AppWindowRegistry*>( | |
320 GetInstance()->GetServiceForBrowserContext(context, create)); | |
321 } | |
322 | |
323 AppWindowRegistry::Factory* AppWindowRegistry::Factory::GetInstance() { | |
324 return Singleton<AppWindowRegistry::Factory>::get(); | |
325 } | |
326 | |
327 AppWindowRegistry::Factory::Factory() | |
328 : BrowserContextKeyedServiceFactory( | |
329 "AppWindowRegistry", | |
330 BrowserContextDependencyManager::GetInstance()) {} | |
331 | |
332 AppWindowRegistry::Factory::~Factory() {} | |
333 | |
334 KeyedService* AppWindowRegistry::Factory::BuildServiceInstanceFor( | |
335 content::BrowserContext* context) const { | |
336 return new AppWindowRegistry(context); | |
337 } | |
338 | |
339 bool AppWindowRegistry::Factory::ServiceIsCreatedWithBrowserContext() const { | |
340 return true; | |
341 } | |
342 | |
343 bool AppWindowRegistry::Factory::ServiceIsNULLWhileTesting() const { | |
344 return false; | |
345 } | |
346 | |
347 content::BrowserContext* AppWindowRegistry::Factory::GetBrowserContextToUse( | |
348 content::BrowserContext* context) const { | |
349 return extensions::ExtensionsBrowserClient::Get()->GetOriginalContext( | |
350 context); | |
351 } | |
352 | |
353 } // namespace apps | |
OLD | NEW |