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