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" | 8 #include "base/message_loop.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 | 105 |
106 struct ExtensionProcessManager::BackgroundPageData { | 106 struct ExtensionProcessManager::BackgroundPageData { |
107 // The count of things keeping the lazy background page alive. | 107 // The count of things keeping the lazy background page alive. |
108 int lazy_keepalive_count; | 108 int lazy_keepalive_count; |
109 | 109 |
110 // 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 |
111 // remained idle between sending the message and receiving the ack. | 111 // remained idle between sending the message and receiving the ack. |
112 int close_sequence_id; | 112 int close_sequence_id; |
113 | 113 |
114 // 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 |
115 // dispatching the unload event. We use this to ignore any activity | 115 // dispatching the unload event. During this time any events that arrive will |
116 // generated during the unload event that would otherwise keep the | 116 // cancel the unload process and an onSuspendCanceled event will be dispatched |
117 // extension alive. | 117 // to the page. |
118 bool is_closing; | 118 bool is_closing; |
119 | 119 |
120 // 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. |
121 linked_ptr<PerfTimer> since_unloaded; | 121 linked_ptr<PerfTimer> since_unloaded; |
122 | 122 |
123 BackgroundPageData() | 123 BackgroundPageData() |
124 : lazy_keepalive_count(0), close_sequence_id(0), is_closing(false) {} | 124 : lazy_keepalive_count(0), close_sequence_id(0), is_closing(false) {} |
125 }; | 125 }; |
126 | 126 |
127 // | 127 // |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 return count; | 424 return count; |
425 } | 425 } |
426 | 426 |
427 int ExtensionProcessManager::DecrementLazyKeepaliveCount( | 427 int ExtensionProcessManager::DecrementLazyKeepaliveCount( |
428 const Extension* extension) { | 428 const Extension* extension) { |
429 if (!extension->has_lazy_background_page()) | 429 if (!extension->has_lazy_background_page()) |
430 return 0; | 430 return 0; |
431 | 431 |
432 int& count = background_page_data_[extension->id()].lazy_keepalive_count; | 432 int& count = background_page_data_[extension->id()].lazy_keepalive_count; |
433 DCHECK_GT(count, 0); | 433 DCHECK_GT(count, 0); |
434 if (--count == 0) { | 434 --count; |
435 MessageLoop::current()->PostDelayedTask( | 435 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 } | |
442 | 436 |
443 return count; | 437 return count; |
444 } | 438 } |
| 439 |
445 void ExtensionProcessManager::IncrementLazyKeepaliveCountForView( | 440 void ExtensionProcessManager::IncrementLazyKeepaliveCountForView( |
446 RenderViewHost* render_view_host) { | 441 RenderViewHost* render_view_host) { |
447 WebContents* web_contents = | 442 WebContents* web_contents = |
448 WebContents::FromRenderViewHost(render_view_host); | 443 WebContents::FromRenderViewHost(render_view_host); |
449 chrome::ViewType view_type = chrome::GetViewType(web_contents); | 444 chrome::ViewType view_type = chrome::GetViewType(web_contents); |
450 if (view_type != chrome::VIEW_TYPE_INVALID && | 445 if (view_type != chrome::VIEW_TYPE_INVALID && |
451 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 446 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
452 const Extension* extension = GetExtensionForRenderViewHost( | 447 const Extension* extension = GetExtensionForRenderViewHost( |
453 render_view_host); | 448 render_view_host); |
454 if (extension) | 449 if (extension) |
455 IncrementLazyKeepaliveCount(extension); | 450 IncrementLazyKeepaliveCount(extension); |
456 } | 451 } |
457 } | 452 } |
458 | 453 |
| 454 void ExtensionProcessManager::MaybePostOnLazyBackgroundPageIdle( |
| 455 const std::string& extension_id) { |
| 456 if (background_page_data_[extension_id].lazy_keepalive_count == 0) { |
| 457 MessageLoop::current()->PostDelayedTask( |
| 458 FROM_HERE, |
| 459 base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, |
| 460 weak_ptr_factory_.GetWeakPtr(), extension_id, |
| 461 ++background_page_data_[extension_id].close_sequence_id), |
| 462 event_page_idle_time_); |
| 463 } |
| 464 } |
| 465 |
459 void ExtensionProcessManager::OnLazyBackgroundPageIdle( | 466 void ExtensionProcessManager::OnLazyBackgroundPageIdle( |
460 const std::string& extension_id, int sequence_id) { | 467 const std::string& extension_id, int sequence_id) { |
461 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 468 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
462 if (host && !background_page_data_[extension_id].is_closing && | 469 if (host && !background_page_data_[extension_id].is_closing && |
463 sequence_id == background_page_data_[extension_id].close_sequence_id) { | 470 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 | 471 // 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 | 472 // 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 | 473 // 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 | 474 // know that the extension process is ready to shut down. If our |
468 // close_sequence_id has already changed, then we would ignore the | 475 // close_sequence_id has already changed, then we would ignore the |
(...skipping 16 matching lines...) Expand all Loading... |
485 void ExtensionProcessManager::OnShouldUnloadAck( | 492 void ExtensionProcessManager::OnShouldUnloadAck( |
486 const std::string& extension_id, int sequence_id) { | 493 const std::string& extension_id, int sequence_id) { |
487 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 494 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
488 if (host && | 495 if (host && |
489 sequence_id == background_page_data_[extension_id].close_sequence_id) { | 496 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
490 host->render_view_host()->Send(new ExtensionMsg_Unload(extension_id)); | 497 host->render_view_host()->Send(new ExtensionMsg_Unload(extension_id)); |
491 } | 498 } |
492 } | 499 } |
493 | 500 |
494 void ExtensionProcessManager::OnUnloadAck(const std::string& extension_id) { | 501 void ExtensionProcessManager::OnUnloadAck(const std::string& extension_id) { |
| 502 background_page_data_[extension_id].is_closing = true; |
| 503 int sequence_id = background_page_data_[extension_id].close_sequence_id; |
495 MessageLoop::current()->PostDelayedTask( | 504 MessageLoop::current()->PostDelayedTask( |
496 FROM_HERE, | 505 FROM_HERE, |
497 base::Bind(&ExtensionProcessManager::CloseLazyBackgroundPageNow, | 506 base::Bind(&ExtensionProcessManager::CloseLazyBackgroundPageNow, |
498 weak_ptr_factory_.GetWeakPtr(), extension_id), | 507 weak_ptr_factory_.GetWeakPtr(), extension_id, sequence_id), |
499 event_page_unloading_time_); | 508 event_page_unloading_time_); |
500 } | 509 } |
501 | 510 |
502 void ExtensionProcessManager::CloseLazyBackgroundPageNow( | 511 void ExtensionProcessManager::CloseLazyBackgroundPageNow( |
503 const std::string& extension_id) { | 512 const std::string& extension_id, int sequence_id) { |
504 background_page_data_[extension_id].is_closing = true; | |
505 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 513 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
506 if (host) | 514 if (host && |
507 CloseBackgroundHost(host); | 515 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
| 516 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 517 if (host) |
| 518 CloseBackgroundHost(host); |
| 519 } |
508 } | 520 } |
509 | 521 |
510 void ExtensionProcessManager::OnNetworkRequestStarted( | 522 void ExtensionProcessManager::OnNetworkRequestStarted( |
511 RenderViewHost* render_view_host) { | 523 RenderViewHost* render_view_host) { |
512 ExtensionHost* host = GetBackgroundHostForExtension( | 524 ExtensionHost* host = GetBackgroundHostForExtension( |
513 GetExtensionID(render_view_host)); | 525 GetExtensionID(render_view_host)); |
514 if (host && host->render_view_host() == render_view_host) | 526 if (host && host->render_view_host() == render_view_host) |
515 IncrementLazyKeepaliveCount(host->extension()); | 527 IncrementLazyKeepaliveCount(host->extension()); |
516 } | 528 } |
517 | 529 |
518 void ExtensionProcessManager::OnNetworkRequestDone( | 530 void ExtensionProcessManager::OnNetworkRequestDone( |
519 RenderViewHost* render_view_host) { | 531 RenderViewHost* render_view_host) { |
520 ExtensionHost* host = GetBackgroundHostForExtension( | 532 ExtensionHost* host = GetBackgroundHostForExtension( |
521 GetExtensionID(render_view_host)); | 533 GetExtensionID(render_view_host)); |
522 if (host && host->render_view_host() == render_view_host) | 534 if (host && host->render_view_host() == render_view_host) |
523 DecrementLazyKeepaliveCount(host->extension()); | 535 DecrementLazyKeepaliveCount(host->extension()); |
524 } | 536 } |
525 | 537 |
| 538 void ExtensionProcessManager::CancelSuspend(const std::string& extension_id) { |
| 539 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 540 if (host) { |
| 541 bool& is_closing = background_page_data_[extension_id].is_closing; |
| 542 if (is_closing) { |
| 543 host->render_view_host()->Send( |
| 544 new ExtensionMsg_CancelUnload(extension_id)); |
| 545 is_closing = false; |
| 546 } |
| 547 } |
| 548 OnLazyBackgroundPageActive(extension_id); |
| 549 MaybePostOnLazyBackgroundPageIdle(extension_id); |
| 550 } |
| 551 |
526 void ExtensionProcessManager::Observe( | 552 void ExtensionProcessManager::Observe( |
527 int type, | 553 int type, |
528 const content::NotificationSource& source, | 554 const content::NotificationSource& source, |
529 const content::NotificationDetails& details) { | 555 const content::NotificationDetails& details) { |
530 switch (type) { | 556 switch (type) { |
531 case chrome::NOTIFICATION_EXTENSIONS_READY: { | 557 case chrome::NOTIFICATION_EXTENSIONS_READY: { |
532 CreateBackgroundHostsForProfileStartup(this, | 558 CreateBackgroundHostsForProfileStartup(this, |
533 content::Source<Profile>(source).ptr()-> | 559 content::Source<Profile>(source).ptr()-> |
534 GetExtensionService()->extensions()); | 560 GetExtensionService()->extensions()); |
535 break; | 561 break; |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 if (service && service->is_ready()) | 805 if (service && service->is_ready()) |
780 CreateBackgroundHostsForProfileStartup(this, service->extensions()); | 806 CreateBackgroundHostsForProfileStartup(this, service->extensions()); |
781 } | 807 } |
782 break; | 808 break; |
783 } | 809 } |
784 default: | 810 default: |
785 ExtensionProcessManager::Observe(type, source, details); | 811 ExtensionProcessManager::Observe(type, source, details); |
786 break; | 812 break; |
787 } | 813 } |
788 } | 814 } |
OLD | NEW |