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 // Data of a RenderViewHost associated with an extension. |
| 196 struct ProcessManager::ExtensionRenderViewData { |
| 197 // The type of the view. |
| 198 extensions::ViewType view_type; |
| 199 |
| 200 // Whether the view is keeping the lazy background page alive or not. |
| 201 bool has_keepalive; |
| 202 |
| 203 ExtensionRenderViewData() |
| 204 : view_type(VIEW_TYPE_INVALID), has_keepalive(false) {} |
| 205 |
| 206 // Returns whether the view can keep the lazy background page alive or not. |
| 207 bool CanKeepalive() const { |
| 208 switch (view_type) { |
| 209 case VIEW_TYPE_APP_WINDOW: |
| 210 case VIEW_TYPE_BACKGROUND_CONTENTS: |
| 211 case VIEW_TYPE_EXTENSION_DIALOG: |
| 212 case VIEW_TYPE_EXTENSION_INFOBAR: |
| 213 case VIEW_TYPE_EXTENSION_POPUP: |
| 214 case VIEW_TYPE_LAUNCHER_PAGE: |
| 215 case VIEW_TYPE_PANEL: |
| 216 case VIEW_TYPE_TAB_CONTENTS: |
| 217 case VIEW_TYPE_VIRTUAL_KEYBOARD: |
| 218 return true; |
| 219 |
| 220 case VIEW_TYPE_INVALID: |
| 221 case VIEW_TYPE_EXTENSION_BACKGROUND_PAGE: |
| 222 return false; |
| 223 } |
| 224 NOTREACHED(); |
| 225 return false; |
| 226 } |
| 227 }; |
| 228 |
195 // | 229 // |
196 // ProcessManager | 230 // ProcessManager |
197 // | 231 // |
198 | 232 |
199 // static | 233 // static |
200 ProcessManager* ProcessManager::Get(BrowserContext* context) { | 234 ProcessManager* ProcessManager::Get(BrowserContext* context) { |
201 return ProcessManagerFactory::GetForBrowserContext(context); | 235 return ProcessManagerFactory::GetForBrowserContext(context); |
202 } | 236 } |
203 | 237 |
204 // static | 238 // static |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 | 395 |
362 const Extension* ProcessManager::GetExtensionForRenderViewHost( | 396 const Extension* ProcessManager::GetExtensionForRenderViewHost( |
363 RenderViewHost* render_view_host) { | 397 RenderViewHost* render_view_host) { |
364 if (!render_view_host->GetSiteInstance()) | 398 if (!render_view_host->GetSiteInstance()) |
365 return NULL; | 399 return NULL; |
366 | 400 |
367 return extension_registry_->enabled_extensions().GetByID( | 401 return extension_registry_->enabled_extensions().GetByID( |
368 GetExtensionID(render_view_host)); | 402 GetExtensionID(render_view_host)); |
369 } | 403 } |
370 | 404 |
| 405 void ProcessManager::AcquireLazyKeepaliveCountForView( |
| 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 IncrementLazyKeepaliveCount(extension); |
| 417 data->has_keepalive = true; |
| 418 } |
| 419 } |
| 420 } |
| 421 |
| 422 void ProcessManager::ReleaseLazyKeepaliveCountForView( |
| 423 content::RenderViewHost* render_view_host) { |
| 424 auto it = all_extension_views_.find(render_view_host); |
| 425 if (it == all_extension_views_.end()) |
| 426 return; |
| 427 |
| 428 ExtensionRenderViewData* data = &it->second; |
| 429 if (data->CanKeepalive() && data->has_keepalive) { |
| 430 const Extension* extension = |
| 431 GetExtensionForRenderViewHost(render_view_host); |
| 432 if (extension) { |
| 433 DecrementLazyKeepaliveCount(extension); |
| 434 data->has_keepalive = false; |
| 435 } |
| 436 } |
| 437 } |
| 438 |
371 void ProcessManager::UnregisterRenderViewHost( | 439 void ProcessManager::UnregisterRenderViewHost( |
372 RenderViewHost* render_view_host) { | 440 RenderViewHost* render_view_host) { |
373 ExtensionRenderViews::iterator view = | 441 ExtensionRenderViews::iterator view = |
374 all_extension_views_.find(render_view_host); | 442 all_extension_views_.find(render_view_host); |
375 if (view == all_extension_views_.end()) | 443 if (view == all_extension_views_.end()) |
376 return; | 444 return; |
377 | 445 |
378 OnRenderViewHostUnregistered(GetBrowserContext(), render_view_host); | 446 OnRenderViewHostUnregistered(GetBrowserContext(), render_view_host); |
379 ViewType view_type = view->second; | |
380 all_extension_views_.erase(view); | |
381 | 447 |
382 // Keepalive count, balanced in RegisterRenderViewHost. | 448 // Keepalive count, balanced in RegisterRenderViewHost. |
383 if (view_type != VIEW_TYPE_INVALID && | 449 ReleaseLazyKeepaliveCountForView(render_view_host); |
384 view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 450 all_extension_views_.erase(view); |
385 const Extension* extension = GetExtensionForRenderViewHost( | |
386 render_view_host); | |
387 if (extension) | |
388 DecrementLazyKeepaliveCount(extension); | |
389 } | |
390 } | 451 } |
391 | 452 |
392 bool ProcessManager::RegisterRenderViewHost(RenderViewHost* render_view_host) { | 453 bool ProcessManager::RegisterRenderViewHost(RenderViewHost* render_view_host) { |
393 const Extension* extension = GetExtensionForRenderViewHost( | 454 const Extension* extension = GetExtensionForRenderViewHost( |
394 render_view_host); | 455 render_view_host); |
395 if (!extension) | 456 if (!extension) |
396 return false; | 457 return false; |
397 | 458 |
398 WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host); | 459 WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host); |
399 all_extension_views_[render_view_host] = GetViewType(web_contents); | 460 ExtensionRenderViewData* data = &all_extension_views_[render_view_host]; |
| 461 data->view_type = GetViewType(web_contents); |
400 | 462 |
401 // Keep the lazy background page alive as long as any non-background-page | 463 // Keep the lazy background page alive as long as any non-background-page |
402 // extension views are visible. Keepalive count balanced in | 464 // extension views are visible. Keepalive count balanced in |
403 // UnregisterRenderViewHost. | 465 // UnregisterRenderViewHost. |
404 IncrementLazyKeepaliveCountForView(render_view_host); | 466 AcquireLazyKeepaliveCountForView(render_view_host); |
405 return true; | 467 return true; |
406 } | 468 } |
407 | 469 |
408 SiteInstance* ProcessManager::GetSiteInstanceForURL(const GURL& url) { | 470 SiteInstance* ProcessManager::GetSiteInstanceForURL(const GURL& url) { |
409 return site_instance_->GetRelatedSiteInstance(url); | 471 return site_instance_->GetRelatedSiteInstance(url); |
410 } | 472 } |
411 | 473 |
412 bool ProcessManager::IsBackgroundHostClosing(const std::string& extension_id) { | 474 bool ProcessManager::IsBackgroundHostClosing(const std::string& extension_id) { |
413 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 475 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
414 return (host && background_page_data_[extension_id].is_closing); | 476 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( | 514 base::MessageLoop::current()->PostDelayedTask( |
453 FROM_HERE, | 515 FROM_HERE, |
454 base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, | 516 base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, |
455 weak_ptr_factory_.GetWeakPtr(), | 517 weak_ptr_factory_.GetWeakPtr(), |
456 extension_id, | 518 extension_id, |
457 last_background_close_sequence_id_), | 519 last_background_close_sequence_id_), |
458 base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); | 520 base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); |
459 } | 521 } |
460 } | 522 } |
461 | 523 |
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 | 524 // 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 | 525 // 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. | 526 // from the flag not being set to set cause an IncrementLazyKeepaliveCount. |
479 void ProcessManager::KeepaliveImpulse(const Extension* extension) { | 527 void ProcessManager::KeepaliveImpulse(const Extension* extension) { |
480 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) | 528 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
481 return; | 529 return; |
482 | 530 |
483 BackgroundPageData& bd = background_page_data_[extension->id()]; | 531 BackgroundPageData& bd = background_page_data_[extension->id()]; |
484 | 532 |
485 if (!bd.keepalive_impulse) { | 533 if (!bd.keepalive_impulse) { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 extension_id, | 647 extension_id, |
600 sequence_id), | 648 sequence_id), |
601 base::TimeDelta::FromMilliseconds(g_event_page_suspending_time_msec)); | 649 base::TimeDelta::FromMilliseconds(g_event_page_suspending_time_msec)); |
602 } | 650 } |
603 | 651 |
604 void ProcessManager::CloseLazyBackgroundPageNow(const std::string& extension_id, | 652 void ProcessManager::CloseLazyBackgroundPageNow(const std::string& extension_id, |
605 uint64 sequence_id) { | 653 uint64 sequence_id) { |
606 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 654 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
607 if (host && | 655 if (host && |
608 sequence_id == background_page_data_[extension_id].close_sequence_id) { | 656 sequence_id == background_page_data_[extension_id].close_sequence_id) { |
| 657 // Close remaining views. |
| 658 std::vector<RenderViewHost*> views_to_close; |
| 659 for (const auto& view : all_extension_views_) { |
| 660 if (view.second.CanKeepalive() && |
| 661 GetExtensionID(view.first) == extension_id) { |
| 662 DCHECK(!view.second.has_keepalive); |
| 663 views_to_close.push_back(view.first); |
| 664 } |
| 665 } |
| 666 for (auto view : views_to_close) { |
| 667 view->ClosePage(); |
| 668 // RenderViewHost::ClosePage() may result in calling |
| 669 // UnregisterRenderViewHost() asynchronously and may cause race conditions |
| 670 // when the background page is reloaded. |
| 671 // To avoid this, unregister the view now. |
| 672 UnregisterRenderViewHost(view); |
| 673 } |
| 674 |
609 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 675 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
610 if (host) | 676 if (host) |
611 CloseBackgroundHost(host); | 677 CloseBackgroundHost(host); |
612 } | 678 } |
613 } | 679 } |
614 | 680 |
615 void ProcessManager::OnNetworkRequestStarted( | 681 void ProcessManager::OnNetworkRequestStarted( |
616 content::RenderFrameHost* render_frame_host) { | 682 content::RenderFrameHost* render_frame_host) { |
617 ExtensionHost* host = GetBackgroundHostForExtension( | 683 ExtensionHost* host = GetBackgroundHostForExtension( |
618 GetExtensionIDFromFrame(render_frame_host)); | 684 GetExtensionIDFromFrame(render_frame_host)); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 } | 967 } |
902 | 968 |
903 void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) { | 969 void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) { |
904 background_page_data_.erase(extension_id); | 970 background_page_data_.erase(extension_id); |
905 | 971 |
906 // Re-register all RenderViews for this extension. We do this to restore | 972 // 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 | 973 // the lazy_keepalive_count (if any) to properly reflect the number of open |
908 // views. | 974 // views. |
909 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); | 975 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); |
910 it != all_extension_views_.end(); ++it) { | 976 it != all_extension_views_.end(); ++it) { |
911 if (GetExtensionID(it->first) == extension_id) | 977 RenderViewHost* view = it->first; |
912 IncrementLazyKeepaliveCountForView(it->first); | 978 const ExtensionRenderViewData& data = it->second; |
| 979 // Do not increment the count when |has_keepalive| is false |
| 980 // (i.e. ReleaseLazyKeepaliveCountForView() was called). |
| 981 if (GetExtensionID(view) == extension_id && data.has_keepalive) { |
| 982 const Extension* extension = GetExtensionForRenderViewHost(view); |
| 983 if (extension) |
| 984 IncrementLazyKeepaliveCount(extension); |
| 985 } |
913 } | 986 } |
914 } | 987 } |
915 | 988 |
916 // | 989 // |
917 // IncognitoProcessManager | 990 // IncognitoProcessManager |
918 // | 991 // |
919 | 992 |
920 IncognitoProcessManager::IncognitoProcessManager( | 993 IncognitoProcessManager::IncognitoProcessManager( |
921 BrowserContext* incognito_context, | 994 BrowserContext* incognito_context, |
922 BrowserContext* original_context, | 995 BrowserContext* original_context, |
(...skipping 29 matching lines...) Expand all Loading... |
952 if (extension && !IncognitoInfo::IsSplitMode(extension)) { | 1025 if (extension && !IncognitoInfo::IsSplitMode(extension)) { |
953 BrowserContext* original_context = | 1026 BrowserContext* original_context = |
954 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); | 1027 ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); |
955 return ProcessManager::Get(original_context)->GetSiteInstanceForURL(url); | 1028 return ProcessManager::Get(original_context)->GetSiteInstanceForURL(url); |
956 } | 1029 } |
957 | 1030 |
958 return ProcessManager::GetSiteInstanceForURL(url); | 1031 return ProcessManager::GetSiteInstanceForURL(url); |
959 } | 1032 } |
960 | 1033 |
961 } // namespace extensions | 1034 } // namespace extensions |
OLD | NEW |