• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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