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_TEST_TEST_RENDER_VIEW_HOST_H_
6#define CONTENT_TEST_TEST_RENDER_VIEW_HOST_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/gtest_prod_util.h"
13#include "build/build_config.h"
14#include "content/browser/renderer_host/render_view_host_impl.h"
15#include "content/browser/renderer_host/render_widget_host_view_base.h"
16#include "content/public/common/page_transition_types.h"
17#include "content/public/test/test_renderer_host.h"
18#include "content/test/test_render_frame_host.h"
19#include "ui/base/layout.h"
20#include "ui/gfx/vector2d_f.h"
21
22// This file provides a testing framework for mocking out the RenderProcessHost
23// layer. It allows you to test RenderViewHost, WebContentsImpl,
24// NavigationController, and other layers above that without running an actual
25// renderer process.
26//
27// To use, derive your test base class from RenderViewHostImplTestHarness.
28
29struct ViewHostMsg_FrameNavigate_Params;
30
31namespace gfx {
32class Rect;
33}
34
35namespace content {
36
37class SiteInstance;
38class TestWebContents;
39
40// Utility function to initialize ViewHostMsg_NavigateParams_Params
41// with given |page_id|, |url| and |transition_type|.
42void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params,
43                        int page_id,
44                        const GURL& url,
45                        PageTransition transition_type);
46
47// TestRenderViewHostView ------------------------------------------------------
48
49// Subclass the RenderViewHost's view so that we can call Show(), etc.,
50// without having side-effects.
51class TestRenderWidgetHostView : public RenderWidgetHostViewBase {
52 public:
53  explicit TestRenderWidgetHostView(RenderWidgetHost* rwh);
54  virtual ~TestRenderWidgetHostView();
55
56  // RenderWidgetHostView implementation.
57  virtual void InitAsChild(gfx::NativeView parent_view) OVERRIDE {}
58  virtual RenderWidgetHost* GetRenderWidgetHost() const OVERRIDE;
59  virtual void SetSize(const gfx::Size& size) OVERRIDE {}
60  virtual void SetBounds(const gfx::Rect& rect) OVERRIDE {}
61  virtual gfx::NativeView GetNativeView() const OVERRIDE;
62  virtual gfx::NativeViewId GetNativeViewId() const OVERRIDE;
63  virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
64  virtual bool HasFocus() const OVERRIDE;
65  virtual bool IsSurfaceAvailableForCopy() const OVERRIDE;
66  virtual void Show() OVERRIDE;
67  virtual void Hide() OVERRIDE;
68  virtual bool IsShowing() OVERRIDE;
69  virtual gfx::Rect GetViewBounds() const OVERRIDE;
70#if defined(OS_MACOSX)
71  virtual void SetActive(bool active) OVERRIDE;
72  virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE {}
73  virtual void SetWindowVisibility(bool visible) OVERRIDE {}
74  virtual void WindowFrameChanged() OVERRIDE {}
75  virtual void ShowDefinitionForSelection() OVERRIDE {}
76  virtual bool SupportsSpeech() const OVERRIDE;
77  virtual void SpeakSelection() OVERRIDE;
78  virtual bool IsSpeaking() const OVERRIDE;
79  virtual void StopSpeaking() OVERRIDE;
80#endif  // defined(OS_MACOSX)
81#if defined(TOOLKIT_GTK)
82  virtual GdkEventButton* GetLastMouseDown() OVERRIDE;
83  virtual gfx::NativeView BuildInputMethodsGtkMenu() OVERRIDE;
84#endif  // defined(TOOLKIT_GTK)
85  virtual void OnSwapCompositorFrame(
86      uint32 output_surface_id,
87      scoped_ptr<cc::CompositorFrame> frame) OVERRIDE;
88
89  // RenderWidgetHostViewPort implementation.
90  virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
91                           const gfx::Rect& pos) OVERRIDE {}
92  virtual void InitAsFullscreen(
93      RenderWidgetHostView* reference_host_view) OVERRIDE {}
94  virtual void WasShown() OVERRIDE {}
95  virtual void WasHidden() OVERRIDE {}
96  virtual void MovePluginWindows(
97      const gfx::Vector2d& scroll_offset,
98      const std::vector<WebPluginGeometry>& moves) OVERRIDE {}
99  virtual void Focus() OVERRIDE {}
100  virtual void Blur() OVERRIDE {}
101  virtual void SetIsLoading(bool is_loading) OVERRIDE {}
102  virtual void UpdateCursor(const WebCursor& cursor) OVERRIDE {}
103  virtual void TextInputTypeChanged(ui::TextInputType type,
104                                    ui::TextInputMode input_mode,
105                                    bool can_compose_inline) OVERRIDE {}
106  virtual void ImeCancelComposition() OVERRIDE {}
107#if defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_AURA)
108  virtual void ImeCompositionRangeChanged(
109      const gfx::Range& range,
110      const std::vector<gfx::Rect>& character_bounds) OVERRIDE {}
111#endif
112  virtual void DidUpdateBackingStore(
113      const gfx::Rect& scroll_rect,
114      const gfx::Vector2d& scroll_delta,
115      const std::vector<gfx::Rect>& rects,
116      const ui::LatencyInfo& latency_info) OVERRIDE {}
117  virtual void RenderProcessGone(base::TerminationStatus status,
118                                 int error_code) OVERRIDE;
119  virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) { }
120  virtual void Destroy() OVERRIDE;
121  virtual void SetTooltipText(const base::string16& tooltip_text) OVERRIDE {}
122  virtual void SelectionBoundsChanged(
123      const ViewHostMsg_SelectionBounds_Params& params) OVERRIDE {}
124  virtual void ScrollOffsetChanged() OVERRIDE {}
125  virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE;
126  virtual void CopyFromCompositingSurface(
127      const gfx::Rect& src_subrect,
128      const gfx::Size& dst_size,
129      const base::Callback<void(bool, const SkBitmap&)>& callback) OVERRIDE;
130  virtual void CopyFromCompositingSurfaceToVideoFrame(
131      const gfx::Rect& src_subrect,
132      const scoped_refptr<media::VideoFrame>& target,
133      const base::Callback<void(bool)>& callback) OVERRIDE;
134  virtual bool CanCopyToVideoFrame() const OVERRIDE;
135  virtual void OnAcceleratedCompositingStateChange() OVERRIDE;
136  virtual void AcceleratedSurfaceInitialized(int host_id,
137                                             int route_id) OVERRIDE;
138  virtual void AcceleratedSurfaceBuffersSwapped(
139      const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
140      int gpu_host_id) OVERRIDE;
141  virtual void AcceleratedSurfacePostSubBuffer(
142      const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
143      int gpu_host_id) OVERRIDE;
144  virtual void AcceleratedSurfaceSuspend() OVERRIDE;
145  virtual void AcceleratedSurfaceRelease() OVERRIDE {}
146  virtual bool HasAcceleratedSurface(const gfx::Size& desired_size) OVERRIDE;
147#if defined(OS_MACOSX)
148  virtual void AboutToWaitForBackingStoreMsg() OVERRIDE;
149  virtual bool PostProcessEventForPluginIme(
150      const NativeWebKeyboardEvent& event) OVERRIDE;
151#elif defined(OS_ANDROID)
152  virtual void ShowDisambiguationPopup(
153      const gfx::Rect& target_rect,
154      const SkBitmap& zoomed_bitmap) OVERRIDE {}
155  virtual void HasTouchEventHandlers(bool need_touch_events) OVERRIDE {}
156#elif defined(OS_WIN) && !defined(USE_AURA)
157  virtual void WillWmDestroy() OVERRIDE;
158#endif
159  virtual void GetScreenInfo(blink::WebScreenInfo* results) OVERRIDE {}
160  virtual gfx::Rect GetBoundsInRootWindow() OVERRIDE;
161  virtual void SetHasHorizontalScrollbar(
162      bool has_horizontal_scrollbar) OVERRIDE { }
163  virtual void SetScrollOffsetPinning(
164      bool is_pinned_to_left, bool is_pinned_to_right) OVERRIDE { }
165  virtual void OnAccessibilityEvents(
166      const std::vector<AccessibilityHostMsg_EventParams>& params) OVERRIDE {}
167  virtual gfx::GLSurfaceHandle GetCompositingSurface() OVERRIDE;
168#if defined(OS_WIN) && !defined(USE_AURA)
169  virtual void SetClickthroughRegion(SkRegion* region) OVERRIDE;
170#endif
171  virtual bool LockMouse() OVERRIDE;
172  virtual void UnlockMouse() OVERRIDE;
173#if defined(OS_WIN) && defined(USE_AURA)
174  virtual void SetParentNativeViewAccessible(
175      gfx::NativeViewAccessible accessible_parent) OVERRIDE;
176  virtual gfx::NativeViewId GetParentForWindowlessPlugin() const OVERRIDE;
177#endif
178
179  bool is_showing() const { return is_showing_; }
180  bool did_swap_compositor_frame() const { return did_swap_compositor_frame_; }
181
182 protected:
183  RenderWidgetHostImpl* rwh_;
184
185 private:
186  bool is_showing_;
187  bool did_swap_compositor_frame_;
188};
189
190#if defined(COMPILER_MSVC)
191// See comment for same warning on RenderViewHostImpl.
192#pragma warning(push)
193#pragma warning(disable: 4250)
194#endif
195
196// TestRenderViewHost ----------------------------------------------------------
197
198// TODO(brettw) this should use a TestWebContents which should be generalized
199// from the WebContentsImpl test. We will probably also need that class' version
200// of CreateRenderViewForRenderManager when more complicated tests start using
201// this.
202//
203// Note that users outside of content must use this class by getting
204// the separate RenderViewHostTester interface via
205// RenderViewHostTester::For(rvh) on the RenderViewHost they want to
206// drive tests on.
207//
208// Users within content may directly static_cast from a
209// RenderViewHost* to a TestRenderViewHost*.
210//
211// The reasons we do it this way rather than extending the parallel
212// inheritance hierarchy we have for RenderWidgetHost/RenderViewHost
213// vs. RenderWidgetHostImpl/RenderViewHostImpl are:
214//
215// a) Extending the parallel class hierarchy further would require
216// more classes to use virtual inheritance.  This is a complexity that
217// is better to avoid, especially when it would be introduced in the
218// production code solely to facilitate testing code.
219//
220// b) While users outside of content only need to drive tests on a
221// RenderViewHost, content needs a test version of the full
222// RenderViewHostImpl so that it can test all methods on that concrete
223// class (e.g. overriding a method such as
224// RenderViewHostImpl::CreateRenderView).  This would have complicated
225// the dual class hierarchy even further.
226//
227// The reason we do it this way instead of using composition is
228// similar to (b) above, essentially it gets very tricky.  By using
229// the split interface we avoid complexity within content and maintain
230// reasonable utility for embedders.
231class TestRenderViewHost
232    : public RenderViewHostImpl,
233      public RenderViewHostTester {
234 public:
235  TestRenderViewHost(SiteInstance* instance,
236                     RenderViewHostDelegate* delegate,
237                     RenderFrameHostDelegate* frame_delegate,
238                     RenderWidgetHostDelegate* widget_delegate,
239                     int routing_id,
240                     int main_frame_routing_id,
241                     bool swapped_out);
242  virtual ~TestRenderViewHost();
243
244  // RenderViewHostTester implementation.  Note that CreateRenderView
245  // is not specified since it is synonymous with the one from
246  // RenderViewHostImpl, see below.
247  virtual void SendNavigate(int page_id, const GURL& url) OVERRIDE;
248  virtual void SendFailedNavigate(int page_id, const GURL& url) OVERRIDE;
249  virtual void SendNavigateWithTransition(int page_id, const GURL& url,
250                                          PageTransition transition) OVERRIDE;
251  virtual void SendShouldCloseACK(bool proceed) OVERRIDE;
252  virtual void SetContentsMimeType(const std::string& mime_type) OVERRIDE;
253  virtual void SimulateSwapOutACK() OVERRIDE;
254  virtual void SimulateWasHidden() OVERRIDE;
255  virtual void SimulateWasShown() OVERRIDE;
256
257  // Calls OnNavigate on the RenderViewHost with the given information,
258  // including a custom original request URL.  Sets the rest of the
259  // parameters in the message to the "typical" values.  This is a helper
260  // function for simulating the most common types of loads.
261  void SendNavigateWithOriginalRequestURL(
262      int page_id, const GURL& url, const GURL& original_request_url);
263
264  void SendNavigateWithFile(
265      int page_id, const GURL& url, const base::FilePath& file_path);
266
267  void SendNavigateWithParams(ViewHostMsg_FrameNavigate_Params* params);
268
269  void TestOnUpdateStateWithFile(
270      int process_id, const base::FilePath& file_path);
271
272  void TestOnStartDragging(const DropData& drop_data);
273
274  // If set, *delete_counter is incremented when this object destructs.
275  void set_delete_counter(int* delete_counter) {
276    delete_counter_ = delete_counter;
277  }
278
279  // Sets whether the RenderView currently exists or not. This controls the
280  // return value from IsRenderViewLive, which the rest of the system uses to
281  // check whether the RenderView has crashed or not.
282  void set_render_view_created(bool created) {
283    render_view_created_ = created;
284  }
285
286  // Returns whether the RenderViewHost is currently waiting to hear the result
287  // of a before unload handler from the renderer.
288  bool is_waiting_for_beforeunload_ack() const {
289    return is_waiting_for_beforeunload_ack_;
290  }
291
292  // Returns whether the RenderViewHost is currently waiting to hear the result
293  // of an unload handler from the renderer.
294  bool is_waiting_for_unload_ack() const {
295    return is_waiting_for_unload_ack_;
296  }
297
298  // Sets whether the RenderViewHost is currently swapped out, and thus
299  // filtering messages from the renderer.
300  void set_is_swapped_out(bool is_swapped_out) {
301    is_swapped_out_ = is_swapped_out;
302  }
303
304  // If set, navigations will appear to have loaded through a proxy
305  // (ViewHostMsg_FrameNavigte_Params::was_fetched_via_proxy).
306  // False by default.
307  void set_simulate_fetch_via_proxy(bool proxy);
308
309  // If set, navigations will appear to have cleared the history list in the
310  // RenderView (ViewHostMsg_FrameNavigate_Params::history_list_was_cleared).
311  // False by default.
312  void set_simulate_history_list_was_cleared(bool cleared);
313
314  // The opener route id passed to CreateRenderView().
315  int opener_route_id() const { return opener_route_id_; }
316
317  // RenderViewHost overrides --------------------------------------------------
318
319  virtual bool CreateRenderView(const base::string16& frame_name,
320                                int opener_route_id,
321                                int32 max_page_id) OVERRIDE;
322  virtual bool IsRenderViewLive() const OVERRIDE;
323
324 private:
325  FRIEND_TEST_ALL_PREFIXES(RenderViewHostTest, FilterNavigate);
326
327  void SendNavigateWithTransitionAndResponseCode(int page_id,
328                                                 const GURL& url,
329                                                 PageTransition transition,
330                                                 int response_code);
331
332  // Calls OnNavigate on the RenderViewHost with the given information.
333  // Sets the rest of the parameters in the message to the "typical" values.
334  // This is a helper function for simulating the most common types of loads.
335  void SendNavigateWithParameters(
336      int page_id,
337      const GURL& url,
338      PageTransition transition,
339      const GURL& original_request_url,
340      int response_code,
341      const base::FilePath* file_path_for_history_item);
342
343  // Tracks if the caller thinks if it created the RenderView. This is so we can
344  // respond to IsRenderViewLive appropriately.
345  bool render_view_created_;
346
347  // See set_delete_counter() above. May be NULL.
348  int* delete_counter_;
349
350  // See set_simulate_fetch_via_proxy() above.
351  bool simulate_fetch_via_proxy_;
352
353  // See set_simulate_history_list_was_cleared() above.
354  bool simulate_history_list_was_cleared_;
355
356  // See SetContentsMimeType() above.
357  std::string contents_mime_type_;
358
359  // See opener_route_id() above.
360  int opener_route_id_;
361
362  DISALLOW_COPY_AND_ASSIGN(TestRenderViewHost);
363};
364
365#if defined(COMPILER_MSVC)
366#pragma warning(pop)
367#endif
368
369// Adds methods to get straight at the impl classes.
370class RenderViewHostImplTestHarness : public RenderViewHostTestHarness {
371 public:
372  RenderViewHostImplTestHarness();
373  virtual ~RenderViewHostImplTestHarness();
374
375  TestRenderViewHost* test_rvh();
376  TestRenderViewHost* pending_test_rvh();
377  TestRenderViewHost* active_test_rvh();
378  TestRenderFrameHost* main_test_rfh();
379  TestWebContents* contents();
380
381 private:
382  typedef scoped_ptr<ui::test::ScopedSetSupportedScaleFactors>
383      ScopedSetSupportedScaleFactors;
384  ScopedSetSupportedScaleFactors scoped_set_supported_scale_factors_;
385  DISALLOW_COPY_AND_ASSIGN(RenderViewHostImplTestHarness);
386};
387
388}  // namespace content
389
390#endif  // CONTENT_TEST_TEST_RENDER_VIEW_HOST_H_
391