1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_IMPL_H_ 6 #define CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_IMPL_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/callback.h" 13 #include "base/compiler_specific.h" 14 #include "base/logging.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/process/kill.h" 17 #include "content/browser/renderer_host/render_widget_host_impl.h" 18 #include "content/browser/site_instance_impl.h" 19 #include "content/common/drag_event_source_info.h" 20 #include "content/public/browser/notification_observer.h" 21 #include "content/public/browser/render_view_host.h" 22 #include "content/public/common/window_container_type.h" 23 #include "net/base/load_states.h" 24 #include "third_party/WebKit/public/web/WebAXEnums.h" 25 #include "third_party/WebKit/public/web/WebConsoleMessage.h" 26 #include "third_party/WebKit/public/web/WebPopupType.h" 27 #include "third_party/skia/include/core/SkColor.h" 28 #include "ui/base/window_open_disposition.h" 29 30 class SkBitmap; 31 class FrameMsg_Navigate; 32 struct FrameMsg_Navigate_Params; 33 struct MediaPlayerAction; 34 struct ViewHostMsg_CreateWindow_Params; 35 struct ViewMsg_PostMessage_Params; 36 37 namespace base { 38 class ListValue; 39 } 40 41 namespace gfx { 42 class Range; 43 } 44 45 namespace ui { 46 class AXTree; 47 struct SelectedFileInfo; 48 } 49 50 namespace content { 51 52 class MediaWebContentsObserver; 53 class ChildProcessSecurityPolicyImpl; 54 class PageState; 55 class RenderWidgetHostDelegate; 56 class SessionStorageNamespace; 57 class SessionStorageNamespaceImpl; 58 class TestRenderViewHost; 59 class TimeoutMonitor; 60 struct FileChooserParams; 61 62 #if defined(COMPILER_MSVC) 63 // RenderViewHostImpl is the bottom of a diamond-shaped hierarchy, 64 // with RenderWidgetHost at the root. VS warns when methods from the 65 // root are overridden in only one of the base classes and not both 66 // (in this case, RenderWidgetHostImpl provides implementations of 67 // many of the methods). This is a silly warning when dealing with 68 // pure virtual methods that only have a single implementation in the 69 // hierarchy above this class, and is safe to ignore in this case. 70 #pragma warning(push) 71 #pragma warning(disable: 4250) 72 #endif 73 74 // This implements the RenderViewHost interface that is exposed to 75 // embedders of content, and adds things only visible to content. 76 // 77 // The exact API of this object needs to be more thoroughly designed. Right 78 // now it mimics what WebContentsImpl exposed, which is a fairly large API and 79 // may contain things that are not relevant to a common subset of views. See 80 // also the comment in render_view_host_delegate.h about the size and scope of 81 // the delegate API. 82 // 83 // Right now, the concept of page navigation (both top level and frame) exists 84 // in the WebContentsImpl still, so if you instantiate one of these elsewhere, 85 // you will not be able to traverse pages back and forward. We need to determine 86 // if we want to bring that and other functionality down into this object so it 87 // can be shared by others. 88 class CONTENT_EXPORT RenderViewHostImpl 89 : public RenderViewHost, 90 public RenderWidgetHostImpl { 91 public: 92 // Keeps track of the state of the RenderViewHostImpl, particularly with 93 // respect to swap out. 94 enum RenderViewHostImplState { 95 // The standard state for a RVH handling the communication with a 96 // RenderView. 97 STATE_DEFAULT = 0, 98 // The RVH is waiting for the CloseACK from the RenderView. 99 STATE_WAITING_FOR_CLOSE, 100 // The RVH has not received the SwapOutACK yet, but the new page has 101 // committed in a different RVH. The number of active views of the RVH 102 // SiteInstanceImpl is not zero. Upon reception of the SwapOutACK, the RVH 103 // will be swapped out. 104 STATE_PENDING_SWAP_OUT, 105 // The RVH has not received the SwapOutACK yet, but the new page has 106 // committed in a different RVH. The number of active views of the RVH 107 // SiteInstanceImpl is zero. Upon reception of the SwapOutACK, the RVH will 108 // be shutdown. 109 STATE_PENDING_SHUTDOWN, 110 // The RVH is swapped out, and it is being used as a placeholder to allow 111 // for cross-process communication. 112 STATE_SWAPPED_OUT, 113 }; 114 // Helper function to determine whether the RVH state should contribute to the 115 // number of active views of a SiteInstance or not. 116 static bool IsRVHStateActive(RenderViewHostImplState rvh_state); 117 118 // Convenience function, just like RenderViewHost::FromID. 119 static RenderViewHostImpl* FromID(int render_process_id, int render_view_id); 120 121 // |routing_id| could be a valid route id, or it could be MSG_ROUTING_NONE, in 122 // which case RenderWidgetHost will create a new one. |swapped_out| indicates 123 // whether the view should initially be swapped out (e.g., for an opener 124 // frame being rendered by another process). |hidden| indicates whether the 125 // view is initially hidden or visible. 126 // 127 // The |session_storage_namespace| parameter allows multiple render views and 128 // WebContentses to share the same session storage (part of the WebStorage 129 // spec) space. This is useful when restoring contentses, but most callers 130 // should pass in NULL which will cause a new SessionStorageNamespace to be 131 // created. 132 RenderViewHostImpl( 133 SiteInstance* instance, 134 RenderViewHostDelegate* delegate, 135 RenderWidgetHostDelegate* widget_delegate, 136 int routing_id, 137 int main_frame_routing_id, 138 bool swapped_out, 139 bool hidden); 140 virtual ~RenderViewHostImpl(); 141 142 // RenderViewHost implementation. 143 virtual RenderFrameHost* GetMainFrame() OVERRIDE; 144 virtual void AllowBindings(int binding_flags) OVERRIDE; 145 virtual void ClearFocusedElement() OVERRIDE; 146 virtual bool IsFocusedElementEditable() OVERRIDE; 147 virtual void ClosePage() OVERRIDE; 148 virtual void CopyImageAt(int x, int y) OVERRIDE; 149 virtual void SaveImageAt(int x, int y) OVERRIDE; 150 virtual void DirectoryEnumerationFinished( 151 int request_id, 152 const std::vector<base::FilePath>& files) OVERRIDE; 153 virtual void DisableScrollbarsForThreshold(const gfx::Size& size) OVERRIDE; 154 virtual void DragSourceEndedAt( 155 int client_x, int client_y, int screen_x, int screen_y, 156 blink::WebDragOperation operation) OVERRIDE; 157 virtual void DragSourceSystemDragEnded() OVERRIDE; 158 virtual void DragTargetDragEnter( 159 const DropData& drop_data, 160 const gfx::Point& client_pt, 161 const gfx::Point& screen_pt, 162 blink::WebDragOperationsMask operations_allowed, 163 int key_modifiers) OVERRIDE; 164 virtual void DragTargetDragOver( 165 const gfx::Point& client_pt, 166 const gfx::Point& screen_pt, 167 blink::WebDragOperationsMask operations_allowed, 168 int key_modifiers) OVERRIDE; 169 virtual void DragTargetDragLeave() OVERRIDE; 170 virtual void DragTargetDrop(const gfx::Point& client_pt, 171 const gfx::Point& screen_pt, 172 int key_modifiers) OVERRIDE; 173 virtual void EnableAutoResize(const gfx::Size& min_size, 174 const gfx::Size& max_size) OVERRIDE; 175 virtual void DisableAutoResize(const gfx::Size& new_size) OVERRIDE; 176 virtual void EnablePreferredSizeMode() OVERRIDE; 177 virtual void ExecuteMediaPlayerActionAtLocation( 178 const gfx::Point& location, 179 const blink::WebMediaPlayerAction& action) OVERRIDE; 180 virtual void ExecutePluginActionAtLocation( 181 const gfx::Point& location, 182 const blink::WebPluginAction& action) OVERRIDE; 183 virtual void ExitFullscreen() OVERRIDE; 184 virtual void FilesSelectedInChooser( 185 const std::vector<ui::SelectedFileInfo>& files, 186 FileChooserParams::Mode permissions) OVERRIDE; 187 virtual RenderViewHostDelegate* GetDelegate() const OVERRIDE; 188 virtual int GetEnabledBindings() const OVERRIDE; 189 virtual SiteInstance* GetSiteInstance() const OVERRIDE; 190 virtual bool IsRenderViewLive() const OVERRIDE; 191 virtual void NotifyMoveOrResizeStarted() OVERRIDE; 192 virtual void SetWebUIProperty(const std::string& name, 193 const std::string& value) OVERRIDE; 194 virtual void Zoom(PageZoom zoom) OVERRIDE; 195 virtual void SyncRendererPrefs() OVERRIDE; 196 virtual WebPreferences GetWebkitPreferences() OVERRIDE; 197 virtual void UpdateWebkitPreferences( 198 const WebPreferences& prefs) OVERRIDE; 199 virtual void OnWebkitPreferencesChanged() OVERRIDE; 200 virtual void GetAudioOutputControllers( 201 const GetAudioOutputControllersCallback& callback) const OVERRIDE; 202 virtual void SelectWordAroundCaret() OVERRIDE; 203 204 #if defined(OS_ANDROID) 205 virtual void ActivateNearestFindResult(int request_id, 206 float x, 207 float y) OVERRIDE; 208 virtual void RequestFindMatchRects(int current_version) OVERRIDE; 209 #endif 210 set_delegate(RenderViewHostDelegate * d)211 void set_delegate(RenderViewHostDelegate* d) { 212 CHECK(d); // http://crbug.com/82827 213 delegate_ = d; 214 } 215 216 // Set up the RenderView child process. Virtual because it is overridden by 217 // TestRenderViewHost. If the |frame_name| parameter is non-empty, it is used 218 // as the name of the new top-level frame. 219 // The |opener_route_id| parameter indicates which RenderView created this 220 // (MSG_ROUTING_NONE if none). If |max_page_id| is larger than -1, the 221 // RenderView is told to start issuing page IDs at |max_page_id| + 1. 222 // |window_was_created_with_opener| is true if this top-level frame was 223 // created with an opener. (The opener may have been closed since.) 224 // The |proxy_route_id| is only used when creating a RenderView in swapped out 225 // state. 226 virtual bool CreateRenderView(const base::string16& frame_name, 227 int opener_route_id, 228 int proxy_route_id, 229 int32 max_page_id, 230 bool window_was_created_with_opener); 231 render_view_termination_status()232 base::TerminationStatus render_view_termination_status() const { 233 return render_view_termination_status_; 234 } 235 236 // Returns the content specific prefs for this RenderViewHost. 237 WebPreferences ComputeWebkitPrefs(const GURL& url); 238 239 // Whether this RenderViewHost has been swapped out to be displayed by a 240 // different process. IsSwappedOut()241 bool IsSwappedOut() const { return rvh_state_ == STATE_SWAPPED_OUT; } 242 243 // The current state of this RVH. rvh_state()244 RenderViewHostImplState rvh_state() const { return rvh_state_; } 245 246 // Tells the renderer that this RenderView will soon be swapped out, and thus 247 // not to create any new modal dialogs until it happens. This must be done 248 // separately so that the PageGroupLoadDeferrers of any current dialogs are no 249 // longer on the stack when we attempt to swap it out. 250 void SuppressDialogsUntilSwapOut(); 251 252 // Called when either the SwapOut request has been acknowledged or has timed 253 // out. 254 void OnSwappedOut(bool timed_out); 255 256 // Set |this| as pending shutdown. |on_swap_out| will be called 257 // when the SwapOutACK is received, or when the unload timer times out. 258 void SetPendingShutdown(const base::Closure& on_swap_out); 259 260 // Close the page ignoring whether it has unload events registers. 261 // This is called after the beforeunload and unload events have fired 262 // and the user has agreed to continue with closing the page. 263 void ClosePageIgnoringUnloadEvents(); 264 265 // Tells the renderer view to focus the first (last if reverse is true) node. 266 void SetInitialFocus(bool reverse); 267 268 // Get html data by serializing all frames of current page with lists 269 // which contain all resource links that have local copy. 270 // The parameter links contain original URLs of all saved links. 271 // The parameter local_paths contain corresponding local file paths of 272 // all saved links, which matched with vector:links one by one. 273 // The parameter local_directory_name is relative path of directory which 274 // contain all saved auxiliary files included all sub frames and resouces. 275 void GetSerializedHtmlDataForCurrentPageWithLocalLinks( 276 const std::vector<GURL>& links, 277 const std::vector<base::FilePath>& local_paths, 278 const base::FilePath& local_directory_name); 279 280 // Notifies the RenderViewHost that its load state changed. 281 void LoadStateChanged(const GURL& url, 282 const net::LoadStateWithParam& load_state, 283 uint64 upload_position, 284 uint64 upload_size); 285 286 bool SuddenTerminationAllowed() const; set_sudden_termination_allowed(bool enabled)287 void set_sudden_termination_allowed(bool enabled) { 288 sudden_termination_allowed_ = enabled; 289 } 290 291 // RenderWidgetHost public overrides. 292 virtual void Init() OVERRIDE; 293 virtual void Shutdown() OVERRIDE; 294 virtual void WasHidden() OVERRIDE; 295 virtual void WasShown(const ui::LatencyInfo& latency_info) OVERRIDE; 296 virtual bool IsRenderView() const OVERRIDE; 297 virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; 298 virtual void GotFocus() OVERRIDE; 299 virtual void LostCapture() OVERRIDE; 300 virtual void LostMouseLock() OVERRIDE; 301 virtual void SetIsLoading(bool is_loading) OVERRIDE; 302 virtual void ForwardMouseEvent( 303 const blink::WebMouseEvent& mouse_event) OVERRIDE; 304 virtual void OnPointerEventActivate() OVERRIDE; 305 virtual void ForwardKeyboardEvent( 306 const NativeWebKeyboardEvent& key_event) OVERRIDE; 307 virtual gfx::Rect GetRootWindowResizerRect() const OVERRIDE; 308 309 // Creates a new RenderView with the given route id. 310 void CreateNewWindow( 311 int route_id, 312 int main_frame_route_id, 313 const ViewHostMsg_CreateWindow_Params& params, 314 SessionStorageNamespace* session_storage_namespace); 315 316 // Creates a new RenderWidget with the given route id. |popup_type| indicates 317 // if this widget is a popup and what kind of popup it is (select, autofill). 318 void CreateNewWidget(int route_id, blink::WebPopupType popup_type); 319 320 // Creates a full screen RenderWidget. 321 void CreateNewFullscreenWidget(int route_id); 322 323 #if defined(ENABLE_BROWSER_CDMS) media_web_contents_observer()324 MediaWebContentsObserver* media_web_contents_observer() { 325 return media_web_contents_observer_.get(); 326 } 327 #endif 328 main_frame_routing_id()329 int main_frame_routing_id() const { 330 return main_frame_routing_id_; 331 } 332 is_waiting_for_beforeunload_ack()333 bool is_waiting_for_beforeunload_ack() { 334 return is_waiting_for_beforeunload_ack_; 335 } 336 337 // Whether the RVH is waiting for the unload ack from the renderer. 338 bool IsWaitingForUnloadACK() const; 339 340 void OnTextSurroundingSelectionResponse(const base::string16& content, 341 size_t start_offset, 342 size_t end_offset); 343 344 // Update the FrameTree to use this RenderViewHost's main frame 345 // RenderFrameHost. Called when the RenderViewHost is committed. 346 // 347 // TODO(ajwong): Remove once RenderViewHost no longer owns the main frame 348 // RenderFrameHost. 349 void AttachToFrameTree(); 350 351 // Increases the refcounting on this RVH. This is done by the FrameTree on 352 // creation of a RenderFrameHost. increment_ref_count()353 void increment_ref_count() { ++frames_ref_count_; } 354 355 // Decreases the refcounting on this RVH. This is done by the FrameTree on 356 // destruction of a RenderFrameHost. decrement_ref_count()357 void decrement_ref_count() { --frames_ref_count_; } 358 359 // Returns the refcount on this RVH, that is the number of RenderFrameHosts 360 // currently using it. ref_count()361 int ref_count() { return frames_ref_count_; } 362 363 // NOTE: Do not add functions that just send an IPC message that are called in 364 // one or two places. Have the caller send the IPC message directly (unless 365 // the caller places are in different platforms, in which case it's better 366 // to keep them consistent). 367 368 protected: 369 // RenderWidgetHost protected overrides. 370 virtual void OnUserGesture() OVERRIDE; 371 virtual void NotifyRendererUnresponsive() OVERRIDE; 372 virtual void NotifyRendererResponsive() OVERRIDE; 373 virtual void OnRenderAutoResized(const gfx::Size& size) OVERRIDE; 374 virtual void RequestToLockMouse(bool user_gesture, 375 bool last_unlocked_by_target) OVERRIDE; 376 virtual bool IsFullscreen() const OVERRIDE; 377 virtual void OnFocus() OVERRIDE; 378 virtual void OnBlur() OVERRIDE; 379 380 // IPC message handlers. 381 void OnShowView(int route_id, 382 WindowOpenDisposition disposition, 383 const gfx::Rect& initial_pos, 384 bool user_gesture); 385 void OnShowWidget(int route_id, const gfx::Rect& initial_pos); 386 void OnShowFullscreenWidget(int route_id); 387 void OnRunModal(int opener_id, IPC::Message* reply_msg); 388 void OnRenderViewReady(); 389 void OnRenderProcessGone(int status, int error_code); 390 void OnUpdateState(int32 page_id, const PageState& state); 391 void OnUpdateTargetURL(const GURL& url); 392 void OnClose(); 393 void OnRequestMove(const gfx::Rect& pos); 394 void OnDocumentAvailableInMainFrame(bool uses_temporary_zoom_level); 395 void OnToggleFullscreen(bool enter_fullscreen); 396 void OnDidContentsPreferredSizeChange(const gfx::Size& new_size); 397 void OnPasteFromSelectionClipboard(); 398 void OnRouteCloseEvent(); 399 void OnRouteMessageEvent(const ViewMsg_PostMessage_Params& params); 400 void OnStartDragging(const DropData& drop_data, 401 blink::WebDragOperationsMask operations_allowed, 402 const SkBitmap& bitmap, 403 const gfx::Vector2d& bitmap_offset_in_dip, 404 const DragEventSourceInfo& event_info); 405 void OnUpdateDragCursor(blink::WebDragOperation drag_operation); 406 void OnTargetDropACK(); 407 void OnTakeFocus(bool reverse); 408 void OnFocusedNodeChanged(bool is_editable_node); 409 void OnClosePageACK(); 410 void OnDidZoomURL(double zoom_level, const GURL& url); 411 void OnRunFileChooser(const FileChooserParams& params); 412 void OnFocusedNodeTouched(bool editable); 413 414 private: 415 // TODO(nasko): Temporarily friend RenderFrameHostImpl, so we don't duplicate 416 // utility functions and state needed in both classes, while we move frame 417 // specific code away from this class. 418 friend class RenderFrameHostImpl; 419 friend class TestRenderViewHost; 420 FRIEND_TEST_ALL_PREFIXES(RenderViewHostTest, BasicRenderFrameHost); 421 FRIEND_TEST_ALL_PREFIXES(RenderViewHostTest, RoutingIdSane); 422 423 // TODO(creis): Move to a private namespace on RenderFrameHostImpl. 424 // Delay to wait on closing the WebContents for a beforeunload/unload handler 425 // to fire. 426 static const int kUnloadTimeoutMS; 427 428 // Updates the state of this RenderViewHost and clears any waiting state 429 // that is no longer relevant. 430 void SetState(RenderViewHostImplState rvh_state); 431 432 bool CanAccessFilesOfPageState(const PageState& state) const; 433 434 // The number of RenderFrameHosts which have a reference to this RVH. 435 int frames_ref_count_; 436 437 // Our delegate, which wants to know about changes in the RenderView. 438 RenderViewHostDelegate* delegate_; 439 440 // The SiteInstance associated with this RenderViewHost. All pages drawn 441 // in this RenderViewHost are part of this SiteInstance. Should not change 442 // over time. 443 scoped_refptr<SiteInstanceImpl> instance_; 444 445 // true if we are currently waiting for a response for drag context 446 // information. 447 bool waiting_for_drag_context_response_; 448 449 // A bitwise OR of bindings types that have been enabled for this RenderView. 450 // See BindingsPolicy for details. 451 int enabled_bindings_; 452 453 // The most recent page ID we've heard from the renderer process. This is 454 // used as context when other session history related IPCs arrive. 455 // TODO(creis): Allocate this in WebContents/NavigationController instead. 456 int32 page_id_; 457 458 // The current state of this RVH. 459 // TODO(nasko): Move to RenderFrameHost, as this is per-frame state. 460 RenderViewHostImplState rvh_state_; 461 462 // Routing ID for the main frame's RenderFrameHost. 463 int main_frame_routing_id_; 464 465 // If we were asked to RunModal, then this will hold the reply_msg that we 466 // must return to the renderer to unblock it. 467 IPC::Message* run_modal_reply_msg_; 468 // This will hold the routing id of the RenderView that opened us. 469 int run_modal_opener_id_; 470 471 // Set to true when there is a pending ViewMsg_ShouldClose message. This 472 // ensures we don't spam the renderer with multiple beforeunload requests. 473 // When either this value or IsWaitingForUnloadACK is true, the value of 474 // unload_ack_is_for_cross_site_transition_ indicates whether this is for a 475 // cross-site transition or a tab close attempt. 476 // TODO(clamy): Remove this boolean and add one more state to the state 477 // machine. 478 // TODO(nasko): Move to RenderFrameHost, as this is per-frame state. 479 bool is_waiting_for_beforeunload_ack_; 480 481 // Valid only when is_waiting_for_beforeunload_ack_ or 482 // IsWaitingForUnloadACK is true. This tells us if the unload request 483 // is for closing the entire tab ( = false), or only this RenderViewHost in 484 // the case of a cross-site transition ( = true). 485 // TODO(nasko): Move to RenderFrameHost, as this is per-frame state. 486 bool unload_ack_is_for_cross_site_transition_; 487 488 // True if the render view can be shut down suddenly. 489 bool sudden_termination_allowed_; 490 491 // The termination status of the last render view that terminated. 492 base::TerminationStatus render_view_termination_status_; 493 494 // Set to true if we requested the on screen keyboard to be displayed. 495 bool virtual_keyboard_requested_; 496 497 #if defined(ENABLE_BROWSER_CDMS) 498 // Manages all the media player and CDM managers and forwards IPCs to them. 499 scoped_ptr<MediaWebContentsObserver> media_web_contents_observer_; 500 #endif 501 502 // Used to swap out or shutdown this RVH when the unload event is taking too 503 // long to execute, depending on the number of active views in the 504 // SiteInstance. 505 // TODO(nasko): Move to RenderFrameHost, as this is per-frame state. 506 scoped_ptr<TimeoutMonitor> unload_event_monitor_timeout_; 507 508 // Called after receiving the SwapOutACK when the RVH is in state pending 509 // shutdown. Also called if the unload timer times out. 510 // TODO(nasko): Move to RenderFrameHost, as this is per-frame state. 511 base::Closure pending_shutdown_on_swap_out_; 512 513 // True if the current focused element is editable. 514 bool is_focused_element_editable_; 515 516 // This is updated every time UpdateWebkitPreferences is called. That method 517 // is in turn called when any of the settings change that the WebPreferences 518 // values depend on. 519 scoped_ptr<WebPreferences> web_preferences_; 520 521 bool updating_web_preferences_; 522 523 base::WeakPtrFactory<RenderViewHostImpl> weak_factory_; 524 525 DISALLOW_COPY_AND_ASSIGN(RenderViewHostImpl); 526 }; 527 528 #if defined(COMPILER_MSVC) 529 #pragma warning(pop) 530 #endif 531 532 } // namespace content 533 534 #endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_IMPL_H_ 535