| 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" |
| 9 #include "base/string_number_conversions.h" |
| 10 #include "base/time.h" |
| 8 #include "chrome/browser/extensions/extension_event_router.h" | 11 #include "chrome/browser/extensions/extension_event_router.h" |
| 9 #include "chrome/browser/extensions/extension_process_manager.h" | 12 #include "chrome/browser/extensions/extension_process_manager.h" |
| 10 #include "chrome/browser/extensions/extension_host.h" | 13 #include "chrome/browser/extensions/extension_host.h" |
| 11 #include "chrome/browser/extensions/extension_info_map.h" | 14 #include "chrome/browser/extensions/extension_info_map.h" |
| 12 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
| 13 #include "chrome/browser/extensions/extension_system.h" | 16 #include "chrome/browser/extensions/extension_system.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/browser/ui/browser.h" | 18 #include "chrome/browser/ui/browser.h" |
| 16 #include "chrome/browser/ui/browser_window.h" | 19 #include "chrome/browser/ui/browser_window.h" |
| 17 #include "chrome/common/chrome_notification_types.h" | 20 #include "chrome/common/chrome_notification_types.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 // | 121 // |
| 119 | 122 |
| 120 // static | 123 // static |
| 121 ExtensionProcessManager* ExtensionProcessManager::Create(Profile* profile) { | 124 ExtensionProcessManager* ExtensionProcessManager::Create(Profile* profile) { |
| 122 return (profile->IsOffTheRecord()) ? | 125 return (profile->IsOffTheRecord()) ? |
| 123 new IncognitoExtensionProcessManager(profile) : | 126 new IncognitoExtensionProcessManager(profile) : |
| 124 new ExtensionProcessManager(profile); | 127 new ExtensionProcessManager(profile); |
| 125 } | 128 } |
| 126 | 129 |
| 127 ExtensionProcessManager::ExtensionProcessManager(Profile* profile) | 130 ExtensionProcessManager::ExtensionProcessManager(Profile* profile) |
| 128 : site_instance_(SiteInstance::Create(profile)) { | 131 : site_instance_(SiteInstance::Create(profile)), |
| 132 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 129 Profile* original_profile = profile->GetOriginalProfile(); | 133 Profile* original_profile = profile->GetOriginalProfile(); |
| 130 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, | 134 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
| 131 content::Source<Profile>(original_profile)); | 135 content::Source<Profile>(original_profile)); |
| 132 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 136 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| 133 content::Source<Profile>(original_profile)); | 137 content::Source<Profile>(original_profile)); |
| 134 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 138 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 135 content::Source<Profile>(original_profile)); | 139 content::Source<Profile>(original_profile)); |
| 136 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 140 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
| 137 content::Source<Profile>(profile)); | 141 content::Source<Profile>(profile)); |
| 138 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, | 142 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, |
| 139 content::Source<Profile>(profile)); | 143 content::Source<Profile>(profile)); |
| 140 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, | 144 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, |
| 141 content::NotificationService::AllSources()); | 145 content::NotificationService::AllSources()); |
| 142 registrar_.Add(this, content::NOTIFICATION_APP_TERMINATING, | 146 registrar_.Add(this, content::NOTIFICATION_APP_TERMINATING, |
| 143 content::NotificationService::AllSources()); | 147 content::NotificationService::AllSources()); |
| 144 registrar_.Add(this, content::NOTIFICATION_DEVTOOLS_WINDOW_OPENING, | 148 registrar_.Add(this, content::NOTIFICATION_DEVTOOLS_WINDOW_OPENING, |
| 145 content::Source<content::BrowserContext>(profile)); | 149 content::Source<content::BrowserContext>(profile)); |
| 146 registrar_.Add(this, content::NOTIFICATION_DEVTOOLS_WINDOW_CLOSING, | 150 registrar_.Add(this, content::NOTIFICATION_DEVTOOLS_WINDOW_CLOSING, |
| 147 content::Source<content::BrowserContext>(profile)); | 151 content::Source<content::BrowserContext>(profile)); |
| 152 |
| 153 event_page_idle_time_ = base::TimeDelta::FromSeconds(10); |
| 154 unsigned idle_time_sec = 0; |
| 155 if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 156 switches::kEventPageIdleTime), &idle_time_sec)) { |
| 157 event_page_idle_time_ = base::TimeDelta::FromSeconds(idle_time_sec); |
| 158 } |
| 159 event_page_unloading_time_ = base::TimeDelta::FromSeconds(5); |
| 160 unsigned unloading_time_sec = 0; |
| 161 if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 162 switches::kEventPageUnloadingTime), &unloading_time_sec)) { |
| 163 event_page_unloading_time_ = base::TimeDelta::FromSeconds( |
| 164 unloading_time_sec); |
| 165 } |
| 148 } | 166 } |
| 149 | 167 |
| 150 ExtensionProcessManager::~ExtensionProcessManager() { | 168 ExtensionProcessManager::~ExtensionProcessManager() { |
| 151 CloseBackgroundHosts(); | 169 CloseBackgroundHosts(); |
| 152 DCHECK(background_hosts_.empty()); | 170 DCHECK(background_hosts_.empty()); |
| 153 } | 171 } |
| 154 | 172 |
| 155 ExtensionHost* ExtensionProcessManager::CreateShellHost( | 173 ExtensionHost* ExtensionProcessManager::CreateShellHost( |
| 156 const Extension* extension, | 174 const Extension* extension, |
| 157 const GURL& url) { | 175 const GURL& url) { |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 return count; | 425 return count; |
| 408 } | 426 } |
| 409 | 427 |
| 410 int ExtensionProcessManager::DecrementLazyKeepaliveCount( | 428 int ExtensionProcessManager::DecrementLazyKeepaliveCount( |
| 411 const Extension* extension) { | 429 const Extension* extension) { |
| 412 if (!extension->has_lazy_background_page()) | 430 if (!extension->has_lazy_background_page()) |
| 413 return 0; | 431 return 0; |
| 414 | 432 |
| 415 int& count = background_page_data_[extension->id()].lazy_keepalive_count; | 433 int& count = background_page_data_[extension->id()].lazy_keepalive_count; |
| 416 DCHECK_GT(count, 0); | 434 DCHECK_GT(count, 0); |
| 417 if (--count == 0) | 435 if (--count == 0) { |
| 418 OnLazyBackgroundPageIdle(extension->id()); | 436 MessageLoop::current()->PostDelayedTask( |
| 437 FROM_HERE, |
| 438 base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, |
| 439 weak_ptr_factory_.GetWeakPtr(), extension->id(), |
| 440 ++background_page_data_[extension->id()].close_sequence_id), |
| 441 event_page_idle_time_); |
| 442 } |
| 419 | 443 |
| 420 return count; | 444 return count; |
| 421 } | 445 } |
| 422 | 446 |
| 423 void ExtensionProcessManager::OnLazyBackgroundPageIdle( | 447 void ExtensionProcessManager::OnLazyBackgroundPageIdle( |
| 424 const std::string& extension_id) { | 448 const std::string& extension_id, int sequence_id) { |
| 425 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 449 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 426 if (host && !background_page_data_[extension_id].is_closing) { | 450 if (host && !background_page_data_[extension_id].is_closing && |
| 451 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
| 427 // Tell the renderer we are about to close. This is a simple ping that the | 452 // Tell the renderer we are about to close. This is a simple ping that the |
| 428 // renderer will respond to. The purpose is to control sequencing: if the | 453 // renderer will respond to. The purpose is to control sequencing: if the |
| 429 // extension remains idle until the renderer responds with an ACK, then we | 454 // extension remains idle until the renderer responds with an ACK, then we |
| 430 // know that the extension process is ready to shut down. | 455 // know that the extension process is ready to shut down. If our |
| 456 // close_sequence_id has already changed, then we would ignore the |
| 457 // ShouldUnloadAck, so we don't send the ping. |
| 431 host->render_view_host()->Send(new ExtensionMsg_ShouldUnload( | 458 host->render_view_host()->Send(new ExtensionMsg_ShouldUnload( |
| 432 extension_id, ++background_page_data_[extension_id].close_sequence_id)); | 459 extension_id, sequence_id)); |
| 433 } | 460 } |
| 434 } | 461 } |
| 435 | 462 |
| 436 void ExtensionProcessManager::OnLazyBackgroundPageActive( | 463 void ExtensionProcessManager::OnLazyBackgroundPageActive( |
| 437 const std::string& extension_id) { | 464 const std::string& extension_id) { |
| 438 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 465 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 439 if (host && !background_page_data_[extension_id].is_closing) { | 466 if (host && !background_page_data_[extension_id].is_closing) { |
| 440 // Cancel the current close sequence by changing the close_sequence_id, | 467 // Cancel the current close sequence by changing the close_sequence_id, |
| 441 // which causes us to ignore the next ShouldUnloadAck. | 468 // which causes us to ignore the next ShouldUnloadAck. |
| 442 ++background_page_data_[extension_id].close_sequence_id; | 469 ++background_page_data_[extension_id].close_sequence_id; |
| 443 } | 470 } |
| 444 } | 471 } |
| 445 | 472 |
| 446 void ExtensionProcessManager::OnShouldUnloadAck( | 473 void ExtensionProcessManager::OnShouldUnloadAck( |
| 447 const std::string& extension_id, int sequence_id) { | 474 const std::string& extension_id, int sequence_id) { |
| 448 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 475 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 449 if (host && | 476 if (host && |
| 450 sequence_id == background_page_data_[extension_id].close_sequence_id) { | 477 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
| 451 background_page_data_[extension_id].is_closing = true; | 478 background_page_data_[extension_id].is_closing = true; |
| 479 MessageLoop::current()->PostDelayedTask( |
| 480 FROM_HERE, |
| 481 base::Bind(&ExtensionProcessManager::CloseLazyBackgroundPageNow, |
| 482 weak_ptr_factory_.GetWeakPtr(), extension_id), |
| 483 event_page_unloading_time_); |
| 484 } |
| 485 } |
| 486 |
| 487 void ExtensionProcessManager::CloseLazyBackgroundPageNow( |
| 488 const std::string& extension_id) { |
| 489 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 490 if (host) |
| 452 host->render_view_host()->Send(new ExtensionMsg_Unload(extension_id)); | 491 host->render_view_host()->Send(new ExtensionMsg_Unload(extension_id)); |
| 453 } | |
| 454 } | 492 } |
| 455 | 493 |
| 456 void ExtensionProcessManager::OnUnloadAck(const std::string& extension_id) { | 494 void ExtensionProcessManager::OnUnloadAck(const std::string& extension_id) { |
| 457 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 495 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 458 if (host) | 496 if (host) |
| 459 CloseBackgroundHost(host); | 497 CloseBackgroundHost(host); |
| 460 } | 498 } |
| 461 | 499 |
| 462 void ExtensionProcessManager::OnNetworkRequestStarted( | 500 void ExtensionProcessManager::OnNetworkRequestStarted( |
| 463 RenderViewHost* render_view_host) { | 501 RenderViewHost* render_view_host) { |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 if (service && service->is_ready()) | 741 if (service && service->is_ready()) |
| 704 CreateBackgroundHostsForProfileStartup(this, service->extensions()); | 742 CreateBackgroundHostsForProfileStartup(this, service->extensions()); |
| 705 } | 743 } |
| 706 break; | 744 break; |
| 707 } | 745 } |
| 708 default: | 746 default: |
| 709 ExtensionProcessManager::Observe(type, source, details); | 747 ExtensionProcessManager::Observe(type, source, details); |
| 710 break; | 748 break; |
| 711 } | 749 } |
| 712 } | 750 } |
| OLD | NEW |