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 "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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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); |
| 792 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 Loading... |
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 } |
OLD | NEW |