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