OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_process_manager.h" | 5 #include "chrome/browser/extensions/extension_process_manager.h" |
6 | 6 |
7 #include "chrome/browser/ui/browser_window.h" | 7 #include "chrome/browser/ui/browser_window.h" |
8 #include "content/browser/browsing_instance.h" | 8 #include "content/browser/browsing_instance.h" |
9 #if defined(OS_MACOSX) | 9 #if defined(OS_MACOSX) |
10 #include "chrome/browser/extensions/extension_host_mac.h" | 10 #include "chrome/browser/extensions/extension_host_mac.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 explicit IncognitoExtensionProcessManager(Profile* profile); | 30 explicit IncognitoExtensionProcessManager(Profile* profile); |
31 virtual ~IncognitoExtensionProcessManager() {} | 31 virtual ~IncognitoExtensionProcessManager() {} |
32 virtual ExtensionHost* CreateViewHost(const Extension* extension, | 32 virtual ExtensionHost* CreateViewHost(const Extension* extension, |
33 const GURL& url, | 33 const GURL& url, |
34 Browser* browser, | 34 Browser* browser, |
35 ViewType::Type view_type) OVERRIDE; | 35 ViewType::Type view_type) OVERRIDE; |
36 virtual void CreateBackgroundHost(const Extension* extension, | 36 virtual void CreateBackgroundHost(const Extension* extension, |
37 const GURL& url); | 37 const GURL& url); |
38 virtual SiteInstance* GetSiteInstanceForURL(const GURL& url); | 38 virtual SiteInstance* GetSiteInstanceForURL(const GURL& url); |
39 virtual RenderProcessHost* GetExtensionProcess(const GURL& url); | 39 virtual RenderProcessHost* GetExtensionProcess(const GURL& url); |
| 40 virtual const Extension* GetExtensionForSiteInstance(int site_instance_id); |
40 | 41 |
41 private: | 42 private: |
42 // NotificationObserver: | 43 // NotificationObserver: |
43 virtual void Observe(int type, | 44 virtual void Observe(int type, |
44 const NotificationSource& source, | 45 const NotificationSource& source, |
45 const NotificationDetails& details); | 46 const NotificationDetails& details); |
46 | 47 |
47 // Returns the extension for an URL, which can either be a chrome-extension | 48 // Returns the extension for an URL, which can either be a chrome-extension |
48 // URL or a web app URL. | 49 // URL or a web app URL. |
49 const Extension* GetExtensionOrAppByURL(const GURL& url); | 50 const Extension* GetExtensionOrAppByURL(const GURL& url); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 : browsing_instance_(new BrowsingInstance(profile)) { | 89 : browsing_instance_(new BrowsingInstance(profile)) { |
89 Profile* original_profile = profile->GetOriginalProfile(); | 90 Profile* original_profile = profile->GetOriginalProfile(); |
90 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, | 91 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
91 Source<Profile>(original_profile)); | 92 Source<Profile>(original_profile)); |
92 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 93 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
93 Source<Profile>(original_profile)); | 94 Source<Profile>(original_profile)); |
94 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 95 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
95 Source<Profile>(original_profile)); | 96 Source<Profile>(original_profile)); |
96 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 97 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
97 Source<Profile>(profile)); | 98 Source<Profile>(profile)); |
98 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 99 registrar_.Add(this, content::NOTIFICATION_SITE_INSTANCE_DELETED, |
99 NotificationService::AllSources()); | |
100 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | |
101 NotificationService::AllSources()); | 100 NotificationService::AllSources()); |
102 registrar_.Add(this, content::NOTIFICATION_APP_TERMINATING, | 101 registrar_.Add(this, content::NOTIFICATION_APP_TERMINATING, |
103 NotificationService::AllSources()); | 102 NotificationService::AllSources()); |
104 } | 103 } |
105 | 104 |
106 ExtensionProcessManager::~ExtensionProcessManager() { | 105 ExtensionProcessManager::~ExtensionProcessManager() { |
107 VLOG_IF(1, g_log_bug53991) << "~ExtensionProcessManager: " << this; | 106 VLOG_IF(1, g_log_bug53991) << "~ExtensionProcessManager: " << this; |
108 CloseBackgroundHosts(); | 107 CloseBackgroundHosts(); |
109 DCHECK(background_hosts_.empty()); | 108 DCHECK(background_hosts_.empty()); |
110 } | 109 } |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 const Extension* extension) { | 213 const Extension* extension) { |
215 for (ExtensionHostSet::iterator iter = background_hosts_.begin(); | 214 for (ExtensionHostSet::iterator iter = background_hosts_.begin(); |
216 iter != background_hosts_.end(); ++iter) { | 215 iter != background_hosts_.end(); ++iter) { |
217 ExtensionHost* host = *iter; | 216 ExtensionHost* host = *iter; |
218 if (host->extension() == extension) | 217 if (host->extension() == extension) |
219 return host; | 218 return host; |
220 } | 219 } |
221 return NULL; | 220 return NULL; |
222 } | 221 } |
223 | 222 |
224 void ExtensionProcessManager::RegisterExtensionProcess( | 223 void ExtensionProcessManager::RegisterExtensionSiteInstance( |
225 const std::string& extension_id, int process_id) { | 224 int site_instance_id, const std::string& extension_id) { |
226 // TODO(mpcomplete): This is the only place we actually read process_ids_. | 225 SiteInstanceIDMap::const_iterator it = extension_ids_.find(site_instance_id); |
227 // Is it necessary? | 226 if (it != extension_ids_.end() && (*it).second == extension_id) |
228 ProcessIDMap::const_iterator it = process_ids_.find(extension_id); | |
229 if (it != process_ids_.end() && (*it).second == process_id) | |
230 return; | 227 return; |
231 | 228 |
232 // Extension ids should get removed from the map before the process ids get | 229 // SiteInstance ids should get removed from the map before the extension ids |
233 // reused from a dead renderer. | 230 // get used for a new SiteInstance. |
234 DCHECK(it == process_ids_.end()); | 231 DCHECK(it == extension_ids_.end()); |
235 process_ids_[extension_id] = process_id; | 232 extension_ids_[site_instance_id] = extension_id; |
236 } | 233 } |
237 | 234 |
238 void ExtensionProcessManager::UnregisterExtensionProcess(int process_id) { | 235 void ExtensionProcessManager::UnregisterExtensionSiteInstance( |
239 ProcessIDMap::iterator it = process_ids_.begin(); | 236 int site_instance_id) { |
240 while (it != process_ids_.end()) { | 237 SiteInstanceIDMap::iterator it = extension_ids_.find(site_instance_id); |
241 if (it->second == process_id) | 238 if (it != extension_ids_.end()) |
242 process_ids_.erase(it++); | 239 extension_ids_.erase(it++); |
243 else | |
244 ++it; | |
245 } | |
246 } | 240 } |
247 | 241 |
248 RenderProcessHost* ExtensionProcessManager::GetExtensionProcess( | 242 RenderProcessHost* ExtensionProcessManager::GetExtensionProcess( |
249 const GURL& url) { | 243 const GURL& url) { |
250 if (!browsing_instance_->HasSiteInstance(url)) | 244 if (!browsing_instance_->HasSiteInstance(url)) |
251 return NULL; | 245 return NULL; |
252 scoped_refptr<SiteInstance> site( | 246 scoped_refptr<SiteInstance> site( |
253 browsing_instance_->GetSiteInstanceForURL(url)); | 247 browsing_instance_->GetSiteInstanceForURL(url)); |
254 if (site->HasProcess()) | 248 if (site->HasProcess()) |
255 return site->GetProcess(); | 249 return site->GetProcess(); |
256 return NULL; | 250 return NULL; |
257 } | 251 } |
258 | 252 |
259 RenderProcessHost* ExtensionProcessManager::GetExtensionProcess( | 253 RenderProcessHost* ExtensionProcessManager::GetExtensionProcess( |
260 const std::string& extension_id) { | 254 const std::string& extension_id) { |
261 return GetExtensionProcess( | 255 return GetExtensionProcess( |
262 Extension::GetBaseURLFromExtensionId(extension_id)); | 256 Extension::GetBaseURLFromExtensionId(extension_id)); |
263 } | 257 } |
264 | 258 |
| 259 const Extension* ExtensionProcessManager::GetExtensionForSiteInstance( |
| 260 int site_instance_id) { |
| 261 SiteInstanceIDMap::const_iterator it = extension_ids_.find(site_instance_id); |
| 262 if (it != extension_ids_.end()) { |
| 263 // Look up the extension by ID, including disabled extensions in case |
| 264 // this gets called while an old process is still around. |
| 265 ExtensionService* service = |
| 266 browsing_instance_->profile()->GetExtensionService(); |
| 267 return service->GetExtensionById(it->second, false); |
| 268 } |
| 269 |
| 270 return NULL; |
| 271 } |
| 272 |
265 SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) { | 273 SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) { |
266 return browsing_instance_->GetSiteInstanceForURL(url); | 274 return browsing_instance_->GetSiteInstanceForURL(url); |
267 } | 275 } |
268 | 276 |
269 bool ExtensionProcessManager::HasExtensionHost(ExtensionHost* host) const { | 277 bool ExtensionProcessManager::HasExtensionHost(ExtensionHost* host) const { |
270 return all_hosts_.find(host) != all_hosts_.end(); | 278 return all_hosts_.find(host) != all_hosts_.end(); |
271 } | 279 } |
272 | 280 |
273 void ExtensionProcessManager::Observe(int type, | 281 void ExtensionProcessManager::Observe(int type, |
274 const NotificationSource& source, | 282 const NotificationSource& source, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 break; | 314 break; |
307 } | 315 } |
308 | 316 |
309 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { | 317 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { |
310 ExtensionHost* host = Details<ExtensionHost>(details).ptr(); | 318 ExtensionHost* host = Details<ExtensionHost>(details).ptr(); |
311 all_hosts_.erase(host); | 319 all_hosts_.erase(host); |
312 background_hosts_.erase(host); | 320 background_hosts_.erase(host); |
313 break; | 321 break; |
314 } | 322 } |
315 | 323 |
316 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | 324 case content::NOTIFICATION_SITE_INSTANCE_DELETED: { |
317 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | 325 SiteInstance* site_instance = Source<SiteInstance>(source).ptr(); |
318 RenderProcessHost* host = Source<RenderProcessHost>(source).ptr(); | 326 UnregisterExtensionSiteInstance(site_instance->id()); |
319 UnregisterExtensionProcess(host->id()); | |
320 break; | 327 break; |
321 } | 328 } |
322 | 329 |
323 case content::NOTIFICATION_APP_TERMINATING: { | 330 case content::NOTIFICATION_APP_TERMINATING: { |
324 // Close background hosts when the last browser is closed so that they | 331 // Close background hosts when the last browser is closed so that they |
325 // have time to shutdown various objects on different threads. Our | 332 // have time to shutdown various objects on different threads. Our |
326 // destructor is called too late in the shutdown sequence. | 333 // destructor is called too late in the shutdown sequence. |
327 CloseBackgroundHosts(); | 334 CloseBackgroundHosts(); |
328 break; | 335 break; |
329 } | 336 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 RenderProcessHost* IncognitoExtensionProcessManager::GetExtensionProcess( | 422 RenderProcessHost* IncognitoExtensionProcessManager::GetExtensionProcess( |
416 const GURL& url) { | 423 const GURL& url) { |
417 const Extension* extension = GetExtensionOrAppByURL(url); | 424 const Extension* extension = GetExtensionOrAppByURL(url); |
418 if (!extension || extension->incognito_split_mode()) { | 425 if (!extension || extension->incognito_split_mode()) { |
419 return ExtensionProcessManager::GetExtensionProcess(url); | 426 return ExtensionProcessManager::GetExtensionProcess(url); |
420 } else { | 427 } else { |
421 return original_manager_->GetExtensionProcess(url); | 428 return original_manager_->GetExtensionProcess(url); |
422 } | 429 } |
423 } | 430 } |
424 | 431 |
| 432 const Extension* IncognitoExtensionProcessManager::GetExtensionForSiteInstance( |
| 433 int site_instance_id) { |
| 434 const Extension* extension = |
| 435 ExtensionProcessManager::GetExtensionForSiteInstance(site_instance_id); |
| 436 if (extension && extension->incognito_split_mode()) { |
| 437 return extension; |
| 438 } else { |
| 439 return original_manager_->GetExtensionForSiteInstance(site_instance_id); |
| 440 } |
| 441 } |
| 442 |
425 const Extension* IncognitoExtensionProcessManager::GetExtensionOrAppByURL( | 443 const Extension* IncognitoExtensionProcessManager::GetExtensionOrAppByURL( |
426 const GURL& url) { | 444 const GURL& url) { |
427 ExtensionService* service = | 445 ExtensionService* service = |
428 browsing_instance_->profile()->GetExtensionService(); | 446 browsing_instance_->profile()->GetExtensionService(); |
429 if (!service) | 447 if (!service) |
430 return NULL; | 448 return NULL; |
431 return (url.SchemeIs(chrome::kExtensionScheme)) ? | 449 return (url.SchemeIs(chrome::kExtensionScheme)) ? |
432 service->GetExtensionByURL(url) : service->GetExtensionByWebExtent(url); | 450 service->GetExtensionByURL(url) : service->GetExtensionByWebExtent(url); |
433 } | 451 } |
434 | 452 |
(...skipping 23 matching lines...) Expand all Loading... |
458 if (service && service->is_ready()) | 476 if (service && service->is_ready()) |
459 CreateBackgroundHosts(this, service->extensions()); | 477 CreateBackgroundHosts(this, service->extensions()); |
460 } | 478 } |
461 break; | 479 break; |
462 } | 480 } |
463 default: | 481 default: |
464 ExtensionProcessManager::Observe(type, source, details); | 482 ExtensionProcessManager::Observe(type, source, details); |
465 break; | 483 break; |
466 } | 484 } |
467 } | 485 } |
OLD | NEW |