| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "extensions/browser/process_manager.h" | 5 #include "extensions/browser/process_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "content/public/browser/web_contents.h" | 26 #include "content/public/browser/web_contents.h" |
| 27 #include "content/public/browser/web_contents_delegate.h" | 27 #include "content/public/browser/web_contents_delegate.h" |
| 28 #include "content/public/browser/web_contents_observer.h" | 28 #include "content/public/browser/web_contents_observer.h" |
| 29 #include "content/public/browser/web_contents_user_data.h" | 29 #include "content/public/browser/web_contents_user_data.h" |
| 30 #include "content/public/common/renderer_preferences.h" | 30 #include "content/public/common/renderer_preferences.h" |
| 31 #include "content/public/common/url_constants.h" | 31 #include "content/public/common/url_constants.h" |
| 32 #include "extensions/browser/extension_host.h" | 32 #include "extensions/browser/extension_host.h" |
| 33 #include "extensions/browser/extension_registry.h" | 33 #include "extensions/browser/extension_registry.h" |
| 34 #include "extensions/browser/extension_system.h" | 34 #include "extensions/browser/extension_system.h" |
| 35 #include "extensions/browser/extensions_browser_client.h" | 35 #include "extensions/browser/extensions_browser_client.h" |
| 36 #include "extensions/browser/process_manager_delegate.h" |
| 36 #include "extensions/browser/process_manager_observer.h" | 37 #include "extensions/browser/process_manager_observer.h" |
| 37 #include "extensions/browser/view_type_utils.h" | 38 #include "extensions/browser/view_type_utils.h" |
| 38 #include "extensions/common/constants.h" | 39 #include "extensions/common/constants.h" |
| 39 #include "extensions/common/extension.h" | 40 #include "extensions/common/extension.h" |
| 40 #include "extensions/common/extension_messages.h" | 41 #include "extensions/common/extension_messages.h" |
| 41 #include "extensions/common/manifest_handlers/background_info.h" | 42 #include "extensions/common/manifest_handlers/background_info.h" |
| 42 #include "extensions/common/manifest_handlers/incognito_info.h" | 43 #include "extensions/common/manifest_handlers/incognito_info.h" |
| 43 #include "extensions/common/one_shot_event.h" | 44 #include "extensions/common/one_shot_event.h" |
| 44 #include "extensions/common/switches.h" | 45 #include "extensions/common/switches.h" |
| 45 | 46 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 content::Details<RenderViewHost>(render_view_host)); | 99 content::Details<RenderViewHost>(render_view_host)); |
| 99 } | 100 } |
| 100 | 101 |
| 101 // Incognito profiles use this process manager. It is mostly a shim that decides | 102 // Incognito profiles use this process manager. It is mostly a shim that decides |
| 102 // whether to fall back on the original profile's ProcessManager based | 103 // whether to fall back on the original profile's ProcessManager based |
| 103 // on whether a given extension uses "split" or "spanning" incognito behavior. | 104 // on whether a given extension uses "split" or "spanning" incognito behavior. |
| 104 class IncognitoProcessManager : public ProcessManager { | 105 class IncognitoProcessManager : public ProcessManager { |
| 105 public: | 106 public: |
| 106 IncognitoProcessManager(BrowserContext* incognito_context, | 107 IncognitoProcessManager(BrowserContext* incognito_context, |
| 107 BrowserContext* original_context, | 108 BrowserContext* original_context, |
| 108 ProcessManager* original_manager); | 109 ProcessManager* original_manager, |
| 110 ExtensionRegistry* extension_registry); |
| 109 virtual ~IncognitoProcessManager() {} | 111 virtual ~IncognitoProcessManager() {} |
| 110 virtual bool CreateBackgroundHost(const Extension* extension, | 112 virtual bool CreateBackgroundHost(const Extension* extension, |
| 111 const GURL& url) OVERRIDE; | 113 const GURL& url) OVERRIDE; |
| 112 virtual SiteInstance* GetSiteInstanceForURL(const GURL& url) OVERRIDE; | 114 virtual SiteInstance* GetSiteInstanceForURL(const GURL& url) OVERRIDE; |
| 113 | 115 |
| 114 private: | 116 private: |
| 115 ProcessManager* original_manager_; | 117 ProcessManager* original_manager_; |
| 116 | 118 |
| 117 DISALLOW_COPY_AND_ASSIGN(IncognitoProcessManager); | 119 DISALLOW_COPY_AND_ASSIGN(IncognitoProcessManager); |
| 118 }; | 120 }; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 is_closing(false), | 185 is_closing(false), |
| 184 close_sequence_id(0) {} | 186 close_sequence_id(0) {} |
| 185 }; | 187 }; |
| 186 | 188 |
| 187 // | 189 // |
| 188 // ProcessManager | 190 // ProcessManager |
| 189 // | 191 // |
| 190 | 192 |
| 191 // static | 193 // static |
| 192 ProcessManager* ProcessManager::Create(BrowserContext* context) { | 194 ProcessManager* ProcessManager::Create(BrowserContext* context) { |
| 195 ExtensionRegistry* extension_registry = ExtensionRegistry::Get(context); |
| 193 ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); | 196 ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); |
| 194 if (client->IsGuestSession(context)) { | 197 if (client->IsGuestSession(context)) { |
| 195 // In the guest session, there is a single off-the-record context. Unlike | 198 // In the guest session, there is a single off-the-record context. Unlike |
| 196 // a regular incognito mode, background pages of extensions must be | 199 // a regular incognito mode, background pages of extensions must be |
| 197 // created regardless of whether extensions use "spanning" or "split" | 200 // created regardless of whether extensions use "spanning" or "split" |
| 198 // incognito behavior. | 201 // incognito behavior. |
| 199 BrowserContext* original_context = client->GetOriginalContext(context); | 202 BrowserContext* original_context = client->GetOriginalContext(context); |
| 200 return new ProcessManager(context, original_context); | 203 return new ProcessManager(context, original_context, extension_registry); |
| 201 } | 204 } |
| 202 | 205 |
| 203 if (context->IsOffTheRecord()) { | 206 if (context->IsOffTheRecord()) { |
| 204 BrowserContext* original_context = client->GetOriginalContext(context); | 207 BrowserContext* original_context = client->GetOriginalContext(context); |
| 205 ProcessManager* original_manager = | 208 ProcessManager* original_manager = |
| 206 ExtensionSystem::Get(original_context)->process_manager(); | 209 ExtensionSystem::Get(original_context)->process_manager(); |
| 207 return new IncognitoProcessManager( | 210 return new IncognitoProcessManager( |
| 208 context, original_context, original_manager); | 211 context, original_context, original_manager, extension_registry); |
| 209 } | 212 } |
| 210 | 213 |
| 211 return new ProcessManager(context, context); | 214 return new ProcessManager(context, context, extension_registry); |
| 215 } |
| 216 |
| 217 // static |
| 218 ProcessManager* ProcessManager::CreateForTesting( |
| 219 BrowserContext* context, |
| 220 ExtensionRegistry* extension_registry) { |
| 221 DCHECK(!context->IsOffTheRecord()); |
| 222 return new ProcessManager(context, context, extension_registry); |
| 212 } | 223 } |
| 213 | 224 |
| 214 // static | 225 // static |
| 215 ProcessManager* ProcessManager::CreateIncognitoForTesting( | 226 ProcessManager* ProcessManager::CreateIncognitoForTesting( |
| 216 BrowserContext* incognito_context, | 227 BrowserContext* incognito_context, |
| 217 BrowserContext* original_context, | 228 BrowserContext* original_context, |
| 218 ProcessManager* original_manager) { | 229 ProcessManager* original_manager, |
| 230 ExtensionRegistry* extension_registry) { |
| 219 DCHECK(incognito_context->IsOffTheRecord()); | 231 DCHECK(incognito_context->IsOffTheRecord()); |
| 220 DCHECK(!original_context->IsOffTheRecord()); | 232 DCHECK(!original_context->IsOffTheRecord()); |
| 221 return new IncognitoProcessManager( | 233 return new IncognitoProcessManager(incognito_context, |
| 222 incognito_context, original_context, original_manager); | 234 original_context, |
| 235 original_manager, |
| 236 extension_registry); |
| 223 } | 237 } |
| 224 | 238 |
| 225 ProcessManager::ProcessManager(BrowserContext* context, | 239 ProcessManager::ProcessManager(BrowserContext* context, |
| 226 BrowserContext* original_context) | 240 BrowserContext* original_context, |
| 241 ExtensionRegistry* extension_registry) |
| 227 : site_instance_(SiteInstance::Create(context)), | 242 : site_instance_(SiteInstance::Create(context)), |
| 243 extension_registry_(extension_registry), |
| 228 startup_background_hosts_created_(false), | 244 startup_background_hosts_created_(false), |
| 229 devtools_callback_(base::Bind(&ProcessManager::OnDevToolsStateChanged, | 245 devtools_callback_(base::Bind(&ProcessManager::OnDevToolsStateChanged, |
| 230 base::Unretained(this))), | 246 base::Unretained(this))), |
| 231 last_background_close_sequence_id_(0), | 247 last_background_close_sequence_id_(0), |
| 232 weak_ptr_factory_(this) { | 248 weak_ptr_factory_(this) { |
| 249 // ExtensionRegistry is shared between incognito and regular contexts. |
| 250 DCHECK_EQ(original_context, extension_registry_->browser_context()); |
| 233 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, | 251 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
| 234 content::Source<BrowserContext>(original_context)); | 252 content::Source<BrowserContext>(original_context)); |
| 235 registrar_.Add(this, | 253 registrar_.Add(this, |
| 236 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, | 254 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, |
| 237 content::Source<BrowserContext>(original_context)); | 255 content::Source<BrowserContext>(original_context)); |
| 238 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, | 256 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, |
| 239 content::Source<BrowserContext>(original_context)); | 257 content::Source<BrowserContext>(original_context)); |
| 240 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 258 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
| 241 content::Source<BrowserContext>(context)); | 259 content::Source<BrowserContext>(context)); |
| 242 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, | 260 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, |
| 243 content::Source<BrowserContext>(context)); | 261 content::Source<BrowserContext>(context)); |
| 244 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, | 262 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, |
| 245 content::NotificationService::AllSources()); | 263 content::NotificationService::AllSources()); |
| 246 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, | 264 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, |
| 247 content::NotificationService::AllSources()); | 265 content::NotificationService::AllSources()); |
| 248 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED, | |
| 249 content::Source<BrowserContext>(original_context)); | |
| 250 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 266 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 251 content::Source<BrowserContext>(context)); | 267 content::Source<BrowserContext>(context)); |
| 252 if (context->IsOffTheRecord()) { | 268 if (context->IsOffTheRecord()) { |
| 253 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 269 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 254 content::Source<BrowserContext>(original_context)); | 270 content::Source<BrowserContext>(original_context)); |
| 255 } | 271 } |
| 256 | 272 |
| 257 // Note: event_page_idle_time_ must be sufficiently larger (e.g. 2x) than | 273 // Note: event_page_idle_time_ must be sufficiently larger (e.g. 2x) than |
| 258 // kKeepaliveThrottleIntervalInSeconds in ppapi/proxy/plugin_globals. | 274 // kKeepaliveThrottleIntervalInSeconds in ppapi/proxy/plugin_globals. |
| 259 event_page_idle_time_ = base::TimeDelta::FromSeconds(10); | 275 event_page_idle_time_ = base::TimeDelta::FromSeconds(10); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 } | 316 } |
| 301 | 317 |
| 302 void ProcessManager::RemoveObserver(ProcessManagerObserver* observer) { | 318 void ProcessManager::RemoveObserver(ProcessManagerObserver* observer) { |
| 303 observer_list_.RemoveObserver(observer); | 319 observer_list_.RemoveObserver(observer); |
| 304 } | 320 } |
| 305 | 321 |
| 306 bool ProcessManager::CreateBackgroundHost(const Extension* extension, | 322 bool ProcessManager::CreateBackgroundHost(const Extension* extension, |
| 307 const GURL& url) { | 323 const GURL& url) { |
| 308 // Hosted apps are taken care of from BackgroundContentsService. Ignore them | 324 // Hosted apps are taken care of from BackgroundContentsService. Ignore them |
| 309 // here. | 325 // here. |
| 310 if (extension->is_hosted_app() || | 326 if (extension->is_hosted_app()) |
| 311 !ExtensionsBrowserClient::Get()-> | |
| 312 IsBackgroundPageAllowed(GetBrowserContext())) { | |
| 313 return false; | 327 return false; |
| 314 } | 328 |
| 329 // Don't create hosts if the embedder doesn't allow it. |
| 330 ProcessManagerDelegate* delegate = |
| 331 ExtensionsBrowserClient::Get()->GetProcessManagerDelegate(); |
| 332 if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext())) |
| 333 return false; |
| 315 | 334 |
| 316 // Don't create multiple background hosts for an extension. | 335 // Don't create multiple background hosts for an extension. |
| 317 if (GetBackgroundHostForExtension(extension->id())) | 336 if (GetBackgroundHostForExtension(extension->id())) |
| 318 return true; // TODO(kalman): return false here? It might break things... | 337 return true; // TODO(kalman): return false here? It might break things... |
| 319 | 338 |
| 320 ExtensionHost* host = | 339 ExtensionHost* host = |
| 321 new ExtensionHost(extension, GetSiteInstanceForURL(url), url, | 340 new ExtensionHost(extension, GetSiteInstanceForURL(url), url, |
| 322 VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); | 341 VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); |
| 323 host->CreateRenderViewSoon(); | 342 host->CreateRenderViewSoon(); |
| 324 OnBackgroundHostCreated(host); | 343 OnBackgroundHostCreated(host); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 353 } | 372 } |
| 354 | 373 |
| 355 return result; | 374 return result; |
| 356 } | 375 } |
| 357 | 376 |
| 358 const Extension* ProcessManager::GetExtensionForRenderViewHost( | 377 const Extension* ProcessManager::GetExtensionForRenderViewHost( |
| 359 RenderViewHost* render_view_host) { | 378 RenderViewHost* render_view_host) { |
| 360 if (!render_view_host->GetSiteInstance()) | 379 if (!render_view_host->GetSiteInstance()) |
| 361 return NULL; | 380 return NULL; |
| 362 | 381 |
| 363 ExtensionRegistry* registry = ExtensionRegistry::Get(GetBrowserContext()); | 382 return extension_registry_->enabled_extensions().GetByID( |
| 364 if (!registry) | |
| 365 return NULL; | |
| 366 | |
| 367 return registry->enabled_extensions().GetByID( | |
| 368 GetExtensionID(render_view_host)); | 383 GetExtensionID(render_view_host)); |
| 369 } | 384 } |
| 370 | 385 |
| 371 void ProcessManager::UnregisterRenderViewHost( | 386 void ProcessManager::UnregisterRenderViewHost( |
| 372 RenderViewHost* render_view_host) { | 387 RenderViewHost* render_view_host) { |
| 373 ExtensionRenderViews::iterator view = | 388 ExtensionRenderViews::iterator view = |
| 374 all_extension_views_.find(render_view_host); | 389 all_extension_views_.find(render_view_host); |
| 375 if (view == all_extension_views_.end()) | 390 if (view == all_extension_views_.end()) |
| 376 return; | 391 return; |
| 377 | 392 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 void ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) { | 448 void ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) { |
| 434 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) | 449 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
| 435 return; | 450 return; |
| 436 DecrementLazyKeepaliveCount(extension->id()); | 451 DecrementLazyKeepaliveCount(extension->id()); |
| 437 } | 452 } |
| 438 | 453 |
| 439 void ProcessManager::DecrementLazyKeepaliveCount( | 454 void ProcessManager::DecrementLazyKeepaliveCount( |
| 440 const std::string& extension_id) { | 455 const std::string& extension_id) { |
| 441 int& count = background_page_data_[extension_id].lazy_keepalive_count; | 456 int& count = background_page_data_[extension_id].lazy_keepalive_count; |
| 442 DCHECK(count > 0 || | 457 DCHECK(count > 0 || |
| 443 !ExtensionRegistry::Get(GetBrowserContext()) | 458 !extension_registry_->enabled_extensions().Contains(extension_id)); |
| 444 ->enabled_extensions() | |
| 445 .Contains(extension_id)); | |
| 446 | 459 |
| 447 // If we reach a zero keepalive count when the lazy background page is about | 460 // If we reach a zero keepalive count when the lazy background page is about |
| 448 // to be closed, incrementing close_sequence_id will cancel the close | 461 // to be closed, incrementing close_sequence_id will cancel the close |
| 449 // sequence and cause the background page to linger. So check is_closing | 462 // sequence and cause the background page to linger. So check is_closing |
| 450 // before initiating another close sequence. | 463 // before initiating another close sequence. |
| 451 if (--count == 0 && !background_page_data_[extension_id].is_closing) { | 464 if (--count == 0 && !background_page_data_[extension_id].is_closing) { |
| 452 background_page_data_[extension_id].close_sequence_id = | 465 background_page_data_[extension_id].close_sequence_id = |
| 453 ++last_background_close_sequence_id_; | 466 ++last_background_close_sequence_id_; |
| 454 base::MessageLoop::current()->PostDelayedTask( | 467 base::MessageLoop::current()->PostDelayedTask( |
| 455 FROM_HERE, | 468 FROM_HERE, |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 new ExtensionMsg_CancelSuspend(extension->id())); | 626 new ExtensionMsg_CancelSuspend(extension->id())); |
| 614 // This increment / decrement is to simulate an instantaneous event. This | 627 // This increment / decrement is to simulate an instantaneous event. This |
| 615 // has the effect of invalidating close_sequence_id, preventing any in | 628 // has the effect of invalidating close_sequence_id, preventing any in |
| 616 // progress closes from completing and starting a new close process if | 629 // progress closes from completing and starting a new close process if |
| 617 // necessary. | 630 // necessary. |
| 618 IncrementLazyKeepaliveCount(extension); | 631 IncrementLazyKeepaliveCount(extension); |
| 619 DecrementLazyKeepaliveCount(extension); | 632 DecrementLazyKeepaliveCount(extension); |
| 620 } | 633 } |
| 621 } | 634 } |
| 622 | 635 |
| 623 void ProcessManager::OnBrowserWindowReady() { | |
| 624 // If the extension system isn't ready yet the background hosts will be | |
| 625 // created via NOTIFICATION_EXTENSIONS_READY below. | |
| 626 ExtensionSystem* system = ExtensionSystem::Get(GetBrowserContext()); | |
| 627 if (!system->ready().is_signaled()) | |
| 628 return; | |
| 629 | |
| 630 CreateBackgroundHostsForProfileStartup(); | |
| 631 } | |
| 632 | |
| 633 content::BrowserContext* ProcessManager::GetBrowserContext() const { | 636 content::BrowserContext* ProcessManager::GetBrowserContext() const { |
| 634 return site_instance_->GetBrowserContext(); | 637 return site_instance_->GetBrowserContext(); |
| 635 } | 638 } |
| 636 | 639 |
| 637 void ProcessManager::SetKeepaliveImpulseCallbackForTesting( | 640 void ProcessManager::SetKeepaliveImpulseCallbackForTesting( |
| 638 const ImpulseCallbackForTesting& callback) { | 641 const ImpulseCallbackForTesting& callback) { |
| 639 keepalive_impulse_callback_for_testing_ = callback; | 642 keepalive_impulse_callback_for_testing_ = callback; |
| 640 } | 643 } |
| 641 | 644 |
| 642 void ProcessManager::SetKeepaliveImpulseDecrementCallbackForTesting( | 645 void ProcessManager::SetKeepaliveImpulseDecrementCallbackForTesting( |
| 643 const ImpulseCallbackForTesting& callback) { | 646 const ImpulseCallbackForTesting& callback) { |
| 644 keepalive_impulse_decrement_callback_for_testing_ = callback; | 647 keepalive_impulse_decrement_callback_for_testing_ = callback; |
| 645 } | 648 } |
| 646 | 649 |
| 647 void ProcessManager::Observe(int type, | 650 void ProcessManager::Observe(int type, |
| 648 const content::NotificationSource& source, | 651 const content::NotificationSource& source, |
| 649 const content::NotificationDetails& details) { | 652 const content::NotificationDetails& details) { |
| 650 switch (type) { | 653 switch (type) { |
| 651 case chrome::NOTIFICATION_EXTENSIONS_READY: | 654 case chrome::NOTIFICATION_EXTENSIONS_READY: { |
| 652 case chrome::NOTIFICATION_PROFILE_CREATED: { | 655 // TODO(jamescook): Convert this to use ExtensionSystem::ready() instead |
| 653 // Don't load background hosts now if the loading should be deferred. | 656 // of a notification. |
| 654 // Instead they will be loaded when a browser window for this profile | 657 MaybeCreateStartupBackgroundHosts(); |
| 655 // (or an incognito profile from this profile) is ready. | |
| 656 if (DeferLoadingBackgroundHosts()) | |
| 657 break; | |
| 658 | |
| 659 CreateBackgroundHostsForProfileStartup(); | |
| 660 break; | 658 break; |
| 661 } | 659 } |
| 662 | 660 |
| 663 case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: { | 661 case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: { |
| 664 BrowserContext* context = content::Source<BrowserContext>(source).ptr(); | 662 BrowserContext* context = content::Source<BrowserContext>(source).ptr(); |
| 665 ExtensionSystem* system = ExtensionSystem::Get(context); | 663 ExtensionSystem* system = ExtensionSystem::Get(context); |
| 666 if (system->ready().is_signaled()) { | 664 if (system->ready().is_signaled()) { |
| 667 // The extension system is ready, so create the background host. | 665 // The extension system is ready, so create the background host. |
| 668 const Extension* extension = | 666 const Extension* extension = |
| 669 content::Details<const Extension>(details).ptr(); | 667 content::Details<const Extension>(details).ptr(); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 return; | 775 return; |
| 778 if (attached) { | 776 if (attached) { |
| 779 // Keep the lazy background page alive while it's being inspected. | 777 // Keep the lazy background page alive while it's being inspected. |
| 780 CancelSuspend(extension); | 778 CancelSuspend(extension); |
| 781 IncrementLazyKeepaliveCount(extension); | 779 IncrementLazyKeepaliveCount(extension); |
| 782 } else { | 780 } else { |
| 783 DecrementLazyKeepaliveCount(extension); | 781 DecrementLazyKeepaliveCount(extension); |
| 784 } | 782 } |
| 785 } | 783 } |
| 786 | 784 |
| 787 void ProcessManager::CreateBackgroundHostsForProfileStartup() { | 785 void ProcessManager::MaybeCreateStartupBackgroundHosts() { |
| 788 if (startup_background_hosts_created_ || | 786 if (startup_background_hosts_created_) |
| 789 !ExtensionsBrowserClient::Get()-> | |
| 790 IsBackgroundPageAllowed(GetBrowserContext())) { | |
| 791 return; | 787 return; |
| 792 } | |
| 793 | 788 |
| 794 const ExtensionSet& enabled_extensions = | 789 // The embedder might disallow background pages entirely. |
| 795 ExtensionRegistry::Get(GetBrowserContext())->enabled_extensions(); | 790 ProcessManagerDelegate* delegate = |
| 796 for (ExtensionSet::const_iterator extension = enabled_extensions.begin(); | 791 ExtensionsBrowserClient::Get()->GetProcessManagerDelegate(); |
| 797 extension != enabled_extensions.end(); | 792 if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext())) |
| 798 ++extension) { | 793 return; |
| 799 CreateBackgroundHostForExtensionLoad(this, extension->get()); | |
| 800 | 794 |
| 801 FOR_EACH_OBSERVER(ProcessManagerObserver, | 795 // The embedder might want to defer background page loading. For example, |
| 802 observer_list_, | 796 // Chrome defers background page loading when it is launched to show the app |
| 803 OnBackgroundHostStartup(*extension)); | 797 // list, then triggers a load later when a browser window opens. |
| 804 } | 798 if (delegate && |
| 799 delegate->DeferCreatingStartupBackgroundHosts(GetBrowserContext())) |
| 800 return; |
| 801 |
| 802 CreateStartupBackgroundHosts(); |
| 805 startup_background_hosts_created_ = true; | 803 startup_background_hosts_created_ = true; |
| 806 | 804 |
| 807 // Background pages should only be loaded once. To prevent any further loads | 805 // Background pages should only be loaded once. To prevent any further loads |
| 808 // occurring, we remove the notification listeners. | 806 // occurring, we remove the notification listeners. |
| 809 BrowserContext* original_context = | 807 BrowserContext* original_context = |
| 810 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); | 808 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); |
| 811 if (registrar_.IsRegistered( | 809 if (registrar_.IsRegistered( |
| 812 this, | 810 this, |
| 813 chrome::NOTIFICATION_PROFILE_CREATED, | |
| 814 content::Source<BrowserContext>(original_context))) { | |
| 815 registrar_.Remove(this, | |
| 816 chrome::NOTIFICATION_PROFILE_CREATED, | |
| 817 content::Source<BrowserContext>(original_context)); | |
| 818 } | |
| 819 if (registrar_.IsRegistered( | |
| 820 this, | |
| 821 chrome::NOTIFICATION_EXTENSIONS_READY, | 811 chrome::NOTIFICATION_EXTENSIONS_READY, |
| 822 content::Source<BrowserContext>(original_context))) { | 812 content::Source<BrowserContext>(original_context))) { |
| 823 registrar_.Remove(this, | 813 registrar_.Remove(this, |
| 824 chrome::NOTIFICATION_EXTENSIONS_READY, | 814 chrome::NOTIFICATION_EXTENSIONS_READY, |
| 825 content::Source<BrowserContext>(original_context)); | 815 content::Source<BrowserContext>(original_context)); |
| 826 } | 816 } |
| 827 } | 817 } |
| 828 | 818 |
| 819 void ProcessManager::CreateStartupBackgroundHosts() { |
| 820 DCHECK(!startup_background_hosts_created_); |
| 821 const ExtensionSet& enabled_extensions = |
| 822 extension_registry_->enabled_extensions(); |
| 823 for (ExtensionSet::const_iterator extension = enabled_extensions.begin(); |
| 824 extension != enabled_extensions.end(); |
| 825 ++extension) { |
| 826 CreateBackgroundHostForExtensionLoad(this, extension->get()); |
| 827 |
| 828 FOR_EACH_OBSERVER(ProcessManagerObserver, |
| 829 observer_list_, |
| 830 OnBackgroundHostStartup(*extension)); |
| 831 } |
| 832 } |
| 833 |
| 829 void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) { | 834 void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) { |
| 830 DCHECK_EQ(GetBrowserContext(), host->browser_context()); | 835 DCHECK_EQ(GetBrowserContext(), host->browser_context()); |
| 831 background_hosts_.insert(host); | 836 background_hosts_.insert(host); |
| 832 | 837 |
| 833 if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) { | 838 if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) { |
| 834 linked_ptr<base::ElapsedTimer> since_suspended( | 839 linked_ptr<base::ElapsedTimer> since_suspended( |
| 835 background_page_data_[host->extension()->id()]. | 840 background_page_data_[host->extension()->id()]. |
| 836 since_suspended.release()); | 841 since_suspended.release()); |
| 837 if (since_suspended.get()) { | 842 if (since_suspended.get()) { |
| 838 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageIdleTime", | 843 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageIdleTime", |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 // Re-register all RenderViews for this extension. We do this to restore | 888 // Re-register all RenderViews for this extension. We do this to restore |
| 884 // the lazy_keepalive_count (if any) to properly reflect the number of open | 889 // the lazy_keepalive_count (if any) to properly reflect the number of open |
| 885 // views. | 890 // views. |
| 886 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); | 891 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); |
| 887 it != all_extension_views_.end(); ++it) { | 892 it != all_extension_views_.end(); ++it) { |
| 888 if (GetExtensionID(it->first) == extension_id) | 893 if (GetExtensionID(it->first) == extension_id) |
| 889 IncrementLazyKeepaliveCountForView(it->first); | 894 IncrementLazyKeepaliveCountForView(it->first); |
| 890 } | 895 } |
| 891 } | 896 } |
| 892 | 897 |
| 893 bool ProcessManager::DeferLoadingBackgroundHosts() const { | |
| 894 // The extensions embedder may have special rules about background hosts. | |
| 895 return ExtensionsBrowserClient::Get()->DeferLoadingBackgroundHosts( | |
| 896 GetBrowserContext()); | |
| 897 } | |
| 898 | |
| 899 // | 898 // |
| 900 // IncognitoProcessManager | 899 // IncognitoProcessManager |
| 901 // | 900 // |
| 902 | 901 |
| 903 IncognitoProcessManager::IncognitoProcessManager( | 902 IncognitoProcessManager::IncognitoProcessManager( |
| 904 BrowserContext* incognito_context, | 903 BrowserContext* incognito_context, |
| 905 BrowserContext* original_context, | 904 BrowserContext* original_context, |
| 906 ProcessManager* original_manager) | 905 ProcessManager* original_manager, |
| 907 : ProcessManager(incognito_context, original_context), | 906 ExtensionRegistry* extension_registry) |
| 907 : ProcessManager(incognito_context, original_context, extension_registry), |
| 908 original_manager_(original_manager) { | 908 original_manager_(original_manager) { |
| 909 DCHECK(incognito_context->IsOffTheRecord()); | 909 DCHECK(incognito_context->IsOffTheRecord()); |
| 910 | 910 |
| 911 // The original profile will have its own ProcessManager to | 911 // The original profile will have its own ProcessManager to |
| 912 // load the background pages of the spanning extensions. This process | 912 // load the background pages of the spanning extensions. This process |
| 913 // manager need only worry about the split mode extensions, which is handled | 913 // manager need only worry about the split mode extensions, which is handled |
| 914 // in the NOTIFICATION_BROWSER_WINDOW_READY notification handler. | 914 // in the NOTIFICATION_BROWSER_WINDOW_READY notification handler. |
| 915 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY, | 915 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
| 916 content::Source<BrowserContext>(original_context)); | 916 content::Source<BrowserContext>(original_context)); |
| 917 registrar_.Remove(this, chrome::NOTIFICATION_PROFILE_CREATED, | |
| 918 content::Source<BrowserContext>(original_context)); | |
| 919 } | 917 } |
| 920 | 918 |
| 921 bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension, | 919 bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension, |
| 922 const GURL& url) { | 920 const GURL& url) { |
| 923 if (IncognitoInfo::IsSplitMode(extension)) { | 921 if (IncognitoInfo::IsSplitMode(extension)) { |
| 924 if (ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled( | 922 if (ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled( |
| 925 extension->id(), GetBrowserContext())) | 923 extension->id(), GetBrowserContext())) |
| 926 return ProcessManager::CreateBackgroundHost(extension, url); | 924 return ProcessManager::CreateBackgroundHost(extension, url); |
| 927 } else { | 925 } else { |
| 928 // Do nothing. If an extension is spanning, then its original-profile | 926 // Do nothing. If an extension is spanning, then its original-profile |
| 929 // background page is shared with incognito, so we don't create another. | 927 // background page is shared with incognito, so we don't create another. |
| 930 } | 928 } |
| 931 return false; | 929 return false; |
| 932 } | 930 } |
| 933 | 931 |
| 934 SiteInstance* IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) { | 932 SiteInstance* IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) { |
| 935 ExtensionRegistry* registry = ExtensionRegistry::Get(GetBrowserContext()); | 933 const Extension* extension = |
| 936 if (registry) { | 934 extension_registry_->enabled_extensions().GetExtensionOrAppByURL(url); |
| 937 const Extension* extension = | 935 if (extension && !IncognitoInfo::IsSplitMode(extension)) |
| 938 registry->enabled_extensions().GetExtensionOrAppByURL(url); | 936 return original_manager_->GetSiteInstanceForURL(url); |
| 939 if (extension && !IncognitoInfo::IsSplitMode(extension)) { | 937 |
| 940 return original_manager_->GetSiteInstanceForURL(url); | |
| 941 } | |
| 942 } | |
| 943 return ProcessManager::GetSiteInstanceForURL(url); | 938 return ProcessManager::GetSiteInstanceForURL(url); |
| 944 } | 939 } |
| 945 | 940 |
| 946 } // namespace extensions | 941 } // namespace extensions |
| OLD | NEW |