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 |