OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 #include "chrome/browser/renderer_host/render_view_host.h" | |
6 | |
7 #include <string> | |
8 #include <utility> | |
9 #include <vector> | |
10 | |
11 #include "base/command_line.h" | |
12 #include "base/i18n/rtl.h" | |
13 #include "base/json/json_reader.h" | |
14 #include "base/string_util.h" | |
15 #include "base/time.h" | |
16 #include "base/utf_string_conversions.h" | |
17 #include "base/values.h" | |
18 #include "chrome/browser/child_process_security_policy.h" | |
19 #include "chrome/browser/cross_site_request_manager.h" | |
20 #include "chrome/browser/debugger/devtools_manager.h" | |
21 #include "chrome/browser/dom_operation_notification_details.h" | |
22 #include "chrome/browser/extensions/extension_message_service.h" | |
23 #include "chrome/browser/in_process_webkit/session_storage_namespace.h" | |
24 #include "chrome/browser/metrics/user_metrics.h" | |
25 #include "chrome/browser/net/predictor_api.h" | |
26 #include "chrome/browser/profiles/profile.h" | |
27 #include "chrome/browser/renderer_host/render_process_host.h" | |
28 #include "chrome/browser/renderer_host/render_view_host_delegate.h" | |
29 #include "chrome/browser/renderer_host/render_widget_host.h" | |
30 #include "chrome/browser/renderer_host/render_widget_host_view.h" | |
31 #include "chrome/browser/renderer_host/site_instance.h" | |
32 #include "chrome/common/bindings_policy.h" | |
33 #include "chrome/common/chrome_constants.h" | |
34 #include "chrome/common/chrome_switches.h" | |
35 #include "chrome/common/native_web_keyboard_event.h" | |
36 #include "chrome/common/net/url_request_context_getter.h" | |
37 #include "chrome/common/notification_details.h" | |
38 #include "chrome/common/notification_service.h" | |
39 #include "chrome/common/notification_type.h" | |
40 #include "chrome/common/render_messages.h" | |
41 #include "chrome/common/render_messages_params.h" | |
42 #include "chrome/common/result_codes.h" | |
43 #include "chrome/common/thumbnail_score.h" | |
44 #include "chrome/common/translate_errors.h" | |
45 #include "chrome/common/url_constants.h" | |
46 #include "chrome/common/web_apps.h" | |
47 #include "net/base/net_util.h" | |
48 #include "printing/native_metafile.h" | |
49 #include "third_party/skia/include/core/SkBitmap.h" | |
50 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFindOptions.h" | |
51 #include "ui/gfx/native_widget_types.h" | |
52 #include "webkit/glue/context_menu.h" | |
53 #include "webkit/glue/webaccessibility.h" | |
54 #include "webkit/glue/webdropdata.h" | |
55 | |
56 using base::TimeDelta; | |
57 using WebKit::WebConsoleMessage; | |
58 using WebKit::WebDragOperation; | |
59 using WebKit::WebDragOperationNone; | |
60 using WebKit::WebDragOperationsMask; | |
61 using WebKit::WebFindOptions; | |
62 using WebKit::WebInputEvent; | |
63 using WebKit::WebMediaPlayerAction; | |
64 using WebKit::WebTextDirection; | |
65 | |
66 namespace { | |
67 | |
68 // Delay to wait on closing the tab for a beforeunload/unload handler to fire. | |
69 const int kUnloadTimeoutMS = 1000; | |
70 | |
71 } // namespace | |
72 | |
73 /////////////////////////////////////////////////////////////////////////////// | |
74 // RenderViewHost, public: | |
75 | |
76 // static | |
77 RenderViewHost* RenderViewHost::FromID(int render_process_id, | |
78 int render_view_id) { | |
79 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id); | |
80 if (!process) | |
81 return NULL; | |
82 RenderWidgetHost* widget = static_cast<RenderWidgetHost*>( | |
83 process->GetListenerByID(render_view_id)); | |
84 if (!widget || !widget->IsRenderView()) | |
85 return NULL; | |
86 return static_cast<RenderViewHost*>(widget); | |
87 } | |
88 | |
89 RenderViewHost::RenderViewHost(SiteInstance* instance, | |
90 RenderViewHostDelegate* delegate, | |
91 int routing_id, | |
92 SessionStorageNamespace* session_storage) | |
93 : RenderWidgetHost(instance->GetProcess(), routing_id), | |
94 instance_(instance), | |
95 delegate_(delegate), | |
96 waiting_for_drag_context_response_(false), | |
97 enabled_bindings_(0), | |
98 pending_request_id_(0), | |
99 navigations_suspended_(false), | |
100 suspended_nav_message_(NULL), | |
101 run_modal_reply_msg_(NULL), | |
102 is_waiting_for_beforeunload_ack_(false), | |
103 is_waiting_for_unload_ack_(false), | |
104 unload_ack_is_for_cross_site_transition_(false), | |
105 are_javascript_messages_suppressed_(false), | |
106 sudden_termination_allowed_(false), | |
107 session_storage_namespace_(session_storage), | |
108 is_extension_process_(false), | |
109 save_accessibility_tree_for_testing_(false), | |
110 render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING) { | |
111 if (!session_storage_namespace_) { | |
112 session_storage_namespace_ = | |
113 new SessionStorageNamespace(process()->profile()); | |
114 } | |
115 | |
116 DCHECK(instance_); | |
117 DCHECK(delegate_); | |
118 } | |
119 | |
120 RenderViewHost::~RenderViewHost() { | |
121 delegate()->RenderViewDeleted(this); | |
122 | |
123 // Be sure to clean up any leftover state from cross-site requests. | |
124 CrossSiteRequestManager::GetInstance()->SetHasPendingCrossSiteRequest( | |
125 process()->id(), routing_id(), false); | |
126 } | |
127 | |
128 bool RenderViewHost::CreateRenderView(const string16& frame_name) { | |
129 DCHECK(!IsRenderViewLive()) << "Creating view twice"; | |
130 | |
131 // The process may (if we're sharing a process with another host that already | |
132 // initialized it) or may not (we have our own process or the old process | |
133 // crashed) have been initialized. Calling Init multiple times will be | |
134 // ignored, so this is safe. | |
135 if (!process()->Init(renderer_accessible(), is_extension_process_)) | |
136 return false; | |
137 DCHECK(process()->HasConnection()); | |
138 DCHECK(process()->profile()); | |
139 | |
140 if (BindingsPolicy::is_web_ui_enabled(enabled_bindings_)) { | |
141 ChildProcessSecurityPolicy::GetInstance()->GrantWebUIBindings( | |
142 process()->id()); | |
143 } | |
144 | |
145 if (BindingsPolicy::is_extension_enabled(enabled_bindings_)) { | |
146 ChildProcessSecurityPolicy::GetInstance()->GrantExtensionBindings( | |
147 process()->id()); | |
148 | |
149 // Extensions may have permission to access chrome:// URLs. | |
150 ChildProcessSecurityPolicy::GetInstance()->GrantScheme( | |
151 process()->id(), chrome::kChromeUIScheme); | |
152 } | |
153 | |
154 renderer_initialized_ = true; | |
155 | |
156 ViewMsg_New_Params params; | |
157 params.parent_window = GetNativeViewId(); | |
158 params.renderer_preferences = | |
159 delegate_->GetRendererPrefs(process()->profile()); | |
160 params.web_preferences = delegate_->GetWebkitPrefs(); | |
161 params.view_id = routing_id(); | |
162 params.session_storage_namespace_id = session_storage_namespace_->id(); | |
163 params.frame_name = frame_name; | |
164 Send(new ViewMsg_New(params)); | |
165 | |
166 // Set the alternate error page, which is profile specific, in the renderer. | |
167 GURL url = delegate_->GetAlternateErrorPageURL(); | |
168 SetAlternateErrorPageURL(url); | |
169 | |
170 // If it's enabled, tell the renderer to set up the Javascript bindings for | |
171 // sending messages back to the browser. | |
172 Send(new ViewMsg_AllowBindings(routing_id(), enabled_bindings_)); | |
173 UpdateBrowserWindowId(delegate_->GetBrowserWindowID()); | |
174 Send(new ViewMsg_NotifyRenderViewType(routing_id(), | |
175 delegate_->GetRenderViewType())); | |
176 // Let our delegate know that we created a RenderView. | |
177 delegate_->RenderViewCreated(this); | |
178 process()->ViewCreated(); | |
179 | |
180 return true; | |
181 } | |
182 | |
183 bool RenderViewHost::IsRenderViewLive() const { | |
184 return process()->HasConnection() && renderer_initialized_; | |
185 } | |
186 | |
187 void RenderViewHost::SyncRendererPrefs() { | |
188 Send(new ViewMsg_SetRendererPrefs(routing_id(), | |
189 delegate_->GetRendererPrefs( | |
190 process()->profile()))); | |
191 } | |
192 | |
193 void RenderViewHost::Navigate(const ViewMsg_Navigate_Params& params) { | |
194 ChildProcessSecurityPolicy::GetInstance()->GrantRequestURL( | |
195 process()->id(), params.url); | |
196 | |
197 ViewMsg_Navigate* nav_message = new ViewMsg_Navigate(routing_id(), params); | |
198 | |
199 // Only send the message if we aren't suspended at the start of a cross-site | |
200 // request. | |
201 if (navigations_suspended_) { | |
202 // Shouldn't be possible to have a second navigation while suspended, since | |
203 // navigations will only be suspended during a cross-site request. If a | |
204 // second navigation occurs, TabContents will cancel this pending RVH | |
205 // create a new pending RVH. | |
206 DCHECK(!suspended_nav_message_.get()); | |
207 suspended_nav_message_.reset(nav_message); | |
208 } else { | |
209 // Unset this, otherwise if true and the hang monitor fires we'll | |
210 // incorrectly close the tab. | |
211 is_waiting_for_unload_ack_ = false; | |
212 | |
213 Send(nav_message); | |
214 | |
215 // Force the throbber to start. We do this because WebKit's "started | |
216 // loading" message will be received asynchronously from the UI of the | |
217 // browser. But we want to keep the throbber in sync with what's happening | |
218 // in the UI. For example, we want to start throbbing immediately when the | |
219 // user naivgates even if the renderer is delayed. There is also an issue | |
220 // with the throbber starting because the WebUI (which controls whether the | |
221 // favicon is displayed) happens synchronously. If the start loading | |
222 // messages was asynchronous, then the default favicon would flash in. | |
223 // | |
224 // WebKit doesn't send throb notifications for JavaScript URLs, so we | |
225 // don't want to either. | |
226 if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) | |
227 delegate_->DidStartLoading(); | |
228 } | |
229 const GURL& url = params.url; | |
230 if (!delegate_->IsExternalTabContainer() && | |
231 (url.SchemeIs("http") || url.SchemeIs("https"))) | |
232 chrome_browser_net::PreconnectUrlAndSubresources(url); | |
233 } | |
234 | |
235 void RenderViewHost::NavigateToURL(const GURL& url) { | |
236 ViewMsg_Navigate_Params params; | |
237 params.page_id = -1; | |
238 params.url = url; | |
239 params.transition = PageTransition::LINK; | |
240 params.navigation_type = ViewMsg_Navigate_Params::NORMAL; | |
241 Navigate(params); | |
242 } | |
243 | |
244 void RenderViewHost::SetNavigationsSuspended(bool suspend) { | |
245 // This should only be called to toggle the state. | |
246 DCHECK(navigations_suspended_ != suspend); | |
247 | |
248 navigations_suspended_ = suspend; | |
249 if (!suspend && suspended_nav_message_.get()) { | |
250 // There's a navigation message waiting to be sent. Now that we're not | |
251 // suspended anymore, resume navigation by sending it. | |
252 Send(suspended_nav_message_.release()); | |
253 } | |
254 } | |
255 | |
256 void RenderViewHost::FirePageBeforeUnload(bool for_cross_site_transition) { | |
257 if (!IsRenderViewLive()) { | |
258 // This RenderViewHost doesn't have a live renderer, so just skip running | |
259 // the onbeforeunload handler. | |
260 is_waiting_for_beforeunload_ack_ = true; // Checked by OnMsgShouldCloseACK. | |
261 unload_ack_is_for_cross_site_transition_ = for_cross_site_transition; | |
262 OnMsgShouldCloseACK(true); | |
263 return; | |
264 } | |
265 | |
266 // This may be called more than once (if the user clicks the tab close button | |
267 // several times, or if she clicks the tab close button then the browser close | |
268 // button), and we only send the message once. | |
269 if (is_waiting_for_beforeunload_ack_) { | |
270 // Some of our close messages could be for the tab, others for cross-site | |
271 // transitions. We always want to think it's for closing the tab if any | |
272 // of the messages were, since otherwise it might be impossible to close | |
273 // (if there was a cross-site "close" request pending when the user clicked | |
274 // the close button). We want to keep the "for cross site" flag only if | |
275 // both the old and the new ones are also for cross site. | |
276 unload_ack_is_for_cross_site_transition_ = | |
277 unload_ack_is_for_cross_site_transition_ && for_cross_site_transition; | |
278 } else { | |
279 // Start the hang monitor in case the renderer hangs in the beforeunload | |
280 // handler. | |
281 is_waiting_for_beforeunload_ack_ = true; | |
282 unload_ack_is_for_cross_site_transition_ = for_cross_site_transition; | |
283 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); | |
284 Send(new ViewMsg_ShouldClose(routing_id())); | |
285 } | |
286 } | |
287 | |
288 void RenderViewHost::ClosePage(bool for_cross_site_transition, | |
289 int new_render_process_host_id, | |
290 int new_request_id) { | |
291 // In most cases, this will not be set to false afterward. Either the tab | |
292 // will be closed, or a pending RenderViewHost will replace this one. | |
293 is_waiting_for_unload_ack_ = true; | |
294 // Start the hang monitor in case the renderer hangs in the unload handler. | |
295 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); | |
296 | |
297 ViewMsg_ClosePage_Params params; | |
298 params.closing_process_id = process()->id(); | |
299 params.closing_route_id = routing_id(); | |
300 params.for_cross_site_transition = for_cross_site_transition; | |
301 params.new_render_process_host_id = new_render_process_host_id; | |
302 params.new_request_id = new_request_id; | |
303 if (IsRenderViewLive()) { | |
304 NotificationService::current()->Notify( | |
305 NotificationType::RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW, | |
306 Source<RenderViewHost>(this), | |
307 NotificationService::NoDetails()); | |
308 | |
309 Send(new ViewMsg_ClosePage(routing_id(), params)); | |
310 } else { | |
311 // This RenderViewHost doesn't have a live renderer, so just skip closing | |
312 // the page. We must notify the ResourceDispatcherHost on the IO thread, | |
313 // which we will do through the RenderProcessHost's widget helper. | |
314 process()->CrossSiteClosePageACK(params); | |
315 } | |
316 } | |
317 | |
318 void RenderViewHost::ClosePageIgnoringUnloadEvents() { | |
319 StopHangMonitorTimeout(); | |
320 is_waiting_for_beforeunload_ack_ = false; | |
321 is_waiting_for_unload_ack_ = false; | |
322 | |
323 sudden_termination_allowed_ = true; | |
324 delegate_->Close(this); | |
325 } | |
326 | |
327 void RenderViewHost::SetHasPendingCrossSiteRequest(bool has_pending_request, | |
328 int request_id) { | |
329 CrossSiteRequestManager::GetInstance()->SetHasPendingCrossSiteRequest( | |
330 process()->id(), routing_id(), has_pending_request); | |
331 pending_request_id_ = request_id; | |
332 } | |
333 | |
334 int RenderViewHost::GetPendingRequestId() { | |
335 return pending_request_id_; | |
336 } | |
337 | |
338 RenderViewHost::CommandState RenderViewHost::GetStateForCommand( | |
339 RenderViewCommand command) const { | |
340 if (command != RENDER_VIEW_COMMAND_TOGGLE_SPELL_CHECK) | |
341 LOG(DFATAL) << "Unknown command " << command; | |
342 | |
343 std::map<RenderViewCommand, CommandState>::const_iterator it = | |
344 command_states_.find(command); | |
345 if (it == command_states_.end()) { | |
346 CommandState state; | |
347 state.is_enabled = false; | |
348 state.checked_state = RENDER_VIEW_COMMAND_CHECKED_STATE_UNCHECKED; | |
349 return state; | |
350 } | |
351 return it->second; | |
352 } | |
353 | |
354 void RenderViewHost::Stop() { | |
355 Send(new ViewMsg_Stop(routing_id())); | |
356 } | |
357 | |
358 void RenderViewHost::ReloadFrame() { | |
359 Send(new ViewMsg_ReloadFrame(routing_id())); | |
360 } | |
361 | |
362 bool RenderViewHost::PrintPages() { | |
363 return Send(new ViewMsg_PrintPages(routing_id())); | |
364 } | |
365 | |
366 bool RenderViewHost::PrintPreview() { | |
367 return Send(new ViewMsg_PrintPreview(routing_id())); | |
368 } | |
369 | |
370 void RenderViewHost::PrintingDone(int document_cookie, bool success) { | |
371 Send(new ViewMsg_PrintingDone(routing_id(), document_cookie, success)); | |
372 } | |
373 | |
374 void RenderViewHost::StartFinding(int request_id, | |
375 const string16& search_text, | |
376 bool forward, | |
377 bool match_case, | |
378 bool find_next) { | |
379 if (search_text.empty()) | |
380 return; | |
381 | |
382 WebFindOptions options; | |
383 options.forward = forward; | |
384 options.matchCase = match_case; | |
385 options.findNext = find_next; | |
386 Send(new ViewMsg_Find(routing_id(), request_id, search_text, options)); | |
387 | |
388 // This call is asynchronous and returns immediately. | |
389 // The result of the search is sent as a notification message by the renderer. | |
390 } | |
391 | |
392 void RenderViewHost::StopFinding( | |
393 FindBarController::SelectionAction selection_action) { | |
394 ViewMsg_StopFinding_Params params; | |
395 | |
396 switch (selection_action) { | |
397 case FindBarController::kClearSelection: | |
398 params.action = ViewMsg_StopFinding_Params::kClearSelection; | |
399 break; | |
400 case FindBarController::kKeepSelection: | |
401 params.action = ViewMsg_StopFinding_Params::kKeepSelection; | |
402 break; | |
403 case FindBarController::kActivateSelection: | |
404 params.action = ViewMsg_StopFinding_Params::kActivateSelection; | |
405 break; | |
406 default: | |
407 NOTREACHED(); | |
408 params.action = ViewMsg_StopFinding_Params::kKeepSelection; | |
409 } | |
410 Send(new ViewMsg_StopFinding(routing_id(), params)); | |
411 } | |
412 | |
413 void RenderViewHost::Zoom(PageZoom::Function function) { | |
414 Send(new ViewMsg_Zoom(routing_id(), function)); | |
415 } | |
416 | |
417 void RenderViewHost::SetZoomLevel(double zoom_level) { | |
418 Send(new ViewMsg_SetZoomLevel(routing_id(), zoom_level)); | |
419 } | |
420 | |
421 void RenderViewHost::SetPageEncoding(const std::string& encoding_name) { | |
422 Send(new ViewMsg_SetPageEncoding(routing_id(), encoding_name)); | |
423 } | |
424 | |
425 void RenderViewHost::ResetPageEncodingToDefault() { | |
426 Send(new ViewMsg_ResetPageEncodingToDefault(routing_id())); | |
427 } | |
428 | |
429 void RenderViewHost::SetAlternateErrorPageURL(const GURL& url) { | |
430 Send(new ViewMsg_SetAltErrorPageURL(routing_id(), url)); | |
431 } | |
432 | |
433 void RenderViewHost::DragTargetDragEnter( | |
434 const WebDropData& drop_data, | |
435 const gfx::Point& client_pt, | |
436 const gfx::Point& screen_pt, | |
437 WebDragOperationsMask operations_allowed) { | |
438 // Grant the renderer the ability to load the drop_data. | |
439 ChildProcessSecurityPolicy* policy = | |
440 ChildProcessSecurityPolicy::GetInstance(); | |
441 policy->GrantRequestURL(process()->id(), drop_data.url); | |
442 for (std::vector<string16>::const_iterator iter(drop_data.filenames.begin()); | |
443 iter != drop_data.filenames.end(); ++iter) { | |
444 FilePath path = FilePath::FromWStringHack(UTF16ToWideHack(*iter)); | |
445 policy->GrantRequestURL(process()->id(), | |
446 net::FilePathToFileURL(path)); | |
447 policy->GrantReadFile(process()->id(), path); | |
448 } | |
449 Send(new ViewMsg_DragTargetDragEnter(routing_id(), drop_data, client_pt, | |
450 screen_pt, operations_allowed)); | |
451 } | |
452 | |
453 void RenderViewHost::DragTargetDragOver( | |
454 const gfx::Point& client_pt, const gfx::Point& screen_pt, | |
455 WebDragOperationsMask operations_allowed) { | |
456 Send(new ViewMsg_DragTargetDragOver(routing_id(), client_pt, screen_pt, | |
457 operations_allowed)); | |
458 } | |
459 | |
460 void RenderViewHost::DragTargetDragLeave() { | |
461 Send(new ViewMsg_DragTargetDragLeave(routing_id())); | |
462 } | |
463 | |
464 void RenderViewHost::DragTargetDrop( | |
465 const gfx::Point& client_pt, const gfx::Point& screen_pt) { | |
466 Send(new ViewMsg_DragTargetDrop(routing_id(), client_pt, screen_pt)); | |
467 } | |
468 | |
469 void RenderViewHost::ReservePageIDRange(int size) { | |
470 Send(new ViewMsg_ReservePageIDRange(routing_id(), size)); | |
471 } | |
472 | |
473 void RenderViewHost::ExecuteJavascriptInWebFrame( | |
474 const string16& frame_xpath, | |
475 const string16& jscript) { | |
476 Send(new ViewMsg_ScriptEvalRequest(routing_id(), frame_xpath, jscript, | |
477 0, false)); | |
478 } | |
479 | |
480 int RenderViewHost::ExecuteJavascriptInWebFrameNotifyResult( | |
481 const string16& frame_xpath, | |
482 const string16& jscript) { | |
483 static int next_id = 1; | |
484 Send(new ViewMsg_ScriptEvalRequest(routing_id(), frame_xpath, jscript, | |
485 next_id, true)); | |
486 return next_id++; | |
487 } | |
488 | |
489 void RenderViewHost::InsertCSSInWebFrame( | |
490 const std::wstring& frame_xpath, | |
491 const std::string& css, | |
492 const std::string& id) { | |
493 Send(new ViewMsg_CSSInsertRequest(routing_id(), frame_xpath, css, id)); | |
494 } | |
495 | |
496 void RenderViewHost::AddMessageToConsole( | |
497 const string16& frame_xpath, | |
498 const string16& message, | |
499 const WebConsoleMessage::Level& level) { | |
500 Send(new ViewMsg_AddMessageToConsole( | |
501 routing_id(), frame_xpath, message, level)); | |
502 } | |
503 | |
504 void RenderViewHost::Undo() { | |
505 Send(new ViewMsg_Undo(routing_id())); | |
506 } | |
507 | |
508 void RenderViewHost::Redo() { | |
509 Send(new ViewMsg_Redo(routing_id())); | |
510 } | |
511 | |
512 void RenderViewHost::Cut() { | |
513 Send(new ViewMsg_Cut(routing_id())); | |
514 } | |
515 | |
516 void RenderViewHost::Copy() { | |
517 Send(new ViewMsg_Copy(routing_id())); | |
518 } | |
519 | |
520 void RenderViewHost::CopyToFindPboard() { | |
521 #if defined(OS_MACOSX) | |
522 // Windows/Linux don't have the concept of a find pasteboard. | |
523 Send(new ViewMsg_CopyToFindPboard(routing_id())); | |
524 #endif | |
525 } | |
526 | |
527 void RenderViewHost::Paste() { | |
528 Send(new ViewMsg_Paste(routing_id())); | |
529 } | |
530 | |
531 void RenderViewHost::ToggleSpellCheck() { | |
532 Send(new ViewMsg_ToggleSpellCheck(routing_id())); | |
533 } | |
534 | |
535 void RenderViewHost::Delete() { | |
536 Send(new ViewMsg_Delete(routing_id())); | |
537 } | |
538 | |
539 void RenderViewHost::SelectAll() { | |
540 Send(new ViewMsg_SelectAll(routing_id())); | |
541 } | |
542 | |
543 void RenderViewHost::ToggleSpellPanel(bool is_currently_visible) { | |
544 Send(new ViewMsg_ToggleSpellPanel(routing_id(), is_currently_visible)); | |
545 } | |
546 | |
547 int RenderViewHost::DownloadFavIcon(const GURL& url, int image_size) { | |
548 if (!url.is_valid()) { | |
549 NOTREACHED(); | |
550 return 0; | |
551 } | |
552 static int next_id = 1; | |
553 int id = next_id++; | |
554 Send(new ViewMsg_DownloadFavIcon(routing_id(), id, url, image_size)); | |
555 return id; | |
556 } | |
557 | |
558 void RenderViewHost::GetApplicationInfo(int32 page_id) { | |
559 Send(new ViewMsg_GetApplicationInfo(routing_id(), page_id)); | |
560 } | |
561 | |
562 void RenderViewHost::CaptureThumbnail() { | |
563 Send(new ViewMsg_CaptureThumbnail(routing_id())); | |
564 } | |
565 | |
566 void RenderViewHost::CaptureSnapshot() { | |
567 Send(new ViewMsg_CaptureSnapshot(routing_id())); | |
568 } | |
569 | |
570 void RenderViewHost::JavaScriptMessageBoxClosed(IPC::Message* reply_msg, | |
571 bool success, | |
572 const std::wstring& prompt) { | |
573 process()->set_ignore_input_events(false); | |
574 bool is_waiting = | |
575 is_waiting_for_beforeunload_ack_ || is_waiting_for_unload_ack_; | |
576 if (is_waiting) | |
577 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); | |
578 | |
579 ViewHostMsg_RunJavaScriptMessage::WriteReplyParams(reply_msg, | |
580 success, prompt); | |
581 Send(reply_msg); | |
582 | |
583 // If we are waiting for an unload or beforeunload ack and the user has | |
584 // suppressed messages, kill the tab immediately; a page that's spamming | |
585 // alerts in onbeforeunload is presumably malicious, so there's no point in | |
586 // continuing to run its script and dragging out the process. | |
587 // This must be done after sending the reply since RenderView can't close | |
588 // correctly while waiting for a response. | |
589 if (is_waiting && are_javascript_messages_suppressed_) | |
590 delegate_->RendererUnresponsive(this, is_waiting); | |
591 } | |
592 | |
593 void RenderViewHost::ModalHTMLDialogClosed(IPC::Message* reply_msg, | |
594 const std::string& json_retval) { | |
595 if (is_waiting_for_beforeunload_ack_ || is_waiting_for_unload_ack_) | |
596 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); | |
597 | |
598 ViewHostMsg_ShowModalHTMLDialog::WriteReplyParams(reply_msg, json_retval); | |
599 Send(reply_msg); | |
600 } | |
601 | |
602 void RenderViewHost::CopyImageAt(int x, int y) { | |
603 Send(new ViewMsg_CopyImageAt(routing_id(), x, y)); | |
604 } | |
605 | |
606 void RenderViewHost::DragSourceEndedAt( | |
607 int client_x, int client_y, int screen_x, int screen_y, | |
608 WebDragOperation operation) { | |
609 Send(new ViewMsg_DragSourceEndedOrMoved( | |
610 routing_id(), | |
611 gfx::Point(client_x, client_y), | |
612 gfx::Point(screen_x, screen_y), | |
613 true, operation)); | |
614 } | |
615 | |
616 void RenderViewHost::DragSourceMovedTo( | |
617 int client_x, int client_y, int screen_x, int screen_y) { | |
618 Send(new ViewMsg_DragSourceEndedOrMoved( | |
619 routing_id(), | |
620 gfx::Point(client_x, client_y), | |
621 gfx::Point(screen_x, screen_y), | |
622 false, WebDragOperationNone)); | |
623 } | |
624 | |
625 void RenderViewHost::DragSourceSystemDragEnded() { | |
626 Send(new ViewMsg_DragSourceSystemDragEnded(routing_id())); | |
627 } | |
628 | |
629 void RenderViewHost::AllowBindings(int bindings_flags) { | |
630 DCHECK(!renderer_initialized_); | |
631 enabled_bindings_ |= bindings_flags; | |
632 } | |
633 | |
634 void RenderViewHost::SetWebUIProperty(const std::string& name, | |
635 const std::string& value) { | |
636 DCHECK(BindingsPolicy::is_web_ui_enabled(enabled_bindings_)); | |
637 Send(new ViewMsg_SetWebUIProperty(routing_id(), name, value)); | |
638 } | |
639 | |
640 void RenderViewHost::GotFocus() { | |
641 RenderWidgetHost::GotFocus(); // Notifies the renderer it got focus. | |
642 | |
643 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
644 if (view) | |
645 view->GotFocus(); | |
646 } | |
647 | |
648 void RenderViewHost::LostCapture() { | |
649 RenderWidgetHost::LostCapture(); | |
650 | |
651 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
652 if (view) | |
653 view->LostCapture(); | |
654 } | |
655 | |
656 void RenderViewHost::SetInitialFocus(bool reverse) { | |
657 Send(new ViewMsg_SetInitialFocus(routing_id(), reverse)); | |
658 } | |
659 | |
660 void RenderViewHost::ClearFocusedNode() { | |
661 Send(new ViewMsg_ClearFocusedNode(routing_id())); | |
662 } | |
663 | |
664 void RenderViewHost::ScrollFocusedEditableNodeIntoView() { | |
665 Send(new ViewMsg_ScrollFocusedEditableNodeIntoView(routing_id())); | |
666 } | |
667 | |
668 void RenderViewHost::UpdateWebPreferences(const WebPreferences& prefs) { | |
669 Send(new ViewMsg_UpdateWebPreferences(routing_id(), prefs)); | |
670 } | |
671 | |
672 void RenderViewHost::InstallMissingPlugin() { | |
673 Send(new ViewMsg_InstallMissingPlugin(routing_id())); | |
674 } | |
675 | |
676 void RenderViewHost::LoadBlockedPlugins() { | |
677 Send(new ViewMsg_LoadBlockedPlugins(routing_id())); | |
678 } | |
679 | |
680 void RenderViewHost::FilesSelectedInChooser( | |
681 const std::vector<FilePath>& files) { | |
682 // Grant the security access requested to the given files. | |
683 for (std::vector<FilePath>::const_iterator file = files.begin(); | |
684 file != files.end(); ++file) { | |
685 ChildProcessSecurityPolicy::GetInstance()->GrantReadFile( | |
686 process()->id(), *file); | |
687 } | |
688 Send(new ViewMsg_RunFileChooserResponse(routing_id(), files)); | |
689 } | |
690 | |
691 void RenderViewHost::LoadStateChanged(const GURL& url, | |
692 net::LoadState load_state, | |
693 uint64 upload_position, | |
694 uint64 upload_size) { | |
695 delegate_->LoadStateChanged(url, load_state, upload_position, upload_size); | |
696 } | |
697 | |
698 bool RenderViewHost::SuddenTerminationAllowed() const { | |
699 return sudden_termination_allowed_ || process()->sudden_termination_allowed(); | |
700 } | |
701 | |
702 /////////////////////////////////////////////////////////////////////////////// | |
703 // RenderViewHost, IPC message handlers: | |
704 | |
705 bool RenderViewHost::OnMessageReceived(const IPC::Message& msg) { | |
706 #if defined(OS_WIN) | |
707 // On Windows there's a potential deadlock with sync messsages going in | |
708 // a circle from browser -> plugin -> renderer -> browser. | |
709 // On Linux we can avoid this by avoiding sync messages from browser->plugin. | |
710 // On Mac we avoid this by not supporting windowed plugins. | |
711 if (msg.is_sync() && !msg.is_caller_pumping_messages()) { | |
712 // NOTE: IF YOU HIT THIS ASSERT, THE SOLUTION IS ALMOST NEVER TO RUN A | |
713 // NESTED MESSAGE LOOP IN THE RENDERER!!! | |
714 // That introduces reentrancy which causes hard to track bugs. You should | |
715 // find a way to either turn this into an asynchronous message, or one | |
716 // that can be answered on the IO thread. | |
717 NOTREACHED() << "Can't send sync messages to UI thread without pumping " | |
718 "messages in the renderer or else deadlocks can occur if the page " | |
719 "has windowed plugins! (message type " << msg.type() << ")"; | |
720 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg); | |
721 reply->set_reply_error(); | |
722 Send(reply); | |
723 return true; | |
724 } | |
725 #endif | |
726 | |
727 if (delegate_->OnMessageReceived(msg)) | |
728 return true; | |
729 | |
730 bool handled = true; | |
731 bool msg_is_ok = true; | |
732 IPC_BEGIN_MESSAGE_MAP_EX(RenderViewHost, msg, msg_is_ok) | |
733 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowView, OnMsgShowView) | |
734 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnMsgShowWidget) | |
735 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowFullscreenWidget, | |
736 OnMsgShowFullscreenWidget) | |
737 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunModal, OnMsgRunModal) | |
738 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnMsgRenderViewReady) | |
739 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewGone, OnMsgRenderViewGone) | |
740 IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_FrameNavigate, OnMsgNavigate(msg)) | |
741 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateState, OnMsgUpdateState) | |
742 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTitle, OnMsgUpdateTitle) | |
743 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateEncoding, OnMsgUpdateEncoding) | |
744 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnMsgUpdateTargetURL) | |
745 IPC_MESSAGE_HANDLER(ViewHostMsg_Thumbnail, OnMsgThumbnail) | |
746 IPC_MESSAGE_HANDLER(ViewHostMsg_Snapshot, OnMsgScreenshot) | |
747 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateInspectorSetting, | |
748 OnUpdateInspectorSetting) | |
749 IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnMsgClose) | |
750 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnMsgRequestMove) | |
751 IPC_MESSAGE_HANDLER(ViewHostMsg_DidStartLoading, OnMsgDidStartLoading) | |
752 IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopLoading, OnMsgDidStopLoading) | |
753 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeLoadProgress, | |
754 OnMsgDidChangeLoadProgress) | |
755 IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentAvailableInMainFrame, | |
756 OnMsgDocumentAvailableInMainFrame) | |
757 IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentOnLoadCompletedInMainFrame, | |
758 OnMsgDocumentOnLoadCompletedInMainFrame) | |
759 IPC_MESSAGE_HANDLER(ViewMsg_ExecuteCodeFinished, | |
760 OnExecuteCodeFinished) | |
761 IPC_MESSAGE_HANDLER(ViewHostMsg_ContextMenu, OnMsgContextMenu) | |
762 IPC_MESSAGE_HANDLER(ViewHostMsg_OpenURL, OnMsgOpenURL) | |
763 IPC_MESSAGE_HANDLER(ViewHostMsg_DidContentsPreferredSizeChange, | |
764 OnMsgDidContentsPreferredSizeChange) | |
765 IPC_MESSAGE_HANDLER(ViewHostMsg_DomOperationResponse, | |
766 OnMsgDomOperationResponse) | |
767 IPC_MESSAGE_HANDLER(ViewHostMsg_WebUISend, OnMsgWebUISend) | |
768 IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardMessageToExternalHost, | |
769 OnMsgForwardMessageToExternalHost) | |
770 IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnMsgSetTooltipText) | |
771 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunJavaScriptMessage, | |
772 OnMsgRunJavaScriptMessage) | |
773 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunBeforeUnloadConfirm, | |
774 OnMsgRunBeforeUnloadConfirm) | |
775 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ShowModalHTMLDialog, | |
776 OnMsgShowModalHTMLDialog) | |
777 IPC_MESSAGE_HANDLER(ViewHostMsg_StartDragging, OnMsgStartDragging) | |
778 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateDragCursor, OnUpdateDragCursor) | |
779 IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus) | |
780 IPC_MESSAGE_HANDLER(ViewHostMsg_AddMessageToConsole, OnAddMessageToConsole) | |
781 IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToDevToolsAgent, | |
782 OnForwardToDevToolsAgent) | |
783 IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToDevToolsClient, | |
784 OnForwardToDevToolsClient) | |
785 IPC_MESSAGE_HANDLER(ViewHostMsg_ActivateDevToolsWindow, | |
786 OnActivateDevToolsWindow) | |
787 IPC_MESSAGE_HANDLER(ViewHostMsg_CloseDevToolsWindow, | |
788 OnCloseDevToolsWindow) | |
789 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestDockDevToolsWindow, | |
790 OnRequestDockDevToolsWindow) | |
791 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestUndockDevToolsWindow, | |
792 OnRequestUndockDevToolsWindow) | |
793 IPC_MESSAGE_HANDLER(ViewHostMsg_DevToolsRuntimePropertyChanged, | |
794 OnDevToolsRuntimePropertyChanged) | |
795 IPC_MESSAGE_HANDLER(ViewHostMsg_ShouldClose_ACK, OnMsgShouldCloseACK) | |
796 IPC_MESSAGE_HANDLER(ViewHostMsg_ExtensionRequest, OnExtensionRequest) | |
797 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectionChanged, OnMsgSelectionChanged) | |
798 IPC_MESSAGE_HANDLER(ViewHostMsg_ExtensionPostMessage, | |
799 OnExtensionPostMessage) | |
800 IPC_MESSAGE_HANDLER(ViewHostMsg_AccessibilityNotifications, | |
801 OnAccessibilityNotifications) | |
802 IPC_MESSAGE_HANDLER(ViewHostMsg_OnCSSInserted, OnCSSInserted) | |
803 IPC_MESSAGE_HANDLER(ViewHostMsg_ContentBlocked, OnContentBlocked) | |
804 IPC_MESSAGE_HANDLER(ViewHostMsg_AppCacheAccessed, OnAppCacheAccessed) | |
805 IPC_MESSAGE_HANDLER(ViewHostMsg_WebDatabaseAccessed, OnWebDatabaseAccessed) | |
806 IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnMsgFocusedNodeChanged) | |
807 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateZoomLimits, OnUpdateZoomLimits) | |
808 IPC_MESSAGE_HANDLER(ViewHostMsg_ScriptEvalResponse, OnScriptEvalResponse) | |
809 #if defined(OS_MACOSX) | |
810 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowPopup, OnMsgShowPopup) | |
811 #endif | |
812 IPC_MESSAGE_HANDLER(ViewHostMsg_CommandStateChanged, | |
813 OnCommandStateChanged) | |
814 // Have the super handle all other messages. | |
815 IPC_MESSAGE_UNHANDLED(handled = RenderWidgetHost::OnMessageReceived(msg)) | |
816 IPC_END_MESSAGE_MAP_EX() | |
817 | |
818 if (!msg_is_ok) { | |
819 // The message had a handler, but its de-serialization failed. | |
820 // Kill the renderer. | |
821 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_RVH")); | |
822 process()->ReceivedBadMessage(); | |
823 } | |
824 | |
825 return handled; | |
826 } | |
827 | |
828 void RenderViewHost::Shutdown() { | |
829 // If we are being run modally (see RunModal), then we need to cleanup. | |
830 if (run_modal_reply_msg_) { | |
831 Send(run_modal_reply_msg_); | |
832 run_modal_reply_msg_ = NULL; | |
833 } | |
834 | |
835 DevToolsManager* devtools_manager = DevToolsManager::GetInstance(); | |
836 if (devtools_manager) // NULL in tests | |
837 devtools_manager->UnregisterDevToolsClientHostFor(this); | |
838 | |
839 RenderWidgetHost::Shutdown(); | |
840 } | |
841 | |
842 bool RenderViewHost::IsRenderView() const { | |
843 return true; | |
844 } | |
845 | |
846 void RenderViewHost::CreateNewWindow( | |
847 int route_id, | |
848 const ViewHostMsg_CreateWindow_Params& params) { | |
849 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
850 if (!view) | |
851 return; | |
852 | |
853 view->CreateNewWindow(route_id, params); | |
854 } | |
855 | |
856 void RenderViewHost::CreateNewWidget(int route_id, | |
857 WebKit::WebPopupType popup_type) { | |
858 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
859 if (view) | |
860 view->CreateNewWidget(route_id, popup_type); | |
861 } | |
862 | |
863 void RenderViewHost::CreateNewFullscreenWidget(int route_id) { | |
864 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
865 if (view) | |
866 view->CreateNewFullscreenWidget(route_id); | |
867 } | |
868 | |
869 void RenderViewHost::OnMsgShowView(int route_id, | |
870 WindowOpenDisposition disposition, | |
871 const gfx::Rect& initial_pos, | |
872 bool user_gesture) { | |
873 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
874 if (view) { | |
875 view->ShowCreatedWindow(route_id, disposition, initial_pos, user_gesture); | |
876 Send(new ViewMsg_Move_ACK(route_id)); | |
877 } | |
878 } | |
879 | |
880 void RenderViewHost::OnMsgShowWidget(int route_id, | |
881 const gfx::Rect& initial_pos) { | |
882 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
883 if (view) { | |
884 view->ShowCreatedWidget(route_id, initial_pos); | |
885 Send(new ViewMsg_Move_ACK(route_id)); | |
886 } | |
887 } | |
888 | |
889 void RenderViewHost::OnMsgShowFullscreenWidget(int route_id) { | |
890 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
891 if (view) { | |
892 view->ShowCreatedFullscreenWidget(route_id); | |
893 Send(new ViewMsg_Move_ACK(route_id)); | |
894 } | |
895 } | |
896 | |
897 void RenderViewHost::OnMsgRunModal(IPC::Message* reply_msg) { | |
898 DCHECK(!run_modal_reply_msg_); | |
899 run_modal_reply_msg_ = reply_msg; | |
900 | |
901 // TODO(darin): Bug 1107929: Need to inform our delegate to show this view in | |
902 // an app-modal fashion. | |
903 } | |
904 | |
905 void RenderViewHost::OnMsgRenderViewReady() { | |
906 render_view_termination_status_ = base::TERMINATION_STATUS_STILL_RUNNING; | |
907 WasResized(); | |
908 delegate_->RenderViewReady(this); | |
909 } | |
910 | |
911 void RenderViewHost::OnMsgRenderViewGone(int status, int exit_code) { | |
912 // Keep the termination status so we can get at it later when we | |
913 // need to know why it died. | |
914 render_view_termination_status_ = | |
915 static_cast<base::TerminationStatus>(status); | |
916 | |
917 // Our base class RenderWidgetHost needs to reset some stuff. | |
918 RendererExited(render_view_termination_status_, exit_code); | |
919 | |
920 delegate_->RenderViewGone(this, | |
921 static_cast<base::TerminationStatus>(status), | |
922 exit_code); | |
923 } | |
924 | |
925 // Called when the renderer navigates. For every frame loaded, we'll get this | |
926 // notification containing parameters identifying the navigation. | |
927 // | |
928 // Subframes are identified by the page transition type. For subframes loaded | |
929 // as part of a wider page load, the page_id will be the same as for the top | |
930 // level frame. If the user explicitly requests a subframe navigation, we will | |
931 // get a new page_id because we need to create a new navigation entry for that | |
932 // action. | |
933 void RenderViewHost::OnMsgNavigate(const IPC::Message& msg) { | |
934 // Read the parameters out of the IPC message directly to avoid making another | |
935 // copy when we filter the URLs. | |
936 void* iter = NULL; | |
937 ViewHostMsg_FrameNavigate_Params validated_params; | |
938 if (!IPC::ParamTraits<ViewHostMsg_FrameNavigate_Params>:: | |
939 Read(&msg, &iter, &validated_params)) | |
940 return; | |
941 | |
942 // If we're waiting for a beforeunload ack from this renderer and we receive | |
943 // a Navigate message from the main frame, then the renderer was navigating | |
944 // before it received the request. If it is during a cross-site navigation, | |
945 // then we should forget about the beforeunload, because the navigation will | |
946 // now be canceled. (If it is instead during an attempt to close the page, | |
947 // we should be sure to keep waiting for the ack, which the new page will | |
948 // send.) | |
949 // | |
950 // If we did not clear this state, an unresponsiveness timer might think we | |
951 // are waiting for an ack but are not in a cross-site navigation, and would | |
952 // close the tab. TODO(creis): That timer code should be refactored to only | |
953 // close the tab if we explicitly know the user tried to close the tab, and | |
954 // not just check for the absence of a cross-site navigation. Once that's | |
955 // fixed, this check can go away. | |
956 if (is_waiting_for_beforeunload_ack_ && | |
957 unload_ack_is_for_cross_site_transition_ && | |
958 PageTransition::IsMainFrame(validated_params.transition)) { | |
959 is_waiting_for_beforeunload_ack_ = false; | |
960 StopHangMonitorTimeout(); | |
961 } | |
962 | |
963 // If we're waiting for an unload ack from this renderer and we receive a | |
964 // Navigate message, then the renderer was navigating before it received the | |
965 // unload request. It will either respond to the unload request soon or our | |
966 // timer will expire. Either way, we should ignore this message, because we | |
967 // have already committed to closing this renderer. | |
968 if (is_waiting_for_unload_ack_) | |
969 return; | |
970 | |
971 const int renderer_id = process()->id(); | |
972 ChildProcessSecurityPolicy* policy = | |
973 ChildProcessSecurityPolicy::GetInstance(); | |
974 // Without this check, an evil renderer can trick the browser into creating | |
975 // a navigation entry for a banned URL. If the user clicks the back button | |
976 // followed by the forward button (or clicks reload, or round-trips through | |
977 // session restore, etc), we'll think that the browser commanded the | |
978 // renderer to load the URL and grant the renderer the privileges to request | |
979 // the URL. To prevent this attack, we block the renderer from inserting | |
980 // banned URLs into the navigation controller in the first place. | |
981 FilterURL(policy, renderer_id, &validated_params.url); | |
982 FilterURL(policy, renderer_id, &validated_params.referrer); | |
983 for (std::vector<GURL>::iterator it(validated_params.redirects.begin()); | |
984 it != validated_params.redirects.end(); ++it) { | |
985 FilterURL(policy, renderer_id, &(*it)); | |
986 } | |
987 FilterURL(policy, renderer_id, &validated_params.searchable_form_url); | |
988 FilterURL(policy, renderer_id, &validated_params.password_form.origin); | |
989 FilterURL(policy, renderer_id, &validated_params.password_form.action); | |
990 | |
991 delegate_->DidNavigate(this, validated_params); | |
992 } | |
993 | |
994 void RenderViewHost::OnMsgUpdateState(int32 page_id, | |
995 const std::string& state) { | |
996 delegate_->UpdateState(this, page_id, state); | |
997 } | |
998 | |
999 void RenderViewHost::OnMsgUpdateTitle(int32 page_id, | |
1000 const std::wstring& title) { | |
1001 if (title.length() > chrome::kMaxTitleChars) { | |
1002 NOTREACHED() << "Renderer sent too many characters in title."; | |
1003 return; | |
1004 } | |
1005 delegate_->UpdateTitle(this, page_id, title); | |
1006 } | |
1007 | |
1008 void RenderViewHost::OnMsgUpdateEncoding(const std::string& encoding_name) { | |
1009 delegate_->UpdateEncoding(this, encoding_name); | |
1010 } | |
1011 | |
1012 void RenderViewHost::OnMsgUpdateTargetURL(int32 page_id, | |
1013 const GURL& url) { | |
1014 delegate_->UpdateTargetURL(page_id, url); | |
1015 | |
1016 // Send a notification back to the renderer that we are ready to | |
1017 // receive more target urls. | |
1018 Send(new ViewMsg_UpdateTargetURL_ACK(routing_id())); | |
1019 } | |
1020 | |
1021 void RenderViewHost::OnMsgThumbnail(const GURL& url, | |
1022 const ThumbnailScore& score, | |
1023 const SkBitmap& bitmap) { | |
1024 delegate_->UpdateThumbnail(url, bitmap, score); | |
1025 } | |
1026 | |
1027 void RenderViewHost::OnMsgScreenshot(const SkBitmap& bitmap) { | |
1028 NotificationService::current()->Notify( | |
1029 NotificationType::TAB_SNAPSHOT_TAKEN, | |
1030 Source<RenderViewHost>(this), | |
1031 Details<const SkBitmap>(&bitmap)); | |
1032 } | |
1033 | |
1034 void RenderViewHost::OnUpdateInspectorSetting( | |
1035 const std::string& key, const std::string& value) { | |
1036 delegate_->UpdateInspectorSetting(key, value); | |
1037 } | |
1038 | |
1039 void RenderViewHost::OnMsgClose() { | |
1040 // If the renderer is telling us to close, it has already run the unload | |
1041 // events, and we can take the fast path. | |
1042 ClosePageIgnoringUnloadEvents(); | |
1043 } | |
1044 | |
1045 void RenderViewHost::OnMsgRequestMove(const gfx::Rect& pos) { | |
1046 delegate_->RequestMove(pos); | |
1047 Send(new ViewMsg_Move_ACK(routing_id())); | |
1048 } | |
1049 | |
1050 void RenderViewHost::OnMsgDidStartLoading() { | |
1051 delegate_->DidStartLoading(); | |
1052 } | |
1053 | |
1054 void RenderViewHost::OnMsgDidStopLoading() { | |
1055 delegate_->DidStopLoading(); | |
1056 } | |
1057 | |
1058 void RenderViewHost::OnMsgDidChangeLoadProgress(double load_progress) { | |
1059 delegate_->DidChangeLoadProgress(load_progress); | |
1060 } | |
1061 | |
1062 void RenderViewHost::OnMsgDocumentAvailableInMainFrame() { | |
1063 delegate_->DocumentAvailableInMainFrame(this); | |
1064 } | |
1065 | |
1066 void RenderViewHost::OnMsgDocumentOnLoadCompletedInMainFrame(int32 page_id) { | |
1067 delegate_->DocumentOnLoadCompletedInMainFrame(this, page_id); | |
1068 } | |
1069 | |
1070 void RenderViewHost::OnExecuteCodeFinished(int request_id, bool success) { | |
1071 std::pair<int, bool> result_details(request_id, success); | |
1072 NotificationService::current()->Notify( | |
1073 NotificationType::TAB_CODE_EXECUTED, | |
1074 NotificationService::AllSources(), | |
1075 Details<std::pair<int, bool> >(&result_details)); | |
1076 } | |
1077 | |
1078 void RenderViewHost::OnMsgContextMenu(const ContextMenuParams& params) { | |
1079 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1080 if (!view) | |
1081 return; | |
1082 | |
1083 // Validate the URLs in |params|. If the renderer can't request the URLs | |
1084 // directly, don't show them in the context menu. | |
1085 ContextMenuParams validated_params(params); | |
1086 int renderer_id = process()->id(); | |
1087 ChildProcessSecurityPolicy* policy = | |
1088 ChildProcessSecurityPolicy::GetInstance(); | |
1089 | |
1090 // We don't validate |unfiltered_link_url| so that this field can be used | |
1091 // when users want to copy the original link URL. | |
1092 FilterURL(policy, renderer_id, &validated_params.link_url); | |
1093 FilterURL(policy, renderer_id, &validated_params.src_url); | |
1094 FilterURL(policy, renderer_id, &validated_params.page_url); | |
1095 FilterURL(policy, renderer_id, &validated_params.frame_url); | |
1096 | |
1097 view->ShowContextMenu(validated_params); | |
1098 } | |
1099 | |
1100 void RenderViewHost::OnMsgOpenURL(const GURL& url, | |
1101 const GURL& referrer, | |
1102 WindowOpenDisposition disposition) { | |
1103 GURL validated_url(url); | |
1104 FilterURL(ChildProcessSecurityPolicy::GetInstance(), | |
1105 process()->id(), &validated_url); | |
1106 | |
1107 delegate_->RequestOpenURL(validated_url, referrer, disposition); | |
1108 } | |
1109 | |
1110 void RenderViewHost::OnMsgDidContentsPreferredSizeChange( | |
1111 const gfx::Size& new_size) { | |
1112 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1113 if (!view) | |
1114 return; | |
1115 view->UpdatePreferredSize(new_size); | |
1116 } | |
1117 | |
1118 void RenderViewHost::OnMsgDomOperationResponse( | |
1119 const std::string& json_string, int automation_id) { | |
1120 delegate_->DomOperationResponse(json_string, automation_id); | |
1121 | |
1122 // We also fire a notification for more loosely-coupled use cases. | |
1123 DomOperationNotificationDetails details(json_string, automation_id); | |
1124 NotificationService::current()->Notify( | |
1125 NotificationType::DOM_OPERATION_RESPONSE, Source<RenderViewHost>(this), | |
1126 Details<DomOperationNotificationDetails>(&details)); | |
1127 } | |
1128 | |
1129 void RenderViewHost::OnMsgWebUISend( | |
1130 const GURL& source_url, const std::string& message, | |
1131 const std::string& content) { | |
1132 if (!ChildProcessSecurityPolicy::GetInstance()-> | |
1133 HasWebUIBindings(process()->id())) { | |
1134 NOTREACHED() << "Blocked unauthorized use of WebUIBindings."; | |
1135 return; | |
1136 } | |
1137 | |
1138 scoped_ptr<Value> value; | |
1139 if (!content.empty()) { | |
1140 value.reset(base::JSONReader::Read(content, false)); | |
1141 if (!value.get() || !value->IsType(Value::TYPE_LIST)) { | |
1142 // The page sent us something that we didn't understand. | |
1143 // This probably indicates a programming error. | |
1144 NOTREACHED() << "Invalid JSON argument in OnMsgWebUISend."; | |
1145 return; | |
1146 } | |
1147 } | |
1148 | |
1149 ViewHostMsg_DomMessage_Params params; | |
1150 params.name = message; | |
1151 if (value.get()) | |
1152 params.arguments.Swap(static_cast<ListValue*>(value.get())); | |
1153 params.source_url = source_url; | |
1154 // WebUI doesn't use these values yet. | |
1155 // TODO(aa): When WebUI is ported to ExtensionFunctionDispatcher, send real | |
1156 // values here. | |
1157 params.request_id = -1; | |
1158 params.has_callback = false; | |
1159 params.user_gesture = false; | |
1160 delegate_->ProcessWebUIMessage(params); | |
1161 } | |
1162 | |
1163 void RenderViewHost::OnMsgForwardMessageToExternalHost( | |
1164 const std::string& message, const std::string& origin, | |
1165 const std::string& target) { | |
1166 delegate_->ProcessExternalHostMessage(message, origin, target); | |
1167 } | |
1168 | |
1169 void RenderViewHost::DisassociateFromPopupCount() { | |
1170 Send(new ViewMsg_DisassociateFromPopupCount(routing_id())); | |
1171 } | |
1172 | |
1173 void RenderViewHost::AllowScriptToClose(bool script_can_close) { | |
1174 Send(new ViewMsg_AllowScriptToClose(routing_id(), script_can_close)); | |
1175 } | |
1176 | |
1177 void RenderViewHost::OnMsgSetTooltipText( | |
1178 const std::wstring& tooltip_text, | |
1179 WebTextDirection text_direction_hint) { | |
1180 // First, add directionality marks around tooltip text if necessary. | |
1181 // A naive solution would be to simply always wrap the text. However, on | |
1182 // windows, Unicode directional embedding characters can't be displayed on | |
1183 // systems that lack RTL fonts and are instead displayed as empty squares. | |
1184 // | |
1185 // To get around this we only wrap the string when we deem it necessary i.e. | |
1186 // when the locale direction is different than the tooltip direction hint. | |
1187 // | |
1188 // Currently, we use element's directionality as the tooltip direction hint. | |
1189 // An alternate solution would be to set the overall directionality based on | |
1190 // trying to detect the directionality from the tooltip text rather than the | |
1191 // element direction. One could argue that would be a preferable solution | |
1192 // but we use the current approach to match Fx & IE's behavior. | |
1193 std::wstring wrapped_tooltip_text = tooltip_text; | |
1194 if (!tooltip_text.empty()) { | |
1195 if (text_direction_hint == WebKit::WebTextDirectionLeftToRight) { | |
1196 // Force the tooltip to have LTR directionality. | |
1197 wrapped_tooltip_text = UTF16ToWide( | |
1198 base::i18n::GetDisplayStringInLTRDirectionality( | |
1199 WideToUTF16(wrapped_tooltip_text))); | |
1200 } else if (text_direction_hint == WebKit::WebTextDirectionRightToLeft && | |
1201 !base::i18n::IsRTL()) { | |
1202 // Force the tooltip to have RTL directionality. | |
1203 base::i18n::WrapStringWithRTLFormatting(&wrapped_tooltip_text); | |
1204 } | |
1205 } | |
1206 if (view()) | |
1207 view()->SetTooltipText(wrapped_tooltip_text); | |
1208 } | |
1209 | |
1210 void RenderViewHost::OnMsgSelectionChanged(const std::string& text) { | |
1211 if (view()) | |
1212 view()->SelectionChanged(text); | |
1213 } | |
1214 | |
1215 void RenderViewHost::OnMsgRunJavaScriptMessage( | |
1216 const std::wstring& message, | |
1217 const std::wstring& default_prompt, | |
1218 const GURL& frame_url, | |
1219 const int flags, | |
1220 IPC::Message* reply_msg) { | |
1221 // While a JS message dialog is showing, tabs in the same process shouldn't | |
1222 // process input events. | |
1223 process()->set_ignore_input_events(true); | |
1224 StopHangMonitorTimeout(); | |
1225 delegate_->RunJavaScriptMessage(message, default_prompt, frame_url, flags, | |
1226 reply_msg, | |
1227 &are_javascript_messages_suppressed_); | |
1228 } | |
1229 | |
1230 void RenderViewHost::OnMsgRunBeforeUnloadConfirm(const GURL& frame_url, | |
1231 const std::wstring& message, | |
1232 IPC::Message* reply_msg) { | |
1233 // While a JS before unload dialog is showing, tabs in the same process | |
1234 // shouldn't process input events. | |
1235 process()->set_ignore_input_events(true); | |
1236 StopHangMonitorTimeout(); | |
1237 delegate_->RunBeforeUnloadConfirm(message, reply_msg); | |
1238 } | |
1239 | |
1240 void RenderViewHost::OnMsgShowModalHTMLDialog( | |
1241 const GURL& url, int width, int height, const std::string& json_arguments, | |
1242 IPC::Message* reply_msg) { | |
1243 StopHangMonitorTimeout(); | |
1244 delegate_->ShowModalHTMLDialog(url, width, height, json_arguments, reply_msg); | |
1245 } | |
1246 | |
1247 void RenderViewHost::MediaPlayerActionAt(const gfx::Point& location, | |
1248 const WebMediaPlayerAction& action) { | |
1249 // TODO(ajwong): Which thread should run this? Does it matter? | |
1250 Send(new ViewMsg_MediaPlayerActionAt(routing_id(), location, action)); | |
1251 } | |
1252 | |
1253 void RenderViewHost::ContextMenuClosed( | |
1254 const webkit_glue::CustomContextMenuContext& custom_context) { | |
1255 Send(new ViewMsg_ContextMenuClosed(routing_id(), custom_context)); | |
1256 } | |
1257 | |
1258 void RenderViewHost::PrintNodeUnderContextMenu() { | |
1259 Send(new ViewMsg_PrintNodeUnderContextMenu(routing_id())); | |
1260 } | |
1261 | |
1262 void RenderViewHost::PrintForPrintPreview() { | |
1263 Send(new ViewMsg_PrintForPrintPreview(routing_id())); | |
1264 } | |
1265 | |
1266 void RenderViewHost::OnMsgStartDragging( | |
1267 const WebDropData& drop_data, | |
1268 WebDragOperationsMask drag_operations_mask, | |
1269 const SkBitmap& image, | |
1270 const gfx::Point& image_offset) { | |
1271 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1272 if (view) | |
1273 view->StartDragging(drop_data, drag_operations_mask, image, image_offset); | |
1274 } | |
1275 | |
1276 void RenderViewHost::OnUpdateDragCursor(WebDragOperation current_op) { | |
1277 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1278 if (view) | |
1279 view->UpdateDragCursor(current_op); | |
1280 } | |
1281 | |
1282 void RenderViewHost::OnTakeFocus(bool reverse) { | |
1283 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1284 if (view) | |
1285 view->TakeFocus(reverse); | |
1286 } | |
1287 | |
1288 void RenderViewHost::OnAddMessageToConsole(const std::wstring& message, | |
1289 int32 line_no, | |
1290 const std::wstring& source_id) { | |
1291 std::wstring msg = StringPrintf(L"\"%ls,\" source: %ls (%d)", message.c_str(), | |
1292 source_id.c_str(), line_no); | |
1293 logging::LogMessage("CONSOLE", 0).stream() << msg; | |
1294 } | |
1295 | |
1296 void RenderViewHost::OnForwardToDevToolsAgent(const IPC::Message& message) { | |
1297 DevToolsManager::GetInstance()->ForwardToDevToolsAgent(this, message); | |
1298 } | |
1299 | |
1300 void RenderViewHost::OnForwardToDevToolsClient(const IPC::Message& message) { | |
1301 DevToolsManager::GetInstance()->ForwardToDevToolsClient(this, message); | |
1302 } | |
1303 | |
1304 void RenderViewHost::OnActivateDevToolsWindow() { | |
1305 DevToolsManager::GetInstance()->ActivateWindow(this); | |
1306 } | |
1307 | |
1308 void RenderViewHost::OnCloseDevToolsWindow() { | |
1309 DevToolsManager::GetInstance()->CloseWindow(this); | |
1310 } | |
1311 | |
1312 void RenderViewHost::OnRequestDockDevToolsWindow() { | |
1313 DevToolsManager::GetInstance()->RequestDockWindow(this); | |
1314 } | |
1315 | |
1316 void RenderViewHost::OnRequestUndockDevToolsWindow() { | |
1317 DevToolsManager::GetInstance()->RequestUndockWindow(this); | |
1318 } | |
1319 | |
1320 void RenderViewHost::OnDevToolsRuntimePropertyChanged( | |
1321 const std::string& name, | |
1322 const std::string& value) { | |
1323 DevToolsManager::GetInstance()-> | |
1324 RuntimePropertyChanged(this, name, value); | |
1325 } | |
1326 | |
1327 bool RenderViewHost::PreHandleKeyboardEvent( | |
1328 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) { | |
1329 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1330 return view && view->PreHandleKeyboardEvent(event, is_keyboard_shortcut); | |
1331 } | |
1332 | |
1333 void RenderViewHost::UnhandledKeyboardEvent( | |
1334 const NativeWebKeyboardEvent& event) { | |
1335 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1336 if (view) | |
1337 view->HandleKeyboardEvent(event); | |
1338 } | |
1339 | |
1340 void RenderViewHost::OnUserGesture() { | |
1341 delegate_->OnUserGesture(); | |
1342 } | |
1343 | |
1344 void RenderViewHost::GetMalwareDOMDetails() { | |
1345 Send(new ViewMsg_GetMalwareDOMDetails(routing_id())); | |
1346 } | |
1347 | |
1348 void RenderViewHost::GetAllSavableResourceLinksForCurrentPage( | |
1349 const GURL& page_url) { | |
1350 Send(new ViewMsg_GetAllSavableResourceLinksForCurrentPage(routing_id(), | |
1351 page_url)); | |
1352 } | |
1353 | |
1354 void RenderViewHost::GetSerializedHtmlDataForCurrentPageWithLocalLinks( | |
1355 const std::vector<GURL>& links, | |
1356 const std::vector<FilePath>& local_paths, | |
1357 const FilePath& local_directory_name) { | |
1358 Send(new ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks( | |
1359 routing_id(), links, local_paths, local_directory_name)); | |
1360 } | |
1361 | |
1362 void RenderViewHost::OnMsgShouldCloseACK(bool proceed) { | |
1363 StopHangMonitorTimeout(); | |
1364 // If this renderer navigated while the beforeunload request was in flight, we | |
1365 // may have cleared this state in OnMsgNavigate, in which case we can ignore | |
1366 // this message. | |
1367 if (!is_waiting_for_beforeunload_ack_) | |
1368 return; | |
1369 | |
1370 is_waiting_for_beforeunload_ack_ = false; | |
1371 | |
1372 RenderViewHostDelegate::RendererManagement* management_delegate = | |
1373 delegate_->GetRendererManagementDelegate(); | |
1374 if (management_delegate) { | |
1375 management_delegate->ShouldClosePage( | |
1376 unload_ack_is_for_cross_site_transition_, proceed); | |
1377 } | |
1378 } | |
1379 | |
1380 void RenderViewHost::WindowMoveOrResizeStarted() { | |
1381 Send(new ViewMsg_MoveOrResizeStarted(routing_id())); | |
1382 } | |
1383 | |
1384 void RenderViewHost::NotifyRendererUnresponsive() { | |
1385 delegate_->RendererUnresponsive( | |
1386 this, is_waiting_for_beforeunload_ack_ || is_waiting_for_unload_ack_); | |
1387 } | |
1388 | |
1389 void RenderViewHost::NotifyRendererResponsive() { | |
1390 delegate_->RendererResponsive(this); | |
1391 } | |
1392 | |
1393 void RenderViewHost::OnMsgFocusedNodeChanged(bool is_editable_node) { | |
1394 delegate_->FocusedNodeChanged(is_editable_node); | |
1395 } | |
1396 | |
1397 void RenderViewHost::OnMsgFocus() { | |
1398 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1399 if (view) | |
1400 view->Activate(); | |
1401 } | |
1402 | |
1403 void RenderViewHost::OnMsgBlur() { | |
1404 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1405 if (view) | |
1406 view->Deactivate(); | |
1407 } | |
1408 | |
1409 void RenderViewHost::ForwardMouseEvent( | |
1410 const WebKit::WebMouseEvent& mouse_event) { | |
1411 | |
1412 // We make a copy of the mouse event because | |
1413 // RenderWidgetHost::ForwardMouseEvent will delete |mouse_event|. | |
1414 WebKit::WebMouseEvent event_copy(mouse_event); | |
1415 RenderWidgetHost::ForwardMouseEvent(event_copy); | |
1416 | |
1417 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1418 if (view) { | |
1419 switch (event_copy.type) { | |
1420 case WebInputEvent::MouseMove: | |
1421 view->HandleMouseMove(); | |
1422 break; | |
1423 case WebInputEvent::MouseLeave: | |
1424 view->HandleMouseLeave(); | |
1425 break; | |
1426 case WebInputEvent::MouseDown: | |
1427 view->HandleMouseDown(); | |
1428 break; | |
1429 case WebInputEvent::MouseWheel: | |
1430 if (ignore_input_events() && delegate_) | |
1431 delegate_->OnIgnoredUIEvent(); | |
1432 break; | |
1433 case WebInputEvent::MouseUp: | |
1434 view->HandleMouseUp(); | |
1435 default: | |
1436 // For now, we don't care about the rest. | |
1437 break; | |
1438 } | |
1439 } | |
1440 } | |
1441 | |
1442 void RenderViewHost::OnMouseActivate() { | |
1443 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1444 if (view) | |
1445 view->HandleMouseActivate(); | |
1446 } | |
1447 | |
1448 void RenderViewHost::ForwardKeyboardEvent( | |
1449 const NativeWebKeyboardEvent& key_event) { | |
1450 if (ignore_input_events()) { | |
1451 if (key_event.type == WebInputEvent::RawKeyDown && delegate_) | |
1452 delegate_->OnIgnoredUIEvent(); | |
1453 return; | |
1454 } | |
1455 RenderWidgetHost::ForwardKeyboardEvent(key_event); | |
1456 } | |
1457 | |
1458 void RenderViewHost::ForwardEditCommand(const std::string& name, | |
1459 const std::string& value) { | |
1460 IPC::Message* message = new ViewMsg_ExecuteEditCommand(routing_id(), | |
1461 name, | |
1462 value); | |
1463 Send(message); | |
1464 } | |
1465 | |
1466 void RenderViewHost::ForwardEditCommandsForNextKeyEvent( | |
1467 const EditCommands& edit_commands) { | |
1468 IPC::Message* message = new ViewMsg_SetEditCommandsForNextKeyEvent( | |
1469 routing_id(), edit_commands); | |
1470 Send(message); | |
1471 } | |
1472 | |
1473 void RenderViewHost::ForwardMessageFromExternalHost(const std::string& message, | |
1474 const std::string& origin, | |
1475 const std::string& target) { | |
1476 Send(new ViewMsg_HandleMessageFromExternalHost(routing_id(), message, origin, | |
1477 target)); | |
1478 } | |
1479 | |
1480 void RenderViewHost::OnExtensionRequest( | |
1481 const ViewHostMsg_DomMessage_Params& params) { | |
1482 if (!ChildProcessSecurityPolicy::GetInstance()-> | |
1483 HasExtensionBindings(process()->id())) { | |
1484 // This can happen if someone uses window.open() to open an extension URL | |
1485 // from a non-extension context. | |
1486 BlockExtensionRequest(params.request_id); | |
1487 return; | |
1488 } | |
1489 | |
1490 delegate_->ProcessWebUIMessage(params); | |
1491 } | |
1492 | |
1493 void RenderViewHost::SendExtensionResponse(int request_id, bool success, | |
1494 const std::string& response, | |
1495 const std::string& error) { | |
1496 Send(new ViewMsg_ExtensionResponse(routing_id(), request_id, success, | |
1497 response, error)); | |
1498 } | |
1499 | |
1500 void RenderViewHost::BlockExtensionRequest(int request_id) { | |
1501 SendExtensionResponse(request_id, false, "", | |
1502 "Access to extension API denied."); | |
1503 } | |
1504 | |
1505 void RenderViewHost::UpdateBrowserWindowId(int window_id) { | |
1506 Send(new ViewMsg_UpdateBrowserWindowId(routing_id(), window_id)); | |
1507 } | |
1508 | |
1509 void RenderViewHost::PerformCustomContextMenuAction( | |
1510 const webkit_glue::CustomContextMenuContext& custom_context, | |
1511 unsigned action) { | |
1512 Send(new ViewMsg_CustomContextMenuAction(routing_id(), | |
1513 custom_context, | |
1514 action)); | |
1515 } | |
1516 | |
1517 void RenderViewHost::SendContentSettings(const GURL& url, | |
1518 const ContentSettings& settings) { | |
1519 Send(new ViewMsg_SetContentSettingsForCurrentURL(url, settings)); | |
1520 } | |
1521 | |
1522 void RenderViewHost::EnablePreferredSizeChangedMode(int flags) { | |
1523 Send(new ViewMsg_EnablePreferredSizeChangedMode(routing_id(), flags)); | |
1524 } | |
1525 | |
1526 #if defined(OS_MACOSX) | |
1527 void RenderViewHost::DidSelectPopupMenuItem(int selected_index) { | |
1528 Send(new ViewMsg_SelectPopupMenuItem(routing_id(), selected_index)); | |
1529 } | |
1530 | |
1531 void RenderViewHost::DidCancelPopupMenu() { | |
1532 Send(new ViewMsg_SelectPopupMenuItem(routing_id(), -1)); | |
1533 } | |
1534 #endif | |
1535 | |
1536 void RenderViewHost::SearchBoxChange(const string16& value, | |
1537 bool verbatim, | |
1538 int selection_start, | |
1539 int selection_end) { | |
1540 Send(new ViewMsg_SearchBoxChange( | |
1541 routing_id(), value, verbatim, selection_start, selection_end)); | |
1542 } | |
1543 | |
1544 void RenderViewHost::SearchBoxSubmit(const string16& value, | |
1545 bool verbatim) { | |
1546 Send(new ViewMsg_SearchBoxSubmit(routing_id(), value, verbatim)); | |
1547 } | |
1548 | |
1549 void RenderViewHost::SearchBoxCancel() { | |
1550 Send(new ViewMsg_SearchBoxCancel(routing_id())); | |
1551 } | |
1552 | |
1553 void RenderViewHost::SearchBoxResize(const gfx::Rect& search_box_bounds) { | |
1554 Send(new ViewMsg_SearchBoxResize(routing_id(), search_box_bounds)); | |
1555 } | |
1556 | |
1557 void RenderViewHost::DetermineIfPageSupportsInstant(const string16& value, | |
1558 bool verbatim, | |
1559 int selection_start, | |
1560 int selection_end) { | |
1561 Send(new ViewMsg_DetermineIfPageSupportsInstant( | |
1562 routing_id(), value, verbatim, selection_start, selection_end)); | |
1563 } | |
1564 | |
1565 void RenderViewHost::FilterURL(ChildProcessSecurityPolicy* policy, | |
1566 int renderer_id, | |
1567 GURL* url) { | |
1568 if (!url->is_valid()) | |
1569 return; // We don't need to block invalid URLs. | |
1570 | |
1571 if (url->SchemeIs(chrome::kAboutScheme)) { | |
1572 // The renderer treats all URLs in the about: scheme as being about:blank. | |
1573 // Canonicalize about: URLs to about:blank. | |
1574 *url = GURL(chrome::kAboutBlankURL); | |
1575 } | |
1576 | |
1577 if (!policy->CanRequestURL(renderer_id, *url)) { | |
1578 // If this renderer is not permitted to request this URL, we invalidate the | |
1579 // URL. This prevents us from storing the blocked URL and becoming confused | |
1580 // later. | |
1581 VLOG(1) << "Blocked URL " << url->spec(); | |
1582 *url = GURL(); | |
1583 } | |
1584 } | |
1585 | |
1586 void RenderViewHost::JavaScriptStressTestControl(int cmd, int param) { | |
1587 Send(new ViewMsg_JavaScriptStressTestControl(routing_id(), cmd, param)); | |
1588 } | |
1589 | |
1590 void RenderViewHost::OnExtensionPostMessage( | |
1591 int port_id, const std::string& message) { | |
1592 if (process()->profile()->GetExtensionMessageService()) { | |
1593 process()->profile()->GetExtensionMessageService()-> | |
1594 PostMessageFromRenderer(port_id, message); | |
1595 } | |
1596 } | |
1597 | |
1598 void RenderViewHost::OnAccessibilityNotifications( | |
1599 const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params) { | |
1600 if (view()) | |
1601 view()->OnAccessibilityNotifications(params); | |
1602 | |
1603 if (params.size() > 0) { | |
1604 for (unsigned i = 0; i < params.size(); i++) { | |
1605 const ViewHostMsg_AccessibilityNotification_Params& param = params[i]; | |
1606 | |
1607 if (param.notification_type == | |
1608 ViewHostMsg_AccessibilityNotification_Params:: | |
1609 NOTIFICATION_TYPE_LOAD_COMPLETE) { | |
1610 // TODO(ctguil): Remove when mac processes OnAccessibilityNotifications. | |
1611 if (view()) | |
1612 view()->UpdateAccessibilityTree(param.acc_obj); | |
1613 | |
1614 if (save_accessibility_tree_for_testing_) | |
1615 accessibility_tree_ = param.acc_obj; | |
1616 } | |
1617 } | |
1618 | |
1619 NotificationService::current()->Notify( | |
1620 NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED, | |
1621 Source<RenderViewHost>(this), | |
1622 NotificationService::NoDetails()); | |
1623 } | |
1624 | |
1625 AccessibilityNotificationsAck(); | |
1626 } | |
1627 | |
1628 void RenderViewHost::OnCSSInserted() { | |
1629 delegate_->DidInsertCSS(); | |
1630 } | |
1631 | |
1632 void RenderViewHost::OnContentBlocked(ContentSettingsType type, | |
1633 const std::string& resource_identifier) { | |
1634 RenderViewHostDelegate::ContentSettings* content_settings_delegate = | |
1635 delegate_->GetContentSettingsDelegate(); | |
1636 if (content_settings_delegate) | |
1637 content_settings_delegate->OnContentBlocked(type, resource_identifier); | |
1638 } | |
1639 | |
1640 void RenderViewHost::OnAppCacheAccessed(const GURL& manifest_url, | |
1641 bool blocked_by_policy) { | |
1642 RenderViewHostDelegate::ContentSettings* content_settings_delegate = | |
1643 delegate_->GetContentSettingsDelegate(); | |
1644 if (content_settings_delegate) | |
1645 content_settings_delegate->OnAppCacheAccessed(manifest_url, | |
1646 blocked_by_policy); | |
1647 } | |
1648 | |
1649 void RenderViewHost::OnWebDatabaseAccessed(const GURL& url, | |
1650 const string16& name, | |
1651 const string16& display_name, | |
1652 unsigned long estimated_size, | |
1653 bool blocked_by_policy) { | |
1654 RenderViewHostDelegate::ContentSettings* content_settings_delegate = | |
1655 delegate_->GetContentSettingsDelegate(); | |
1656 if (content_settings_delegate) | |
1657 content_settings_delegate->OnWebDatabaseAccessed( | |
1658 url, name, display_name, estimated_size, blocked_by_policy); | |
1659 } | |
1660 | |
1661 void RenderViewHost::OnUpdateZoomLimits(int minimum_percent, | |
1662 int maximum_percent, | |
1663 bool remember) { | |
1664 delegate_->UpdateZoomLimits(minimum_percent, maximum_percent, remember); | |
1665 } | |
1666 | |
1667 void RenderViewHost::OnScriptEvalResponse(int id, const ListValue& result) { | |
1668 Value* result_value; | |
1669 result.Get(0, &result_value); | |
1670 std::pair<int, Value*> details(id, result_value); | |
1671 NotificationService::current()->Notify( | |
1672 NotificationType::EXECUTE_JAVASCRIPT_RESULT, | |
1673 Source<RenderViewHost>(this), | |
1674 Details<std::pair<int, Value*> >(&details)); | |
1675 } | |
1676 | |
1677 #if defined(OS_MACOSX) | |
1678 void RenderViewHost::OnMsgShowPopup( | |
1679 const ViewHostMsg_ShowPopup_Params& params) { | |
1680 RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); | |
1681 if (view) { | |
1682 view->ShowPopupMenu(params.bounds, | |
1683 params.item_height, | |
1684 params.item_font_size, | |
1685 params.selected_item, | |
1686 params.popup_items, | |
1687 params.right_aligned); | |
1688 } | |
1689 } | |
1690 #endif | |
1691 | |
1692 void RenderViewHost::OnCommandStateChanged(int command, | |
1693 bool is_enabled, | |
1694 int checked_state) { | |
1695 if (command != RENDER_VIEW_COMMAND_TOGGLE_SPELL_CHECK) { | |
1696 LOG(DFATAL) << "Unknown command " << command; | |
1697 return; | |
1698 } | |
1699 | |
1700 if (checked_state != RENDER_VIEW_COMMAND_CHECKED_STATE_UNCHECKED && | |
1701 checked_state != RENDER_VIEW_COMMAND_CHECKED_STATE_CHECKED && | |
1702 checked_state != RENDER_VIEW_COMMAND_CHECKED_STATE_MIXED) { | |
1703 LOG(DFATAL) << "Invalid checked state " << checked_state; | |
1704 return; | |
1705 } | |
1706 | |
1707 CommandState state; | |
1708 state.is_enabled = is_enabled; | |
1709 state.checked_state = | |
1710 static_cast<RenderViewCommandCheckedState>(checked_state); | |
1711 command_states_[static_cast<RenderViewCommand>(command)] = state; | |
1712 } | |
OLD | NEW |