Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: extensions/browser/process_manager.cc

Issue 689833005: Add a way to kill apps without killing windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« extensions/browser/process_manager.h ('K') | « extensions/browser/process_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698