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