extension_web_contents_observer.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef EXTENSIONS_BROWSER_EXTENSION_WEB_CONTENTS_OBSERVER_H_
  5. #define EXTENSIONS_BROWSER_EXTENSION_WEB_CONTENTS_OBSERVER_H_
  6. #include <map>
  7. #include <string>
  8. #include "base/compiler_specific.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/types/pass_key.h"
  11. #include "components/sessions/core/session_id.h"
  12. #include "content/public/browser/web_contents_observer.h"
  13. #include "extensions/browser/extension_function_dispatcher.h"
  14. #include "extensions/common/mojom/frame.mojom.h"
  15. #include "mojo/public/cpp/bindings/associated_remote.h"
  16. namespace content {
  17. class BrowserContext;
  18. class RenderFrameHost;
  19. class WebContents;
  20. }
  21. namespace sessions {
  22. class SessionTabHelper;
  23. }
  24. namespace extensions {
  25. class Extension;
  26. class ExtensionFrameHost;
  27. // A web contents observer used for renderer and extension processes. Grants the
  28. // renderer access to certain URL scheme patterns for extensions and notifies
  29. // the renderer that the extension was loaded.
  30. //
  31. // Extension system embedders must create an instance for every extension
  32. // WebContents. It must be a subclass so that creating an instance via
  33. // content::WebContentsUserData::CreateForWebContents() provides an object of
  34. // the correct type. For an example, see ChromeExtensionWebContentsObserver.
  35. //
  36. // This class is responsible for maintaining the registrations of extension
  37. // frames with the ProcessManager. Only frames in an extension process are
  38. // registered. If out-of-process frames are enabled, every frame hosts a
  39. // chrome-extension: page. Otherwise non-extension frames may erroneously be
  40. // registered, but only briefly until they are correctly classified. This is
  41. // achieved using the following notifications:
  42. // 1. RenderFrameCreated - registers all new frames in extension processes.
  43. // 2. DidCommitProvisionalLoadForFrame - unregisters non-extension frames.
  44. // 3. DidNavigateAnyFrame - registers extension frames if they had been
  45. // unregistered.
  46. //
  47. // Without OOPIF, non-extension frames created by the Chrome extension are also
  48. // registered at RenderFrameCreated. When the non-extension page is committed,
  49. // we detect that the unexpected URL and unregister the frame.
  50. // With OOPIF only the first notification is sufficient in most cases, except
  51. // for sandboxed frames with a unique origin.
  52. class ExtensionWebContentsObserver
  53. : public content::WebContentsObserver,
  54. public ExtensionFunctionDispatcher::Delegate {
  55. public:
  56. ExtensionWebContentsObserver(const ExtensionWebContentsObserver&) = delete;
  57. ExtensionWebContentsObserver& operator=(const ExtensionWebContentsObserver&) =
  58. delete;
  59. // Returns the ExtensionWebContentsObserver for the given |web_contents|.
  60. static ExtensionWebContentsObserver* GetForWebContents(
  61. content::WebContents* web_contents);
  62. // Binds the LocalFrameHost interface to the ExtensionFrameHost associated
  63. // with the RenderFrameHost.
  64. static void BindLocalFrameHost(
  65. mojo::PendingAssociatedReceiver<mojom::LocalFrameHost> receiver,
  66. content::RenderFrameHost* rfh);
  67. // This must be called by clients directly after the EWCO has been created.
  68. void Initialize();
  69. ExtensionFunctionDispatcher* dispatcher() { return &dispatcher_; }
  70. // Returns the extension associated with the given |render_frame_host|, or
  71. // null if there is none.
  72. // If |verify_url| is false, only the SiteInstance is taken into account.
  73. // If |verify_url| is true, the frame's last committed URL is also used to
  74. // improve the classification of the frame.
  75. const Extension* GetExtensionFromFrame(
  76. content::RenderFrameHost* render_frame_host,
  77. bool verify_url) const;
  78. // Returns mojom::LocalFrame* corresponding |render_frame_host|. It emplaces
  79. // AssociatedRemote<mojom::LocalFrame> to |local_frame_map_| if the map
  80. // doesn't have it. Note that it could return nullptr if |render_frame_host|
  81. // is not live.
  82. mojom::LocalFrame* GetLocalFrame(content::RenderFrameHost* render_frame_host);
  83. // Tells the receiver to start listening to window ID changes from the
  84. // supplied SessionTabHelper. This method is public to allow the code that
  85. // installs new SessionTabHelpers to call it; that in turn is required because
  86. // SessionTabHelpers may be created after the corresponding
  87. // ExtensionWebContentsObserver has already been initialized.
  88. void ListenToWindowIdChangesFrom(sessions::SessionTabHelper* helper);
  89. ExtensionFrameHost* extension_frame_host_for_testing() {
  90. return extension_frame_host_.get();
  91. }
  92. protected:
  93. explicit ExtensionWebContentsObserver(content::WebContents* web_contents);
  94. ~ExtensionWebContentsObserver() override;
  95. bool initialized() const { return initialized_; }
  96. content::BrowserContext* browser_context() { return browser_context_; }
  97. // Initializes a new render frame. Subclasses should invoke this
  98. // implementation if extending. Note: this should be called for both extension
  99. // and non-extension frames.
  100. virtual void InitializeRenderFrame(
  101. content::RenderFrameHost* render_frame_host);
  102. // Creates ExtensionFrameHost which implements mojom::LocalFrameHost.
  103. virtual std::unique_ptr<ExtensionFrameHost> CreateExtensionFrameHost(
  104. content::WebContents* web_contents);
  105. // ExtensionFunctionDispatcher::Delegate overrides.
  106. content::WebContents* GetAssociatedWebContents() const override;
  107. // content::WebContentsObserver overrides.
  108. void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
  109. void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
  110. void ReadyToCommitNavigation(
  111. content::NavigationHandle* navigation_handle) override;
  112. void DidFinishNavigation(
  113. content::NavigationHandle* navigation_handle) override;
  114. void MediaPictureInPictureChanged(bool is_picture_in_picture) override;
  115. // Per the documentation in WebContentsObserver, these two methods are invoked
  116. // when a Pepper plugin instance is attached/detached in the page DOM.
  117. void PepperInstanceCreated() override;
  118. void PepperInstanceDeleted() override;
  119. // Returns the extension id associated with the given |render_frame_host|, or
  120. // the empty string if there is none.
  121. std::string GetExtensionIdFromFrame(
  122. content::RenderFrameHost* render_frame_host) const;
  123. private:
  124. using PassKey = base::PassKey<ExtensionWebContentsObserver>;
  125. void OnWindowIdChanged(const SessionID& id);
  126. // The BrowserContext associated with the WebContents being observed.
  127. raw_ptr<content::BrowserContext> browser_context_;
  128. ExtensionFunctionDispatcher dispatcher_;
  129. // Whether this object has been initialized.
  130. bool initialized_;
  131. std::unique_ptr<ExtensionFrameHost> extension_frame_host_;
  132. base::CallbackListSubscription window_id_subscription_;
  133. // A map of render frame host to mojo remotes.
  134. std::map<content::RenderFrameHost*, mojo::AssociatedRemote<mojom::LocalFrame>>
  135. local_frame_map_;
  136. };
  137. } // namespace extensions
  138. #endif // EXTENSIONS_BROWSER_EXTENSION_WEB_CONTENTS_OBSERVER_H_