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 |