File: extension_host_registry.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (155 lines) | stat: -rw-r--r-- 6,410 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2021 The Chromium Authors
// 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/memory/raw_ptr.h"
#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;
class RenderFrameHost;
}

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) {}

    // Called when `registry` is starting to shut down.
    virtual void OnExtensionHostRegistryShutdown(
        ExtensionHostRegistry* registry) {}
  };

  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);

  // Returns the ExtensionHost for the given `render_frame_host`, if one exists.
  // `render_frame_host` must be the primary main frame host; we do this to
  // avoid returning an ExtensionHost for a non-extension frame within an
  // extension document.
  ExtensionHost* GetExtensionHostForPrimaryMainFrame(
      content::RenderFrameHost* render_frame_host);

  const std::unordered_set<raw_ptr<ExtensionHost, CtnExperimental>>&
  extension_hosts() {
    return extension_hosts_;
  }

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // KeyedService:
  void Shutdown() override;

 private:
  // The active set of ExtensionHosts.
  std::unordered_set<raw_ptr<ExtensionHost, CtnExperimental>> extension_hosts_;

  base::ObserverList<Observer> observers_;
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_EXTENSION_HOST_REGISTRY_H_