blob: 9d66bbc409c1ee5da8e290d4e9f44675dafe85f4 [file] [log] [blame]
// Copyright 2021 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.
#ifndef EXTENSIONS_BROWSER_EXTENSION_HOST_REGISTRY_H_
#define EXTENSIONS_BROWSER_EXTENSION_HOST_REGISTRY_H_
#include <unordered_set>
#include <vector>
#include "base/observer_list.h"
#include "components/keyed_service/core/keyed_service.h"
#include "extensions/common/extension_id.h"
class BrowserContextKeyedServiceFactory;
namespace content {
class BrowserContext;
}
namespace extensions {
class ExtensionHost;
// A class responsible for tracking ExtensionHosts and notifying observers of
// relevant changes.
// See also ProcessManager, which is responsible for more of the construction
// lifetime management of these hosts.
class ExtensionHostRegistry : public KeyedService {
public:
class Observer : public base::CheckedObserver {
public:
// Called when the RenderProcessHost for an ExtensionHost is ready.
// In practice, this corresponds to "shortly after" the first render frame
// is created in the host.
// The `browser_context` is the context associated with that host (which
// might be an incognito version of
// ExtensionHostRegistry::browser_context_).
virtual void OnExtensionHostRenderProcessReady(
content::BrowserContext* browser_context,
ExtensionHost* host) {}
// Called when an ExtensionHost is destroyed. The `browser_context` is
// the context associated with that host (which might be an incognito
// version of ExtensionHostRegistry::browser_context_).
virtual void OnExtensionHostDestroyed(
content::BrowserContext* browser_context,
ExtensionHost* host) {}
// Called when an ExtensionHost completes its first load. The
// `browser_context` is the context associated with that host (which might
// be an incognito version of ExtensionHostRegistry::browser_context_).
// Note: If you only need to observe a single ExtensionHost (that's already
// created), prefer overriding
// ExtensionHostObserver::OnExtensionHostDidStopFirstLoad().
virtual void OnExtensionHostCompletedFirstLoad(
content::BrowserContext* browser_context,
ExtensionHost* host) {}
// Called when a document element is first available in an ExtensionHost.
// `browser_context` is the context associated with that host (which might
// be an incognito version of ExtensionHostRegistry::browser_context_).
// TODO(devlin): Do we really need both first load completed and document
// element available notifications? This matches previous implementations,
// but I'm not sure the distinction is relevant.
virtual void OnExtensionHostDocumentElementAvailable(
content::BrowserContext* browser_context,
ExtensionHost* extension_host) {}
// Called when an ExtensionHost's render process is terminated. Note that
// this may be called multiple times for a single process termination, since
// there may be multiple ExtensionHosts in the same process.
// `browser_context` is the context associated with that host (which might
// be an incognito version of ExtensionHostRegistry::browser_context_).
virtual void OnExtensionHostRenderProcessGone(
content::BrowserContext* browser_context,
ExtensionHost* extension_host) {}
};
ExtensionHostRegistry();
ExtensionHostRegistry(const ExtensionHostRegistry&) = delete;
ExtensionHostRegistry& operator=(const ExtensionHostRegistry&) = delete;
~ExtensionHostRegistry() override;
// Retrieves the ExtensionHostRegistry for a given `browser_context`.
// NOTE: ExtensionHostRegistry is shared between on- and off-the-record
// contexts. See also the comment
// ExtensionHostRegistryFactory::GetBrowserContextToUse().
static ExtensionHostRegistry* Get(content::BrowserContext* browser_context);
// Retrieves the factory instance for the ExtensionHostRegistry.
static BrowserContextKeyedServiceFactory* GetFactory();
// Called when a new ExtensionHost is created, and starts tracking the host
// in `extension_hosts_`.
void ExtensionHostCreated(ExtensionHost* extension_host);
// Called when an ExtensionHost's corresponding renderer process is ready, and
// and notifies observers.
void ExtensionHostRenderProcessReady(ExtensionHost* extension_host);
// Called when an ExtensionHost completes its first load.
void ExtensionHostCompletedFirstLoad(ExtensionHost* extension_host);
// Called when an ExtensionHost has created a document element for its first
// time.
void ExtensionHostDocumentElementAvailable(ExtensionHost* extension_host);
// Called when an ExtensionHost's render process is terminated.
void ExtensionHostRenderProcessGone(ExtensionHost* extension_host);
// Called when an ExtensionHost is destroyed. Stops tracking the host and
// notifies observers.
void ExtensionHostDestroyed(ExtensionHost* extension_host);
// Returns the collection of ExtensionHosts associated with the specified
// `extension_id`.
// If performance ever becomes a consideration here, we can update the
// storage in the registry to be an unordered_map split apart by extension.
std::vector<ExtensionHost*> GetHostsForExtension(
const ExtensionId& extension_id);
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
private:
// The active set of ExtensionHosts.
std::unordered_set<ExtensionHost*> extension_hosts_;
base::ObserverList<Observer> observers_;
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_EXTENSION_HOST_REGISTRY_H_