| 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 |