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_event_router.h" | 13 #include "chrome/browser/extensions/extension_event_router.h" |
13 #include "chrome/browser/extensions/extension_process_manager.h" | 14 #include "chrome/browser/extensions/extension_process_manager.h" |
14 #include "chrome/browser/extensions/extension_host.h" | 15 #include "chrome/browser/extensions/extension_host.h" |
15 #include "chrome/browser/extensions/extension_info_map.h" | 16 #include "chrome/browser/extensions/extension_info_map.h" |
16 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
17 #include "chrome/browser/extensions/extension_system.h" | 18 #include "chrome/browser/extensions/extension_system.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 | 106 |
106 struct ExtensionProcessManager::BackgroundPageData { | 107 struct ExtensionProcessManager::BackgroundPageData { |
107 // The count of things keeping the lazy background page alive. | 108 // The count of things keeping the lazy background page alive. |
108 int lazy_keepalive_count; | 109 int lazy_keepalive_count; |
109 | 110 |
110 // This is used with the ShouldUnload message, to ensure that the extension | 111 // This is used with the ShouldUnload message, to ensure that the extension |
111 // remained idle between sending the message and receiving the ack. | 112 // remained idle between sending the message and receiving the ack. |
112 int close_sequence_id; | 113 int close_sequence_id; |
113 | 114 |
114 // True if the page responded to the ShouldUnload message and is currently | 115 // True if the page responded to the ShouldUnload message and is currently |
115 // dispatching the unload event. We use this to ignore any activity | 116 // dispatching the unload event. During this time any events that arrive will |
116 // generated during the unload event that would otherwise keep the | 117 // cancel the unload process and an onSuspendCanceled event will be dispatched |
117 // extension alive. | 118 // to the page. |
118 bool is_closing; | 119 bool is_closing; |
119 | 120 |
120 // Keeps track of when this page was last unloaded. Used for perf metrics. | 121 // Keeps track of when this page was last unloaded. Used for perf metrics. |
121 linked_ptr<PerfTimer> since_unloaded; | 122 linked_ptr<PerfTimer> since_unloaded; |
122 | 123 |
123 BackgroundPageData() | 124 BackgroundPageData() |
124 : lazy_keepalive_count(0), close_sequence_id(0), is_closing(false) {} | 125 : lazy_keepalive_count(0), close_sequence_id(0), is_closing(false) {} |
125 }; | 126 }; |
126 | 127 |
127 // | 128 // |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 } | 426 } |
426 | 427 |
427 int ExtensionProcessManager::DecrementLazyKeepaliveCount( | 428 int ExtensionProcessManager::DecrementLazyKeepaliveCount( |
428 const Extension* extension) { | 429 const Extension* extension) { |
429 if (!extension->has_lazy_background_page()) | 430 if (!extension->has_lazy_background_page()) |
430 return 0; | 431 return 0; |
431 | 432 |
432 int& count = background_page_data_[extension->id()].lazy_keepalive_count; | 433 int& count = background_page_data_[extension->id()].lazy_keepalive_count; |
433 DCHECK_GT(count, 0); | 434 DCHECK_GT(count, 0); |
434 if (--count == 0) { | 435 if (--count == 0) { |
435 MessageLoop::current()->PostDelayedTask( | 436 MaybePostOnLazyBackgroundPageIdle(extension->id()); |
436 FROM_HERE, | |
437 base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, | |
438 weak_ptr_factory_.GetWeakPtr(), extension->id(), | |
439 ++background_page_data_[extension->id()].close_sequence_id), | |
440 event_page_idle_time_); | |
441 } | 437 } |
442 | 438 |
443 return count; | 439 return count; |
444 } | 440 } |
441 | |
445 void ExtensionProcessManager::IncrementLazyKeepaliveCountForView( | 442 void ExtensionProcessManager::IncrementLazyKeepaliveCountForView( |
446 RenderViewHost* render_view_host) { | 443 RenderViewHost* render_view_host) { |
447 WebContents* web_contents = | 444 WebContents* web_contents = |
448 WebContents::FromRenderViewHost(render_view_host); | 445 WebContents::FromRenderViewHost(render_view_host); |
449 chrome::ViewType view_type = chrome::GetViewType(web_contents); | 446 chrome::ViewType view_type = chrome::GetViewType(web_contents); |
450 if (view_type != chrome::VIEW_TYPE_INVALID && | 447 if (view_type != chrome::VIEW_TYPE_INVALID && |
451 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 448 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
452 const Extension* extension = GetExtensionForRenderViewHost( | 449 const Extension* extension = GetExtensionForRenderViewHost( |
453 render_view_host); | 450 render_view_host); |
454 if (extension) | 451 if (extension) |
455 IncrementLazyKeepaliveCount(extension); | 452 IncrementLazyKeepaliveCount(extension); |
456 } | 453 } |
457 } | 454 } |
458 | 455 |
456 void ExtensionProcessManager::MaybePostOnLazyBackgroundPageIdle( | |
457 const std::string& extension_id) { | |
458 if (background_page_data_[extension_id].lazy_keepalive_count == 0) { | |
459 MessageLoop::current()->PostDelayedTask( | |
460 FROM_HERE, | |
461 base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, | |
462 weak_ptr_factory_.GetWeakPtr(), extension_id, | |
463 ++background_page_data_[extension_id].close_sequence_id), | |
464 event_page_idle_time_); | |
465 } | |
466 } | |
467 | |
459 void ExtensionProcessManager::OnLazyBackgroundPageIdle( | 468 void ExtensionProcessManager::OnLazyBackgroundPageIdle( |
460 const std::string& extension_id, int sequence_id) { | 469 const std::string& extension_id, int sequence_id) { |
461 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 470 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
462 if (host && !background_page_data_[extension_id].is_closing && | 471 if (host && !background_page_data_[extension_id].is_closing && |
463 sequence_id == background_page_data_[extension_id].close_sequence_id) { | 472 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
464 // Tell the renderer we are about to close. This is a simple ping that the | 473 // Tell the renderer we are about to close. This is a simple ping that the |
465 // renderer will respond to. The purpose is to control sequencing: if the | 474 // renderer will respond to. The purpose is to control sequencing: if the |
466 // extension remains idle until the renderer responds with an ACK, then we | 475 // extension remains idle until the renderer responds with an ACK, then we |
467 // know that the extension process is ready to shut down. If our | 476 // know that the extension process is ready to shut down. If our |
468 // close_sequence_id has already changed, then we would ignore the | 477 // close_sequence_id has already changed, then we would ignore the |
469 // ShouldUnloadAck, so we don't send the ping. | 478 // ShouldUnloadAck, so we don't send the ping. |
470 host->render_view_host()->Send(new ExtensionMsg_ShouldUnload( | 479 host->render_view_host()->Send(new ExtensionMsg_ShouldUnload( |
471 extension_id, sequence_id)); | 480 extension_id, sequence_id)); |
472 } | 481 } |
473 } | 482 } |
474 | 483 |
475 void ExtensionProcessManager::OnLazyBackgroundPageActive( | 484 void ExtensionProcessManager::OnLazyBackgroundPageActive( |
476 const std::string& extension_id) { | 485 const std::string& extension_id) { |
477 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 486 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
478 if (host && !background_page_data_[extension_id].is_closing) { | 487 if (host) { |
488 bool& is_closing = background_page_data_[extension_id].is_closing; | |
489 if (is_closing) { | |
490 host->render_view_host()->Send( | |
491 new ExtensionMsg_CancelUnload(extension_id)); | |
492 is_closing = false; | |
493 } | |
479 // Cancel the current close sequence by changing the close_sequence_id, | 494 // Cancel the current close sequence by changing the close_sequence_id, |
480 // which causes us to ignore the next ShouldUnloadAck. | 495 // which causes us to ignore the next ShouldUnloadAck. |
481 ++background_page_data_[extension_id].close_sequence_id; | 496 ++background_page_data_[extension_id].close_sequence_id; |
482 } | 497 } |
483 } | 498 } |
484 | 499 |
485 void ExtensionProcessManager::OnShouldUnloadAck( | 500 void ExtensionProcessManager::OnShouldUnloadAck( |
486 const std::string& extension_id, int sequence_id) { | 501 const std::string& extension_id, int sequence_id) { |
487 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 502 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
488 if (host && | 503 if (host && |
489 sequence_id == background_page_data_[extension_id].close_sequence_id) { | 504 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
490 host->render_view_host()->Send(new ExtensionMsg_Unload(extension_id)); | 505 host->render_view_host()->Send(new ExtensionMsg_Unload(extension_id)); |
491 } | 506 } |
492 } | 507 } |
493 | 508 |
494 void ExtensionProcessManager::OnUnloadAck(const std::string& extension_id) { | 509 void ExtensionProcessManager::OnUnloadAck(const std::string& extension_id) { |
510 background_page_data_[extension_id].is_closing = true; | |
511 int sequence_id = background_page_data_[extension_id].close_sequence_id; | |
495 MessageLoop::current()->PostDelayedTask( | 512 MessageLoop::current()->PostDelayedTask( |
496 FROM_HERE, | 513 FROM_HERE, |
497 base::Bind(&ExtensionProcessManager::CloseLazyBackgroundPageNow, | 514 base::Bind(&ExtensionProcessManager::CloseLazyBackgroundPageNow, |
498 weak_ptr_factory_.GetWeakPtr(), extension_id), | 515 weak_ptr_factory_.GetWeakPtr(), extension_id, sequence_id), |
499 event_page_unloading_time_); | 516 event_page_unloading_time_); |
500 } | 517 } |
501 | 518 |
502 void ExtensionProcessManager::CloseLazyBackgroundPageNow( | 519 void ExtensionProcessManager::CloseLazyBackgroundPageNow( |
503 const std::string& extension_id) { | 520 const std::string& extension_id, int sequence_id) { |
504 background_page_data_[extension_id].is_closing = true; | |
505 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 521 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
506 if (host) | 522 if (host && |
507 CloseBackgroundHost(host); | 523 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
524 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | |
525 if (host) | |
526 CloseBackgroundHost(host); | |
527 } | |
508 } | 528 } |
509 | 529 |
510 void ExtensionProcessManager::OnNetworkRequestStarted( | 530 void ExtensionProcessManager::OnNetworkRequestStarted( |
511 RenderViewHost* render_view_host) { | 531 RenderViewHost* render_view_host) { |
512 ExtensionHost* host = GetBackgroundHostForExtension( | 532 ExtensionHost* host = GetBackgroundHostForExtension( |
513 GetExtensionID(render_view_host)); | 533 GetExtensionID(render_view_host)); |
514 if (host && host->render_view_host() == render_view_host) | 534 if (host && host->render_view_host() == render_view_host) |
515 IncrementLazyKeepaliveCount(host->extension()); | 535 IncrementLazyKeepaliveCount(host->extension()); |
516 } | 536 } |
517 | 537 |
518 void ExtensionProcessManager::OnNetworkRequestDone( | 538 void ExtensionProcessManager::OnNetworkRequestDone( |
519 RenderViewHost* render_view_host) { | 539 RenderViewHost* render_view_host) { |
520 ExtensionHost* host = GetBackgroundHostForExtension( | 540 ExtensionHost* host = GetBackgroundHostForExtension( |
521 GetExtensionID(render_view_host)); | 541 GetExtensionID(render_view_host)); |
522 if (host && host->render_view_host() == render_view_host) | 542 if (host && host->render_view_host() == render_view_host) |
523 DecrementLazyKeepaliveCount(host->extension()); | 543 DecrementLazyKeepaliveCount(host->extension()); |
524 } | 544 } |
525 | 545 |
546 void ExtensionProcessManager::CancelSuspend(const std::string& extension_id) { | |
547 OnLazyBackgroundPageActive(extension_id); | |
548 MaybePostOnLazyBackgroundPageIdle(extension_id); | |
Matt Perry
2012/07/23 19:15:49
This change confuses me. If we're canceling a susp
koz (OOO until 15th September)
2012/07/24 06:49:52
This doesn't transition us to idle straight away,
Matt Perry
2012/07/24 19:25:15
AddPendingTask is often called when the keepalive
koz (OOO until 15th September)
2012/07/25 07:48:31
Done.
| |
549 } | |
550 | |
526 void ExtensionProcessManager::Observe( | 551 void ExtensionProcessManager::Observe( |
527 int type, | 552 int type, |
528 const content::NotificationSource& source, | 553 const content::NotificationSource& source, |
529 const content::NotificationDetails& details) { | 554 const content::NotificationDetails& details) { |
530 switch (type) { | 555 switch (type) { |
531 case chrome::NOTIFICATION_EXTENSIONS_READY: { | 556 case chrome::NOTIFICATION_EXTENSIONS_READY: { |
532 CreateBackgroundHostsForProfileStartup(this, | 557 CreateBackgroundHostsForProfileStartup(this, |
533 content::Source<Profile>(source).ptr()-> | 558 content::Source<Profile>(source).ptr()-> |
534 GetExtensionService()->extensions()); | 559 GetExtensionService()->extensions()); |
535 break; | 560 break; |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
779 if (service && service->is_ready()) | 804 if (service && service->is_ready()) |
780 CreateBackgroundHostsForProfileStartup(this, service->extensions()); | 805 CreateBackgroundHostsForProfileStartup(this, service->extensions()); |
781 } | 806 } |
782 break; | 807 break; |
783 } | 808 } |
784 default: | 809 default: |
785 ExtensionProcessManager::Observe(type, source, details); | 810 ExtensionProcessManager::Observe(type, source, details); |
786 break; | 811 break; |
787 } | 812 } |
788 } | 813 } |
OLD | NEW |