OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "extensions/browser/process_manager.h" | 5 #include "extensions/browser/process_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 linked_ptr<base::ElapsedTimer> since_suspended; | 185 linked_ptr<base::ElapsedTimer> since_suspended; |
186 | 186 |
187 BackgroundPageData() | 187 BackgroundPageData() |
188 : lazy_keepalive_count(0), | 188 : lazy_keepalive_count(0), |
189 keepalive_impulse(false), | 189 keepalive_impulse(false), |
190 previous_keepalive_impulse(false), | 190 previous_keepalive_impulse(false), |
191 is_closing(false), | 191 is_closing(false), |
192 close_sequence_id(0) {} | 192 close_sequence_id(0) {} |
193 }; | 193 }; |
194 | 194 |
195 struct ProcessManager::ExtensionRenderViewData { | |
scheib
2014/10/31 19:49:05
Probably comment the struct. All classes have summ
hashimoto
2014/11/03 16:02:26
Done.
| |
196 // The type of the view. | |
197 extensions::ViewType view_type; | |
198 | |
199 // Whether the view is keeping the lazy background page alive or not. | |
200 bool has_keepalive; | |
201 | |
202 ExtensionRenderViewData() | |
203 : view_type(VIEW_TYPE_INVALID), has_keepalive(false) {} | |
204 | |
205 // Returns whether the view can keep the lazy background page alive or not. | |
206 bool CanKeepalive() const { | |
207 return view_type != VIEW_TYPE_INVALID && | |
scheib
2014/10/31 19:49:05
Consider a switch(view_type) so that there will be
hashimoto
2014/11/03 16:02:26
Done.
| |
208 view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE; | |
209 } | |
210 }; | |
211 | |
195 // | 212 // |
196 // ProcessManager | 213 // ProcessManager |
197 // | 214 // |
198 | 215 |
199 // static | 216 // static |
200 ProcessManager* ProcessManager::Get(BrowserContext* context) { | 217 ProcessManager* ProcessManager::Get(BrowserContext* context) { |
201 return ProcessManagerFactory::GetForBrowserContext(context); | 218 return ProcessManagerFactory::GetForBrowserContext(context); |
202 } | 219 } |
203 | 220 |
204 // static | 221 // static |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 | 378 |
362 const Extension* ProcessManager::GetExtensionForRenderViewHost( | 379 const Extension* ProcessManager::GetExtensionForRenderViewHost( |
363 RenderViewHost* render_view_host) { | 380 RenderViewHost* render_view_host) { |
364 if (!render_view_host->GetSiteInstance()) | 381 if (!render_view_host->GetSiteInstance()) |
365 return NULL; | 382 return NULL; |
366 | 383 |
367 return extension_registry_->enabled_extensions().GetByID( | 384 return extension_registry_->enabled_extensions().GetByID( |
368 GetExtensionID(render_view_host)); | 385 GetExtensionID(render_view_host)); |
369 } | 386 } |
370 | 387 |
388 void ProcessManager::AcquireLazyKeepaliveCountForView( | |
389 content::RenderViewHost* render_view_host) { | |
390 auto it = all_extension_views_.find(render_view_host); | |
391 if (it == all_extension_views_.end()) | |
392 return; | |
393 | |
394 ExtensionRenderViewData* data = &it->second; | |
395 if (data->CanKeepalive() && !data->has_keepalive) { | |
396 const Extension* extension = | |
397 GetExtensionForRenderViewHost(render_view_host); | |
398 if (extension) { | |
399 IncrementLazyKeepaliveCount(extension); | |
400 data->has_keepalive = true; | |
401 } | |
402 } | |
403 } | |
404 | |
405 void ProcessManager::ReleaseLazyKeepaliveCountForView( | |
406 content::RenderViewHost* render_view_host) { | |
407 auto it = all_extension_views_.find(render_view_host); | |
408 if (it == all_extension_views_.end()) | |
409 return; | |
410 | |
411 ExtensionRenderViewData* data = &it->second; | |
412 if (data->CanKeepalive() && data->has_keepalive) { | |
413 const Extension* extension = | |
414 GetExtensionForRenderViewHost(render_view_host); | |
415 if (extension) { | |
416 DecrementLazyKeepaliveCount(extension); | |
417 data->has_keepalive = false; | |
418 } | |
419 } | |
420 } | |
421 | |
371 void ProcessManager::UnregisterRenderViewHost( | 422 void ProcessManager::UnregisterRenderViewHost( |
372 RenderViewHost* render_view_host) { | 423 RenderViewHost* render_view_host) { |
373 ExtensionRenderViews::iterator view = | 424 ExtensionRenderViews::iterator view = |
374 all_extension_views_.find(render_view_host); | 425 all_extension_views_.find(render_view_host); |
375 if (view == all_extension_views_.end()) | 426 if (view == all_extension_views_.end()) |
376 return; | 427 return; |
377 | 428 |
378 OnRenderViewHostUnregistered(GetBrowserContext(), render_view_host); | 429 OnRenderViewHostUnregistered(GetBrowserContext(), render_view_host); |
379 ViewType view_type = view->second; | |
380 all_extension_views_.erase(view); | |
381 | 430 |
382 // Keepalive count, balanced in RegisterRenderViewHost. | 431 // Keepalive count, balanced in RegisterRenderViewHost. |
383 if (view_type != VIEW_TYPE_INVALID && | 432 ReleaseLazyKeepaliveCountForView(render_view_host); |
384 view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 433 all_extension_views_.erase(view); |
385 const Extension* extension = GetExtensionForRenderViewHost( | |
386 render_view_host); | |
387 if (extension) | |
388 DecrementLazyKeepaliveCount(extension); | |
389 } | |
390 } | 434 } |
391 | 435 |
392 bool ProcessManager::RegisterRenderViewHost(RenderViewHost* render_view_host) { | 436 bool ProcessManager::RegisterRenderViewHost(RenderViewHost* render_view_host) { |
393 const Extension* extension = GetExtensionForRenderViewHost( | 437 const Extension* extension = GetExtensionForRenderViewHost( |
394 render_view_host); | 438 render_view_host); |
395 if (!extension) | 439 if (!extension) |
396 return false; | 440 return false; |
397 | 441 |
398 WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host); | 442 WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host); |
399 all_extension_views_[render_view_host] = GetViewType(web_contents); | 443 ExtensionRenderViewData* data = &all_extension_views_[render_view_host]; |
444 data->view_type = GetViewType(web_contents); | |
400 | 445 |
401 // Keep the lazy background page alive as long as any non-background-page | 446 // Keep the lazy background page alive as long as any non-background-page |
402 // extension views are visible. Keepalive count balanced in | 447 // extension views are visible. Keepalive count balanced in |
403 // UnregisterRenderViewHost. | 448 // UnregisterRenderViewHost. |
404 IncrementLazyKeepaliveCountForView(render_view_host); | 449 AcquireLazyKeepaliveCountForView(render_view_host); |
405 return true; | 450 return true; |
406 } | 451 } |
407 | 452 |
408 SiteInstance* ProcessManager::GetSiteInstanceForURL(const GURL& url) { | 453 SiteInstance* ProcessManager::GetSiteInstanceForURL(const GURL& url) { |
409 return site_instance_->GetRelatedSiteInstance(url); | 454 return site_instance_->GetRelatedSiteInstance(url); |
410 } | 455 } |
411 | 456 |
412 bool ProcessManager::IsBackgroundHostClosing(const std::string& extension_id) { | 457 bool ProcessManager::IsBackgroundHostClosing(const std::string& extension_id) { |
413 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 458 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
414 return (host && background_page_data_[extension_id].is_closing); | 459 return (host && background_page_data_[extension_id].is_closing); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 base::MessageLoop::current()->PostDelayedTask( | 497 base::MessageLoop::current()->PostDelayedTask( |
453 FROM_HERE, | 498 FROM_HERE, |
454 base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, | 499 base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, |
455 weak_ptr_factory_.GetWeakPtr(), | 500 weak_ptr_factory_.GetWeakPtr(), |
456 extension_id, | 501 extension_id, |
457 last_background_close_sequence_id_), | 502 last_background_close_sequence_id_), |
458 base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); | 503 base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); |
459 } | 504 } |
460 } | 505 } |
461 | 506 |
462 void ProcessManager::IncrementLazyKeepaliveCountForView( | |
463 RenderViewHost* render_view_host) { | |
464 WebContents* web_contents = | |
465 WebContents::FromRenderViewHost(render_view_host); | |
466 ViewType view_type = GetViewType(web_contents); | |
467 if (view_type != VIEW_TYPE_INVALID && | |
468 view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | |
469 const Extension* extension = GetExtensionForRenderViewHost( | |
470 render_view_host); | |
471 if (extension) | |
472 IncrementLazyKeepaliveCount(extension); | |
473 } | |
474 } | |
475 | |
476 // This implementation layers on top of the keepalive count. An impulse sets | 507 // This implementation layers on top of the keepalive count. An impulse sets |
477 // a per extension flag. On a regular interval that flag is checked. Changes | 508 // a per extension flag. On a regular interval that flag is checked. Changes |
478 // from the flag not being set to set cause an IncrementLazyKeepaliveCount. | 509 // from the flag not being set to set cause an IncrementLazyKeepaliveCount. |
479 void ProcessManager::KeepaliveImpulse(const Extension* extension) { | 510 void ProcessManager::KeepaliveImpulse(const Extension* extension) { |
480 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) | 511 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
481 return; | 512 return; |
482 | 513 |
483 BackgroundPageData& bd = background_page_data_[extension->id()]; | 514 BackgroundPageData& bd = background_page_data_[extension->id()]; |
484 | 515 |
485 if (!bd.keepalive_impulse) { | 516 if (!bd.keepalive_impulse) { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
599 extension_id, | 630 extension_id, |
600 sequence_id), | 631 sequence_id), |
601 base::TimeDelta::FromMilliseconds(g_event_page_suspending_time_msec)); | 632 base::TimeDelta::FromMilliseconds(g_event_page_suspending_time_msec)); |
602 } | 633 } |
603 | 634 |
604 void ProcessManager::CloseLazyBackgroundPageNow(const std::string& extension_id, | 635 void ProcessManager::CloseLazyBackgroundPageNow(const std::string& extension_id, |
605 uint64 sequence_id) { | 636 uint64 sequence_id) { |
606 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 637 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
607 if (host && | 638 if (host && |
608 sequence_id == background_page_data_[extension_id].close_sequence_id) { | 639 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
640 // Close remaining views. | |
641 std::vector<RenderViewHost*> views_to_close; | |
642 for (const auto& view : all_extension_views_) { | |
643 if (view.second.CanKeepalive() && | |
644 GetExtensionID(view.first) == extension_id) { | |
645 DCHECK(!view.second.has_keepalive); | |
646 views_to_close.push_back(view.first); | |
647 } | |
648 } | |
649 for (auto view : views_to_close) { | |
650 view->ClosePage(); | |
651 // RenderViewHost::ClosePage() may result in calling | |
652 // UnregisterRenderViewHost() asynchronously and may cause race conditions | |
653 // when the background page is reloaded. | |
654 // To avoid this, unregister the view now. | |
655 UnregisterRenderViewHost(view); | |
656 } | |
657 | |
609 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 658 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
610 if (host) | 659 if (host) |
611 CloseBackgroundHost(host); | 660 CloseBackgroundHost(host); |
612 } | 661 } |
613 } | 662 } |
614 | 663 |
615 void ProcessManager::OnNetworkRequestStarted( | 664 void ProcessManager::OnNetworkRequestStarted( |
616 content::RenderFrameHost* render_frame_host) { | 665 content::RenderFrameHost* render_frame_host) { |
617 ExtensionHost* host = GetBackgroundHostForExtension( | 666 ExtensionHost* host = GetBackgroundHostForExtension( |
618 GetExtensionIDFromFrame(render_frame_host)); | 667 GetExtensionIDFromFrame(render_frame_host)); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
901 } | 950 } |
902 | 951 |
903 void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) { | 952 void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) { |
904 background_page_data_.erase(extension_id); | 953 background_page_data_.erase(extension_id); |
905 | 954 |
906 // Re-register all RenderViews for this extension. We do this to restore | 955 // Re-register all RenderViews for this extension. We do this to restore |
907 // the lazy_keepalive_count (if any) to properly reflect the number of open | 956 // the lazy_keepalive_count (if any) to properly reflect the number of open |
908 // views. | 957 // views. |
909 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); | 958 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); |
910 it != all_extension_views_.end(); ++it) { | 959 it != all_extension_views_.end(); ++it) { |
911 if (GetExtensionID(it->first) == extension_id) | 960 if (GetExtensionID(it->first) == extension_id && it->second.has_keepalive) |
scheib
2014/10/31 19:49:05
If this is only run when has_keepalive is true,
th
hashimoto
2014/11/03 16:02:26
Thanks!
You're right.
I was about to break this lo
scheib
2014/11/03 17:48:28
It is hard to be certain that this method is not n
hashimoto
2014/11/04 05:47:33
Sounds good.
Filed crbug.com/429959.
| |
912 IncrementLazyKeepaliveCountForView(it->first); | 961 AcquireLazyKeepaliveCountForView(it->first); |
913 } | 962 } |
914 } | 963 } |
915 | 964 |
916 // | 965 // |
917 // IncognitoProcessManager | 966 // IncognitoProcessManager |
918 // | 967 // |
919 | 968 |
920 IncognitoProcessManager::IncognitoProcessManager( | 969 IncognitoProcessManager::IncognitoProcessManager( |
921 BrowserContext* incognito_context, | 970 BrowserContext* incognito_context, |
922 BrowserContext* original_context, | 971 BrowserContext* original_context, |
(...skipping 29 matching lines...) Expand all Loading... | |
952 if (extension && !IncognitoInfo::IsSplitMode(extension)) { | 1001 if (extension && !IncognitoInfo::IsSplitMode(extension)) { |
953 BrowserContext* original_context = | 1002 BrowserContext* original_context = |
954 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); | 1003 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); |
955 return ProcessManager::Get(original_context)->GetSiteInstanceForURL(url); | 1004 return ProcessManager::Get(original_context)->GetSiteInstanceForURL(url); |
956 } | 1005 } |
957 | 1006 |
958 return ProcessManager::GetSiteInstanceForURL(url); | 1007 return ProcessManager::GetSiteInstanceForURL(url); |
959 } | 1008 } |
960 | 1009 |
961 } // namespace extensions | 1010 } // namespace extensions |
OLD | NEW |