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.
5 #include "content/public/test/mock_render_process_host.h"
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"
22 MockRenderProcessHost::MockRenderProcessHost(
23 BrowserContext* browser_context)
24 : transport_dib_(NULL),
27 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
28 browser_context_(browser_context),
30 fast_shutdown_started_(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());
35 RenderProcessHostImpl::RegisterHost(GetID(), this);
38 MockRenderProcessHost::~MockRenderProcessHost() {
39 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID());
40 delete transport_dib_;
42 factory_->Remove(this);
43 // In unit tests, Release() might not have been called.
44 RenderProcessHostImpl::UnregisterHost(GetID());
47 void MockRenderProcessHost::EnableSendQueue() {
50 bool MockRenderProcessHost::Init() {
54 int MockRenderProcessHost::GetNextRoutingID() {
55 return ++prev_routing_id_;
58 void MockRenderProcessHost::AddRoute(
60 IPC::Listener* listener) {
61 listeners_.AddWithID(listener, routing_id);
64 void MockRenderProcessHost::RemoveRoute(int32 routing_id) {
65 DCHECK(listeners_.Lookup(routing_id) != NULL);
66 listeners_.Remove(routing_id);
70 bool MockRenderProcessHost::WaitForBackingStoreMsg(
72 const base::TimeDelta& max_delay,
77 void MockRenderProcessHost::ReceivedBadMessage() {
81 void MockRenderProcessHost::WidgetRestored() {
84 void MockRenderProcessHost::WidgetHidden() {
87 int MockRenderProcessHost::VisibleWidgetCount() const {
91 bool MockRenderProcessHost::IsGuest() const {
95 StoragePartition* MockRenderProcessHost::GetStoragePartition() const {
99 void MockRenderProcessHost::AddWord(const string16& word) {
102 bool 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;
109 bool MockRenderProcessHost::FastShutdownStarted() const {
110 return fast_shutdown_started_;
113 void MockRenderProcessHost::DumpHandles() {
116 base::ProcessHandle MockRenderProcessHost::GetHandle() const {
117 // Return the current-process handle for the IPC::GetFileHandleForProcess
119 return base::Process::Current().handle();
122 bool MockRenderProcessHost::Send(IPC::Message* msg) {
123 // Save the message in the sink.
124 sink_.OnMessageReceived(*msg);
129 TransportDIB* MockRenderProcessHost::MapTransportDIB(TransportDIB::Id dib_id) {
132 DuplicateHandle(GetCurrentProcess(), dib_id.handle, GetCurrentProcess(),
133 &duped, 0, TRUE, DUPLICATE_SAME_ACCESS);
134 return TransportDIB::Map(duped);
135 #elif defined(TOOLKIT_GTK)
136 return TransportDIB::Map(dib_id.shmkey);
137 #elif defined(OS_ANDROID)
138 // On Android, Handles and Ids are the same underlying type.
139 return TransportDIB::Map(dib_id);
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);
147 TransportDIB* MockRenderProcessHost::GetTransportDIB(TransportDIB::Id dib_id) {
149 return transport_dib_;
151 transport_dib_ = MapTransportDIB(dib_id);
152 return transport_dib_;
155 int MockRenderProcessHost::GetID() const {
159 bool MockRenderProcessHost::HasConnection() const {
163 void MockRenderProcessHost::SetIgnoreInputEvents(bool ignore_input_events) {
166 bool MockRenderProcessHost::IgnoreInputEvents() const {
170 void MockRenderProcessHost::Cleanup() {
171 if (listeners_.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());
181 void MockRenderProcessHost::AddPendingView() {
184 void MockRenderProcessHost::RemovePendingView() {
187 void MockRenderProcessHost::SetSuddenTerminationAllowed(bool allowed) {
190 bool MockRenderProcessHost::SuddenTerminationAllowed() const {
194 BrowserContext* MockRenderProcessHost::GetBrowserContext() const {
195 return browser_context_;
198 bool MockRenderProcessHost::InSameStoragePartition(
199 StoragePartition* partition) const {
200 // Mock RPHs only have one partition.
204 IPC::ChannelProxy* MockRenderProcessHost::GetChannel() {
208 void MockRenderProcessHost::AddFilter(BrowserMessageFilter* filter) {
211 int MockRenderProcessHost::GetActiveViewCount() {
212 int num_active_views = 0;
213 scoped_ptr<RenderWidgetHostIterator> widgets(
214 RenderWidgetHost::GetRenderWidgetHosts());
215 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
216 // Count only RenderWidgetHosts in this process.
217 if (widget->GetProcess()->GetID() == GetID())
220 return num_active_views;
223 bool MockRenderProcessHost::FastShutdownForPageCount(size_t count) {
224 if (static_cast<size_t>(GetActiveViewCount()) == count)
225 return FastShutdownIfPossible();
229 base::TimeDelta MockRenderProcessHost::GetChildProcessIdleTime() const {
230 return base::TimeDelta::FromMilliseconds(0);
233 void MockRenderProcessHost::SurfaceUpdated(int32 surface_id) {
236 void MockRenderProcessHost::ResumeRequestsForView(int route_id) {
240 bool MockRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
241 IPC::Listener* listener = listeners_.Lookup(msg.routing_id());
243 return listener->OnMessageReceived(msg);
247 void MockRenderProcessHost::OnChannelConnected(int32 peer_pid) {
250 MockRenderProcessHostFactory::MockRenderProcessHostFactory() {}
252 MockRenderProcessHostFactory::~MockRenderProcessHostFactory() {
253 // Detach this object from MockRenderProcesses to prevent STLDeleteElements()
254 // from calling MockRenderProcessHostFactory::Remove().
255 for (ScopedVector<MockRenderProcessHost>::iterator it = processes_.begin();
256 it != processes_.end(); ++it) {
257 (*it)->SetFactory(NULL);
261 RenderProcessHost* MockRenderProcessHostFactory::CreateRenderProcessHost(
262 BrowserContext* browser_context,
263 SiteInstance* site_instance) const {
264 MockRenderProcessHost* host = new MockRenderProcessHost(browser_context);
266 processes_.push_back(host);
267 host->SetFactory(this);
272 void MockRenderProcessHostFactory::Remove(MockRenderProcessHost* host) const {
273 for (ScopedVector<MockRenderProcessHost>::iterator it = processes_.begin();
274 it != processes_.end(); ++it) {
276 processes_.weak_erase(it);