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/logging.h" |
8 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
9 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
10 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
11 #include "base/time.h" | 12 #include "base/time.h" |
12 #include "chrome/browser/extensions/extension_process_manager.h" | 13 #include "chrome/browser/extensions/extension_process_manager.h" |
13 #include "chrome/browser/extensions/extension_host.h" | 14 #include "chrome/browser/extensions/extension_host.h" |
14 #include "chrome/browser/extensions/extension_info_map.h" | 15 #include "chrome/browser/extensions/extension_info_map.h" |
15 #include "chrome/browser/extensions/extension_service.h" | 16 #include "chrome/browser/extensions/extension_service.h" |
16 #include "chrome/browser/extensions/extension_system.h" | 17 #include "chrome/browser/extensions/extension_system.h" |
17 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 | 105 |
105 struct ExtensionProcessManager::BackgroundPageData { | 106 struct ExtensionProcessManager::BackgroundPageData { |
106 // The count of things keeping the lazy background page alive. | 107 // The count of things keeping the lazy background page alive. |
107 int lazy_keepalive_count; | 108 int lazy_keepalive_count; |
108 | 109 |
109 // This is used with the ShouldUnload message, to ensure that the extension | 110 // This is used with the ShouldUnload message, to ensure that the extension |
110 // remained idle between sending the message and receiving the ack. | 111 // remained idle between sending the message and receiving the ack. |
111 int close_sequence_id; | 112 int close_sequence_id; |
112 | 113 |
113 // True if the page responded to the ShouldUnload message and is currently | 114 // True if the page responded to the ShouldUnload message and is currently |
114 // dispatching the unload event. We use this to ignore any activity | 115 // dispatching the unload event. During this time any events that arrive will |
115 // generated during the unload event that would otherwise keep the | 116 // cancel the unload process and an onSuspendCanceled event will be dispatched |
116 // extension alive. | 117 // to the page. |
117 bool is_closing; | 118 bool is_closing; |
118 | 119 |
119 // Keeps track of when this page was last unloaded. Used for perf metrics. | 120 // Keeps track of when this page was last unloaded. Used for perf metrics. |
120 linked_ptr<PerfTimer> since_unloaded; | 121 linked_ptr<PerfTimer> since_unloaded; |
121 | 122 |
122 BackgroundPageData() | 123 BackgroundPageData() |
123 : lazy_keepalive_count(0), close_sequence_id(0), is_closing(false) {} | 124 : lazy_keepalive_count(0), close_sequence_id(0), is_closing(false) {} |
124 }; | 125 }; |
125 | 126 |
126 // | 127 // |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 MessageLoop::current()->PostDelayedTask( | 435 MessageLoop::current()->PostDelayedTask( |
435 FROM_HERE, | 436 FROM_HERE, |
436 base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, | 437 base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, |
437 weak_ptr_factory_.GetWeakPtr(), extension->id(), | 438 weak_ptr_factory_.GetWeakPtr(), extension->id(), |
438 ++background_page_data_[extension->id()].close_sequence_id), | 439 ++background_page_data_[extension->id()].close_sequence_id), |
439 event_page_idle_time_); | 440 event_page_idle_time_); |
440 } | 441 } |
441 | 442 |
442 return count; | 443 return count; |
443 } | 444 } |
| 445 |
444 void ExtensionProcessManager::IncrementLazyKeepaliveCountForView( | 446 void ExtensionProcessManager::IncrementLazyKeepaliveCountForView( |
445 RenderViewHost* render_view_host) { | 447 RenderViewHost* render_view_host) { |
446 WebContents* web_contents = | 448 WebContents* web_contents = |
447 WebContents::FromRenderViewHost(render_view_host); | 449 WebContents::FromRenderViewHost(render_view_host); |
448 chrome::ViewType view_type = chrome::GetViewType(web_contents); | 450 chrome::ViewType view_type = chrome::GetViewType(web_contents); |
449 if (view_type != chrome::VIEW_TYPE_INVALID && | 451 if (view_type != chrome::VIEW_TYPE_INVALID && |
450 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 452 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
451 const Extension* extension = GetExtensionForRenderViewHost( | 453 const Extension* extension = GetExtensionForRenderViewHost( |
452 render_view_host); | 454 render_view_host); |
453 if (extension) | 455 if (extension) |
(...skipping 30 matching lines...) Expand all Loading... |
484 void ExtensionProcessManager::OnShouldUnloadAck( | 486 void ExtensionProcessManager::OnShouldUnloadAck( |
485 const std::string& extension_id, int sequence_id) { | 487 const std::string& extension_id, int sequence_id) { |
486 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 488 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
487 if (host && | 489 if (host && |
488 sequence_id == background_page_data_[extension_id].close_sequence_id) { | 490 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
489 host->render_view_host()->Send(new ExtensionMsg_Unload(extension_id)); | 491 host->render_view_host()->Send(new ExtensionMsg_Unload(extension_id)); |
490 } | 492 } |
491 } | 493 } |
492 | 494 |
493 void ExtensionProcessManager::OnUnloadAck(const std::string& extension_id) { | 495 void ExtensionProcessManager::OnUnloadAck(const std::string& extension_id) { |
| 496 background_page_data_[extension_id].is_closing = true; |
| 497 int sequence_id = background_page_data_[extension_id].close_sequence_id; |
494 MessageLoop::current()->PostDelayedTask( | 498 MessageLoop::current()->PostDelayedTask( |
495 FROM_HERE, | 499 FROM_HERE, |
496 base::Bind(&ExtensionProcessManager::CloseLazyBackgroundPageNow, | 500 base::Bind(&ExtensionProcessManager::CloseLazyBackgroundPageNow, |
497 weak_ptr_factory_.GetWeakPtr(), extension_id), | 501 weak_ptr_factory_.GetWeakPtr(), extension_id, sequence_id), |
498 event_page_unloading_time_); | 502 event_page_unloading_time_); |
499 } | 503 } |
500 | 504 |
501 void ExtensionProcessManager::CloseLazyBackgroundPageNow( | 505 void ExtensionProcessManager::CloseLazyBackgroundPageNow( |
502 const std::string& extension_id) { | 506 const std::string& extension_id, int sequence_id) { |
503 background_page_data_[extension_id].is_closing = true; | |
504 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 507 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
505 if (host) | 508 if (host && |
506 CloseBackgroundHost(host); | 509 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
| 510 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 511 if (host) |
| 512 CloseBackgroundHost(host); |
| 513 } |
507 } | 514 } |
508 | 515 |
509 void ExtensionProcessManager::OnNetworkRequestStarted( | 516 void ExtensionProcessManager::OnNetworkRequestStarted( |
510 RenderViewHost* render_view_host) { | 517 RenderViewHost* render_view_host) { |
511 ExtensionHost* host = GetBackgroundHostForExtension( | 518 ExtensionHost* host = GetBackgroundHostForExtension( |
512 GetExtensionID(render_view_host)); | 519 GetExtensionID(render_view_host)); |
513 if (host && host->render_view_host() == render_view_host) | 520 if (host && host->render_view_host() == render_view_host) |
514 IncrementLazyKeepaliveCount(host->extension()); | 521 IncrementLazyKeepaliveCount(host->extension()); |
515 } | 522 } |
516 | 523 |
517 void ExtensionProcessManager::OnNetworkRequestDone( | 524 void ExtensionProcessManager::OnNetworkRequestDone( |
518 RenderViewHost* render_view_host) { | 525 RenderViewHost* render_view_host) { |
519 ExtensionHost* host = GetBackgroundHostForExtension( | 526 ExtensionHost* host = GetBackgroundHostForExtension( |
520 GetExtensionID(render_view_host)); | 527 GetExtensionID(render_view_host)); |
521 if (host && host->render_view_host() == render_view_host) | 528 if (host && host->render_view_host() == render_view_host) |
522 DecrementLazyKeepaliveCount(host->extension()); | 529 DecrementLazyKeepaliveCount(host->extension()); |
523 } | 530 } |
524 | 531 |
| 532 void ExtensionProcessManager::CancelSuspend(const Extension* extension) { |
| 533 bool& is_closing = background_page_data_[extension->id()].is_closing; |
| 534 ExtensionHost* host = GetBackgroundHostForExtension(extension->id()); |
| 535 if (host && is_closing) { |
| 536 is_closing = false; |
| 537 host->render_view_host()->Send( |
| 538 new ExtensionMsg_CancelUnload(extension->id())); |
| 539 // This increment / decrement is to simulate an instantaneous event. This |
| 540 // has the effect of invalidating close_sequence_id, preventing any in |
| 541 // progress closes from completing and starting a new close process if |
| 542 // necessary. |
| 543 IncrementLazyKeepaliveCount(extension); |
| 544 DecrementLazyKeepaliveCount(extension); |
| 545 } |
| 546 } |
| 547 |
525 void ExtensionProcessManager::Observe( | 548 void ExtensionProcessManager::Observe( |
526 int type, | 549 int type, |
527 const content::NotificationSource& source, | 550 const content::NotificationSource& source, |
528 const content::NotificationDetails& details) { | 551 const content::NotificationDetails& details) { |
529 switch (type) { | 552 switch (type) { |
530 case chrome::NOTIFICATION_EXTENSIONS_READY: { | 553 case chrome::NOTIFICATION_EXTENSIONS_READY: { |
531 CreateBackgroundHostsForProfileStartup(this, | 554 CreateBackgroundHostsForProfileStartup(this, |
532 content::Source<Profile>(source).ptr()-> | 555 content::Source<Profile>(source).ptr()-> |
533 GetExtensionService()->extensions()); | 556 GetExtensionService()->extensions()); |
534 break; | 557 break; |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 if (service && service->is_ready()) | 801 if (service && service->is_ready()) |
779 CreateBackgroundHostsForProfileStartup(this, service->extensions()); | 802 CreateBackgroundHostsForProfileStartup(this, service->extensions()); |
780 } | 803 } |
781 break; | 804 break; |
782 } | 805 } |
783 default: | 806 default: |
784 ExtensionProcessManager::Observe(type, source, details); | 807 ExtensionProcessManager::Observe(type, source, details); |
785 break; | 808 break; |
786 } | 809 } |
787 } | 810 } |
OLD | NEW |