Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: chrome/browser/extensions/extension_process_manager.cc

Issue 10272019: Add an arbitrary delay before unloading lazy background pages. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: test Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_process_manager.h ('k') | chrome/browser/extensions/lazy_background_page_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698