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

Side by Side Diff: chrome/browser/extensions/extension_process_manager.cc

Issue 24177003: Fixed crash when chrome.runtime.reload() is called with app windows open (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove RenderViewHosts from all_extension_views on unload instead of re-registering them when the n… Created 7 years, 3 months 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 (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 "chrome/browser/extensions/extension_process_manager.h" 5 #include "chrome/browser/extensions/extension_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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 59
60 std::string GetExtensionID(RenderViewHost* render_view_host) { 60 std::string GetExtensionID(RenderViewHost* render_view_host) {
61 // This works for both apps and extensions because the site has been 61 // This works for both apps and extensions because the site has been
62 // normalized to the extension URL for apps. 62 // normalized to the extension URL for apps.
63 if (!render_view_host->GetSiteInstance()) 63 if (!render_view_host->GetSiteInstance())
64 return std::string(); 64 return std::string();
65 65
66 return render_view_host->GetSiteInstance()->GetSiteURL().host(); 66 return render_view_host->GetSiteInstance()->GetSiteURL().host();
67 } 67 }
68 68
69 void OnRenderViewHostUnregistered(Profile* profile,
70 RenderViewHost* render_view_host) {
71 content::NotificationService::current()->Notify(
72 chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED,
73 content::Source<Profile>(profile),
74 content::Details<RenderViewHost>(render_view_host));
75 }
76
69 // Incognito profiles use this process manager. It is mostly a shim that decides 77 // Incognito profiles use this process manager. It is mostly a shim that decides
70 // whether to fall back on the original profile's ExtensionProcessManager based 78 // whether to fall back on the original profile's ExtensionProcessManager based
71 // on whether a given extension uses "split" or "spanning" incognito behavior. 79 // on whether a given extension uses "split" or "spanning" incognito behavior.
72 class IncognitoExtensionProcessManager : public ExtensionProcessManager { 80 class IncognitoExtensionProcessManager : public ExtensionProcessManager {
73 public: 81 public:
74 explicit IncognitoExtensionProcessManager(Profile* profile); 82 explicit IncognitoExtensionProcessManager(Profile* profile);
75 virtual ~IncognitoExtensionProcessManager(); 83 virtual ~IncognitoExtensionProcessManager();
76 virtual ExtensionHost* CreateViewHost( 84 virtual ExtensionHost* CreateViewHost(
77 const Extension* extension, 85 const Extension* extension,
78 const GURL& url, 86 const GURL& url,
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 return service->extensions()->GetByID(GetExtensionID(render_view_host)); 361 return service->extensions()->GetByID(GetExtensionID(render_view_host));
354 } 362 }
355 363
356 void ExtensionProcessManager::UnregisterRenderViewHost( 364 void ExtensionProcessManager::UnregisterRenderViewHost(
357 RenderViewHost* render_view_host) { 365 RenderViewHost* render_view_host) {
358 ExtensionRenderViews::iterator view = 366 ExtensionRenderViews::iterator view =
359 all_extension_views_.find(render_view_host); 367 all_extension_views_.find(render_view_host);
360 if (view == all_extension_views_.end()) 368 if (view == all_extension_views_.end())
361 return; 369 return;
362 370
363 content::NotificationService::current()->Notify( 371 OnRenderViewHostUnregistered(GetProfile(), render_view_host);
364 chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED,
365 content::Source<Profile>(GetProfile()),
366 content::Details<RenderViewHost>(render_view_host));
367
368 extensions::ViewType view_type = view->second; 372 extensions::ViewType view_type = view->second;
369 all_extension_views_.erase(view); 373 all_extension_views_.erase(view);
370 374
371 // Keepalive count, balanced in RegisterRenderViewHost. 375 // Keepalive count, balanced in RegisterRenderViewHost.
372 if (view_type != extensions::VIEW_TYPE_INVALID && 376 if (view_type != extensions::VIEW_TYPE_INVALID &&
373 view_type != extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 377 view_type != extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
374 const Extension* extension = GetExtensionForRenderViewHost( 378 const Extension* extension = GetExtensionForRenderViewHost(
375 render_view_host); 379 render_view_host);
376 if (extension) 380 if (extension)
377 DecrementLazyKeepaliveCount(extension); 381 DecrementLazyKeepaliveCount(extension);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 content::Details<extensions::UnloadedExtensionInfo>( 604 content::Details<extensions::UnloadedExtensionInfo>(
601 details)->extension; 605 details)->extension;
602 for (ExtensionHostSet::iterator iter = background_hosts_.begin(); 606 for (ExtensionHostSet::iterator iter = background_hosts_.begin();
603 iter != background_hosts_.end(); ++iter) { 607 iter != background_hosts_.end(); ++iter) {
604 ExtensionHost* host = *iter; 608 ExtensionHost* host = *iter;
605 if (host->extension_id() == extension->id()) { 609 if (host->extension_id() == extension->id()) {
606 CloseBackgroundHost(host); 610 CloseBackgroundHost(host);
607 break; 611 break;
608 } 612 }
609 } 613 }
610 background_page_data_.erase(extension->id()); 614 UnregisterExtension(extension->id());
611 break; 615 break;
612 } 616 }
613 617
614 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { 618 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: {
615 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); 619 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr();
616 if (background_hosts_.erase(host)) { 620 if (background_hosts_.erase(host)) {
617 ClearBackgroundPageData(host->extension()->id()); 621 ClearBackgroundPageData(host->extension()->id());
618 background_page_data_[host->extension()->id()].since_suspended.reset( 622 background_page_data_[host->extension()->id()].since_suspended.reset(
619 new PerfTimer()); 623 new PerfTimer());
620 } 624 }
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 } 770 }
767 771
768 void ExtensionProcessManager::CloseBackgroundHosts() { 772 void ExtensionProcessManager::CloseBackgroundHosts() {
769 for (ExtensionHostSet::iterator iter = background_hosts_.begin(); 773 for (ExtensionHostSet::iterator iter = background_hosts_.begin();
770 iter != background_hosts_.end(); ) { 774 iter != background_hosts_.end(); ) {
771 ExtensionHostSet::iterator current = iter++; 775 ExtensionHostSet::iterator current = iter++;
772 delete *current; 776 delete *current;
773 } 777 }
774 } 778 }
775 779
780 void ExtensionProcessManager::UnregisterExtension(
781 const std::string& extension_id) {
782 // The lazy_keepalive_count may be greater than zero at this point because
783 // RenderViewHosts are still alive. During extension reloading, they will
784 // decrement the lazy_keepalive_count to negative for the new extension
785 // instance when they are destroyed. Since we are erasing the background page
786 // data for the unloaded extension, unregister the RenderViewHosts too.
787 Profile* profile = GetProfile();
788 for (ExtensionRenderViews::iterator it = all_extension_views_.begin();
789 it != all_extension_views_.end(); ) {
790 if (GetExtensionID(it->first) == extension_id) {
791 OnRenderViewHostUnregistered(profile, it->first);
benwells 2013/09/23 05:38:23 Would this have been sent out before when unloadin
tmdiep 2013/09/23 05:49:00 This gets sent when the render view process is des
792 it = all_extension_views_.erase(it);
793 } else {
794 ++it;
795 }
796 }
797
798 background_page_data_.erase(extension_id);
799 }
800
776 void ExtensionProcessManager::ClearBackgroundPageData( 801 void ExtensionProcessManager::ClearBackgroundPageData(
777 const std::string& extension_id) { 802 const std::string& extension_id) {
778 background_page_data_.erase(extension_id); 803 background_page_data_.erase(extension_id);
779 804
780 // Re-register all RenderViews for this extension. We do this to restore 805 // Re-register all RenderViews for this extension. We do this to restore
781 // the lazy_keepalive_count (if any) to properly reflect the number of open 806 // the lazy_keepalive_count (if any) to properly reflect the number of open
782 // views. 807 // views.
783 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); 808 for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin();
784 it != all_extension_views_.end(); ++it) { 809 it != all_extension_views_.end(); ++it) {
785 if (GetExtensionID(it->first) == extension_id) 810 if (GetExtensionID(it->first) == extension_id)
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 if (service && service->is_ready()) 934 if (service && service->is_ready())
910 CreateBackgroundHostsForProfileStartup(); 935 CreateBackgroundHostsForProfileStartup();
911 } 936 }
912 break; 937 break;
913 } 938 }
914 default: 939 default:
915 ExtensionProcessManager::Observe(type, source, details); 940 ExtensionProcessManager::Observe(type, source, details);
916 break; 941 break;
917 } 942 }
918 } 943 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698