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