| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/renderer/extension_helper.h" | 5 #include "extensions/renderer/extension_helper.h" |
| 6 | 6 |
| 7 #include "base/lazy_instance.h" | |
| 8 #include "content/public/renderer/render_view.h" | 7 #include "content/public/renderer/render_view.h" |
| 9 #include "content/public/renderer/render_view_visitor.h" | 8 #include "content/public/renderer/render_view_visitor.h" |
| 10 #include "extensions/common/api/messaging/message.h" | 9 #include "extensions/common/api/messaging/message.h" |
| 11 #include "extensions/common/constants.h" | 10 #include "extensions/common/constants.h" |
| 12 #include "extensions/common/extension_messages.h" | 11 #include "extensions/common/extension_messages.h" |
| 13 #include "extensions/renderer/console.h" | 12 #include "extensions/renderer/console.h" |
| 14 #include "extensions/renderer/dispatcher.h" | 13 #include "extensions/renderer/dispatcher.h" |
| 15 #include "extensions/renderer/messaging_bindings.h" | 14 #include "extensions/renderer/messaging_bindings.h" |
| 16 #include "extensions/renderer/user_script_scheduler.h" | |
| 17 #include "extensions/renderer/user_script_slave.h" | |
| 18 #include "third_party/WebKit/public/platform/WebURLRequest.h" | 15 #include "third_party/WebKit/public/platform/WebURLRequest.h" |
| 19 #include "third_party/WebKit/public/web/WebConsoleMessage.h" | 16 #include "third_party/WebKit/public/web/WebConsoleMessage.h" |
| 20 #include "third_party/WebKit/public/web/WebDocument.h" | 17 #include "third_party/WebKit/public/web/WebDocument.h" |
| 21 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 18 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 22 #include "third_party/WebKit/public/web/WebScopedUserGesture.h" | |
| 23 #include "third_party/WebKit/public/web/WebView.h" | 19 #include "third_party/WebKit/public/web/WebView.h" |
| 24 | 20 |
| 25 using content::ConsoleMessageLevel; | 21 using content::ConsoleMessageLevel; |
| 26 using blink::WebConsoleMessage; | 22 using blink::WebConsoleMessage; |
| 27 using blink::WebDataSource; | 23 using blink::WebDataSource; |
| 28 using blink::WebFrame; | 24 using blink::WebFrame; |
| 29 using blink::WebLocalFrame; | 25 using blink::WebLocalFrame; |
| 30 using blink::WebURLRequest; | 26 using blink::WebURLRequest; |
| 31 using blink::WebScopedUserGesture; | |
| 32 using blink::WebView; | 27 using blink::WebView; |
| 33 | 28 |
| 34 namespace extensions { | 29 namespace extensions { |
| 35 | 30 |
| 36 namespace { | 31 namespace { |
| 37 // Keeps a mapping from the frame pointer to a UserScriptScheduler object. | |
| 38 // We store this mapping per process, because a frame can jump from one | |
| 39 // document to another with adoptNode, and so having the object be a | |
| 40 // RenderViewObserver means it might miss some notifications after it moves. | |
| 41 typedef std::map<WebFrame*, UserScriptScheduler*> SchedulerMap; | |
| 42 static base::LazyInstance<SchedulerMap> g_schedulers = | |
| 43 LAZY_INSTANCE_INITIALIZER; | |
| 44 | 32 |
| 45 // A RenderViewVisitor class that iterates through the set of available | 33 // A RenderViewVisitor class that iterates through the set of available |
| 46 // views, looking for a view of the given type, in the given browser window | 34 // views, looking for a view of the given type, in the given browser window |
| 47 // and within the given extension. | 35 // and within the given extension. |
| 48 // Used to accumulate the list of views associated with an extension. | 36 // Used to accumulate the list of views associated with an extension. |
| 49 class ViewAccumulator : public content::RenderViewVisitor { | 37 class ViewAccumulator : public content::RenderViewVisitor { |
| 50 public: | 38 public: |
| 51 ViewAccumulator(const std::string& extension_id, | 39 ViewAccumulator(const std::string& extension_id, |
| 52 int browser_window_id, | 40 int browser_window_id, |
| 53 ViewType view_type) | 41 ViewType view_type) |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 bool ExtensionHelper::OnMessageReceived(const IPC::Message& message) { | 130 bool ExtensionHelper::OnMessageReceived(const IPC::Message& message) { |
| 143 bool handled = true; | 131 bool handled = true; |
| 144 IPC_BEGIN_MESSAGE_MAP(ExtensionHelper, message) | 132 IPC_BEGIN_MESSAGE_MAP(ExtensionHelper, message) |
| 145 IPC_MESSAGE_HANDLER(ExtensionMsg_Response, OnExtensionResponse) | 133 IPC_MESSAGE_HANDLER(ExtensionMsg_Response, OnExtensionResponse) |
| 146 IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnExtensionMessageInvoke) | 134 IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnExtensionMessageInvoke) |
| 147 IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect, | 135 IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect, |
| 148 OnExtensionDispatchOnConnect) | 136 OnExtensionDispatchOnConnect) |
| 149 IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnExtensionDeliverMessage) | 137 IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnExtensionDeliverMessage) |
| 150 IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect, | 138 IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect, |
| 151 OnExtensionDispatchOnDisconnect) | 139 OnExtensionDispatchOnDisconnect) |
| 152 IPC_MESSAGE_HANDLER(ExtensionMsg_ExecuteCode, OnExecuteCode) | |
| 153 IPC_MESSAGE_HANDLER(ExtensionMsg_SetTabId, OnSetTabId) | 140 IPC_MESSAGE_HANDLER(ExtensionMsg_SetTabId, OnSetTabId) |
| 154 IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateBrowserWindowId, | 141 IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateBrowserWindowId, |
| 155 OnUpdateBrowserWindowId) | 142 OnUpdateBrowserWindowId) |
| 156 IPC_MESSAGE_HANDLER(ExtensionMsg_NotifyRenderViewType, | 143 IPC_MESSAGE_HANDLER(ExtensionMsg_NotifyRenderViewType, |
| 157 OnNotifyRendererViewType) | 144 OnNotifyRendererViewType) |
| 158 IPC_MESSAGE_HANDLER(ExtensionMsg_AddMessageToConsole, | 145 IPC_MESSAGE_HANDLER(ExtensionMsg_AddMessageToConsole, |
| 159 OnAddMessageToConsole) | 146 OnAddMessageToConsole) |
| 160 IPC_MESSAGE_HANDLER(ExtensionMsg_AppWindowClosed, | 147 IPC_MESSAGE_HANDLER(ExtensionMsg_AppWindowClosed, |
| 161 OnAppWindowClosed) | 148 OnAppWindowClosed) |
| 162 IPC_MESSAGE_HANDLER(ExtensionMsg_GrantContentScriptPermission, | |
| 163 OnGrantContentScriptPermission) | |
| 164 IPC_MESSAGE_UNHANDLED(handled = false) | 149 IPC_MESSAGE_UNHANDLED(handled = false) |
| 165 IPC_END_MESSAGE_MAP() | 150 IPC_END_MESSAGE_MAP() |
| 166 return handled; | 151 return handled; |
| 167 } | 152 } |
| 168 | 153 |
| 169 void ExtensionHelper::DidFinishDocumentLoad(WebLocalFrame* frame) { | |
| 170 dispatcher_->user_script_slave()->InjectScripts( | |
| 171 frame, UserScript::DOCUMENT_END); | |
| 172 | |
| 173 SchedulerMap::iterator i = g_schedulers.Get().find(frame); | |
| 174 if (i != g_schedulers.Get().end()) | |
| 175 i->second->DidFinishDocumentLoad(); | |
| 176 } | |
| 177 | |
| 178 void ExtensionHelper::DidFinishLoad(blink::WebLocalFrame* frame) { | |
| 179 SchedulerMap::iterator i = g_schedulers.Get().find(frame); | |
| 180 if (i != g_schedulers.Get().end()) | |
| 181 i->second->DidFinishLoad(); | |
| 182 } | |
| 183 | |
| 184 void ExtensionHelper::DidCreateDocumentElement(WebLocalFrame* frame) { | 154 void ExtensionHelper::DidCreateDocumentElement(WebLocalFrame* frame) { |
| 185 dispatcher_->user_script_slave()->InjectScripts( | |
| 186 frame, UserScript::DOCUMENT_START); | |
| 187 SchedulerMap::iterator i = g_schedulers.Get().find(frame); | |
| 188 if (i != g_schedulers.Get().end()) | |
| 189 i->second->DidCreateDocumentElement(); | |
| 190 | |
| 191 dispatcher_->DidCreateDocumentElement(frame); | 155 dispatcher_->DidCreateDocumentElement(frame); |
| 192 } | 156 } |
| 193 | 157 |
| 194 void ExtensionHelper::DidStartProvisionalLoad(blink::WebLocalFrame* frame) { | |
| 195 SchedulerMap::iterator i = g_schedulers.Get().find(frame); | |
| 196 if (i != g_schedulers.Get().end()) | |
| 197 i->second->DidStartProvisionalLoad(); | |
| 198 } | |
| 199 | |
| 200 void ExtensionHelper::DraggableRegionsChanged(blink::WebFrame* frame) { | 158 void ExtensionHelper::DraggableRegionsChanged(blink::WebFrame* frame) { |
| 201 blink::WebVector<blink::WebDraggableRegion> webregions = | 159 blink::WebVector<blink::WebDraggableRegion> webregions = |
| 202 frame->document().draggableRegions(); | 160 frame->document().draggableRegions(); |
| 203 std::vector<DraggableRegion> regions; | 161 std::vector<DraggableRegion> regions; |
| 204 for (size_t i = 0; i < webregions.size(); ++i) { | 162 for (size_t i = 0; i < webregions.size(); ++i) { |
| 205 DraggableRegion region; | 163 DraggableRegion region; |
| 206 region.bounds = webregions[i].bounds; | 164 region.bounds = webregions[i].bounds; |
| 207 region.draggable = webregions[i].draggable; | 165 region.draggable = webregions[i].draggable; |
| 208 regions.push_back(region); | 166 regions.push_back(region); |
| 209 } | 167 } |
| 210 Send(new ExtensionHostMsg_UpdateDraggableRegions(routing_id(), regions)); | 168 Send(new ExtensionHostMsg_UpdateDraggableRegions(routing_id(), regions)); |
| 211 } | 169 } |
| 212 | 170 |
| 213 void ExtensionHelper::FrameDetached(WebFrame* frame) { | |
| 214 // This could be called before DidCreateDataSource, in which case the frame | |
| 215 // won't be in the map. | |
| 216 SchedulerMap::iterator i = g_schedulers.Get().find(frame); | |
| 217 if (i == g_schedulers.Get().end()) | |
| 218 return; | |
| 219 | |
| 220 delete i->second; | |
| 221 g_schedulers.Get().erase(i); | |
| 222 | |
| 223 dispatcher_->user_script_slave()->FrameDetached(frame); | |
| 224 } | |
| 225 | |
| 226 void ExtensionHelper::DidMatchCSS( | 171 void ExtensionHelper::DidMatchCSS( |
| 227 blink::WebLocalFrame* frame, | 172 blink::WebLocalFrame* frame, |
| 228 const blink::WebVector<blink::WebString>& newly_matching_selectors, | 173 const blink::WebVector<blink::WebString>& newly_matching_selectors, |
| 229 const blink::WebVector<blink::WebString>& stopped_matching_selectors) { | 174 const blink::WebVector<blink::WebString>& stopped_matching_selectors) { |
| 230 dispatcher_->DidMatchCSS( | 175 dispatcher_->DidMatchCSS( |
| 231 frame, newly_matching_selectors, stopped_matching_selectors); | 176 frame, newly_matching_selectors, stopped_matching_selectors); |
| 232 } | 177 } |
| 233 | 178 |
| 234 void ExtensionHelper::DidCreateDataSource(WebLocalFrame* frame, | |
| 235 WebDataSource* ds) { | |
| 236 // Check first if we created a scheduler for the frame, since this function | |
| 237 // gets called for navigations within the document. | |
| 238 if (g_schedulers.Get().count(frame)) | |
| 239 return; | |
| 240 | |
| 241 g_schedulers.Get()[frame] = new UserScriptScheduler(frame, dispatcher_); | |
| 242 } | |
| 243 | |
| 244 void ExtensionHelper::OnExtensionResponse(int request_id, | 179 void ExtensionHelper::OnExtensionResponse(int request_id, |
| 245 bool success, | 180 bool success, |
| 246 const base::ListValue& response, | 181 const base::ListValue& response, |
| 247 const std::string& error) { | 182 const std::string& error) { |
| 248 dispatcher_->OnExtensionResponse(request_id, | 183 dispatcher_->OnExtensionResponse(request_id, |
| 249 success, | 184 success, |
| 250 response, | 185 response, |
| 251 error); | 186 error); |
| 252 } | 187 } |
| 253 | 188 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 282 dispatcher_->script_context_set(), target_id, message, render_view()); | 217 dispatcher_->script_context_set(), target_id, message, render_view()); |
| 283 } | 218 } |
| 284 | 219 |
| 285 void ExtensionHelper::OnExtensionDispatchOnDisconnect( | 220 void ExtensionHelper::OnExtensionDispatchOnDisconnect( |
| 286 int port_id, | 221 int port_id, |
| 287 const std::string& error_message) { | 222 const std::string& error_message) { |
| 288 MessagingBindings::DispatchOnDisconnect( | 223 MessagingBindings::DispatchOnDisconnect( |
| 289 dispatcher_->script_context_set(), port_id, error_message, render_view()); | 224 dispatcher_->script_context_set(), port_id, error_message, render_view()); |
| 290 } | 225 } |
| 291 | 226 |
| 292 void ExtensionHelper::OnExecuteCode( | |
| 293 const ExtensionMsg_ExecuteCode_Params& params) { | |
| 294 WebView* webview = render_view()->GetWebView(); | |
| 295 WebFrame* main_frame = webview->mainFrame(); | |
| 296 if (!main_frame) { | |
| 297 base::ListValue val; | |
| 298 Send(new ExtensionHostMsg_ExecuteCodeFinished(routing_id(), | |
| 299 params.request_id, | |
| 300 "No main frame", | |
| 301 -1, | |
| 302 GURL(std::string()), | |
| 303 val)); | |
| 304 return; | |
| 305 } | |
| 306 | |
| 307 // chrome.tabs.executeScript() only supports execution in either the top frame | |
| 308 // or all frames. We handle both cases in the top frame. | |
| 309 SchedulerMap::iterator i = g_schedulers.Get().find(main_frame); | |
| 310 if (i != g_schedulers.Get().end()) | |
| 311 i->second->ExecuteCode(params); | |
| 312 } | |
| 313 | |
| 314 void ExtensionHelper::OnNotifyRendererViewType(ViewType type) { | 227 void ExtensionHelper::OnNotifyRendererViewType(ViewType type) { |
| 315 view_type_ = type; | 228 view_type_ = type; |
| 316 } | 229 } |
| 317 | 230 |
| 318 void ExtensionHelper::OnSetTabId(int init_tab_id) { | 231 void ExtensionHelper::OnSetTabId(int init_tab_id) { |
| 319 CHECK_EQ(tab_id_, -1); | 232 CHECK_EQ(tab_id_, -1); |
| 320 CHECK_GE(init_tab_id, 0); | 233 CHECK_GE(init_tab_id, 0); |
| 321 tab_id_ = init_tab_id; | 234 tab_id_ = init_tab_id; |
| 322 } | 235 } |
| 323 | 236 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 335 v8::Handle<v8::Context> v8_context = | 248 v8::Handle<v8::Context> v8_context = |
| 336 render_view()->GetWebView()->mainFrame()->mainWorldScriptContext(); | 249 render_view()->GetWebView()->mainFrame()->mainWorldScriptContext(); |
| 337 ScriptContext* script_context = | 250 ScriptContext* script_context = |
| 338 dispatcher_->script_context_set().GetByV8Context(v8_context); | 251 dispatcher_->script_context_set().GetByV8Context(v8_context); |
| 339 if (!script_context) | 252 if (!script_context) |
| 340 return; | 253 return; |
| 341 script_context->module_system()->CallModuleMethod("app.window", | 254 script_context->module_system()->CallModuleMethod("app.window", |
| 342 "onAppWindowClosed"); | 255 "onAppWindowClosed"); |
| 343 } | 256 } |
| 344 | 257 |
| 345 void ExtensionHelper::OnGrantContentScriptPermission(int request_id) { | |
| 346 dispatcher_->user_script_slave()->OnContentScriptGrantedPermission( | |
| 347 render_view(), request_id); | |
| 348 } | |
| 349 | |
| 350 } // namespace extensions | 258 } // namespace extensions |
| OLD | NEW |