1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
|
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_RENDERER_HOST_TEST_TEST_RENDER_VIEW_HOST_H_
#define CHROME_BROWSER_RENDERER_HOST_TEST_TEST_RENDER_VIEW_HOST_H_
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/message_loop.h"
#include "build/build_config.h"
#include "chrome/browser/renderer_host/mock_render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_factory.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/test_tab_contents.h"
#include "chrome/common/render_messages.h"
#include "chrome/test/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"
// Utility function to initialize ViewHostMsg_NavigateParams_Params
// with given |page_id|, |url| and |transition_type|.
void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params,
int page_id,
const GURL& url,
PageTransition::Type transition_type);
// This file provides a testing framework for mocking out the RenderProcessHost
// layer. It allows you to test RenderViewHost, TabContents,
// NavigationController, and other layers above that without running an actual
// renderer process.
//
// To use, derive your test base class from RenderViewHostTestHarness.
// TestRenderViewHostView ------------------------------------------------------
// Subclass the RenderViewHost's view so that we can call Show(), etc.,
// without having side-effects.
class TestRenderWidgetHostView : public RenderWidgetHostView {
public:
explicit TestRenderWidgetHostView(RenderWidgetHost* rwh);
virtual void InitAsPopup(RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos) {}
virtual RenderWidgetHost* GetRenderWidgetHost() const { return NULL; }
virtual void DidBecomeSelected() {}
virtual void WasHidden() {}
virtual void SetSize(const gfx::Size& size) {}
virtual gfx::NativeView GetNativeView() { return NULL; }
virtual void MovePluginWindows(
const std::vector<webkit_glue::WebPluginGeometry>& moves) {}
#if defined(OS_WIN)
virtual void ForwardMouseEventToRenderer(UINT message,
WPARAM wparam,
LPARAM lparam) {}
#endif
virtual void Focus() {}
virtual void Blur() {}
virtual bool HasFocus() { return true; }
virtual void AdvanceFocus(bool reverse) {}
virtual void Show() { is_showing_ = true; }
virtual void Hide() { is_showing_ = false; }
virtual bool IsShowing() { return is_showing_; }
virtual gfx::Rect GetViewBounds() const { return gfx::Rect(); }
virtual void SetIsLoading(bool is_loading) {}
virtual void UpdateCursor(const WebCursor& cursor) {}
virtual void UpdateCursorIfOverSelf() {}
virtual void ImeUpdateTextInputState(WebKit::WebTextInputType state,
const gfx::Rect& caret_rect) {}
virtual void ImeCancelComposition() {}
virtual void DidUpdateBackingStore(
const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy,
const std::vector<gfx::Rect>& rects) {}
virtual void RenderViewGone() { delete this; }
virtual void WillDestroyRenderWidget(RenderWidgetHost* rwh) { }
virtual void Destroy() {}
virtual void PrepareToDestroy() {}
virtual void SetTooltipText(const std::wstring& tooltip_text) {}
virtual BackingStore* AllocBackingStore(const gfx::Size& size);
virtual VideoLayer* AllocVideoLayer(const gfx::Size& size);
#if defined(OS_MACOSX)
virtual void ShowPopupWithItems(gfx::Rect bounds,
int item_height,
double item_font_size,
int selected_item,
const std::vector<WebMenuItem>& items,
bool right_aligned) {}
virtual gfx::Rect GetWindowRect();
virtual gfx::Rect GetRootWindowRect();
virtual void SetActive(bool active);
virtual void SetWindowVisibility(bool visible) {}
virtual void WindowFrameChanged() {}
virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle(
bool opaque);
virtual void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window);
virtual void AcceleratedSurfaceSetIOSurface(gfx::PluginWindowHandle window,
int32 width,
int32 height,
uint64 io_surface_identifier);
virtual void AcceleratedSurfaceSetTransportDIB(
gfx::PluginWindowHandle window,
int32 width,
int32 height,
TransportDIB::Handle transport_dib);
virtual void AcceleratedSurfaceBuffersSwapped(gfx::PluginWindowHandle window);
virtual void DrawAcceleratedSurfaceInstances(CGLContextObj context);
#endif
virtual void SetVisuallyDeemphasized(bool deemphasized) { }
#if defined(OS_LINUX)
virtual void CreatePluginContainer(gfx::PluginWindowHandle id) { }
virtual void DestroyPluginContainer(gfx::PluginWindowHandle id) { }
#endif
virtual bool ContainsNativeView(gfx::NativeView native_view) const {
return false;
}
bool is_showing() const { return is_showing_; }
private:
RenderWidgetHost* rwh_;
bool is_showing_;
};
// TestRenderViewHost ----------------------------------------------------------
// TODO(brettw) this should use a TestTabContents which should be generalized
// from the TabContents test. We will probably also need that class' version of
// CreateRenderViewForRenderManager when more complicate tests start using this.
class TestRenderViewHost : public RenderViewHost {
public:
TestRenderViewHost(SiteInstance* instance,
RenderViewHostDelegate* delegate,
int routing_id);
virtual ~TestRenderViewHost();
// Testing functions ---------------------------------------------------------
// Calls the RenderViewHosts' private OnMessageReceived function with the
// given message.
void TestOnMessageReceived(const IPC::Message& msg);
// Calls OnMsgNavigate on the RenderViewHost with the given information,
// setting the rest of the parameters in the message to the "typical" values.
// This is a helper function for simulating the most common types of loads.
void SendNavigate(int page_id, const GURL& url);
// Calls OnMsgNavigate on the RenderViewHost with the given information,
// including a custom PageTransition::Type. Sets the rest of the parameters
// in the message to the "typical" values.
// This is a helper function for simulating the most common types of loads.
void SendNavigateWithTransition(int page_id, const GURL& url,
PageTransition::Type transition);
// If set, *delete_counter is incremented when this object destructs.
void set_delete_counter(int* delete_counter) {
delete_counter_ = delete_counter;
}
// Sets whether the RenderView currently exists or not. This controls the
// return value from IsRenderViewLive, which the rest of the system uses to
// check whether the RenderView has crashed or not.
void set_render_view_created(bool created) {
render_view_created_ = created;
}
// Returns whether the RenderViewHost is currently waiting to hear the result
// of a before unload handler from the renderer.
bool is_waiting_for_beforeunload_ack() const {
return is_waiting_for_beforeunload_ack_;
}
// RenderViewHost overrides --------------------------------------------------
virtual bool CreateRenderView(URLRequestContextGetter* request_context,
const string16& frame_name);
virtual bool IsRenderViewLive() const;
private:
FRIEND_TEST_ALL_PREFIXES(RenderViewHostTest, FilterNavigate);
// Tracks if the caller thinks if it created the RenderView. This is so we can
// respond to IsRenderViewLive appropriately.
bool render_view_created_;
// See set_delete_counter() above. May be NULL.
int* delete_counter_;
DISALLOW_COPY_AND_ASSIGN(TestRenderViewHost);
};
// TestRenderViewHostFactory ---------------------------------------------------
// Manages creation of the RenderViewHosts using our special subclass. This
// automatically registers itself when it goes in scope, and unregisters itself
// when it goes out of scope. Since you can't have more than one factory
// registered at a time, you can only have one of these objects at a time.
class TestRenderViewHostFactory : public RenderViewHostFactory {
public:
explicit TestRenderViewHostFactory(RenderProcessHostFactory* rph_factory)
: render_process_host_factory_(rph_factory) {
RenderViewHostFactory::RegisterFactory(this);
}
virtual ~TestRenderViewHostFactory() {
RenderViewHostFactory::UnregisterFactory();
}
virtual void set_render_process_host_factory(
RenderProcessHostFactory* rph_factory) {
render_process_host_factory_ = rph_factory;
}
virtual RenderViewHost* CreateRenderViewHost(
SiteInstance* instance,
RenderViewHostDelegate* delegate,
int routing_id,
int64 session_storage_namespace_id) {
// See declaration of render_process_host_factory_ below.
instance->set_render_process_host_factory(render_process_host_factory_);
return new TestRenderViewHost(instance, delegate, routing_id);
}
private:
// This is a bit of a hack. With the current design of the site instances /
// browsing instances, it's difficult to pass a RenderProcessHostFactory
// around properly.
//
// Instead, we set it right before we create a new RenderViewHost, which
// happens before the RenderProcessHost is created. This way, the instance
// has the correct factory and creates our special RenderProcessHosts.
RenderProcessHostFactory* render_process_host_factory_;
DISALLOW_COPY_AND_ASSIGN(TestRenderViewHostFactory);
};
// RenderViewHostTestHarness ---------------------------------------------------
class RenderViewHostTestHarness : public testing::Test {
public:
RenderViewHostTestHarness()
: rph_factory_(),
rvh_factory_(&rph_factory_),
contents_(NULL) {}
virtual ~RenderViewHostTestHarness() {}
NavigationController& controller() {
return contents_->controller();
}
TestTabContents* contents() {
return contents_.get();
}
TestRenderViewHost* rvh() {
return static_cast<TestRenderViewHost*>(contents_->render_view_host());
}
TestRenderViewHost* pending_rvh() {
return static_cast<TestRenderViewHost*>(
contents_->render_manager()->pending_render_view_host());
}
TestRenderViewHost* active_rvh() {
return pending_rvh() ? pending_rvh() : rvh();
}
TestingProfile* profile() {
return profile_.get();
}
MockRenderProcessHost* process() {
return static_cast<MockRenderProcessHost*>(rvh()->process());
}
// Frees the current tab contents for tests that want to test destruction.
void DeleteContents() {
contents_.reset();
}
// Creates a pending navigation to the given URL with the default parameters
// and then commits the load with a page ID one larger than any seen. This
// emulates what happens on a new navigation.
void NavigateAndCommit(const GURL& url);
// Simulates a reload of the current page.
void Reload();
protected:
// testing::Test
virtual void SetUp();
virtual void TearDown();
// This profile will be created in SetUp if it has not already been created.
// This allows tests to override the profile if they so choose in their own
// SetUp function before calling the base class's (us) SetUp().
scoped_ptr<TestingProfile> profile_;
MessageLoopForUI message_loop_;
MockRenderProcessHostFactory rph_factory_;
TestRenderViewHostFactory rvh_factory_;
scoped_ptr<TestTabContents> contents_;
DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestHarness);
};
#endif // CHROME_BROWSER_RENDERER_HOST_TEST_TEST_RENDER_VIEW_HOST_H_
|