File: extension_web_contents_observer.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 (177 lines) | stat: -rw-r--r-- 7,354 bytes parent folder | download | duplicates (5)
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// Copyright 2014 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_WEB_CONTENTS_OBSERVER_H_
#define EXTENSIONS_BROWSER_EXTENSION_WEB_CONTENTS_OBSERVER_H_

#include <map>
#include <string>

#include "base/compiler_specific.h"
#include "base/memory/raw_ptr.h"
#include "base/types/pass_key.h"
#include "components/sessions/core/session_id.h"
#include "content/public/browser/web_contents_observer.h"
#include "extensions/browser/extension_function_dispatcher.h"
#include "extensions/common/mojom/frame.mojom.h"
#include "mojo/public/cpp/bindings/associated_remote.h"

namespace content {
class BrowserContext;
class RenderFrameHost;
class WebContents;
}

namespace sessions {
class SessionTabHelper;
}

namespace extensions {
class Extension;
class ExtensionFrameHost;

// A web contents observer used for renderer and extension processes. Grants the
// renderer access to certain URL scheme patterns for extensions and notifies
// the renderer that the extension was loaded.
//
// Extension system embedders must create an instance for every extension
// WebContents. It must be a subclass so that creating an instance via
// content::WebContentsUserData::CreateForWebContents() provides an object of
// the correct type. For an example, see ChromeExtensionWebContentsObserver.
//
// This class is responsible for maintaining the registrations of extension
// frames with the ProcessManager. Only frames in an extension process are
// registered. If out-of-process frames are enabled, every frame hosts a
// chrome-extension: page. Otherwise non-extension frames may erroneously be
// registered, but only briefly until they are correctly classified. This is
// achieved using the following notifications:
// 1. RenderFrameCreated - registers all new frames in extension processes.
// 2. DidCommitProvisionalLoadForFrame - unregisters non-extension frames.
// 3. DidNavigateAnyFrame - registers extension frames if they had been
//    unregistered.
//
// Without OOPIF, non-extension frames created by the Chrome extension are also
// registered at RenderFrameCreated. When the non-extension page is committed,
// we detect that the unexpected URL and unregister the frame.
// With OOPIF only the first notification is sufficient in most cases, except
// for sandboxed frames with a unique origin.
class ExtensionWebContentsObserver
    : public content::WebContentsObserver,
      public ExtensionFunctionDispatcher::Delegate {
 public:
  ExtensionWebContentsObserver(const ExtensionWebContentsObserver&) = delete;
  ExtensionWebContentsObserver& operator=(const ExtensionWebContentsObserver&) =
      delete;

  // Returns the ExtensionWebContentsObserver for the given `web_contents`.
  static ExtensionWebContentsObserver* GetForWebContents(
      content::WebContents* web_contents);

  // Binds the LocalFrameHost interface to the ExtensionFrameHost associated
  // with the RenderFrameHost.
  static void BindLocalFrameHost(
      mojo::PendingAssociatedReceiver<mojom::LocalFrameHost> receiver,
      content::RenderFrameHost* render_frame_host);

  // This must be called by clients directly after the EWCO has been created.
  void Initialize();

  ExtensionFunctionDispatcher* dispatcher() { return &dispatcher_; }

  // Returns the extension associated with the given `render_frame_host`, or
  // null if there is none.
  // If `verify_url` is false, only the SiteInstance is taken into account.
  // If `verify_url` is true, the frame's last committed URL is also used to
  // improve the classification of the frame.
  const Extension* GetExtensionFromFrame(
      content::RenderFrameHost* render_frame_host,
      bool verify_url) const;

  // Returns mojom::LocalFrame* corresponding `render_frame_host`. It emplaces
  // AssociatedRemote<mojom::LocalFrame> to `local_frame_map_` if the map
  // doesn't have it. Note that it could return nullptr if `render_frame_host`
  // is not live or `render_frame_host` does not immediately belong to the
  // associated `WebContents`.
  mojom::LocalFrame* GetLocalFrame(content::RenderFrameHost* render_frame_host);

  // Similar to `GetLocalFrame` but will not return nullptr, will crash.
  mojom::LocalFrame& GetLocalFrameChecked(
      content::RenderFrameHost* render_frame_host);

  // Tells the receiver to start listening to window ID changes from the
  // supplied SessionTabHelper. This method is public to allow the code that
  // installs new SessionTabHelpers to call it; that in turn is required because
  // SessionTabHelpers may be created after the corresponding
  // ExtensionWebContentsObserver has already been initialized.
  void ListenToWindowIdChangesFrom(sessions::SessionTabHelper* helper);

  ExtensionFrameHost* extension_frame_host_for_testing() {
    return extension_frame_host_.get();
  }

 protected:
  explicit ExtensionWebContentsObserver(content::WebContents* web_contents);
  ~ExtensionWebContentsObserver() override;

  bool initialized() const { return initialized_; }

  content::BrowserContext* browser_context() { return browser_context_; }

  // Initializes a new render frame. Subclasses should invoke this
  // implementation if extending. Note: this should be called for both extension
  // and non-extension frames.
  virtual void InitializeRenderFrame(
      content::RenderFrameHost* render_frame_host);

  // Creates ExtensionFrameHost which implements mojom::LocalFrameHost.
  virtual std::unique_ptr<ExtensionFrameHost> CreateExtensionFrameHost(
      content::WebContents* web_contents);

  // ExtensionFunctionDispatcher::Delegate overrides.
  content::WebContents* GetAssociatedWebContents() const override;

  // content::WebContentsObserver overrides.
  void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
  void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
  void ReadyToCommitNavigation(
      content::NavigationHandle* navigation_handle) override;
  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override;
  void MediaPictureInPictureChanged(bool is_picture_in_picture) override;

  // Per the documentation in WebContentsObserver, these two methods are invoked
  // when a Pepper plugin instance is attached/detached in the page DOM.
  void PepperInstanceCreated() override;
  void PepperInstanceDeleted() override;

  // Temporarily needed to host common code between RenderFrameCreated and
  // ReadyToCommitNavigation.
  virtual void SetUpRenderFrameHost(
      content::RenderFrameHost* render_frame_host);

 private:
  using PassKey = base::PassKey<ExtensionWebContentsObserver>;

  void OnWindowIdChanged(SessionID id);

  // The BrowserContext associated with the WebContents being observed.
  raw_ptr<content::BrowserContext> browser_context_;

  ExtensionFunctionDispatcher dispatcher_;

  // Whether this object has been initialized.
  bool initialized_;

  std::unique_ptr<ExtensionFrameHost> extension_frame_host_;

  base::CallbackListSubscription window_id_subscription_;

  // A map of RenderFrameHost to mojo remotes.
  std::map<content::RenderFrameHost*, mojo::AssociatedRemote<mojom::LocalFrame>>
      local_frame_map_;
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_EXTENSION_WEB_CONTENTS_OBSERVER_H_