| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
| 7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/time.h" | 10 #include "base/time.h" |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 event_page_unloading_time_ = base::TimeDelta::FromSeconds( | 163 event_page_unloading_time_ = base::TimeDelta::FromSeconds( |
| 164 unloading_time_sec); | 164 unloading_time_sec); |
| 165 } | 165 } |
| 166 } | 166 } |
| 167 | 167 |
| 168 ExtensionProcessManager::~ExtensionProcessManager() { | 168 ExtensionProcessManager::~ExtensionProcessManager() { |
| 169 CloseBackgroundHosts(); | 169 CloseBackgroundHosts(); |
| 170 DCHECK(background_hosts_.empty()); | 170 DCHECK(background_hosts_.empty()); |
| 171 } | 171 } |
| 172 | 172 |
| 173 ExtensionHost* ExtensionProcessManager::CreateShellHost( | |
| 174 const Extension* extension, | |
| 175 const GURL& url) { | |
| 176 DCHECK(extension); | |
| 177 ExtensionHost* host = new ExtensionHost(extension, | |
| 178 GetSiteInstanceForURL(url), | |
| 179 url, | |
| 180 chrome::VIEW_TYPE_APP_SHELL); | |
| 181 host->CreateViewWithoutBrowser(); | |
| 182 content::WebContents* host_contents = host->host_contents(); | |
| 183 host_contents->GetMutableRendererPrefs()->browser_handles_all_requests = true; | |
| 184 host_contents->GetRenderViewHost()->SyncRendererPrefs(); | |
| 185 OnExtensionHostCreated(host, false /* not a background host */); | |
| 186 return host; | |
| 187 } | |
| 188 | |
| 189 void ExtensionProcessManager::EnsureBrowserWhenRequired( | 173 void ExtensionProcessManager::EnsureBrowserWhenRequired( |
| 190 Browser* browser, | 174 Browser* browser, |
| 191 content::ViewType view_type) { | 175 content::ViewType view_type) { |
| 192 if (!browser) { | 176 if (!browser) { |
| 193 #if defined (OS_CHROMEOS) | 177 #if defined (OS_CHROMEOS) |
| 194 // On ChromeOS we'll only use ExtensionView, which | 178 // On ChromeOS we'll only use ExtensionView, which |
| 195 // does not use the browser parameter. | 179 // does not use the browser parameter. |
| 196 // TODO(rkc): Remove all this once we create a new host for | 180 // TODO(rkc): Remove all this once we create a new host for |
| 197 // screensaver extensions (crosbug.com/28211). | 181 // screensaver extensions (crosbug.com/28211). |
| 198 DCHECK(view_type == chrome::VIEW_TYPE_EXTENSION_POPUP || | 182 DCHECK(view_type == chrome::VIEW_TYPE_EXTENSION_POPUP || |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 all_extension_views_[render_view_host] = content::VIEW_TYPE_INVALID; | 338 all_extension_views_[render_view_host] = content::VIEW_TYPE_INVALID; |
| 355 } | 339 } |
| 356 | 340 |
| 357 void ExtensionProcessManager::UnregisterRenderViewHost( | 341 void ExtensionProcessManager::UnregisterRenderViewHost( |
| 358 RenderViewHost* render_view_host) { | 342 RenderViewHost* render_view_host) { |
| 359 ExtensionRenderViews::iterator view = | 343 ExtensionRenderViews::iterator view = |
| 360 all_extension_views_.find(render_view_host); | 344 all_extension_views_.find(render_view_host); |
| 361 if (view == all_extension_views_.end()) | 345 if (view == all_extension_views_.end()) |
| 362 return; | 346 return; |
| 363 | 347 |
| 348 content::NotificationService::current()->Notify( |
| 349 chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED, |
| 350 content::Source<Profile>(GetProfile()), |
| 351 content::Details<RenderViewHost>(render_view_host)); |
| 352 |
| 364 content::ViewType view_type = view->second; | 353 content::ViewType view_type = view->second; |
| 365 all_extension_views_.erase(view); | 354 all_extension_views_.erase(view); |
| 366 | 355 |
| 367 // Keepalive count, balanced in UpdateRegisteredRenderView. | 356 // Keepalive count, balanced in UpdateRegisteredRenderView. |
| 368 if (view_type != content::VIEW_TYPE_INVALID && | 357 if (view_type != content::VIEW_TYPE_INVALID && |
| 369 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 358 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
| 370 const Extension* extension = GetExtensionForRenderViewHost( | 359 const Extension* extension = GetExtensionForRenderViewHost( |
| 371 render_view_host); | 360 render_view_host); |
| 372 if (extension) | 361 if (extension) |
| 373 DecrementLazyKeepaliveCount(extension); | 362 DecrementLazyKeepaliveCount(extension); |
| 374 } | 363 } |
| 375 } | 364 } |
| 376 | 365 |
| 377 void ExtensionProcessManager::UpdateRegisteredRenderView( | 366 void ExtensionProcessManager::UpdateRegisteredRenderView( |
| 378 RenderViewHost* render_view_host) { | 367 RenderViewHost* render_view_host) { |
| 379 ExtensionRenderViews::iterator view = | 368 ExtensionRenderViews::iterator view = |
| 380 all_extension_views_.find(render_view_host); | 369 all_extension_views_.find(render_view_host); |
| 381 if (view == all_extension_views_.end()) | 370 if (view == all_extension_views_.end()) |
| 382 return; | 371 return; |
| 383 | 372 |
| 373 content::NotificationService::current()->Notify( |
| 374 chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED, |
| 375 content::Source<Profile>(GetProfile()), |
| 376 content::Details<RenderViewHost>(render_view_host)); |
| 377 |
| 384 view->second = render_view_host->GetDelegate()->GetRenderViewType(); | 378 view->second = render_view_host->GetDelegate()->GetRenderViewType(); |
| 385 | 379 |
| 386 // Keep the lazy background page alive as long as any non-background-page | 380 // Keep the lazy background page alive as long as any non-background-page |
| 387 // extension views are visible. Keepalive count balanced in | 381 // extension views are visible. Keepalive count balanced in |
| 388 // UnregisterRenderViewHost. | 382 // UnregisterRenderViewHost. |
| 389 if (view->second != content::VIEW_TYPE_INVALID && | 383 IncrementLazyKeepaliveCountForView(render_view_host); |
| 390 view->second != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | |
| 391 const Extension* extension = GetExtensionForRenderViewHost( | |
| 392 render_view_host); | |
| 393 if (extension) | |
| 394 IncrementLazyKeepaliveCount(extension); | |
| 395 } | |
| 396 } | 384 } |
| 397 | 385 |
| 398 SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) { | 386 SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) { |
| 399 return site_instance_->GetRelatedSiteInstance(url); | 387 return site_instance_->GetRelatedSiteInstance(url); |
| 400 } | 388 } |
| 401 | 389 |
| 402 bool ExtensionProcessManager::IsBackgroundHostClosing( | 390 bool ExtensionProcessManager::IsBackgroundHostClosing( |
| 403 const std::string& extension_id) { | 391 const std::string& extension_id) { |
| 404 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 392 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 405 return (host && background_page_data_[extension_id].is_closing); | 393 return (host && background_page_data_[extension_id].is_closing); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 435 MessageLoop::current()->PostDelayedTask( | 423 MessageLoop::current()->PostDelayedTask( |
| 436 FROM_HERE, | 424 FROM_HERE, |
| 437 base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, | 425 base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, |
| 438 weak_ptr_factory_.GetWeakPtr(), extension->id(), | 426 weak_ptr_factory_.GetWeakPtr(), extension->id(), |
| 439 ++background_page_data_[extension->id()].close_sequence_id), | 427 ++background_page_data_[extension->id()].close_sequence_id), |
| 440 event_page_idle_time_); | 428 event_page_idle_time_); |
| 441 } | 429 } |
| 442 | 430 |
| 443 return count; | 431 return count; |
| 444 } | 432 } |
| 433 void ExtensionProcessManager::IncrementLazyKeepaliveCountForView( |
| 434 RenderViewHost* render_view_host) { |
| 435 content::ViewType view_type = |
| 436 render_view_host->GetDelegate()->GetRenderViewType(); |
| 437 if (view_type != content::VIEW_TYPE_INVALID && |
| 438 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
| 439 const Extension* extension = GetExtensionForRenderViewHost( |
| 440 render_view_host); |
| 441 if (extension) |
| 442 IncrementLazyKeepaliveCount(extension); |
| 443 } |
| 444 } |
| 445 | 445 |
| 446 void ExtensionProcessManager::OnLazyBackgroundPageIdle( | 446 void ExtensionProcessManager::OnLazyBackgroundPageIdle( |
| 447 const std::string& extension_id, int sequence_id) { | 447 const std::string& extension_id, int sequence_id) { |
| 448 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 448 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 449 if (host && !background_page_data_[extension_id].is_closing && | 449 if (host && !background_page_data_[extension_id].is_closing && |
| 450 sequence_id == background_page_data_[extension_id].close_sequence_id) { | 450 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
| 451 // Tell the renderer we are about to close. This is a simple ping that the | 451 // Tell the renderer we are about to close. This is a simple ping that the |
| 452 // renderer will respond to. The purpose is to control sequencing: if the | 452 // renderer will respond to. The purpose is to control sequencing: if the |
| 453 // extension remains idle until the renderer responds with an ACK, then we | 453 // extension remains idle until the renderer responds with an ACK, then we |
| 454 // know that the extension process is ready to shut down. If our | 454 // know that the extension process is ready to shut down. If our |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 } | 545 } |
| 546 } | 546 } |
| 547 background_page_data_.erase(extension->id()); | 547 background_page_data_.erase(extension->id()); |
| 548 break; | 548 break; |
| 549 } | 549 } |
| 550 | 550 |
| 551 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { | 551 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { |
| 552 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); | 552 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); |
| 553 if (background_hosts_.erase(host)) | 553 if (background_hosts_.erase(host)) |
| 554 ClearBackgroundPageData(host->extension()->id()); | 554 ClearBackgroundPageData(host->extension()->id()); |
| 555 platform_app_hosts_.erase(host); | |
| 556 break; | 555 break; |
| 557 } | 556 } |
| 558 | 557 |
| 559 case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: { | 558 case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: { |
| 560 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); | 559 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); |
| 561 if (host->extension_host_type() == | 560 if (host->extension_host_type() == |
| 562 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 561 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
| 563 CloseBackgroundHost(host); | 562 CloseBackgroundHost(host); |
| 564 } | 563 } |
| 565 break; | 564 break; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 | 615 |
| 617 Profile* ExtensionProcessManager::GetProfile() const { | 616 Profile* ExtensionProcessManager::GetProfile() const { |
| 618 return Profile::FromBrowserContext(site_instance_->GetBrowserContext()); | 617 return Profile::FromBrowserContext(site_instance_->GetBrowserContext()); |
| 619 } | 618 } |
| 620 | 619 |
| 621 void ExtensionProcessManager::OnExtensionHostCreated(ExtensionHost* host, | 620 void ExtensionProcessManager::OnExtensionHostCreated(ExtensionHost* host, |
| 622 bool is_background) { | 621 bool is_background) { |
| 623 DCHECK_EQ(site_instance_->GetBrowserContext(), host->profile()); | 622 DCHECK_EQ(site_instance_->GetBrowserContext(), host->profile()); |
| 624 if (is_background) | 623 if (is_background) |
| 625 background_hosts_.insert(host); | 624 background_hosts_.insert(host); |
| 626 if (host->extension()->is_platform_app()) | |
| 627 platform_app_hosts_.insert(host); | |
| 628 } | 625 } |
| 629 | 626 |
| 630 void ExtensionProcessManager::CloseBackgroundHost(ExtensionHost* host) { | 627 void ExtensionProcessManager::CloseBackgroundHost(ExtensionHost* host) { |
| 631 CHECK(host->extension_host_type() == | 628 CHECK(host->extension_host_type() == |
| 632 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); | 629 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); |
| 633 delete host; | 630 delete host; |
| 634 // |host| should deregister itself from our structures. | 631 // |host| should deregister itself from our structures. |
| 635 CHECK(background_hosts_.find(host) == background_hosts_.end()); | 632 CHECK(background_hosts_.find(host) == background_hosts_.end()); |
| 636 } | 633 } |
| 637 | 634 |
| 638 void ExtensionProcessManager::CloseBackgroundHosts() { | 635 void ExtensionProcessManager::CloseBackgroundHosts() { |
| 639 for (ExtensionHostSet::iterator iter = background_hosts_.begin(); | 636 for (ExtensionHostSet::iterator iter = background_hosts_.begin(); |
| 640 iter != background_hosts_.end(); ) { | 637 iter != background_hosts_.end(); ) { |
| 641 ExtensionHostSet::iterator current = iter++; | 638 ExtensionHostSet::iterator current = iter++; |
| 642 delete *current; | 639 delete *current; |
| 643 } | 640 } |
| 644 } | 641 } |
| 645 | 642 |
| 646 void ExtensionProcessManager::ClearBackgroundPageData( | 643 void ExtensionProcessManager::ClearBackgroundPageData( |
| 647 const std::string& extension_id) { | 644 const std::string& extension_id) { |
| 648 background_page_data_.erase(extension_id); | 645 background_page_data_.erase(extension_id); |
| 649 | 646 |
| 650 // Re-register all RenderViews for this extension. We do this to restore | 647 // Re-register all RenderViews for this extension. We do this to restore |
| 651 // the lazy_keepalive_count (if any) to properly reflect the number of open | 648 // the lazy_keepalive_count (if any) to properly reflect the number of open |
| 652 // views. | 649 // views. |
| 653 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); | 650 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); |
| 654 it != all_extension_views_.end(); ++it) { | 651 it != all_extension_views_.end(); ++it) { |
| 655 if (GetExtensionID(it->first) == extension_id) | 652 if (GetExtensionID(it->first) == extension_id) |
| 656 UpdateRegisteredRenderView(it->first); | 653 IncrementLazyKeepaliveCountForView(it->first); |
| 657 } | 654 } |
| 658 } | 655 } |
| 659 | 656 |
| 660 // | 657 // |
| 661 // IncognitoExtensionProcessManager | 658 // IncognitoExtensionProcessManager |
| 662 // | 659 // |
| 663 | 660 |
| 664 IncognitoExtensionProcessManager::IncognitoExtensionProcessManager( | 661 IncognitoExtensionProcessManager::IncognitoExtensionProcessManager( |
| 665 Profile* profile) | 662 Profile* profile) |
| 666 : ExtensionProcessManager(profile), | 663 : ExtensionProcessManager(profile), |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 if (service && service->is_ready()) | 749 if (service && service->is_ready()) |
| 753 CreateBackgroundHostsForProfileStartup(this, service->extensions()); | 750 CreateBackgroundHostsForProfileStartup(this, service->extensions()); |
| 754 } | 751 } |
| 755 break; | 752 break; |
| 756 } | 753 } |
| 757 default: | 754 default: |
| 758 ExtensionProcessManager::Observe(type, source, details); | 755 ExtensionProcessManager::Observe(type, source, details); |
| 759 break; | 756 break; |
| 760 } | 757 } |
| 761 } | 758 } |
| OLD | NEW |