mock_render_process_host.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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#include "content/public/test/mock_render_process_host.h"
6
7#include "base/lazy_instance.h"
8#include "base/message_loop.h"
9#include "base/time.h"
10#include "content/browser/child_process_security_policy_impl.h"
11#include "content/browser/renderer_host/render_process_host_impl.h"
12#include "content/browser/renderer_host/render_widget_host_impl.h"
13#include "content/common/child_process_host_impl.h"
14#include "content/public/browser/notification_service.h"
15#include "content/public/browser/notification_types.h"
16#include "content/public/browser/storage_partition.h"
17
18namespace content {
19
20MockRenderProcessHost::MockRenderProcessHost(
21    BrowserContext* browser_context)
22        : transport_dib_(NULL),
23          bad_msg_count_(0),
24          factory_(NULL),
25          id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
26          browser_context_(browser_context),
27          fast_shutdown_started_(false) {
28  // Child process security operations can't be unit tested unless we add
29  // ourselves as an existing child process.
30  ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID());
31
32  RenderProcessHostImpl::RegisterHost(GetID(), this);
33}
34
35MockRenderProcessHost::~MockRenderProcessHost() {
36  ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID());
37  delete transport_dib_;
38  if (factory_)
39    factory_->Remove(this);
40  // In unit tests, Release() might not have been called.
41  RenderProcessHostImpl::UnregisterHost(GetID());
42}
43
44void MockRenderProcessHost::EnableSendQueue() {
45}
46
47bool MockRenderProcessHost::Init() {
48  return true;
49}
50
51int MockRenderProcessHost::GetNextRoutingID() {
52  static int prev_routing_id = 0;
53  return ++prev_routing_id;
54}
55
56void MockRenderProcessHost::SimulateSwapOutACK(
57    const ViewMsg_SwapOut_Params& params) {
58}
59
60bool MockRenderProcessHost::WaitForBackingStoreMsg(
61    int render_widget_id,
62    const base::TimeDelta& max_delay,
63    IPC::Message* msg) {
64  return false;
65}
66
67void MockRenderProcessHost::ReceivedBadMessage() {
68  ++bad_msg_count_;
69}
70
71void MockRenderProcessHost::WidgetRestored() {
72}
73
74void MockRenderProcessHost::WidgetHidden() {
75}
76
77int MockRenderProcessHost::VisibleWidgetCount() const {
78  return 1;
79}
80
81bool MockRenderProcessHost::IsGuest() const {
82  return false;
83}
84
85StoragePartition* MockRenderProcessHost::GetStoragePartition() const {
86  return NULL;
87}
88
89void MockRenderProcessHost::AddWord(const string16& word) {
90}
91
92bool MockRenderProcessHost::FastShutdownIfPossible() {
93  // We aren't actually going to do anything, but set |fast_shutdown_started_|
94  // to true so that tests know we've been called.
95  fast_shutdown_started_ = true;
96  return true;
97}
98
99bool MockRenderProcessHost::FastShutdownStarted() const {
100  return fast_shutdown_started_;
101}
102
103void MockRenderProcessHost::DumpHandles() {
104}
105
106base::ProcessHandle MockRenderProcessHost::GetHandle() const {
107  // Return the current-process handle for the IPC::GetFileHandleForProcess
108  // function.
109  return base::Process::Current().handle();
110}
111
112bool MockRenderProcessHost::Send(IPC::Message* msg) {
113  // Save the message in the sink.
114  sink_.OnMessageReceived(*msg);
115  delete msg;
116  return true;
117}
118
119TransportDIB* MockRenderProcessHost::MapTransportDIB(TransportDIB::Id dib_id) {
120#if defined(OS_WIN)
121  HANDLE duped;
122  DuplicateHandle(GetCurrentProcess(), dib_id.handle, GetCurrentProcess(),
123                  &duped, 0, TRUE, DUPLICATE_SAME_ACCESS);
124  return TransportDIB::Map(duped);
125#elif defined(TOOLKIT_GTK)
126  return TransportDIB::Map(dib_id.shmkey);
127#elif defined(OS_ANDROID)
128  // On Android, Handles and Ids are the same underlying type.
129  return TransportDIB::Map(dib_id);
130#else
131  // On POSIX, TransportDIBs are always created in the browser, so we cannot map
132  // one from a dib_id.
133  return TransportDIB::Create(100 * 100 * 4, 0);
134#endif
135}
136
137TransportDIB* MockRenderProcessHost::GetTransportDIB(TransportDIB::Id dib_id) {
138  if (transport_dib_)
139    return transport_dib_;
140
141  transport_dib_ = MapTransportDIB(dib_id);
142  return transport_dib_;
143}
144
145int MockRenderProcessHost::GetID() const {
146  return id_;
147}
148
149bool MockRenderProcessHost::HasConnection() const {
150  return true;
151}
152
153void MockRenderProcessHost::SetIgnoreInputEvents(bool ignore_input_events) {
154}
155
156bool MockRenderProcessHost::IgnoreInputEvents() const {
157  return false;
158}
159
160void MockRenderProcessHost::Attach(RenderWidgetHost* host,
161                                   int routing_id) {
162  render_widget_hosts_.AddWithID(host, routing_id);
163}
164
165void MockRenderProcessHost::Release(int routing_id) {
166  render_widget_hosts_.Remove(routing_id);
167  Cleanup();
168}
169
170void MockRenderProcessHost::Cleanup() {
171  if (render_widget_hosts_.IsEmpty()) {
172    NotificationService::current()->Notify(
173        NOTIFICATION_RENDERER_PROCESS_TERMINATED,
174        Source<RenderProcessHost>(this),
175        NotificationService::NoDetails());
176    base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
177    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
194RenderWidgetHost* MockRenderProcessHost::GetRenderWidgetHostByID(
195    int routing_id) {
196  return render_widget_hosts_.Lookup(routing_id);
197}
198
199BrowserContext* MockRenderProcessHost::GetBrowserContext() const {
200  return browser_context_;
201}
202
203bool MockRenderProcessHost::InSameStoragePartition(
204    StoragePartition* partition) const {
205  // Mock RPHs only have one partition.
206  return true;
207}
208
209IPC::ChannelProxy* MockRenderProcessHost::GetChannel() {
210  return NULL;
211}
212
213bool MockRenderProcessHost::FastShutdownForPageCount(size_t count) {
214  if (render_widget_hosts_.size() == count)
215    return FastShutdownIfPossible();
216  return false;
217}
218
219base::TimeDelta MockRenderProcessHost::GetChildProcessIdleTime() const {
220  return base::TimeDelta::FromMilliseconds(0);
221}
222
223void MockRenderProcessHost::SurfaceUpdated(int32 surface_id) {
224}
225
226void MockRenderProcessHost::ResumeRequestsForView(int route_id) {
227}
228
229RenderProcessHost::RenderWidgetHostsIterator
230    MockRenderProcessHost::GetRenderWidgetHostsIterator() {
231  return RenderWidgetHostsIterator(&render_widget_hosts_);
232}
233
234bool MockRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
235  RenderWidgetHost* rwh = render_widget_hosts_.Lookup(msg.routing_id());
236  if (rwh)
237    return RenderWidgetHostImpl::From(rwh)->OnMessageReceived(msg);
238  return false;
239}
240
241void MockRenderProcessHost::OnChannelConnected(int32 peer_pid) {
242}
243
244MockRenderProcessHostFactory::MockRenderProcessHostFactory() {}
245
246MockRenderProcessHostFactory::~MockRenderProcessHostFactory() {
247  // Detach this object from MockRenderProcesses to prevent STLDeleteElements()
248  // from calling MockRenderProcessHostFactory::Remove().
249  for (ScopedVector<MockRenderProcessHost>::iterator it = processes_.begin();
250       it != processes_.end(); ++it) {
251    (*it)->SetFactory(NULL);
252  }
253}
254
255RenderProcessHost* MockRenderProcessHostFactory::CreateRenderProcessHost(
256    BrowserContext* browser_context,
257    SiteInstance* site_instance) const {
258  MockRenderProcessHost* host = new MockRenderProcessHost(browser_context);
259  if (host) {
260    processes_.push_back(host);
261    host->SetFactory(this);
262  }
263  return host;
264}
265
266void MockRenderProcessHostFactory::Remove(MockRenderProcessHost* host) const {
267  for (ScopedVector<MockRenderProcessHost>::iterator it = processes_.begin();
268       it != processes_.end(); ++it) {
269    if (*it == host) {
270      processes_.weak_erase(it);
271      break;
272    }
273  }
274}
275
276}  // content
277