1 // Copyright 2013 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 5 #ifndef EXTENSIONS_RENDERER_EXTENSION_FRAME_HELPER_H_ 6 #define EXTENSIONS_RENDERER_EXTENSION_FRAME_HELPER_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/callback_forward.h" 12 #include "base/macros.h" 13 #include "base/memory/weak_ptr.h" 14 #include "content/public/renderer/render_frame_observer.h" 15 #include "content/public/renderer/render_frame_observer_tracker.h" 16 #include "extensions/common/view_type.h" 17 #include "third_party/blink/public/mojom/devtools/console_message.mojom.h" 18 #include "v8/include/v8.h" 19 20 struct ExtensionMsg_ExternalConnectionInfo; 21 struct ExtensionMsg_TabConnectionInfo; 22 23 namespace base { 24 class ListValue; 25 } 26 27 namespace extensions { 28 29 class Dispatcher; 30 struct Message; 31 struct PortId; 32 class ScriptContext; 33 34 // RenderFrame-level plumbing for extension features. 35 class ExtensionFrameHelper 36 : public content::RenderFrameObserver, 37 public content::RenderFrameObserverTracker<ExtensionFrameHelper> { 38 public: 39 ExtensionFrameHelper(content::RenderFrame* render_frame, 40 Dispatcher* extension_dispatcher); 41 ~ExtensionFrameHelper() override; 42 43 // Returns a list of extension RenderFrames that match the given filter 44 // criteria. A |browser_window_id| of extension_misc::kUnknownWindowId 45 // specifies "all", as does a |view_type| of VIEW_TYPE_INVALID. 46 static std::vector<content::RenderFrame*> GetExtensionFrames( 47 const std::string& extension_id, 48 int browser_window_id, 49 int tab_id, 50 ViewType view_type); 51 // Same as above, but returns a v8::Array of the v8 global objects for those 52 // frames, and only includes main frames. Note: This only returns contexts 53 // that are accessible by |context|, and |context| must be the current 54 // context. 55 // Returns an empty v8::Array if no frames are found. 56 static v8::Local<v8::Array> GetV8MainFrames(v8::Local<v8::Context> context, 57 const std::string& extension_id, 58 int browser_window_id, 59 int tab_id, 60 ViewType view_type); 61 62 // Returns the main frame of the extension's background page, or null if there 63 // isn't one in this process. 64 static content::RenderFrame* GetBackgroundPageFrame( 65 const std::string& extension_id); 66 // Same as above, but returns the background page's main frame, or 67 // v8::Undefined if there is none. Note: This will assert that the 68 // isolate's current context can access the returned object; callers should 69 // ensure that the current context is correct. 70 static v8::Local<v8::Value> GetV8BackgroundPageMainFrame( 71 v8::Isolate* isolate, 72 const std::string& extension_id); 73 74 // Finds a neighboring extension frame with the same extension as the one 75 // owning |relative_to_frame| (if |relative_to_frame| is not an extension 76 // frame, returns nullptr). Pierces the browsing instance boundary because 77 // certain extensions rely on this behavior. 78 // TODO(devlin, lukasza): https://crbug.com/786411: Remove this behavior, and 79 // make extensions follow the web standard for finding frames or use an 80 // explicit API. 81 static content::RenderFrame* FindFrame( 82 content::RenderFrame* relative_to_frame, 83 const std::string& name); 84 85 // Returns true if the given |context| is for any frame in the extension's 86 // event page. 87 // TODO(devlin): This isn't really used properly, and should probably be 88 // deleted. 89 static bool IsContextForEventPage(const ScriptContext* context); 90 view_type()91 ViewType view_type() const { return view_type_; } tab_id()92 int tab_id() const { return tab_id_; } browser_window_id()93 int browser_window_id() const { return browser_window_id_; } did_create_current_document_element()94 bool did_create_current_document_element() const { 95 return did_create_current_document_element_; 96 } 97 98 // Called when the document element has been inserted in this frame. This 99 // method may invoke untrusted JavaScript code that invalidate the frame and 100 // this ExtensionFrameHelper. 101 void RunScriptsAtDocumentStart(); 102 103 // Called after the DOMContentLoaded event has fired. 104 void RunScriptsAtDocumentEnd(); 105 106 // Called before the window.onload event is fired. 107 void RunScriptsAtDocumentIdle(); 108 109 // Schedule a callback, to be run at the next RunScriptsAtDocumentStart 110 // notification. Only call this when you are certain that there will be such a 111 // notification, e.g. from RenderFrameObserver::DidCreateDocumentElement. 112 // Otherwise the callback is never invoked, or invoked for a document that you 113 // were not expecting. 114 void ScheduleAtDocumentStart(const base::Closure& callback); 115 116 // Schedule a callback, to be run at the next RunScriptsAtDocumentEnd call. 117 void ScheduleAtDocumentEnd(const base::Closure& callback); 118 119 // Schedule a callback, to be run at the next RunScriptsAtDocumentIdle call. 120 void ScheduleAtDocumentIdle(const base::Closure& callback); 121 122 private: 123 // RenderFrameObserver implementation. 124 void DidCreateDocumentElement() override; 125 void DidCreateNewDocument() override; 126 void ReadyToCommitNavigation( 127 blink::WebDocumentLoader* document_loader) override; 128 void DidCommitProvisionalLoad(ui::PageTransition transition) override; 129 void DidCreateScriptContext(v8::Local<v8::Context>, 130 int32_t world_id) override; 131 void WillReleaseScriptContext(v8::Local<v8::Context>, 132 int32_t world_id) override; 133 bool OnMessageReceived(const IPC::Message& message) override; 134 void OnDestruct() override; 135 void DraggableRegionsChanged() override; 136 137 // IPC handlers. 138 void OnExtensionValidateMessagePort(int worker_thread_id, const PortId& id); 139 void OnExtensionDispatchOnConnect( 140 int worker_thread_id, 141 const PortId& target_port_id, 142 const std::string& channel_name, 143 const ExtensionMsg_TabConnectionInfo& source, 144 const ExtensionMsg_ExternalConnectionInfo& info); 145 void OnExtensionDeliverMessage(int worker_thread_id, 146 const PortId& target_port_id, 147 const Message& message); 148 void OnExtensionDispatchOnDisconnect(int worker_thread_id, 149 const PortId& id, 150 const std::string& error_message); 151 void OnExtensionSetTabId(int tab_id); 152 void OnUpdateBrowserWindowId(int browser_window_id); 153 void OnNotifyRendererViewType(ViewType view_type); 154 void OnExtensionResponse(int request_id, 155 bool success, 156 const base::ListValue& response, 157 const std::string& error); 158 void OnExtensionMessageInvoke(const std::string& extension_id, 159 const std::string& module_name, 160 const std::string& function_name, 161 const base::ListValue& args); 162 void OnSetFrameName(const std::string& name); 163 void OnAppWindowClosed(bool send_onclosed); 164 void OnSetSpatialNavigationEnabled(bool enabled); 165 166 // Type of view associated with the RenderFrame. 167 ViewType view_type_; 168 169 // The id of the tab the render frame is attached to. 170 int tab_id_; 171 172 // The id of the browser window the render frame is attached to. 173 int browser_window_id_; 174 175 Dispatcher* extension_dispatcher_; 176 177 // Whether or not the current document element has been created. 178 bool did_create_current_document_element_; 179 180 // Callbacks to be run at the next RunScriptsAtDocumentStart notification. 181 std::vector<base::Closure> document_element_created_callbacks_; 182 183 // Callbacks to be run at the next RunScriptsAtDocumentEnd notification. 184 std::vector<base::Closure> document_load_finished_callbacks_; 185 186 // Callbacks to be run at the next RunScriptsAtDocumentIdle notification. 187 std::vector<base::Closure> document_idle_callbacks_; 188 189 bool delayed_main_world_script_initialization_ = false; 190 191 // Whether or not a DocumentLoader has been created at least once for this 192 // RenderFrame. 193 // Note: Chrome Apps intentionally do not support new navigations. When a 194 // navigation happens, it is either the initial one or a reload. 195 bool has_started_first_navigation_ = false; 196 197 base::WeakPtrFactory<ExtensionFrameHelper> weak_ptr_factory_{this}; 198 199 DISALLOW_COPY_AND_ASSIGN(ExtensionFrameHelper); 200 }; 201 202 } // namespace extensions 203 204 #endif // EXTENSIONS_RENDERER_EXTENSION_FRAME_HELPER_H_ 205