blob: 5e4bd1c677482da56432a993101f08c6fc9e1fea [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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#include "content/public/test/mock_render_process_host.h"
6
7#include "base/lazy_instance.h"
Ben Murdoch9ab55632013-07-18 11:57:30 +01008#include "base/message_loop/message_loop.h"
Ben Murdocheb525c52013-07-10 11:40:50 +01009#include "base/time/time.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000010#include "content/browser/child_process_security_policy_impl.h"
11#include "content/browser/renderer_host/render_process_host_impl.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010012#include "content/browser/renderer_host/render_view_host_impl.h"
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +010013#include "content/browser/renderer_host/render_widget_host_impl.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000014#include "content/common/child_process_host_impl.h"
15#include "content/public/browser/notification_service.h"
16#include "content/public/browser/notification_types.h"
Torne (Richard Coles)58537e22013-09-12 12:10:22 +010017#include "content/public/browser/render_widget_host_iterator.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000018#include "content/public/browser/storage_partition.h"
19
20namespace content {
21
22MockRenderProcessHost::MockRenderProcessHost(
23 BrowserContext* browser_context)
24 : transport_dib_(NULL),
25 bad_msg_count_(0),
26 factory_(NULL),
27 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
28 browser_context_(browser_context),
29 fast_shutdown_started_(false) {
30 // Child process security operations can't be unit tested unless we add
31 // ourselves as an existing child process.
32 ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID());
33
34 RenderProcessHostImpl::RegisterHost(GetID(), this);
35}
36
37MockRenderProcessHost::~MockRenderProcessHost() {
38 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID());
39 delete transport_dib_;
40 if (factory_)
41 factory_->Remove(this);
42 // In unit tests, Release() might not have been called.
43 RenderProcessHostImpl::UnregisterHost(GetID());
44}
45
46void MockRenderProcessHost::EnableSendQueue() {
47}
48
49bool MockRenderProcessHost::Init() {
50 return true;
51}
52
53int MockRenderProcessHost::GetNextRoutingID() {
54 static int prev_routing_id = 0;
55 return ++prev_routing_id;
56}
57
Ben Murdocheb525c52013-07-10 11:40:50 +010058void MockRenderProcessHost::AddRoute(
59 int32 routing_id,
60 IPC::Listener* listener) {
61 listeners_.AddWithID(listener, routing_id);
62}
63
64void MockRenderProcessHost::RemoveRoute(int32 routing_id) {
65 DCHECK(listeners_.Lookup(routing_id) != NULL);
66 listeners_.Remove(routing_id);
67 Cleanup();
68}
69
Torne (Richard Coles)58218062012-11-14 11:43:16 +000070bool MockRenderProcessHost::WaitForBackingStoreMsg(
71 int render_widget_id,
72 const base::TimeDelta& max_delay,
73 IPC::Message* msg) {
74 return false;
75}
76
77void MockRenderProcessHost::ReceivedBadMessage() {
78 ++bad_msg_count_;
79}
80
81void MockRenderProcessHost::WidgetRestored() {
82}
83
84void MockRenderProcessHost::WidgetHidden() {
85}
86
87int MockRenderProcessHost::VisibleWidgetCount() const {
88 return 1;
89}
90
91bool MockRenderProcessHost::IsGuest() const {
92 return false;
93}
94
95StoragePartition* MockRenderProcessHost::GetStoragePartition() const {
96 return NULL;
97}
98
99void MockRenderProcessHost::AddWord(const string16& word) {
100}
101
102bool MockRenderProcessHost::FastShutdownIfPossible() {
103 // We aren't actually going to do anything, but set |fast_shutdown_started_|
104 // to true so that tests know we've been called.
105 fast_shutdown_started_ = true;
106 return true;
107}
108
109bool MockRenderProcessHost::FastShutdownStarted() const {
110 return fast_shutdown_started_;
111}
112
113void MockRenderProcessHost::DumpHandles() {
114}
115
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000116base::ProcessHandle MockRenderProcessHost::GetHandle() const {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000117 // Return the current-process handle for the IPC::GetFileHandleForProcess
118 // function.
119 return base::Process::Current().handle();
120}
121
122bool MockRenderProcessHost::Send(IPC::Message* msg) {
123 // Save the message in the sink.
124 sink_.OnMessageReceived(*msg);
125 delete msg;
126 return true;
127}
128
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100129TransportDIB* MockRenderProcessHost::MapTransportDIB(TransportDIB::Id dib_id) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000130#if defined(OS_WIN)
131 HANDLE duped;
132 DuplicateHandle(GetCurrentProcess(), dib_id.handle, GetCurrentProcess(),
133 &duped, 0, TRUE, DUPLICATE_SAME_ACCESS);
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100134 return TransportDIB::Map(duped);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100135#elif defined(TOOLKIT_GTK)
136 return TransportDIB::Map(dib_id.shmkey);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000137#elif defined(OS_ANDROID)
138 // On Android, Handles and Ids are the same underlying type.
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100139 return TransportDIB::Map(dib_id);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100140#else
141 // On POSIX, TransportDIBs are always created in the browser, so we cannot map
142 // one from a dib_id.
143 return TransportDIB::Create(100 * 100 * 4, 0);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000144#endif
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100145}
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000146
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100147TransportDIB* MockRenderProcessHost::GetTransportDIB(TransportDIB::Id dib_id) {
148 if (transport_dib_)
149 return transport_dib_;
150
151 transport_dib_ = MapTransportDIB(dib_id);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000152 return transport_dib_;
153}
154
155int MockRenderProcessHost::GetID() const {
156 return id_;
157}
158
159bool MockRenderProcessHost::HasConnection() const {
160 return true;
161}
162
163void MockRenderProcessHost::SetIgnoreInputEvents(bool ignore_input_events) {
164}
165
166bool MockRenderProcessHost::IgnoreInputEvents() const {
167 return false;
168}
169
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000170void MockRenderProcessHost::Cleanup() {
Ben Murdocheb525c52013-07-10 11:40:50 +0100171 if (listeners_.IsEmpty()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000172 NotificationService::current()->Notify(
173 NOTIFICATION_RENDERER_PROCESS_TERMINATED,
174 Source<RenderProcessHost>(this),
175 NotificationService::NoDetails());
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100176 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000177 RenderProcessHostImpl::UnregisterHost(GetID());
178 }
179}
180
181void MockRenderProcessHost::AddPendingView() {
182}
183
184void MockRenderProcessHost::RemovePendingView() {
185}
186
187void MockRenderProcessHost::SetSuddenTerminationAllowed(bool allowed) {
188}
189
190bool MockRenderProcessHost::SuddenTerminationAllowed() const {
191 return true;
192}
193
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000194BrowserContext* MockRenderProcessHost::GetBrowserContext() const {
195 return browser_context_;
196}
197
198bool MockRenderProcessHost::InSameStoragePartition(
199 StoragePartition* partition) const {
200 // Mock RPHs only have one partition.
201 return true;
202}
203
204IPC::ChannelProxy* MockRenderProcessHost::GetChannel() {
205 return NULL;
206}
207
Ben Murdocheb525c52013-07-10 11:40:50 +0100208int MockRenderProcessHost::GetActiveViewCount() {
209 int num_active_views = 0;
Torne (Richard Coles)58537e22013-09-12 12:10:22 +0100210 scoped_ptr<RenderWidgetHostIterator> widgets(
211 RenderWidgetHost::GetRenderWidgetHosts());
212 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
Ben Murdocheb525c52013-07-10 11:40:50 +0100213 // Count only RenderWidgetHosts in this process.
Torne (Richard Coles)58537e22013-09-12 12:10:22 +0100214 if (widget->GetProcess()->GetID() == GetID())
Ben Murdocheb525c52013-07-10 11:40:50 +0100215 num_active_views++;
216 }
217 return num_active_views;
218}
219
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000220bool MockRenderProcessHost::FastShutdownForPageCount(size_t count) {
Ben Murdocheb525c52013-07-10 11:40:50 +0100221 if (static_cast<size_t>(GetActiveViewCount()) == count)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000222 return FastShutdownIfPossible();
223 return false;
224}
225
226base::TimeDelta MockRenderProcessHost::GetChildProcessIdleTime() const {
227 return base::TimeDelta::FromMilliseconds(0);
228}
229
230void MockRenderProcessHost::SurfaceUpdated(int32 surface_id) {
231}
232
233void MockRenderProcessHost::ResumeRequestsForView(int route_id) {
234}
235
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000236
237bool MockRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
Ben Murdocheb525c52013-07-10 11:40:50 +0100238 IPC::Listener* listener = listeners_.Lookup(msg.routing_id());
239 if (listener)
240 return listener->OnMessageReceived(msg);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000241 return false;
242}
243
244void MockRenderProcessHost::OnChannelConnected(int32 peer_pid) {
245}
246
247MockRenderProcessHostFactory::MockRenderProcessHostFactory() {}
248
249MockRenderProcessHostFactory::~MockRenderProcessHostFactory() {
250 // Detach this object from MockRenderProcesses to prevent STLDeleteElements()
251 // from calling MockRenderProcessHostFactory::Remove().
252 for (ScopedVector<MockRenderProcessHost>::iterator it = processes_.begin();
253 it != processes_.end(); ++it) {
254 (*it)->SetFactory(NULL);
255 }
256}
257
258RenderProcessHost* MockRenderProcessHostFactory::CreateRenderProcessHost(
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100259 BrowserContext* browser_context,
260 SiteInstance* site_instance) const {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000261 MockRenderProcessHost* host = new MockRenderProcessHost(browser_context);
262 if (host) {
263 processes_.push_back(host);
264 host->SetFactory(this);
265 }
266 return host;
267}
268
269void MockRenderProcessHostFactory::Remove(MockRenderProcessHost* host) const {
270 for (ScopedVector<MockRenderProcessHost>::iterator it = processes_.begin();
271 it != processes_.end(); ++it) {
272 if (*it == host) {
273 processes_.weak_erase(it);
274 break;
275 }
276 }
277}
278
279} // content