diff options
| author | rdevlin.cronin <rdevlin.cronin@chromium.org> | 2015-04-03 13:19:40 -0700 | 
|---|---|---|
| committer | Commit bot <commit-bot@chromium.org> | 2015-04-03 20:20:20 +0000 | 
| commit | 6ae04a013f6040f5d38e6cf04f6da224f21b77f9 (patch) | |
| tree | 427696998b1fd65a9549ab695f30e58f9365c960 | |
| parent | 11d52caf494dea19e0feb6184858b9ec24bdb46c (diff) | |
| download | chromium_src-6ae04a013f6040f5d38e6cf04f6da224f21b77f9.zip chromium_src-6ae04a013f6040f5d38e6cf04f6da224f21b77f9.tar.gz chromium_src-6ae04a013f6040f5d38e6cf04f6da224f21b77f9.tar.bz2 | |
Reland: [Extensions] Change ProcessManager to use RenderFrameHosts
(Reland of https://codereview.chromium.org/1037263004)
RenderViewHosts are going to go away, and things using them are blocking
OOPIs. Make ProcessManager use RenderFrameHosts.
Additionally, this takes out ~130 lines of code.
BUG=466373
(TBRing other reviewers from original patch, since no code there changed)
TBR=avi@chromium.org
TBR=asargent@chromium.org
TBR=atwilson@chromium.org
TBR=jamescook@chromium.org
TBR=dgozman@chromium.org
TBR=nick@chromium.org
Review URL: https://codereview.chromium.org/1056463005
Cr-Commit-Position: refs/heads/master@{#323803}
35 files changed, 608 insertions, 827 deletions
| diff --git a/chrome/browser/apps/window_controls_browsertest.cc b/chrome/browser/apps/window_controls_browsertest.cc index 6d4b76a..33cad92 100644 --- a/chrome/browser/apps/window_controls_browsertest.cc +++ b/chrome/browser/apps/window_controls_browsertest.cc @@ -27,27 +27,19 @@ content::WebContents* WindowControlsTest::GetWebContentsForExtensionWindow(    // Lookup render view host for background page.    const extensions::ExtensionHost* extension_host =        process_manager->GetBackgroundHostForExtension(extension->id()); -  content::RenderViewHost* background_view_host = -      extension_host->render_view_host(); - -  // Go through all active views, looking for the first window of the extension -  const extensions::ProcessManager::ViewSet all_views = -      process_manager->GetAllViews(); -  extensions::ProcessManager::ViewSet::const_iterator it = all_views.begin(); -  for (; it != all_views.end(); ++it) { -    content::RenderViewHost* host = *it; +  // Go through all active views, looking for the first window of the extension. +  for (content::RenderFrameHost* host : process_manager->GetAllFrames()) {      // Filter out views not part of this extension -    if (process_manager->GetExtensionForRenderViewHost(host) == extension) { +    if (process_manager->GetExtensionForRenderFrameHost(host) == extension) {        // Filter out the background page view -      if (host != background_view_host) { -        content::WebContents* web_contents = -            content::WebContents::FromRenderViewHost(host); +      content::WebContents* web_contents = +          content::WebContents::FromRenderFrameHost(host); +      if (web_contents != extension_host->web_contents())          return web_contents; -      }      }    } -  return NULL; +  return nullptr;  }  IN_PROC_BROWSER_TEST_F(WindowControlsTest, CloseControlWorks) { diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc index df92be6..db9eb50 100644 --- a/chrome/browser/devtools/devtools_sanity_browsertest.cc +++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc @@ -363,11 +363,11 @@ class DevToolsExtensionTest : public DevToolsSanityTest,      extensions::ProcessManager* manager =          extensions::ProcessManager::Get(browser()->profile()); -    extensions::ProcessManager::ViewSet all_views = manager->GetAllViews(); -    for (extensions::ProcessManager::ViewSet::const_iterator iter = -             all_views.begin(); -         iter != all_views.end();) { -      if (!(*iter)->IsLoading()) +    extensions::ProcessManager::FrameSet all_frames = manager->GetAllFrames(); +    for (extensions::ProcessManager::FrameSet::const_iterator iter = +             all_frames.begin(); +         iter != all_frames.end();) { +      if (!content::WebContents::FromRenderFrameHost(*iter)->IsLoading())          ++iter;        else          content::RunMessageLoop(); diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc index 32cbd69..cce3f3f 100644 --- a/chrome/browser/extensions/active_tab_permission_granter.cc +++ b/chrome/browser/extensions/active_tab_permission_granter.cc @@ -8,8 +8,8 @@  #include "chrome/browser/profiles/profile.h"  #include "content/public/browser/navigation_details.h"  #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/render_frame_host.h"  #include "content/public/browser/render_process_host.h" -#include "content/public/browser/render_view_host.h"  #include "content/public/browser/web_contents.h"  #include "extensions/browser/extension_registry.h"  #include "extensions/browser/process_manager.h" @@ -45,19 +45,19 @@ IPC::Message* CreateClearMessage(const std::vector<std::string>& ids,  }  // Sends a message exactly once to each render process host owning one of the -// given |view_hosts| and |tab_process|. If |tab_process| doesn't own any of the -// |view_hosts|, it will not be signaled to update its origin whitelist. +// given |frame_hosts| and |tab_process|. If |tab_process| doesn't own any of +// the |frame_hosts|, it will not be signaled to update its origin whitelist.  void SendMessageToProcesses( -    const std::set<content::RenderViewHost*>& view_hosts, +    const std::set<content::RenderFrameHost*>& frame_hosts,      content::RenderProcessHost* tab_process,      const CreateMessageFunction& create_message) {    std::set<content::RenderProcessHost*> sent_to_hosts; -  for (content::RenderViewHost* view_host : view_hosts) { -    content::RenderProcessHost* process_host = view_host->GetProcess(); +  for (content::RenderFrameHost* frame_host : frame_hosts) { +    content::RenderProcessHost* process_host = frame_host->GetProcess();      if (sent_to_hosts.count(process_host) == 0) {        // Extension processes have to update the origin whitelists.        process_host->Send(create_message.Run(true)); -      sent_to_hosts.insert(view_host->GetProcess()); +      sent_to_hosts.insert(frame_host->GetProcess());      }    }    // If the tab wasn't one of those processes already updated (it likely @@ -121,7 +121,7 @@ void ActiveTabPermissionGranter::GrantIfRequested(const Extension* extension) {                       tab_id_);        SendMessageToProcesses(            ProcessManager::Get(web_contents()->GetBrowserContext())-> -              GetRenderViewHostsForExtension(extension->id()), +              GetRenderFrameHostsForExtension(extension->id()),            web_contents()->GetRenderProcessHost(),            update_message); @@ -180,21 +180,22 @@ void ActiveTabPermissionGranter::ClearActiveExtensionsAndNotify() {    if (granted_extensions_.is_empty())      return; -  std::set<content::RenderViewHost*> view_hosts; +  std::set<content::RenderFrameHost*> frame_hosts;    std::vector<std::string> extension_ids;    ProcessManager* process_manager =        ProcessManager::Get(web_contents()->GetBrowserContext());    for (const scoped_refptr<const Extension>& extension : granted_extensions_) {      extension->permissions_data()->ClearTabSpecificPermissions(tab_id_);      extension_ids.push_back(extension->id()); -    std::set<content::RenderViewHost*> extension_view_hosts = -        process_manager->GetRenderViewHostsForExtension(extension->id()); -    view_hosts.insert(extension_view_hosts.begin(), extension_view_hosts.end()); +    std::set<content::RenderFrameHost*> extension_frame_hosts = +        process_manager->GetRenderFrameHostsForExtension(extension->id()); +    frame_hosts.insert(extension_frame_hosts.begin(), +                       extension_frame_hosts.end());    }    CreateMessageFunction clear_message =        base::Bind(&CreateClearMessage, extension_ids, tab_id_); -  SendMessageToProcesses(view_hosts, +  SendMessageToProcesses(frame_hosts,                           web_contents()->GetRenderProcessHost(),                           clear_message); diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc index 946ec7a..b48788b 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc @@ -138,13 +138,6 @@ GURL ToDataURL(const base::FilePath& path, developer_private::ItemType type) {    return GetImageURLFromData(contents);  } -std::string GetExtensionID(const content::RenderViewHost* render_view_host) { -  if (!render_view_host->GetSiteInstance()) -    return std::string(); - -  return render_view_host->GetSiteInstance()->GetSiteURL().host(); -} -  void BroadcastItemStateChanged(content::BrowserContext* browser_context,                                 developer::EventType event_type,                                 const std::string& item_id) { @@ -210,22 +203,16 @@ DeveloperPrivateAPI::DeveloperPrivateAPI(content::BrowserContext* context)  }  DeveloperPrivateEventRouter::DeveloperPrivateEventRouter(Profile* profile) -    : extension_registry_observer_(this), profile_(profile) { -  registrar_.Add(this, -                 extensions::NOTIFICATION_EXTENSION_VIEW_REGISTERED, -                 content::Source<Profile>(profile_)); -  registrar_.Add(this, -                 extensions::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED, -                 content::Source<Profile>(profile_)); - -  // TODO(limasdf): Use scoped_observer instead. -  ErrorConsole::Get(profile)->AddObserver(this); - +    : extension_registry_observer_(this), +      error_console_observer_(this), +      process_manager_observer_(this), +      profile_(profile) {    extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); +  error_console_observer_.Add(ErrorConsole::Get(profile)); +  process_manager_observer_.Add(ProcessManager::Get(profile));  }  DeveloperPrivateEventRouter::~DeveloperPrivateEventRouter() { -  ErrorConsole::Get(profile_)->RemoveObserver(this);  }  void DeveloperPrivateEventRouter::AddExtensionId( @@ -238,36 +225,6 @@ void DeveloperPrivateEventRouter::RemoveExtensionId(    extension_ids_.erase(extension_id);  } -void DeveloperPrivateEventRouter::Observe( -    int type, -    const content::NotificationSource& source, -    const content::NotificationDetails& details) { -  Profile* profile = content::Source<Profile>(source).ptr(); -  CHECK(profile); -  CHECK(profile_->IsSameProfile(profile)); -  developer::EventData event_data; - -  switch (type) { -    case extensions::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED: { -      event_data.event_type = developer::EVENT_TYPE_VIEW_UNREGISTERED; -      event_data.item_id = GetExtensionID( -          content::Details<const content::RenderViewHost>(details).ptr()); -      break; -    } -    case extensions::NOTIFICATION_EXTENSION_VIEW_REGISTERED: { -      event_data.event_type = developer::EVENT_TYPE_VIEW_REGISTERED; -      event_data.item_id = GetExtensionID( -          content::Details<const content::RenderViewHost>(details).ptr()); -      break; -    } -    default: -      NOTREACHED(); -      return; -  } - -  BroadcastItemStateChanged(profile, event_data.event_type, event_data.item_id); -} -  void DeveloperPrivateEventRouter::OnExtensionLoaded(      content::BrowserContext* browser_context,      const Extension* extension) { @@ -316,6 +273,20 @@ void DeveloperPrivateEventRouter::OnErrorAdded(const ExtensionError* error) {        profile_, developer::EVENT_TYPE_ERROR_ADDED, error->extension_id());  } +void DeveloperPrivateEventRouter::OnExtensionFrameRegistered( +    const std::string& extension_id, +    content::RenderFrameHost* render_frame_host) { +  BroadcastItemStateChanged( +      profile_, developer::EVENT_TYPE_VIEW_REGISTERED, extension_id); +} + +void DeveloperPrivateEventRouter::OnExtensionFrameUnregistered( +    const std::string& extension_id, +    content::RenderFrameHost* render_frame_host) { +  BroadcastItemStateChanged( +      profile_, developer::EVENT_TYPE_VIEW_UNREGISTERED, extension_id); +} +  void DeveloperPrivateAPI::SetLastUnpackedDirectory(const base::FilePath& path) {    last_unpacked_directory_ = path;  } diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.h b/chrome/browser/extensions/api/developer_private/developer_private_api.h index 707bc8d..8126d77 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api.h +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.h @@ -15,12 +15,10 @@  #include "chrome/browser/extensions/error_console/error_console.h"  #include "chrome/browser/extensions/extension_uninstall_dialog.h"  #include "chrome/browser/extensions/pack_extension_job.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -#include "content/public/browser/render_view_host.h"  #include "extensions/browser/browser_context_keyed_api_factory.h"  #include "extensions/browser/event_router.h"  #include "extensions/browser/extension_registry_observer.h" +#include "extensions/browser/process_manager_observer.h"  #include "storage/browser/fileapi/file_system_context.h"  #include "storage/browser/fileapi/file_system_operation.h"  #include "ui/shell_dialogs/select_file_dialog.h" @@ -33,6 +31,7 @@ class ExtensionError;  class ExtensionRegistry;  class ExtensionSystem;  class ManagementPolicy; +class ProcessManager;  class RequirementsChecker;  namespace api { @@ -61,9 +60,9 @@ typedef std::vector<linked_ptr<developer::ProjectInfo> > ProjectInfoList;  typedef std::vector<linked_ptr<developer::ItemInspectView> >      ItemInspectViewList; -class DeveloperPrivateEventRouter : public content::NotificationObserver, -                                    public ExtensionRegistryObserver, -                                    public ErrorConsole::Observer { +class DeveloperPrivateEventRouter : public ExtensionRegistryObserver, +                                    public ErrorConsole::Observer, +                                    public ProcessManagerObserver {   public:    explicit DeveloperPrivateEventRouter(Profile* profile);    ~DeveloperPrivateEventRouter() override; @@ -73,12 +72,7 @@ class DeveloperPrivateEventRouter : public content::NotificationObserver,    void RemoveExtensionId(const std::string& extension_id);   private: -  // content::NotificationObserver implementation. -  void Observe(int type, -               const content::NotificationSource& source, -               const content::NotificationDetails& details) override; - -  // ExtensionRegistryObserver implementation. +  // ExtensionRegistryObserver:    void OnExtensionLoaded(content::BrowserContext* browser_context,                           const Extension* extension) override;    void OnExtensionUnloaded(content::BrowserContext* browser_context, @@ -93,14 +87,22 @@ class DeveloperPrivateEventRouter : public content::NotificationObserver,                                const Extension* extension,                                extensions::UninstallReason reason) override; -  // ErrorConsole::Observer implementation. +  // ErrorConsole::Observer:    void OnErrorAdded(const ExtensionError* error) override; -  content::NotificationRegistrar registrar_; +  // ProcessManagerObserver: +  void OnExtensionFrameRegistered( +      const std::string& extension_id, +      content::RenderFrameHost* render_frame_host) override; +  void OnExtensionFrameUnregistered( +      const std::string& extension_id, +      content::RenderFrameHost* render_frame_host) override; -  ScopedObserver<extensions::ExtensionRegistry, -                 extensions::ExtensionRegistryObserver> +  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>        extension_registry_observer_; +  ScopedObserver<ErrorConsole, ErrorConsole::Observer> error_console_observer_; +  ScopedObserver<ProcessManager, ProcessManagerObserver> +      process_manager_observer_;    Profile* profile_; diff --git a/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc b/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc index 6bbccf2..431d4ab 100644 --- a/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc +++ b/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc @@ -6,6 +6,7 @@  #include "chrome/browser/profiles/profile.h"  #include "chrome/common/extensions/api/developer_private.h" +#include "content/public/browser/render_frame_host.h"  #include "content/public/browser/render_process_host.h"  #include "content/public/browser/render_view_host.h"  #include "content/public/browser/web_contents.h" @@ -105,7 +106,7 @@ void InspectableViewsFinder::GetViewsForExtensionForProfile(    // Get the extension process's active views.    GetViewsForExtensionProcess(        extension, -      process_manager->GetRenderViewHostsForExtension(extension.id()), +      process_manager->GetRenderFrameHostsForExtension(extension.id()),        is_incognito,        result);    // Get app window views, if not incognito. @@ -126,14 +127,14 @@ void InspectableViewsFinder::GetViewsForExtensionForProfile(  void InspectableViewsFinder::GetViewsForExtensionProcess(      const Extension& extension, -    const std::set<content::RenderViewHost*>& views, +    const std::set<content::RenderFrameHost*>& hosts,      bool is_incognito,      ViewList* result) { -  for (const content::RenderViewHost* host : views) { +  for (content::RenderFrameHost* host : hosts) {      content::WebContents* web_contents = -        content::WebContents::FromRenderViewHost(host); +        content::WebContents::FromRenderFrameHost(host);      ViewType host_type = GetViewType(web_contents); -    if (host == deleting_rvh_ || +    if (host->GetRenderViewHost() == deleting_rvh_ ||          host_type == VIEW_TYPE_EXTENSION_POPUP ||          host_type == VIEW_TYPE_EXTENSION_DIALOG) {        continue; @@ -144,7 +145,7 @@ void InspectableViewsFinder::GetViewsForExtensionProcess(      result->push_back(ConstructView(          url,          process->GetID(), -        host->GetRoutingID(), +        host->GetRenderViewHost()->GetRoutingID(),          is_incognito,          host_type));    } diff --git a/chrome/browser/extensions/api/developer_private/inspectable_views_finder.h b/chrome/browser/extensions/api/developer_private/inspectable_views_finder.h index 3cb50dd..70b5ea1 100644 --- a/chrome/browser/extensions/api/developer_private/inspectable_views_finder.h +++ b/chrome/browser/extensions/api/developer_private/inspectable_views_finder.h @@ -16,6 +16,7 @@ class Profile;  class GURL;  namespace content { +class RenderFrameHost;  class RenderViewHost;  } @@ -63,7 +64,7 @@ class InspectableViewsFinder {    // Returns all inspectable views for the extension process.    void GetViewsForExtensionProcess(        const Extension& extension, -      const std::set<content::RenderViewHost*>& views, +      const std::set<content::RenderFrameHost*>& frames,        bool is_incognito,        ViewList* result); diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc index f1db11c..91b7186 100644 --- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc +++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc @@ -259,11 +259,8 @@ ChromeContentBrowserClientExtensionsPart::ShouldTryToUseExistingProcessHost(        GetLoadedProfiles();    for (size_t i = 0; i < profiles.size(); ++i) {      ProcessManager* epm = ProcessManager::Get(profiles[i]); -    for (ProcessManager::const_iterator iter = epm->background_hosts().begin(); -         iter != epm->background_hosts().end(); ++iter) { -      const ExtensionHost* host = *iter; +    for (extensions::ExtensionHost* host : epm->background_hosts())        process_ids.insert(host->render_process_host()->GetID()); -    }    }    return (process_ids.size() > diff --git a/chrome/browser/extensions/chrome_process_manager_delegate.cc b/chrome/browser/extensions/chrome_process_manager_delegate.cc index e0d9875..e3d1354 100644 --- a/chrome/browser/extensions/chrome_process_manager_delegate.cc +++ b/chrome/browser/extensions/chrome_process_manager_delegate.cc @@ -113,7 +113,7 @@ void ChromeProcessManagerDelegate::OnBrowserWindowReady(Browser* browser) {    // a related incognito profile or other regular profiles.    ProcessManager* manager = ProcessManager::Get(profile);    DCHECK(manager); -  DCHECK_EQ(profile, manager->GetBrowserContext()); +  DCHECK_EQ(profile, manager->browser_context());    manager->MaybeCreateStartupBackgroundHosts();    // For incognito profiles also inform the original profile's process manager @@ -124,7 +124,7 @@ void ChromeProcessManagerDelegate::OnBrowserWindowReady(Browser* browser) {      Profile* original_profile = profile->GetOriginalProfile();      ProcessManager* original_manager = ProcessManager::Get(original_profile);      DCHECK(original_manager); -    DCHECK_EQ(original_profile, original_manager->GetBrowserContext()); +    DCHECK_EQ(original_profile, original_manager->browser_context());      original_manager->MaybeCreateStartupBackgroundHosts();    }  } diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index 2243400..777ad82 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc @@ -637,22 +637,17 @@ extensions::ExtensionHost* ExtensionBrowserTest::FindHostWithPath(      extensions::ProcessManager* manager,      const std::string& path,      int expected_hosts) { -  extensions::ExtensionHost* host = NULL; +  extensions::ExtensionHost* result_host = nullptr;    int num_hosts = 0; -  extensions::ProcessManager::ExtensionHostSet background_hosts = -      manager->background_hosts(); -  for (extensions::ProcessManager::const_iterator iter = -           background_hosts.begin(); -       iter != background_hosts.end(); -       ++iter) { -    if ((*iter)->GetURL().path() == path) { -      EXPECT_FALSE(host); -      host = *iter; +  for (extensions::ExtensionHost* host : manager->background_hosts()) { +    if (host->GetURL().path() == path) { +      EXPECT_FALSE(result_host); +      result_host = host;      }      num_hosts++;    }    EXPECT_EQ(expected_hosts, num_hosts); -  return host; +  return result_host;  }  std::string ExtensionBrowserTest::ExecuteScriptInBackgroundPage( diff --git a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc index 9a40df8..079c2c1 100644 --- a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc +++ b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc @@ -93,11 +93,11 @@ class ExtensionCrashRecoveryTestBase : public ExtensionBrowserTest {      extensions::ExtensionHost* extension_host = GetProcessManager()->          GetBackgroundHostForExtension(extension_id);      ASSERT_TRUE(extension_host); -    extensions::ProcessManager::ViewSet all_views = -        GetProcessManager()->GetAllViews(); -    extensions::ProcessManager::ViewSet::const_iterator it = -        all_views.find(extension_host->host_contents()->GetRenderViewHost()); -    ASSERT_FALSE(it == all_views.end()); +    extensions::ProcessManager::FrameSet frames = +        GetProcessManager()->GetAllFrames(); +    ASSERT_NE(frames.end(), +              frames.find(extension_host->host_contents()->GetMainFrame())); +    ASSERT_FALSE(GetProcessManager()->GetAllFrames().empty());      ASSERT_TRUE(extension_host->IsRenderViewLive());      extensions::ProcessMap* process_map =          extensions::ProcessMap::Get(browser()->profile()); diff --git a/chrome/browser/extensions/extension_test_notification_observer.cc b/chrome/browser/extensions/extension_test_notification_observer.cc index 403e6b9..da99e29 100644 --- a/chrome/browser/extensions/extension_test_notification_observer.cc +++ b/chrome/browser/extensions/extension_test_notification_observer.cc @@ -35,13 +35,11 @@ bool HasPageActionVisibilityReachedTarget(        target_visible_page_action_count;  } -bool HaveAllExtensionRenderViewHostsFinishedLoading( +bool HaveAllExtensionRenderFrameHostsFinishedLoading(      extensions::ProcessManager* manager) { -  extensions::ProcessManager::ViewSet all_views = manager->GetAllViews(); -  for (extensions::ProcessManager::ViewSet::const_iterator iter = -           all_views.begin(); -       iter != all_views.end(); ++iter) { -    if ((*iter)->IsLoading()) +  extensions::ProcessManager::FrameSet all_views = manager->GetAllFrames(); +  for (content::RenderFrameHost* host : manager->GetAllFrames()) { +    if (content::WebContents::FromRenderFrameHost(host)->IsLoading())        return false;    }    return true; @@ -150,7 +148,7 @@ bool ExtensionTestNotificationObserver::WaitForExtensionViewsToLoad() {    notification_set.Add(content::NOTIFICATION_WEB_CONTENTS_DESTROYED);    notification_set.Add(content::NOTIFICATION_LOAD_STOP);    WaitForCondition( -      base::Bind(&HaveAllExtensionRenderViewHostsFinishedLoading, manager), +      base::Bind(&HaveAllExtensionRenderFrameHostsFinishedLoading, manager),        ¬ification_set);    return true;  } diff --git a/chrome/browser/extensions/extension_util.cc b/chrome/browser/extensions/extension_util.cc index 4c3bb79..3491419 100644 --- a/chrome/browser/extensions/extension_util.cc +++ b/chrome/browser/extensions/extension_util.cc @@ -315,7 +315,7 @@ bool IsExtensionIdle(const std::string& extension_id,      if (site_instance && site_instance->HasProcess())        return false; -    if (!process_manager->GetRenderViewHostsForExtension(id).empty()) +    if (!process_manager->GetRenderFrameHostsForExtension(id).empty())        return false;    }    return true; diff --git a/chrome/browser/extensions/gtalk_extension_browsertest.cc b/chrome/browser/extensions/gtalk_extension_browsertest.cc deleted file mode 100644 index 7d5a6d7..0000000 --- a/chrome/browser/extensions/gtalk_extension_browsertest.cc +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/bind.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/extensions/extension_browsertest.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_commands.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/common/url_constants.h" -#include "content/public/test/browser_test_utils.h" -#include "extensions/browser/extension_host.h" -#include "extensions/browser/extension_system.h" -#include "extensions/browser/process_manager.h" -#include "extensions/common/constants.h" - -using content::RenderViewHost; -using content::WebContents; -using extensions::Extension; - -class GtalkExtensionTest : public ExtensionBrowserTest { - protected: -  extensions::ProcessManager* GetProcessManager() { -    return extensions::ExtensionSystem::Get(browser()->profile())-> -        process_manager(); -  } - -  void InstallGtalkExtension(const std::string& version) { -    const Extension* extension = InstallExtensionWithUIAutoConfirm( -        test_data_dir_.AppendASCII("gtalk").AppendASCII(version + ".crx"), -        1, browser()); -    installed_extension_id_ = extension->id(); -  } - -  const std::string& GetInstalledExtensionId() { -    return installed_extension_id_; -  } - -  RenderViewHost* GetViewer() { -    std::vector<RenderViewHost*> views = GetMatchingViews(GetViewerUrl()); -    EXPECT_EQ(1U, views.size()); -    if (views.empty()) -      return NULL; -    return views.front(); -  } - -  std::string GetViewerUrl() { -    return std::string(extensions::kExtensionScheme) + -        url::kStandardSchemeSeparator + GetInstalledExtensionId() + -        "/viewer.html"; -  } - -  std::vector<RenderViewHost*> GetMatchingViews(const std::string& url_query) { -    extensions::ProcessManager* manager = GetProcessManager(); -    extensions::ProcessManager::ViewSet all_views = manager->GetAllViews(); -    std::vector<RenderViewHost*> matching_views; -    for (extensions::ProcessManager::ViewSet::const_iterator iter = -         all_views.begin(); iter != all_views.end(); ++iter) { -      WebContents* web_contents = WebContents::FromRenderViewHost(*iter); -      std::string url = web_contents->GetURL().spec(); -      if (url.find(url_query) != std::string::npos) -        matching_views.push_back(*iter); -    } -    return matching_views; -  } - -  std::string ReadCurrentVersion() { -    std::string response; -    EXPECT_TRUE(base::ReadFileToString( -      test_data_dir_.AppendASCII("gtalk").AppendASCII("current_version"), -      &response)); -    return response; -  } - - private: -  std::string installed_extension_id_; -}; - -IN_PROC_BROWSER_TEST_F(GtalkExtensionTest, InstallCurrent) { -  content::WindowedNotificationObserver panel_loaded( -      extensions::NOTIFICATION_EXTENSION_VIEW_REGISTERED, -      content::NotificationService::AllSources()); -  InstallGtalkExtension(ReadCurrentVersion()); -  panel_loaded.Wait(); -  ASSERT_TRUE(GetViewer()); -} diff --git a/chrome/browser/extensions/process_management_browsertest.cc b/chrome/browser/extensions/process_management_browsertest.cc index 3515540..67ef9e8 100644 --- a/chrome/browser/extensions/process_management_browsertest.cc +++ b/chrome/browser/extensions/process_management_browsertest.cc @@ -226,11 +226,8 @@ IN_PROC_BROWSER_TEST_F(ProcessManagementTest, MAYBE_ExtensionProcessBalancing) {    std::set<int> process_ids;    Profile* profile = browser()->profile();    extensions::ProcessManager* epm = extensions::ProcessManager::Get(profile); -  for (extensions::ProcessManager::const_iterator iter = -           epm->background_hosts().begin(); -       iter != epm->background_hosts().end(); ++iter) { -    process_ids.insert((*iter)->render_process_host()->GetID()); -  } +  for (extensions::ExtensionHost* host : epm->background_hosts()) +    process_ids.insert(host->render_process_host()->GetID());    // We've loaded 5 extensions with background pages, 1 extension without    // background page, and one isolated app. We expect only 2 unique processes diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc index 5bbc2aa..c8a8e00 100644 --- a/chrome/browser/extensions/process_manager_browsertest.cc +++ b/chrome/browser/extensions/process_manager_browsertest.cc @@ -30,7 +30,7 @@ IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,    // We start with no background hosts.    ASSERT_EQ(0u, pm->background_hosts().size()); -  ASSERT_EQ(0u, pm->GetAllViews().size()); +  ASSERT_EQ(0u, pm->GetAllFrames().size());    // Load an extension with a background page.    scoped_refptr<const Extension> extension = @@ -41,10 +41,10 @@ IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,    // Process manager gains a background host.    EXPECT_EQ(1u, pm->background_hosts().size()); -  EXPECT_EQ(1u, pm->GetAllViews().size()); +  EXPECT_EQ(1u, pm->GetAllFrames().size());    EXPECT_TRUE(pm->GetBackgroundHostForExtension(extension->id()));    EXPECT_TRUE(pm->GetSiteInstanceForURL(extension->url())); -  EXPECT_EQ(1u, pm->GetRenderViewHostsForExtension(extension->id()).size()); +  EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());    EXPECT_FALSE(pm->IsBackgroundHostClosing(extension->id()));    EXPECT_EQ(0, pm->GetLazyKeepaliveCount(extension.get())); @@ -53,10 +53,10 @@ IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,    // Background host disappears.    EXPECT_EQ(0u, pm->background_hosts().size()); -  EXPECT_EQ(0u, pm->GetAllViews().size()); +  EXPECT_EQ(0u, pm->GetAllFrames().size());    EXPECT_FALSE(pm->GetBackgroundHostForExtension(extension->id()));    EXPECT_TRUE(pm->GetSiteInstanceForURL(extension->url())); -  EXPECT_EQ(0u, pm->GetRenderViewHostsForExtension(extension->id()).size()); +  EXPECT_EQ(0u, pm->GetRenderFrameHostsForExtension(extension->id()).size());    EXPECT_FALSE(pm->IsBackgroundHostClosing(extension->id()));    EXPECT_EQ(0, pm->GetLazyKeepaliveCount(extension.get()));  } @@ -79,9 +79,9 @@ IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,    // No background host was added.    EXPECT_EQ(0u, pm->background_hosts().size()); -  EXPECT_EQ(0u, pm->GetAllViews().size()); +  EXPECT_EQ(0u, pm->GetAllFrames().size());    EXPECT_FALSE(pm->GetBackgroundHostForExtension(popup->id())); -  EXPECT_EQ(0u, pm->GetRenderViewHostsForExtension(popup->id()).size()); +  EXPECT_EQ(0u, pm->GetRenderFrameHostsForExtension(popup->id()).size());    EXPECT_TRUE(pm->GetSiteInstanceForURL(popup->url()));    EXPECT_FALSE(pm->IsBackgroundHostClosing(popup->id()));    EXPECT_EQ(0, pm->GetLazyKeepaliveCount(popup.get())); @@ -98,9 +98,9 @@ IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest,    // We now have a view, but still no background hosts.    EXPECT_EQ(0u, pm->background_hosts().size()); -  EXPECT_EQ(1u, pm->GetAllViews().size()); +  EXPECT_EQ(1u, pm->GetAllFrames().size());    EXPECT_FALSE(pm->GetBackgroundHostForExtension(popup->id())); -  EXPECT_EQ(1u, pm->GetRenderViewHostsForExtension(popup->id()).size()); +  EXPECT_EQ(1u, pm->GetRenderFrameHostsForExtension(popup->id()).size());    EXPECT_TRUE(pm->GetSiteInstanceForURL(popup->url()));    EXPECT_FALSE(pm->IsBackgroundHostClosing(popup->id()));    EXPECT_EQ(0, pm->GetLazyKeepaliveCount(popup.get())); @@ -114,7 +114,7 @@ IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, HttpHostMatchingExtensionId) {    // We start with no background hosts.    ASSERT_EQ(0u, pm->background_hosts().size()); -  ASSERT_EQ(0u, pm->GetAllViews().size()); +  ASSERT_EQ(0u, pm->GetAllFrames().size());    // Load an extension with a background page.    scoped_refptr<const Extension> extension = @@ -144,13 +144,12 @@ IN_PROC_BROWSER_TEST_F(ProcessManagerBrowserTest, HttpHostMatchingExtensionId) {    content::WebContents* tab_web_contents =        browser()->tab_strip_model()->GetActiveWebContents();    EXPECT_EQ(url, tab_web_contents->GetVisibleURL()); -  EXPECT_TRUE(NULL == pm->GetExtensionForRenderViewHost( -                          tab_web_contents->GetRenderViewHost())) +  EXPECT_FALSE(pm->GetExtensionForWebContents(tab_web_contents))        << "Non-extension content must not have an associated extension"; -  ASSERT_EQ(1u, pm->GetRenderViewHostsForExtension(extension->id()).size()); +  ASSERT_EQ(1u, pm->GetRenderFrameHostsForExtension(extension->id()).size());    content::WebContents* extension_web_contents = -      content::WebContents::FromRenderViewHost( -          *pm->GetRenderViewHostsForExtension(extension->id()).begin()); +      content::WebContents::FromRenderFrameHost( +          *pm->GetRenderFrameHostsForExtension(extension->id()).begin());    EXPECT_TRUE(extension_web_contents->GetSiteInstance() !=                tab_web_contents->GetSiteInstance());    EXPECT_TRUE(pm->GetSiteInstanceForURL(extension->url()) != diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index 902e514..05c0694 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc @@ -1802,23 +1802,23 @@ IN_PROC_BROWSER_TEST_F(PolicyTest, ExtensionInstallForcelist) {    // have been loaded.    extensions::ProcessManager* manager =        extensions::ProcessManager::Get(browser()->profile()); -  extensions::ProcessManager::ViewSet all_views = manager->GetAllViews(); -  for (extensions::ProcessManager::ViewSet::const_iterator iter = -           all_views.begin(); -       iter != all_views.end();) { -    if (!(*iter)->IsLoading()) { +  extensions::ProcessManager::FrameSet all_frames = manager->GetAllFrames(); +  for (extensions::ProcessManager::FrameSet::const_iterator iter = +           all_frames.begin(); +       iter != all_frames.end();) { +    content::WebContents* web_contents = +        content::WebContents::FromRenderFrameHost(*iter); +    ASSERT_TRUE(web_contents); +    if (!web_contents->IsLoading()) {        ++iter;      } else { -      content::WebContents* web_contents = -          content::WebContents::FromRenderViewHost(*iter); -      ASSERT_TRUE(web_contents);        WebContentsLoadedOrDestroyedWatcher(web_contents).Wait();        // Test activity may have modified the set of extension processes during        // message processing, so re-start the iteration to catch added/removed        // processes. -      all_views = manager->GetAllViews(); -      iter = all_views.begin(); +      all_frames = manager->GetAllFrames(); +      iter = all_frames.begin();      }    } diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index b6d877e..6946015 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc @@ -633,8 +633,7 @@ void RenderViewContextMenu::AppendPrintPreviewItems() {  const Extension* RenderViewContextMenu::GetExtension() const {    return extensions::ProcessManager::Get(browser_context_) -      ->GetExtensionForRenderViewHost( -          source_web_contents_->GetRenderViewHost()); +      ->GetExtensionForWebContents(source_web_contents_);  }  void RenderViewContextMenu::AppendDeveloperItems() { diff --git a/chrome/browser/task_manager/extension_information.cc b/chrome/browser/task_manager/extension_information.cc index 6dcf014..df1f0e3 100644 --- a/chrome/browser/task_manager/extension_information.cc +++ b/chrome/browser/task_manager/extension_information.cc @@ -31,7 +31,7 @@ namespace {  const Extension* GetExtensionForWebContents(WebContents* web_contents) {    return extensions::ProcessManager::Get(web_contents->GetBrowserContext()) -      ->GetExtensionForRenderViewHost(web_contents->GetRenderViewHost()); +      ->GetExtensionForWebContents(web_contents);  }  }  // namespace @@ -124,11 +124,10 @@ void ExtensionInformation::GetAll(const NewWebContentsCallback& callback) {    }    for (size_t i = 0; i < profiles.size(); ++i) { -    const extensions::ProcessManager::ViewSet all_views = -        extensions::ProcessManager::Get(profiles[i])->GetAllViews(); -    extensions::ProcessManager::ViewSet::const_iterator jt = all_views.begin(); -    for (; jt != all_views.end(); ++jt) { -      WebContents* web_contents = WebContents::FromRenderViewHost(*jt); +    const extensions::ProcessManager::FrameSet all_frames = +        extensions::ProcessManager::Get(profiles[i])->GetAllFrames(); +    for (content::RenderFrameHost* host : all_frames) { +      WebContents* web_contents = WebContents::FromRenderFrameHost(host);        if (CheckOwnership(web_contents))          callback.Run(web_contents);      } diff --git a/chrome/browser/ui/ash/media_delegate_chromeos.cc b/chrome/browser/ui/ash/media_delegate_chromeos.cc index 53cc92f..3ea4aa4 100644 --- a/chrome/browser/ui/ash/media_delegate_chromeos.cc +++ b/chrome/browser/ui/ash/media_delegate_chromeos.cc @@ -76,15 +76,11 @@ void GetExtensionMediaCaptureState(      const MediaStreamCaptureIndicator* indicator,      content::BrowserContext* context,      int* media_state_out) { -  const extensions::ProcessManager::ViewSet view_set = -      extensions::ProcessManager::Get(context)->GetAllViews(); -  for (extensions::ProcessManager::ViewSet::const_iterator iter = -           view_set.begin(); -       iter != view_set.end(); -       ++iter) { +  for (content::RenderFrameHost* host : +           extensions::ProcessManager::Get(context)->GetAllFrames()) {      content::WebContents* web_contents = -        content::WebContents::FromRenderViewHost(*iter); -    // RVH may not have web contents. +        content::WebContents::FromRenderFrameHost(host); +    // RFH may not have web contents.      if (!web_contents)        continue;      GetMediaCaptureState(indicator, web_contents, media_state_out); diff --git a/chrome/test/data/extensions/gtalk/1.2013.0404.1.crx b/chrome/test/data/extensions/gtalk/1.2013.0404.1.crxBinary files differ deleted file mode 100644 index f6fdac4..0000000 --- a/chrome/test/data/extensions/gtalk/1.2013.0404.1.crx +++ /dev/null diff --git a/chrome/test/data/extensions/gtalk/1.2013.0417.1.crx b/chrome/test/data/extensions/gtalk/1.2013.0417.1.crxBinary files differ deleted file mode 100644 index d27b706..0000000 --- a/chrome/test/data/extensions/gtalk/1.2013.0417.1.crx +++ /dev/null diff --git a/chrome/test/data/extensions/gtalk/current_version b/chrome/test/data/extensions/gtalk/current_version deleted file mode 100644 index 16b978e..0000000 --- a/chrome/test/data/extensions/gtalk/current_version +++ /dev/null @@ -1 +0,0 @@ -1.2013.0404.1
\ No newline at end of file diff --git a/chrome/test/data/extensions/gtalk/rc_version b/chrome/test/data/extensions/gtalk/rc_version deleted file mode 100644 index 34ebd5f..0000000 --- a/chrome/test/data/extensions/gtalk/rc_version +++ /dev/null @@ -1 +0,0 @@ -1.2013.0417.1
\ No newline at end of file diff --git a/components/renderer_context_menu/context_menu_content_type.cc b/components/renderer_context_menu/context_menu_content_type.cc index 60ed1df..6687891 100644 --- a/components/renderer_context_menu/context_menu_content_type.cc +++ b/components/renderer_context_menu/context_menu_content_type.cc @@ -52,8 +52,8 @@ ContextMenuContentType::~ContextMenuContentType() {  const Extension* ContextMenuContentType::GetExtension() const {    ProcessManager* process_manager =        ProcessManager::Get(source_web_contents_->GetBrowserContext()); -  return process_manager->GetExtensionForRenderViewHost( -      source_web_contents_->GetRenderViewHost()); +  return process_manager->GetExtensionForWebContents( +      source_web_contents_);  }  #endif diff --git a/extensions/browser/app_window/app_window.cc b/extensions/browser/app_window/app_window.cc index 0689b13..fc56bae 100644 --- a/extensions/browser/app_window/app_window.cc +++ b/extensions/browser/app_window/app_window.cc @@ -253,6 +253,7 @@ void AppWindow::Init(const GURL& url,    app_window_contents_->Initialize(browser_context(), url);    content::WebContentsObserver::Observe(web_contents()); +  SetViewType(web_contents(), VIEW_TYPE_APP_WINDOW);    app_delegate_->InitWebContents(web_contents());    WebContentsModalDialogManager::CreateForWebContents(web_contents()); @@ -260,7 +261,6 @@ void AppWindow::Init(const GURL& url,    web_contents()->SetDelegate(this);    WebContentsModalDialogManager::FromWebContents(web_contents())        ->SetDelegate(this); -  SetViewType(web_contents(), VIEW_TYPE_APP_WINDOW);    // Initialize the window    CreateParams new_params = LoadDefaults(params); diff --git a/extensions/browser/extension_web_contents_observer.cc b/extensions/browser/extension_web_contents_observer.cc index 020cc32..dd0a628 100644 --- a/extensions/browser/extension_web_contents_observer.cc +++ b/extensions/browser/extension_web_contents_observer.cc @@ -5,6 +5,7 @@  #include "extensions/browser/extension_web_contents_observer.h"  #include "content/public/browser/child_process_security_policy.h" +#include "content/public/browser/render_frame_host.h"  #include "content/public/browser/render_process_host.h"  #include "content/public/browser/render_view_host.h"  #include "content/public/browser/site_instance.h" @@ -13,6 +14,7 @@  #include "extensions/browser/extension_prefs.h"  #include "extensions/browser/extension_registry.h"  #include "extensions/browser/mojo/service_registration.h" +#include "extensions/browser/process_manager.h"  #include "extensions/browser/view_type_utils.h"  #include "extensions/common/constants.h"  #include "extensions/common/extension_messages.h" @@ -24,9 +26,13 @@ ExtensionWebContentsObserver::ExtensionWebContentsObserver(      : content::WebContentsObserver(web_contents),        browser_context_(web_contents->GetBrowserContext()) {    NotifyRenderViewType(web_contents->GetRenderViewHost()); +  content::RenderFrameHost* host = web_contents->GetMainFrame(); +  if (host) +    RenderFrameHostChanged(nullptr, host);  } -ExtensionWebContentsObserver::~ExtensionWebContentsObserver() {} +ExtensionWebContentsObserver::~ExtensionWebContentsObserver() { +}  void ExtensionWebContentsObserver::RenderViewCreated(      content::RenderViewHost* render_view_host) { @@ -95,6 +101,26 @@ void ExtensionWebContentsObserver::RenderFrameCreated(    RegisterCoreExtensionServices(render_frame_host);  } +void ExtensionWebContentsObserver::FrameDeleted( +    content::RenderFrameHost* render_frame_host) { +  ProcessManager::Get(browser_context_)->UnregisterRenderFrameHost( +      render_frame_host); +} + +void ExtensionWebContentsObserver::RenderFrameHostChanged( +    content::RenderFrameHost* old_host, +    content::RenderFrameHost* new_host) { +  ProcessManager* process_manager = ProcessManager::Get(browser_context_); +  if (old_host) +    process_manager->UnregisterRenderFrameHost(old_host); + +  const Extension* extension = GetExtension(new_host->GetRenderViewHost()); +  if (extension) { +    process_manager->RegisterRenderFrameHost( +        web_contents(), new_host, extension); +  } +} +  void ExtensionWebContentsObserver::NotifyRenderViewType(      content::RenderViewHost* render_view_host) {    if (render_view_host) { diff --git a/extensions/browser/extension_web_contents_observer.h b/extensions/browser/extension_web_contents_observer.h index cd48560..993a8fe 100644 --- a/extensions/browser/extension_web_contents_observer.h +++ b/extensions/browser/extension_web_contents_observer.h @@ -42,6 +42,13 @@ class ExtensionWebContentsObserver : public content::WebContentsObserver {    void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; +  // Per the documentation in WebContentsObserver, these two methods are +  // appropriate to track the set of current RenderFrameHosts. +  // NOTE: FrameDeleted() != RenderFrameDeleted(). +  void FrameDeleted(content::RenderFrameHost* render_frame_host) override; +  void RenderFrameHostChanged(content::RenderFrameHost* old_host, +                              content::RenderFrameHost* new_host) override; +    // Returns the extension or app associated with a render view host. Returns    // NULL if the render view host is not for a valid extension.    const Extension* GetExtension(content::RenderViewHost* render_view_host); diff --git a/extensions/browser/guest_view/guest_view_base.cc b/extensions/browser/guest_view/guest_view_base.cc index 899037d..bbbc5cc 100644 --- a/extensions/browser/guest_view/guest_view_base.cc +++ b/extensions/browser/guest_view/guest_view_base.cc @@ -202,8 +202,7 @@ void GuestViewBase::Init(const base::DictionaryValue& create_params,    const Extension* owner_extension =        ProcessManager::Get(owner_web_contents()->GetBrowserContext())-> -          GetExtensionForRenderViewHost( -              owner_web_contents()->GetRenderViewHost()); +          GetExtensionForWebContents(owner_web_contents());    owner_extension_id_ = owner_extension ? owner_extension->id() : std::string();    // Ok for |owner_extension| to be nullptr, the embedder might be WebUI. diff --git a/extensions/browser/notification_types.h b/extensions/browser/notification_types.h index a5908ed..031cb0c 100644 --- a/extensions/browser/notification_types.h +++ b/extensions/browser/notification_types.h @@ -157,14 +157,6 @@ enum NotificationType {    // associated window.    NOTIFICATION_EXTENSION_COMMAND_PAGE_ACTION_MAC, -  // A new extension RenderViewHost has been registered. The details are -  // the RenderViewHost*. -  NOTIFICATION_EXTENSION_VIEW_REGISTERED, - -  // An extension RenderViewHost has been unregistered. The details are -  // the RenderViewHost*. -  NOTIFICATION_EXTENSION_VIEW_UNREGISTERED, -    // Sent by an extension to notify the browser about the results of a unit    // test.    NOTIFICATION_EXTENSION_TEST_PASSED, diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc index 5ba41c4..47f7b19 100644 --- a/extensions/browser/process_manager.cc +++ b/extensions/browser/process_manager.cc @@ -5,16 +5,12 @@  #include "extensions/browser/process_manager.h"  #include "base/bind.h" -#include "base/command_line.h" -#include "base/lazy_instance.h"  #include "base/logging.h"  #include "base/message_loop/message_loop.h"  #include "base/metrics/histogram_macros.h"  #include "base/stl_util.h" -#include "base/strings/string_number_conversions.h"  #include "base/time/time.h"  #include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_thread.h"  #include "content/public/browser/devtools_agent_host.h"  #include "content/public/browser/notification_service.h"  #include "content/public/browser/render_frame_host.h" @@ -22,10 +18,6 @@  #include "content/public/browser/render_view_host.h"  #include "content/public/browser/site_instance.h"  #include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_delegate.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" -#include "content/public/common/renderer_preferences.h"  #include "content/public/common/url_constants.h"  #include "extensions/browser/extension_host.h"  #include "extensions/browser/extension_registry.h" @@ -44,15 +36,6 @@  #include "extensions/common/one_shot_event.h"  using content::BrowserContext; -using content::RenderViewHost; -using content::SiteInstance; -using content::WebContents; - -namespace extensions { -class RenderViewHostDestructionObserver; -} -DEFINE_WEB_CONTENTS_USER_DATA_KEY( -    extensions::RenderViewHostDestructionObserver);  namespace extensions { @@ -68,13 +51,13 @@ unsigned g_event_page_idle_time_msec = 10000;  // sending a Suspend message.  unsigned g_event_page_suspending_time_msec = 5000; -std::string GetExtensionID(RenderViewHost* render_view_host) { -  // This works for both apps and extensions because the site has been -  // normalized to the extension URL for hosted apps. -  content::SiteInstance* site_instance = render_view_host->GetSiteInstance(); +std::string GetExtensionIdForSiteInstance( +    content::SiteInstance* site_instance) {    if (!site_instance)      return std::string(); +  // This works for both apps and extensions because the site has been +  // normalized to the extension URL for hosted apps.    const GURL& site_url = site_instance->GetSiteURL();    if (!site_url.SchemeIs(kExtensionScheme) && @@ -84,33 +67,23 @@ std::string GetExtensionID(RenderViewHost* render_view_host) {    return site_url.host();  } -std::string GetExtensionIDFromFrame( -    content::RenderFrameHost* render_frame_host) { -  // This works for both apps and extensions because the site has been -  // normalized to the extension URL for apps. -  if (!render_frame_host->GetSiteInstance()) -    return std::string(); - -  return render_frame_host->GetSiteInstance()->GetSiteURL().host(); +std::string GetExtensionID(content::RenderFrameHost* render_frame_host) { +  CHECK(render_frame_host); +  return GetExtensionIdForSiteInstance(render_frame_host->GetSiteInstance());  }  bool IsFrameInExtensionHost(ExtensionHost* extension_host,                              content::RenderFrameHost* render_frame_host) { -  return WebContents::FromRenderFrameHost(render_frame_host) == +  return content::WebContents::FromRenderFrameHost(render_frame_host) ==        extension_host->host_contents();  } -void OnRenderViewHostUnregistered(BrowserContext* context, -                                  RenderViewHost* render_view_host) { -  content::NotificationService::current()->Notify( -      extensions::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED, -      content::Source<BrowserContext>(context), -      content::Details<RenderViewHost>(render_view_host)); -} -  // Incognito profiles use this process manager. It is mostly a shim that decides  // whether to fall back on the original profile's ProcessManager based  // on whether a given extension uses "split" or "spanning" incognito behavior. +// TODO(devlin): Given how little this does and the amount of cruft it adds to +// the .h file (in the form of protected members), we should consider just +// moving the incognito logic into the base class.  class IncognitoProcessManager : public ProcessManager {   public:    IncognitoProcessManager(BrowserContext* incognito_context, @@ -119,7 +92,8 @@ class IncognitoProcessManager : public ProcessManager {    ~IncognitoProcessManager() override {}    bool CreateBackgroundHost(const Extension* extension,                              const GURL& url) override; -  scoped_refptr<SiteInstance> GetSiteInstanceForURL(const GURL& url) override; +  scoped_refptr<content::SiteInstance> GetSiteInstanceForURL(const GURL& url) +      override;   private:    DISALLOW_COPY_AND_ASSIGN(IncognitoProcessManager); @@ -135,31 +109,6 @@ static void CreateBackgroundHostForExtensionLoad(  }  // namespace -class RenderViewHostDestructionObserver -    : public content::WebContentsObserver, -      public content::WebContentsUserData<RenderViewHostDestructionObserver> { - public: -  ~RenderViewHostDestructionObserver() override {} - - private: -  explicit RenderViewHostDestructionObserver(WebContents* web_contents) -      : WebContentsObserver(web_contents) { -    BrowserContext* context = web_contents->GetBrowserContext(); -    process_manager_ = ProcessManager::Get(context); -  } - -  friend class content::WebContentsUserData<RenderViewHostDestructionObserver>; - -  // content::WebContentsObserver overrides. -  void RenderViewDeleted(RenderViewHost* render_view_host) override { -    process_manager_->UnregisterRenderViewHost(render_view_host); -  } - -  ProcessManager* process_manager_; - -  DISALLOW_COPY_AND_ASSIGN(RenderViewHostDestructionObserver); -}; -  struct ProcessManager::BackgroundPageData {    // The count of things keeping the lazy background page alive.    int lazy_keepalive_count; @@ -192,15 +141,15 @@ struct ProcessManager::BackgroundPageData {          close_sequence_id(0) {}  }; -// Data of a RenderViewHost associated with an extension. -struct ProcessManager::ExtensionRenderViewData { +// Data of a RenderFrameHost associated with an extension. +struct ProcessManager::ExtensionRenderFrameData {    // The type of the view.    extensions::ViewType view_type;    // Whether the view is keeping the lazy background page alive or not.    bool has_keepalive; -  ExtensionRenderViewData() +  ExtensionRenderFrameData()        : view_type(VIEW_TYPE_INVALID), has_keepalive(false) {}    // Returns whether the view can keep the lazy background page alive or not. @@ -279,30 +228,31 @@ ProcessManager* ProcessManager::CreateIncognitoForTesting(  ProcessManager::ProcessManager(BrowserContext* context,                                 BrowserContext* original_context,                                 ExtensionRegistry* extension_registry) -    : site_instance_(SiteInstance::Create(context)), -      extension_registry_(extension_registry), +    : extension_registry_(extension_registry), +      site_instance_(content::SiteInstance::Create(context)), +      browser_context_(context),        startup_background_hosts_created_(false), -      devtools_callback_(base::Bind(&ProcessManager::OnDevToolsStateChanged, -                                    base::Unretained(this))),        last_background_close_sequence_id_(0),        weak_ptr_factory_(this) {    // ExtensionRegistry is shared between incognito and regular contexts.    DCHECK_EQ(original_context, extension_registry_->browser_context());    extension_registry_->AddObserver(this); -  registrar_.Add(this, + +  if (!context->IsOffTheRecord()) { +    // Only the original profile needs to listen for ready to create background +    // pages for all spanning extensions. +    registrar_.Add(this,                   extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,                   content::Source<BrowserContext>(original_context)); +  }    registrar_.Add(this,                   extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED,                   content::Source<BrowserContext>(context));    registrar_.Add(this,                   extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,                   content::Source<BrowserContext>(context)); -  registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, -                 content::NotificationService::AllSources()); -  registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, -                 content::NotificationService::AllSources()); - +  devtools_callback_ = base::Bind(&ProcessManager::OnDevToolsStateChanged, +                                  weak_ptr_factory_.GetWeakPtr());    content::DevToolsAgentHost::AddAgentStateCallback(devtools_callback_);    OnKeepaliveImpulseCheck(); @@ -315,13 +265,68 @@ ProcessManager::~ProcessManager() {    content::DevToolsAgentHost::RemoveAgentStateCallback(devtools_callback_);  } -const ProcessManager::ViewSet ProcessManager::GetAllViews() const { -  ViewSet result; -  for (ExtensionRenderViews::const_iterator iter = -           all_extension_views_.begin(); -       iter != all_extension_views_.end(); ++iter) { -    result.insert(iter->first); +void ProcessManager::RegisterRenderFrameHost( +    content::WebContents* web_contents, +    content::RenderFrameHost* render_frame_host, +    const Extension* extension) { +  ExtensionRenderFrameData* data = &all_extension_frames_[render_frame_host]; +  data->view_type = GetViewType(web_contents); + +  // Keep the lazy background page alive as long as any non-background-page +  // extension views are visible. Keepalive count balanced in +  // UnregisterRenderFrame. +  AcquireLazyKeepaliveCountForFrame(render_frame_host); + +  FOR_EACH_OBSERVER(ProcessManagerObserver, +                    observer_list_, +                    OnExtensionFrameRegistered(extension->id(), +                                               render_frame_host)); +} + +void ProcessManager::UnregisterRenderFrameHost( +    content::RenderFrameHost* render_frame_host) { +  ExtensionRenderFrames::iterator frame = +      all_extension_frames_.find(render_frame_host); + +  if (frame != all_extension_frames_.end()) { +    std::string extension_id = GetExtensionID(render_frame_host); +    // Keepalive count, balanced in RegisterRenderFrame. +    ReleaseLazyKeepaliveCountForFrame(render_frame_host); +    all_extension_frames_.erase(frame); + +    FOR_EACH_OBSERVER(ProcessManagerObserver, +                      observer_list_, +                      OnExtensionFrameUnregistered(extension_id, +                                                   render_frame_host)); +  } +} + +scoped_refptr<content::SiteInstance> ProcessManager::GetSiteInstanceForURL( +    const GURL& url) { +  return make_scoped_refptr(site_instance_->GetRelatedSiteInstance(url)); +} + +const ProcessManager::FrameSet ProcessManager::GetAllFrames() const { +  FrameSet result; +  for (const auto& key_value : all_extension_frames_) +    result.insert(key_value.first); +  return result; +} + +ProcessManager::FrameSet ProcessManager::GetRenderFrameHostsForExtension( +    const std::string& extension_id) { +  FrameSet result; +  scoped_refptr<content::SiteInstance> site_instance(GetSiteInstanceForURL( +      Extension::GetBaseURLFromExtensionId(extension_id))); +  if (!site_instance.get()) +    return result; + +  // Gather up all the frames for that site. +  for (const auto& key_value : all_extension_frames_) { +    if (key_value.first->GetSiteInstance() == site_instance) +      result.insert(key_value.first);    } +    return result;  } @@ -343,7 +348,7 @@ bool ProcessManager::CreateBackgroundHost(const Extension* extension,    // Don't create hosts if the embedder doesn't allow it.    ProcessManagerDelegate* delegate =        ExtensionsBrowserClient::Get()->GetProcessManagerDelegate(); -  if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext())) +  if (delegate && !delegate->IsBackgroundPageAllowed(browser_context_))      return false;    // Don't create multiple background hosts for an extension. @@ -358,113 +363,47 @@ bool ProcessManager::CreateBackgroundHost(const Extension* extension,    return true;  } -ExtensionHost* ProcessManager::GetBackgroundHostForExtension( -    const std::string& extension_id) { -  for (ExtensionHostSet::iterator iter = background_hosts_.begin(); -       iter != background_hosts_.end(); ++iter) { -    ExtensionHost* host = *iter; -    if (host->extension_id() == extension_id) -      return host; -  } -  return NULL; -} - -std::set<RenderViewHost*> ProcessManager::GetRenderViewHostsForExtension( -    const std::string& extension_id) { -  std::set<RenderViewHost*> result; - -  scoped_refptr<SiteInstance> site_instance(GetSiteInstanceForURL( -      Extension::GetBaseURLFromExtensionId(extension_id))); -  if (!site_instance.get()) -    return result; - -  // Gather up all the views for that site. -  for (ExtensionRenderViews::iterator view = all_extension_views_.begin(); -       view != all_extension_views_.end(); ++view) { -    if (view->first->GetSiteInstance() == site_instance) -      result.insert(view->first); -  } - -  return result; -} - -const Extension* ProcessManager::GetExtensionForRenderViewHost( -    RenderViewHost* render_view_host) { -  if (!render_view_host->GetSiteInstance()) -    return NULL; - -  return extension_registry_->enabled_extensions().GetByID( -      GetExtensionID(render_view_host)); -} - -void ProcessManager::AcquireLazyKeepaliveCountForView( -    content::RenderViewHost* render_view_host) { -  auto it = all_extension_views_.find(render_view_host); -  if (it == all_extension_views_.end()) +void ProcessManager::MaybeCreateStartupBackgroundHosts() { +  if (startup_background_hosts_created_)      return; -  ExtensionRenderViewData* data = &it->second; -  if (data->CanKeepalive() && !data->has_keepalive) { -    const Extension* extension = -        GetExtensionForRenderViewHost(render_view_host); -    if (extension) { -      IncrementLazyKeepaliveCount(extension); -      data->has_keepalive = true; -    } -  } -} - -void ProcessManager::ReleaseLazyKeepaliveCountForView( -    content::RenderViewHost* render_view_host) { -  auto it = all_extension_views_.find(render_view_host); -  if (it == all_extension_views_.end()) +  // The embedder might disallow background pages entirely. +  ProcessManagerDelegate* delegate = +      ExtensionsBrowserClient::Get()->GetProcessManagerDelegate(); +  if (delegate && !delegate->IsBackgroundPageAllowed(browser_context_))      return; -  ExtensionRenderViewData* data = &it->second; -  if (data->CanKeepalive() && data->has_keepalive) { -    const Extension* extension = -        GetExtensionForRenderViewHost(render_view_host); -    if (extension) { -      DecrementLazyKeepaliveCount(extension); -      data->has_keepalive = false; -    } -  } -} - -void ProcessManager::UnregisterRenderViewHost( -    RenderViewHost* render_view_host) { -  ExtensionRenderViews::iterator view = -      all_extension_views_.find(render_view_host); -  if (view == all_extension_views_.end()) +  // The embedder might want to defer background page loading. For example, +  // Chrome defers background page loading when it is launched to show the app +  // list, then triggers a load later when a browser window opens. +  if (delegate && +      delegate->DeferCreatingStartupBackgroundHosts(browser_context_))      return; -  OnRenderViewHostUnregistered(GetBrowserContext(), render_view_host); - -  // Keepalive count, balanced in RegisterRenderViewHost. -  ReleaseLazyKeepaliveCountForView(render_view_host); -  all_extension_views_.erase(view); -} - -bool ProcessManager::RegisterRenderViewHost(RenderViewHost* render_view_host) { -  const Extension* extension = GetExtensionForRenderViewHost( -      render_view_host); -  if (!extension) -    return false; - -  WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host); -  ExtensionRenderViewData* data = &all_extension_views_[render_view_host]; -  data->view_type = GetViewType(web_contents); +  CreateStartupBackgroundHosts(); +  startup_background_hosts_created_ = true; -  // Keep the lazy background page alive as long as any non-background-page -  // extension views are visible. Keepalive count balanced in -  // UnregisterRenderViewHost. -  AcquireLazyKeepaliveCountForView(render_view_host); -  return true; +  // Background pages should only be loaded once. To prevent any further loads +  // occurring, we remove the notification listeners. +  BrowserContext* original_context = +      ExtensionsBrowserClient::Get()->GetOriginalContext(browser_context_); +  if (registrar_.IsRegistered( +          this, +          extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, +          content::Source<BrowserContext>(original_context))) { +    registrar_.Remove(this, +                      extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, +                      content::Source<BrowserContext>(original_context)); +  }  } -scoped_refptr<SiteInstance> ProcessManager::GetSiteInstanceForURL( -    const GURL& url) { -  return make_scoped_refptr(site_instance_->GetRelatedSiteInstance(url)); +ExtensionHost* ProcessManager::GetBackgroundHostForExtension( +    const std::string& extension_id) { +  for (ExtensionHost* host : background_hosts_) { +    if (host->extension_id() == extension_id) +      return host; +  } +  return nullptr;  }  bool ProcessManager::IsBackgroundHostClosing(const std::string& extension_id) { @@ -472,6 +411,20 @@ bool ProcessManager::IsBackgroundHostClosing(const std::string& extension_id) {    return (host && background_page_data_[extension_id].is_closing);  } +const Extension* ProcessManager::GetExtensionForRenderFrameHost( +    content::RenderFrameHost* render_frame_host) { +  return extension_registry_->enabled_extensions().GetByID( +      GetExtensionID(render_frame_host)); +} + +const Extension* ProcessManager::GetExtensionForWebContents( +    content::WebContents* web_contents) { +  if (!web_contents->GetSiteInstance()) +    return nullptr; +  return extension_registry_->enabled_extensions().GetByID( +      GetExtensionIdForSiteInstance(web_contents->GetSiteInstance())); +} +  int ProcessManager::GetLazyKeepaliveCount(const Extension* extension) {    if (!BackgroundInfo::HasLazyBackgroundPage(extension))      return 0; @@ -480,41 +433,16 @@ int ProcessManager::GetLazyKeepaliveCount(const Extension* extension) {  }  void ProcessManager::IncrementLazyKeepaliveCount(const Extension* extension) { -  if (!BackgroundInfo::HasLazyBackgroundPage(extension)) -    return; - -  int& count = background_page_data_[extension->id()].lazy_keepalive_count; -  if (++count == 1) -    OnLazyBackgroundPageActive(extension->id()); +  if (BackgroundInfo::HasLazyBackgroundPage(extension)) { +    int& count = background_page_data_[extension->id()].lazy_keepalive_count; +    if (++count == 1) +      OnLazyBackgroundPageActive(extension->id()); +  }  }  void ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) { -  if (!BackgroundInfo::HasLazyBackgroundPage(extension)) -    return; -  DecrementLazyKeepaliveCount(extension->id()); -} - -void ProcessManager::DecrementLazyKeepaliveCount( -    const std::string& extension_id) { -  int& count = background_page_data_[extension_id].lazy_keepalive_count; -  DCHECK(count > 0 || -         !extension_registry_->enabled_extensions().Contains(extension_id)); - -  // If we reach a zero keepalive count when the lazy background page is about -  // to be closed, incrementing close_sequence_id will cancel the close -  // sequence and cause the background page to linger. So check is_closing -  // before initiating another close sequence. -  if (--count == 0 && !background_page_data_[extension_id].is_closing) { -    background_page_data_[extension_id].close_sequence_id = -        ++last_background_close_sequence_id_; -    base::MessageLoop::current()->PostDelayedTask( -        FROM_HERE, -        base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, -                   weak_ptr_factory_.GetWeakPtr(), -                   extension_id, -                   last_background_close_sequence_id_), -        base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); -  } +  if (BackgroundInfo::HasLazyBackgroundPage(extension)) +    DecrementLazyKeepaliveCount(extension->id());  }  // This implementation layers on top of the keepalive count. An impulse sets @@ -563,73 +491,12 @@ void ProcessManager::OnKeepaliveFromPlugin(int render_process_id,    ProcessManager::Get(browser_context)->KeepaliveImpulse(extension);  } -// DecrementLazyKeepaliveCount is called when no calls to KeepaliveImpulse -// have been made for at least g_event_page_idle_time_msec. In the best case an -// impulse was made just before being cleared, and the decrement will occur -// g_event_page_idle_time_msec later, causing a 2 * g_event_page_idle_time_msec -// total time for extension to be shut down based on impulses. Worst case is -// an impulse just after a clear, adding one check cycle and resulting in 3x -// total time. -void ProcessManager::OnKeepaliveImpulseCheck() { -  for (BackgroundPageDataMap::iterator i = background_page_data_.begin(); -       i != background_page_data_.end(); -       ++i) { -    if (i->second.previous_keepalive_impulse && !i->second.keepalive_impulse) { -      DecrementLazyKeepaliveCount(i->first); -      if (!keepalive_impulse_decrement_callback_for_testing_.is_null()) { -        ImpulseCallbackForTesting callback_may_clear_callbacks_reentrantly = -          keepalive_impulse_decrement_callback_for_testing_; -        callback_may_clear_callbacks_reentrantly.Run(i->first); -      } -    } - -    i->second.previous_keepalive_impulse = i->second.keepalive_impulse; -    i->second.keepalive_impulse = false; -  } - -  // OnKeepaliveImpulseCheck() is always called in constructor, but in unit -  // tests there will be no message loop. In that event don't schedule tasks. -  if (base::MessageLoop::current()) { -    base::MessageLoop::current()->PostDelayedTask( -        FROM_HERE, -        base::Bind(&ProcessManager::OnKeepaliveImpulseCheck, -                   weak_ptr_factory_.GetWeakPtr()), -        base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); -  } -} - -void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id, -                                              uint64 sequence_id) { -  ExtensionHost* host = GetBackgroundHostForExtension(extension_id); -  if (host && !background_page_data_[extension_id].is_closing && -      sequence_id == background_page_data_[extension_id].close_sequence_id) { -    // Tell the renderer we are about to close. This is a simple ping that the -    // renderer will respond to. The purpose is to control sequencing: if the -    // extension remains idle until the renderer responds with an ACK, then we -    // know that the extension process is ready to shut down. If our -    // close_sequence_id has already changed, then we would ignore the -    // ShouldSuspendAck, so we don't send the ping. -    host->render_view_host()->Send(new ExtensionMsg_ShouldSuspend( -        extension_id, sequence_id)); -  } -} - -void ProcessManager::OnLazyBackgroundPageActive( -    const std::string& extension_id) { -  if (!background_page_data_[extension_id].is_closing) { -    // Cancel the current close sequence by changing the close_sequence_id, -    // which causes us to ignore the next ShouldSuspendAck. -    background_page_data_[extension_id].close_sequence_id = -        ++last_background_close_sequence_id_; -  } -} -  void ProcessManager::OnShouldSuspendAck(const std::string& extension_id,                                          uint64 sequence_id) {    ExtensionHost* host = GetBackgroundHostForExtension(extension_id);    if (host &&        sequence_id == background_page_data_[extension_id].close_sequence_id) { -    host->render_view_host()->Send(new ExtensionMsg_Suspend(extension_id)); +    host->render_process_host()->Send(new ExtensionMsg_Suspend(extension_id));    }  } @@ -645,40 +512,11 @@ void ProcessManager::OnSuspendAck(const std::string& extension_id) {        base::TimeDelta::FromMilliseconds(g_event_page_suspending_time_msec));  } -void ProcessManager::CloseLazyBackgroundPageNow(const std::string& extension_id, -                                                uint64 sequence_id) { -  ExtensionHost* host = GetBackgroundHostForExtension(extension_id); -  if (host && -      sequence_id == background_page_data_[extension_id].close_sequence_id) { -    // Close remaining views. -    std::vector<RenderViewHost*> views_to_close; -    for (const auto& view : all_extension_views_) { -      if (view.second.CanKeepalive() && -          GetExtensionID(view.first) == extension_id) { -        DCHECK(!view.second.has_keepalive); -        views_to_close.push_back(view.first); -      } -    } -    for (auto view : views_to_close) { -      view->ClosePage(); -      // RenderViewHost::ClosePage() may result in calling -      // UnregisterRenderViewHost() asynchronously and may cause race conditions -      // when the background page is reloaded. -      // To avoid this, unregister the view now. -      UnregisterRenderViewHost(view); -    } - -    ExtensionHost* host = GetBackgroundHostForExtension(extension_id); -    if (host) -      CloseBackgroundHost(host); -  } -} -  void ProcessManager::OnNetworkRequestStarted(      content::RenderFrameHost* render_frame_host,      uint64 request_id) {    ExtensionHost* host = GetBackgroundHostForExtension( -      GetExtensionIDFromFrame(render_frame_host)); +      GetExtensionID(render_frame_host));    if (host && IsFrameInExtensionHost(host, render_frame_host)) {      IncrementLazyKeepaliveCount(host->extension());      host->OnNetworkRequestStarted(request_id); @@ -689,7 +527,7 @@ void ProcessManager::OnNetworkRequestDone(      content::RenderFrameHost* render_frame_host,      uint64 request_id) {    ExtensionHost* host = GetBackgroundHostForExtension( -      GetExtensionIDFromFrame(render_frame_host)); +      GetExtensionID(render_frame_host));    if (host && IsFrameInExtensionHost(host, render_frame_host)) {      host->OnNetworkRequestDone(request_id);      DecrementLazyKeepaliveCount(host->extension()); @@ -701,7 +539,7 @@ void ProcessManager::CancelSuspend(const Extension* extension) {    ExtensionHost* host = GetBackgroundHostForExtension(extension->id());    if (host && is_closing) {      is_closing = false; -    host->render_view_host()->Send( +    host->render_process_host()->Send(          new ExtensionMsg_CancelSuspend(extension->id()));      // This increment / decrement is to simulate an instantaneous event. This      // has the effect of invalidating close_sequence_id, preventing any in @@ -716,10 +554,6 @@ void ProcessManager::CloseBackgroundHosts() {    STLDeleteElements(&background_hosts_);  } -content::BrowserContext* ProcessManager::GetBrowserContext() const { -  return site_instance_->GetBrowserContext(); -} -  void ProcessManager::SetKeepaliveImpulseCallbackForTesting(      const ImpulseCallbackForTesting& callback) {    keepalive_impulse_callback_for_testing_ = callback; @@ -742,6 +576,9 @@ void ProcessManager::SetEventPageSuspendingTimeForTesting(    g_event_page_suspending_time_msec = suspending_time_msec;  } +//////////////////////////////////////////////////////////////////////////////// +// Private +  void ProcessManager::Observe(int type,                               const content::NotificationSource& source,                               const content::NotificationDetails& details) { @@ -754,7 +591,6 @@ void ProcessManager::Observe(int type,        MaybeCreateStartupBackgroundHosts();        break;      } -      case extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED: {        ExtensionHost* host = content::Details<ExtensionHost>(details).ptr();        if (background_hosts_.erase(host)) { @@ -764,7 +600,6 @@ void ProcessManager::Observe(int type,        }        break;      } -      case extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: {        ExtensionHost* host = content::Details<ExtensionHost>(details).ptr();        if (host->extension_host_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { @@ -772,49 +607,6 @@ void ProcessManager::Observe(int type,        }        break;      } - -    case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED: { -      // We get this notification both for new WebContents and when one -      // has its RenderViewHost replaced (e.g. when a user does a cross-site -      // navigation away from an extension URL). For the replaced case, we must -      // unregister the old RVH so it doesn't count as an active view that would -      // keep the event page alive. -      WebContents* contents = content::Source<WebContents>(source).ptr(); -      if (contents->GetBrowserContext() != GetBrowserContext()) -        break; - -      typedef std::pair<RenderViewHost*, RenderViewHost*> RVHPair; -      RVHPair* switched_details = content::Details<RVHPair>(details).ptr(); -      if (switched_details->first) -        UnregisterRenderViewHost(switched_details->first); - -      // The above will unregister a RVH when it gets swapped out with a new -      // one. However we need to watch the WebContents to know when a RVH is -      // deleted because the WebContents has gone away. -      if (RegisterRenderViewHost(switched_details->second)) { -        RenderViewHostDestructionObserver::CreateForWebContents(contents); -      } -      break; -    } - -    case content::NOTIFICATION_WEB_CONTENTS_CONNECTED: { -      WebContents* contents = content::Source<WebContents>(source).ptr(); -      if (contents->GetBrowserContext() != GetBrowserContext()) -        break; -      const Extension* extension = GetExtensionForRenderViewHost( -          contents->GetRenderViewHost()); -      if (!extension) -        return; - -      // RegisterRenderViewHost is called too early (before the process is -      // available), so we need to wait until now to notify. -      content::NotificationService::current()->Notify( -          extensions::NOTIFICATION_EXTENSION_VIEW_REGISTERED, -          content::Source<BrowserContext>(GetBrowserContext()), -          content::Details<RenderViewHost>(contents->GetRenderViewHost())); -      break; -    } -      default:        NOTREACHED();    } @@ -833,84 +625,24 @@ void ProcessManager::OnExtensionUnloaded(      const Extension* extension,      UnloadedExtensionInfo::Reason reason) {    ExtensionHost* host = GetBackgroundHostForExtension(extension->id()); -  if (host != NULL) +  if (host != nullptr)      CloseBackgroundHost(host);    UnregisterExtension(extension->id());  } -void ProcessManager::OnDevToolsStateChanged( -    content::DevToolsAgentHost* agent_host, -    bool attached) { -  WebContents* web_contents = agent_host->GetWebContents(); -  // Ignore unrelated notifications. -  if (!web_contents || web_contents->GetBrowserContext() != GetBrowserContext()) -    return; -  if (GetViewType(web_contents) != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) -    return; -  const Extension* extension = -      GetExtensionForRenderViewHost(web_contents->GetRenderViewHost()); -  if (!extension) -    return; -  if (attached) { -    // Keep the lazy background page alive while it's being inspected. -    CancelSuspend(extension); -    IncrementLazyKeepaliveCount(extension); -  } else { -    DecrementLazyKeepaliveCount(extension); -  } -} - -void ProcessManager::MaybeCreateStartupBackgroundHosts() { -  if (startup_background_hosts_created_) -    return; - -  // The embedder might disallow background pages entirely. -  ProcessManagerDelegate* delegate = -      ExtensionsBrowserClient::Get()->GetProcessManagerDelegate(); -  if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext())) -    return; - -  // The embedder might want to defer background page loading. For example, -  // Chrome defers background page loading when it is launched to show the app -  // list, then triggers a load later when a browser window opens. -  if (delegate && -      delegate->DeferCreatingStartupBackgroundHosts(GetBrowserContext())) -    return; - -  CreateStartupBackgroundHosts(); -  startup_background_hosts_created_ = true; - -  // Background pages should only be loaded once. To prevent any further loads -  // occurring, we remove the notification listeners. -  BrowserContext* original_context = -      ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); -  if (registrar_.IsRegistered( -          this, -          extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, -          content::Source<BrowserContext>(original_context))) { -    registrar_.Remove(this, -                      extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, -                      content::Source<BrowserContext>(original_context)); -  } -} -  void ProcessManager::CreateStartupBackgroundHosts() {    DCHECK(!startup_background_hosts_created_); -  const ExtensionSet& enabled_extensions = -      extension_registry_->enabled_extensions(); -  for (ExtensionSet::const_iterator extension = enabled_extensions.begin(); -       extension != enabled_extensions.end(); -       ++extension) { -    CreateBackgroundHostForExtensionLoad(this, extension->get()); - +  for (const scoped_refptr<const Extension>& extension : +           extension_registry_->enabled_extensions()) { +    CreateBackgroundHostForExtensionLoad(this, extension.get());      FOR_EACH_OBSERVER(ProcessManagerObserver,                        observer_list_, -                      OnBackgroundHostStartup(extension->get())); +                      OnBackgroundHostStartup(extension.get()));    }  }  void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) { -  DCHECK_EQ(GetBrowserContext(), host->browser_context()); +  DCHECK_EQ(browser_context_, host->browser_context());    background_hosts_.insert(host);    if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) { @@ -928,8 +660,7 @@ void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) {  void ProcessManager::CloseBackgroundHost(ExtensionHost* host) {    ExtensionId extension_id = host->extension_id(); -  CHECK(host->extension_host_type() == -        VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); +  CHECK(host->extension_host_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);    delete host;    // |host| should deregister itself from our structures.    CHECK(background_hosts_.find(host) == background_hosts_.end()); @@ -939,18 +670,192 @@ void ProcessManager::CloseBackgroundHost(ExtensionHost* host) {                      OnBackgroundHostClose(extension_id));  } +void ProcessManager::AcquireLazyKeepaliveCountForFrame( +    content::RenderFrameHost* render_frame_host) { +  ExtensionRenderFrames::iterator it = +      all_extension_frames_.find(render_frame_host); +  if (it == all_extension_frames_.end()) +    return; + +  ExtensionRenderFrameData& data = it->second; +  if (data.CanKeepalive() && !data.has_keepalive) { +    const Extension* extension = +        GetExtensionForRenderFrameHost(render_frame_host); +    if (extension) { +      IncrementLazyKeepaliveCount(extension); +      data.has_keepalive = true; +    } +  } +} + +void ProcessManager::ReleaseLazyKeepaliveCountForFrame( +    content::RenderFrameHost* render_frame_host) { +  ExtensionRenderFrames::iterator iter = +      all_extension_frames_.find(render_frame_host); +  if (iter == all_extension_frames_.end()) +    return; + +  ExtensionRenderFrameData& data = iter->second; +  if (data.CanKeepalive() && data.has_keepalive) { +    const Extension* extension = +        GetExtensionForRenderFrameHost(render_frame_host); +    if (extension) { +      DecrementLazyKeepaliveCount(extension); +      data.has_keepalive = false; +    } +  } +} + +void ProcessManager::DecrementLazyKeepaliveCount( +    const std::string& extension_id) { +  int& count = background_page_data_[extension_id].lazy_keepalive_count; +  DCHECK(count > 0 || +         !extension_registry_->enabled_extensions().Contains(extension_id)); + +  // If we reach a zero keepalive count when the lazy background page is about +  // to be closed, incrementing close_sequence_id will cancel the close +  // sequence and cause the background page to linger. So check is_closing +  // before initiating another close sequence. +  if (--count == 0 && !background_page_data_[extension_id].is_closing) { +    background_page_data_[extension_id].close_sequence_id = +        ++last_background_close_sequence_id_; +    base::MessageLoop::current()->PostDelayedTask( +        FROM_HERE, +        base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, +                   weak_ptr_factory_.GetWeakPtr(), +                   extension_id, +                   last_background_close_sequence_id_), +        base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); +  } +} + +// DecrementLazyKeepaliveCount is called when no calls to KeepaliveImpulse +// have been made for at least g_event_page_idle_time_msec. In the best case an +// impulse was made just before being cleared, and the decrement will occur +// g_event_page_idle_time_msec later, causing a 2 * g_event_page_idle_time_msec +// total time for extension to be shut down based on impulses. Worst case is +// an impulse just after a clear, adding one check cycle and resulting in 3x +// total time. +void ProcessManager::OnKeepaliveImpulseCheck() { +  for (BackgroundPageDataMap::iterator i = background_page_data_.begin(); +       i != background_page_data_.end(); +       ++i) { +    if (i->second.previous_keepalive_impulse && !i->second.keepalive_impulse) { +      DecrementLazyKeepaliveCount(i->first); +      if (!keepalive_impulse_decrement_callback_for_testing_.is_null()) { +        ImpulseCallbackForTesting callback_may_clear_callbacks_reentrantly = +            keepalive_impulse_decrement_callback_for_testing_; +        callback_may_clear_callbacks_reentrantly.Run(i->first); +      } +    } + +    i->second.previous_keepalive_impulse = i->second.keepalive_impulse; +    i->second.keepalive_impulse = false; +  } + +  // OnKeepaliveImpulseCheck() is always called in constructor, but in unit +  // tests there will be no message loop. In that event don't schedule tasks. +  if (base::MessageLoop::current()) { +    base::MessageLoop::current()->PostDelayedTask( +        FROM_HERE, +        base::Bind(&ProcessManager::OnKeepaliveImpulseCheck, +                   weak_ptr_factory_.GetWeakPtr()), +        base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); +  } +} + +void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id, +                                              uint64 sequence_id) { +  ExtensionHost* host = GetBackgroundHostForExtension(extension_id); +  if (host && !background_page_data_[extension_id].is_closing && +      sequence_id == background_page_data_[extension_id].close_sequence_id) { +    // Tell the renderer we are about to close. This is a simple ping that the +    // renderer will respond to. The purpose is to control sequencing: if the +    // extension remains idle until the renderer responds with an ACK, then we +    // know that the extension process is ready to shut down. If our +    // close_sequence_id has already changed, then we would ignore the +    // ShouldSuspendAck, so we don't send the ping. +    host->render_process_host()->Send(new ExtensionMsg_ShouldSuspend( +        extension_id, sequence_id)); +  } +} + +void ProcessManager::OnLazyBackgroundPageActive( +    const std::string& extension_id) { +  if (!background_page_data_[extension_id].is_closing) { +    // Cancel the current close sequence by changing the close_sequence_id, +    // which causes us to ignore the next ShouldSuspendAck. +    background_page_data_[extension_id].close_sequence_id = +        ++last_background_close_sequence_id_; +  } +} + +void ProcessManager::CloseLazyBackgroundPageNow(const std::string& extension_id, +                                                uint64 sequence_id) { +  ExtensionHost* host = GetBackgroundHostForExtension(extension_id); +  if (host && +      sequence_id == background_page_data_[extension_id].close_sequence_id) { +    // Close remaining views. +    std::vector<content::RenderFrameHost*> frames_to_close; +    for (const auto& key_value : all_extension_frames_) { +      if (key_value.second.CanKeepalive() && +          GetExtensionID(key_value.first) == extension_id) { +        DCHECK(!key_value.second.has_keepalive); +        frames_to_close.push_back(key_value.first); +      } +    } +    for (content::RenderFrameHost* frame : frames_to_close) { +      frame->GetRenderViewHost()->ClosePage(); +      // RenderViewHost::ClosePage() may result in calling +      // UnregisterRenderViewHost() asynchronously and may cause race conditions +      // when the background page is reloaded. +      // To avoid this, unregister the view now. +      UnregisterRenderFrameHost(frame); +    } + +    ExtensionHost* host = GetBackgroundHostForExtension(extension_id); +    if (host) +      CloseBackgroundHost(host); +  } +} + +void ProcessManager::OnDevToolsStateChanged( +    content::DevToolsAgentHost* agent_host, +    bool attached) { +  content::WebContents* web_contents = agent_host->GetWebContents(); +  // Ignore unrelated notifications. +  if (!web_contents || web_contents->GetBrowserContext() != browser_context_) +    return; +  if (GetViewType(web_contents) != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) +    return; +  const Extension* extension = +      extension_registry_->enabled_extensions().GetByID( +          GetExtensionIdForSiteInstance(web_contents->GetSiteInstance())); +  if (!extension) +    return; +  if (attached) { +    // Keep the lazy background page alive while it's being inspected. +    CancelSuspend(extension); +    IncrementLazyKeepaliveCount(extension); +  } else { +    DecrementLazyKeepaliveCount(extension); +  } +} +  void ProcessManager::UnregisterExtension(const std::string& extension_id) {    // The lazy_keepalive_count may be greater than zero at this point because -  // RenderViewHosts are still alive. During extension reloading, they will +  // RenderFrameHosts are still alive. During extension reloading, they will    // decrement the lazy_keepalive_count to negative for the new extension    // instance when they are destroyed. Since we are erasing the background page -  // data for the unloaded extension, unregister the RenderViewHosts too. -  BrowserContext* context = GetBrowserContext(); -  for (ExtensionRenderViews::iterator it = all_extension_views_.begin(); -       it != all_extension_views_.end(); ) { -    if (GetExtensionID(it->first) == extension_id) { -      OnRenderViewHostUnregistered(context, it->first); -      all_extension_views_.erase(it++); +  // data for the unloaded extension, unregister the RenderFrameHosts too. +  for (ExtensionRenderFrames::iterator it = all_extension_frames_.begin(); +       it != all_extension_frames_.end(); ) { +    content::RenderFrameHost* host = it->first; +    if (GetExtensionID(host) == extension_id) { +      all_extension_frames_.erase(it++); +      FOR_EACH_OBSERVER(ProcessManagerObserver, +                        observer_list_, +                        OnExtensionFrameUnregistered(extension_id, host));      } else {        ++it;      } @@ -965,14 +870,13 @@ void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) {    // Re-register all RenderViews for this extension. We do this to restore    // the lazy_keepalive_count (if any) to properly reflect the number of open    // views. -  for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); -       it != all_extension_views_.end(); ++it) { -    RenderViewHost* view = it->first; -    const ExtensionRenderViewData& data = it->second; +  for (const auto& key_value : all_extension_frames_) {      // Do not increment the count when |has_keepalive| is false      // (i.e. ReleaseLazyKeepaliveCountForView() was called). -    if (GetExtensionID(view) == extension_id && data.has_keepalive) { -      const Extension* extension = GetExtensionForRenderViewHost(view); +    if (GetExtensionID(key_value.first) == extension_id && +        key_value.second.has_keepalive) { +      const Extension* extension = +          GetExtensionForRenderFrameHost(key_value.first);        if (extension)          IncrementLazyKeepaliveCount(extension);      } @@ -989,21 +893,13 @@ IncognitoProcessManager::IncognitoProcessManager(      ExtensionRegistry* extension_registry)      : ProcessManager(incognito_context, original_context, extension_registry) {    DCHECK(incognito_context->IsOffTheRecord()); - -  // The original profile will have its own ProcessManager to -  // load the background pages of the spanning extensions. This process -  // manager need only worry about the split mode extensions, which is handled -  // in the NOTIFICATION_BROWSER_WINDOW_READY notification handler. -  registrar_.Remove(this, -                    extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, -                    content::Source<BrowserContext>(original_context));  }  bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension,                                                     const GURL& url) {    if (IncognitoInfo::IsSplitMode(extension)) {      if (ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled( -            extension->id(), GetBrowserContext())) +            extension->id(), browser_context()))        return ProcessManager::CreateBackgroundHost(extension, url);    } else {      // Do nothing. If an extension is spanning, then its original-profile @@ -1012,13 +908,13 @@ bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension,    return false;  } -scoped_refptr<SiteInstance> IncognitoProcessManager::GetSiteInstanceForURL( -    const GURL& url) { +scoped_refptr<content::SiteInstance> +IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) {    const Extension* extension =        extension_registry_->enabled_extensions().GetExtensionOrAppByURL(url);    if (extension && !IncognitoInfo::IsSplitMode(extension)) {      BrowserContext* original_context = -        ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); +        ExtensionsBrowserClient::Get()->GetOriginalContext(browser_context());      return ProcessManager::Get(original_context)->GetSiteInstanceForURL(url);    } diff --git a/extensions/browser/process_manager.h b/extensions/browser/process_manager.h index d897d29..de23f1e 100644 --- a/extensions/browser/process_manager.h +++ b/extensions/browser/process_manager.h @@ -14,11 +14,11 @@  #include "base/memory/ref_counted.h"  #include "base/memory/weak_ptr.h"  #include "base/observer_list.h" -#include "base/time/time.h"  #include "components/keyed_service/core/keyed_service.h"  #include "content/public/browser/notification_observer.h"  #include "content/public/browser/notification_registrar.h"  #include "extensions/browser/extension_registry_observer.h" +#include "extensions/common/extension.h"  #include "extensions/common/view_type.h"  class GURL; @@ -26,9 +26,9 @@ class GURL;  namespace content {  class BrowserContext;  class DevToolsAgentHost; -class RenderViewHost;  class RenderFrameHost;  class SiteInstance; +class WebContents;  };  namespace extensions { @@ -36,7 +36,6 @@ namespace extensions {  class Extension;  class ExtensionHost;  class ExtensionRegistry; -class ProcessManagerDelegate;  class ProcessManagerObserver;  // Manages dynamic state of running Chromium extensions. There is one instance @@ -46,20 +45,30 @@ class ProcessManager : public KeyedService,                         public content::NotificationObserver,                         public ExtensionRegistryObserver {   public: -  typedef std::set<extensions::ExtensionHost*> ExtensionHostSet; -  typedef ExtensionHostSet::const_iterator const_iterator; +  using ExtensionHostSet = std::set<extensions::ExtensionHost*>;    static ProcessManager* Get(content::BrowserContext* context);    ~ProcessManager() override; -  const ExtensionHostSet& background_hosts() const { -    return background_hosts_; -  } +  void RegisterRenderFrameHost(content::WebContents* web_contents, +                               content::RenderFrameHost* render_frame_host, +                               const Extension* extension); +  void UnregisterRenderFrameHost(content::RenderFrameHost* render_frame_host); -  typedef std::set<content::RenderViewHost*> ViewSet; -  const ViewSet GetAllViews() const; +  // Returns the SiteInstance that the given URL belongs to. +  // TODO(aa): This only returns correct results for extensions and packaged +  // apps, not hosted apps. +  virtual scoped_refptr<content::SiteInstance> GetSiteInstanceForURL( +      const GURL& url); + +  using FrameSet = std::set<content::RenderFrameHost*>; +  const FrameSet GetAllFrames() const; + +  // Returns all RenderFrameHosts that are registered for the specified +  // extension. +  ProcessManager::FrameSet GetRenderFrameHostsForExtension( +      const std::string& extension_id); -  // The typical observer interface.    void AddObserver(ProcessManagerObserver* observer);    void RemoveObserver(ProcessManagerObserver* observer); @@ -70,43 +79,25 @@ class ProcessManager : public KeyedService,    virtual bool CreateBackgroundHost(const Extension* extension,                                      const GURL& url); -  // Gets the ExtensionHost for the background page for an extension, or NULL if +  // Creates background hosts if the embedder is ready and they are not already +  // loaded. +  void MaybeCreateStartupBackgroundHosts(); + +  // Gets the ExtensionHost for the background page for an extension, or null if    // the extension isn't running or doesn't have a background page.    ExtensionHost* GetBackgroundHostForExtension(const std::string& extension_id); -  // Returns the SiteInstance that the given URL belongs to. -  // TODO(aa): This only returns correct results for extensions and packaged -  // apps, not hosted apps. -  virtual scoped_refptr<content::SiteInstance> GetSiteInstanceForURL( -      const GURL& url); - -  // If the view isn't keeping the lazy background page alive, increments the -  // keepalive count to do so. -  void AcquireLazyKeepaliveCountForView( -      content::RenderViewHost* render_view_host); - -  // If the view is keeping the lazy background page alive, decrements the -  // keepalive count to stop doing it. -  void ReleaseLazyKeepaliveCountForView( -      content::RenderViewHost* render_view_host); - -  // Unregisters a RenderViewHost as hosting any extension. -  void UnregisterRenderViewHost(content::RenderViewHost* render_view_host); - -  // Returns all RenderViewHosts that are registered for the specified -  // extension. -  std::set<content::RenderViewHost*> GetRenderViewHostsForExtension( -      const std::string& extension_id); - -  // Returns the extension associated with the specified RenderViewHost, or -  // NULL. -  const Extension* GetExtensionForRenderViewHost( -      content::RenderViewHost* render_view_host); -    // Returns true if the (lazy) background host for the given extension has    // already been sent the unload event and is shutting down.    bool IsBackgroundHostClosing(const std::string& extension_id); +  // Returns the extension associated with the specified RenderFrameHost/ +  // WebContents, or null. +  const Extension* GetExtensionForRenderFrameHost( +      content::RenderFrameHost* render_frame_host); +  const Extension* GetExtensionForWebContents( +      content::WebContents* web_contents); +    // Getter and setter for the lazy background page's keepalive count. This is    // the count of how many outstanding "things" are keeping the page alive.    // When this reaches 0, we will begin the process of shutting down the page. @@ -143,20 +134,12 @@ class ProcessManager : public KeyedService,    // onSuspendCanceled() event to it.    void CancelSuspend(const Extension* extension); -  // Creates background hosts if the embedder is ready and they are not already -  // loaded. -  void MaybeCreateStartupBackgroundHosts(); -    // Called on shutdown to close our extension hosts.    void CloseBackgroundHosts(); -  // Gets the BrowserContext associated with site_instance_ and all other -  // related SiteInstances. -  content::BrowserContext* GetBrowserContext() const; -    // Sets callbacks for testing keepalive impulse behavior. -  typedef base::Callback<void(const std::string& extension_id)> -      ImpulseCallbackForTesting; +  using ImpulseCallbackForTesting = +      base::Callback<void(const std::string& extension_id)>;    void SetKeepaliveImpulseCallbackForTesting(        const ImpulseCallbackForTesting& callback);    void SetKeepaliveImpulseDecrementCallbackForTesting( @@ -184,6 +167,12 @@ class ProcessManager : public KeyedService,        content::BrowserContext* original_context,        ExtensionRegistry* registry); +  content::BrowserContext* browser_context() const { return browser_context_; } + +  const ExtensionHostSet& background_hosts() const { +    return background_hosts_; +  } +    bool startup_background_hosts_created_for_test() const {      return startup_background_hosts_created_;    } @@ -191,13 +180,20 @@ class ProcessManager : public KeyedService,   protected:    static ProcessManager* Create(content::BrowserContext* context); -  //  |context| is incognito pass the master context as |original_context|. +  // |context| is incognito pass the master context as |original_context|.    // Otherwise pass the same context for both. Pass the ExtensionRegistry for    // |context| as |registry|, or override it for testing.    ProcessManager(content::BrowserContext* context,                   content::BrowserContext* original_context,                   ExtensionRegistry* registry); +  // Not owned. Also used by IncognitoProcessManager. +  ExtensionRegistry* extension_registry_; + + private: +  friend class ProcessManagerFactory; +  friend class ProcessManagerTest; +    // content::NotificationObserver:    void Observe(int type,                 const content::NotificationSource& source, @@ -210,30 +206,12 @@ class ProcessManager : public KeyedService,                             const Extension* extension,                             UnloadedExtensionInfo::Reason reason) override; -  content::NotificationRegistrar registrar_; - -  // The set of ExtensionHosts running viewless background extensions. -  ExtensionHostSet background_hosts_; - -  // A SiteInstance related to the SiteInstance for all extensions in -  // this profile.  We create it in such a way that a new -  // browsing instance is created.  This controls process grouping. -  scoped_refptr<content::SiteInstance> site_instance_; - -  // Not owned. Also used by IncognitoProcessManager. -  ExtensionRegistry* extension_registry_; - - private: -  friend class ProcessManagerFactory; -  friend class ProcessManagerTest; -    // Extra information we keep for each extension's background page.    struct BackgroundPageData; -  struct ExtensionRenderViewData; -  typedef std::string ExtensionId; -  typedef std::map<ExtensionId, BackgroundPageData> BackgroundPageDataMap; -  typedef std::map<content::RenderViewHost*, ExtensionRenderViewData> -      ExtensionRenderViews; +  struct ExtensionRenderFrameData; +  using BackgroundPageDataMap = std::map<ExtensionId, BackgroundPageData>; +  using ExtensionRenderFrames = +      std::map<content::RenderFrameHost*, ExtensionRenderFrameData>;    // Load all background pages once the profile data is ready and the pages    // should be loaded. @@ -245,6 +223,16 @@ class ProcessManager : public KeyedService,    // Close the given |host| iff it's a background page.    void CloseBackgroundHost(ExtensionHost* host); +  // If the frame isn't keeping the lazy background page alive, increments the +  // keepalive count to do so. +  void AcquireLazyKeepaliveCountForFrame( +      content::RenderFrameHost* render_frame_host); + +  // If the frame is keeping the lazy background page alive, decrements the +  // keepalive count to stop doing it. +  void ReleaseLazyKeepaliveCountForFrame( +      content::RenderFrameHost* render_frame_host); +    // Internal implementation of DecrementLazyKeepaliveCount with an    // |extension_id| known to have a lazy background page.    void DecrementLazyKeepaliveCount(const std::string& extension_id); @@ -260,25 +248,32 @@ class ProcessManager : public KeyedService,    void CloseLazyBackgroundPageNow(const std::string& extension_id,                                    uint64 sequence_id); -  // Potentially registers a RenderViewHost, if it is associated with an -  // extension. Does nothing if this is not an extension renderer. -  // Returns true, if render_view_host was registered (it is associated -  // with an extension). -  bool RegisterRenderViewHost(content::RenderViewHost* render_view_host); +  void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached); -  // Unregister RenderViewHosts and clear background page data for an extension +  // Unregister RenderFrameHosts and clear background page data for an extension    // which has been unloaded.    void UnregisterExtension(const std::string& extension_id);    // Clears background page data for this extension.    void ClearBackgroundPageData(const std::string& extension_id); -  void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached); +  content::NotificationRegistrar registrar_; + +  // The set of ExtensionHosts running viewless background extensions. +  ExtensionHostSet background_hosts_; + +  // A SiteInstance related to the SiteInstance for all extensions in +  // this profile.  We create it in such a way that a new +  // browsing instance is created.  This controls process grouping. +  scoped_refptr<content::SiteInstance> site_instance_; + +  // The browser context associated with the |site_instance_|. +  content::BrowserContext* browser_context_; -  // Contains all active extension-related RenderViewHost instances for all +  // Contains all active extension-related RenderFrameHost instances for all    // extensions. We also keep a cache of the host's view type, because that    // information is not accessible at registration/deregistration time. -  ExtensionRenderViews all_extension_views_; +  ExtensionRenderFrames all_extension_frames_;    BackgroundPageDataMap background_page_data_; diff --git a/extensions/browser/process_manager_observer.h b/extensions/browser/process_manager_observer.h index 4b0dfd6..37054ac 100644 --- a/extensions/browser/process_manager_observer.h +++ b/extensions/browser/process_manager_observer.h @@ -7,6 +7,10 @@  #include <string> +namespace content { +class RenderFrameHost; +} +  namespace extensions {  class Extension; @@ -21,6 +25,14 @@ class ProcessManagerObserver {    // Called immediately after the extension background host is destroyed.    virtual void OnBackgroundHostClose(const std::string& extension_id) {} + +  virtual void OnExtensionFrameRegistered( +      const std::string& extension_id, +      content::RenderFrameHost* render_frame_host) {} + +  virtual void OnExtensionFrameUnregistered( +      const std::string& extension_id, +      content::RenderFrameHost* render_frame_host) {}  };  }  // namespace extensions diff --git a/extensions/browser/process_manager_unittest.cc b/extensions/browser/process_manager_unittest.cc index 47ff500..34b74a9 100644 --- a/extensions/browser/process_manager_unittest.cc +++ b/extensions/browser/process_manager_unittest.cc @@ -103,7 +103,7 @@ TEST_F(ProcessManagerTest, ExtensionNotificationRegistration) {    scoped_ptr<ProcessManager> manager1(ProcessManager::CreateForTesting(        original_context(), extension_registry())); -  EXPECT_EQ(original_context(), manager1->GetBrowserContext()); +  EXPECT_EQ(original_context(), manager1->browser_context());    EXPECT_EQ(0u, manager1->background_hosts().size());    // It observes other notifications from this context. @@ -120,7 +120,7 @@ TEST_F(ProcessManagerTest, ExtensionNotificationRegistration) {                                                  original_context(),                                                  extension_registry())); -  EXPECT_EQ(incognito_context(), manager2->GetBrowserContext()); +  EXPECT_EQ(incognito_context(), manager2->browser_context());    EXPECT_EQ(0u, manager2->background_hosts().size());    // Some notifications are observed for the incognito context. diff --git a/extensions/components/javascript_dialog_extensions_client/javascript_dialog_extension_client_impl.cc b/extensions/components/javascript_dialog_extensions_client/javascript_dialog_extension_client_impl.cc index f50b4e9..6874a3a 100644 --- a/extensions/components/javascript_dialog_extensions_client/javascript_dialog_extension_client_impl.cc +++ b/extensions/components/javascript_dialog_extensions_client/javascript_dialog_extension_client_impl.cc @@ -26,8 +26,8 @@ extensions::ProcessManager* GetProcessManager(  // associated extension (or extensions are not supported).  const Extension* GetExtensionForWebContents(      content::WebContents* web_contents) { -  extensions::ProcessManager* pm = GetProcessManager(web_contents); -  return pm->GetExtensionForRenderViewHost(web_contents->GetRenderViewHost()); +  return GetProcessManager(web_contents)->GetExtensionForWebContents( +      web_contents);  }  class JavaScriptDialogExtensionsClientImpl | 
