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"
11 #include "base/lazy_instance.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/process/process_handle.h"
14 #include "base/time/time.h"
15 #include "content/browser/child_process_security_policy_impl.h"
16 #include "content/browser/renderer_host/render_process_host_impl.h"
17 #include "content/browser/renderer_host/render_view_host_impl.h"
18 #include "content/browser/renderer_host/render_widget_host_impl.h"
19 #include "content/common/child_process_host_impl.h"
20 #include "content/common/frame_messages.h"
21 #include "content/public/browser/browser_context.h"
22 #include "content/public/browser/global_request_id.h"
23 #include "content/public/browser/notification_details.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/browser/notification_source.h"
26 #include "content/public/browser/notification_types.h"
27 #include "content/public/browser/render_widget_host_iterator.h"
28 #include "content/public/browser/storage_partition.h"
32 MockRenderProcessHost::MockRenderProcessHost(BrowserContext
* browser_context
)
35 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
36 browser_context_(browser_context
),
38 fast_shutdown_started_(false),
39 deletion_callback_called_(false),
40 is_isolated_guest_(false) {
41 // Child process security operations can't be unit tested unless we add
42 // ourselves as an existing child process.
43 ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID());
45 RenderProcessHostImpl::RegisterHost(GetID(), this);
48 MockRenderProcessHost::~MockRenderProcessHost() {
49 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID());
51 factory_
->Remove(this);
53 // In unit tests, Cleanup() might not have been called.
54 if (!deletion_callback_called_
) {
55 FOR_EACH_OBSERVER(RenderProcessHostObserver
,
57 RenderProcessHostDestroyed(this));
58 RenderProcessHostImpl::UnregisterHost(GetID());
62 void MockRenderProcessHost::SimulateCrash() {
63 RenderProcessHost::RendererClosedDetails
details(
64 base::TERMINATION_STATUS_PROCESS_CRASHED
, 0);
65 NotificationService::current()->Notify(
66 NOTIFICATION_RENDERER_PROCESS_CLOSED
, Source
<RenderProcessHost
>(this),
67 Details
<RenderProcessHost::RendererClosedDetails
>(&details
));
69 // Send every routing ID a FrameHostMsg_RenderProcessGone message. To ensure a
70 // predictable order for unittests which may assert against the order, we sort
71 // the listeners by descending routing ID, instead of using the arbitrary
72 // hash-map order like RenderProcessHostImpl.
73 std::vector
<std::pair
<int32
, IPC::Listener
*>> sorted_listeners_
;
74 IDMap
<IPC::Listener
>::iterator
iter(&listeners_
);
75 while (!iter
.IsAtEnd()) {
76 sorted_listeners_
.push_back(
77 std::make_pair(iter
.GetCurrentKey(), iter
.GetCurrentValue()));
80 std::sort(sorted_listeners_
.rbegin(), sorted_listeners_
.rend());
82 for (auto& entry_pair
: sorted_listeners_
) {
83 entry_pair
.second
->OnMessageReceived(FrameHostMsg_RenderProcessGone(
84 entry_pair
.first
, static_cast<int>(details
.status
), details
.exit_code
));
88 void MockRenderProcessHost::EnableSendQueue() {
91 bool MockRenderProcessHost::Init() {
95 int MockRenderProcessHost::GetNextRoutingID() {
96 return ++prev_routing_id_
;
99 void MockRenderProcessHost::AddRoute(
101 IPC::Listener
* listener
) {
102 listeners_
.AddWithID(listener
, routing_id
);
105 void MockRenderProcessHost::RemoveRoute(int32 routing_id
) {
106 DCHECK(listeners_
.Lookup(routing_id
) != NULL
);
107 listeners_
.Remove(routing_id
);
111 void MockRenderProcessHost::AddObserver(RenderProcessHostObserver
* observer
) {
112 observers_
.AddObserver(observer
);
115 void MockRenderProcessHost::RemoveObserver(
116 RenderProcessHostObserver
* observer
) {
117 observers_
.RemoveObserver(observer
);
120 void MockRenderProcessHost::ShutdownForBadMessage() {
124 void MockRenderProcessHost::WidgetRestored() {
127 void MockRenderProcessHost::WidgetHidden() {
130 int MockRenderProcessHost::VisibleWidgetCount() const {
134 bool MockRenderProcessHost::IsIsolatedGuest() const {
135 return is_isolated_guest_
;
138 StoragePartition
* MockRenderProcessHost::GetStoragePartition() const {
139 return BrowserContext::GetDefaultStoragePartition(browser_context_
);
142 void MockRenderProcessHost::AddWord(const base::string16
& word
) {
145 bool MockRenderProcessHost::Shutdown(int exit_code
, bool wait
) {
149 bool MockRenderProcessHost::FastShutdownIfPossible() {
150 // We aren't actually going to do anything, but set |fast_shutdown_started_|
151 // to true so that tests know we've been called.
152 fast_shutdown_started_
= true;
156 bool MockRenderProcessHost::FastShutdownStarted() const {
157 return fast_shutdown_started_
;
160 void MockRenderProcessHost::DumpHandles() {
163 base::ProcessHandle
MockRenderProcessHost::GetHandle() const {
164 // Return the current-process handle for the IPC::GetFileHandleForProcess
167 return *process_handle
;
168 return base::GetCurrentProcessHandle();
171 bool MockRenderProcessHost::Send(IPC::Message
* msg
) {
172 // Save the message in the sink.
173 sink_
.OnMessageReceived(*msg
);
178 int MockRenderProcessHost::GetID() const {
182 bool MockRenderProcessHost::HasConnection() const {
186 void MockRenderProcessHost::SetIgnoreInputEvents(bool ignore_input_events
) {
189 bool MockRenderProcessHost::IgnoreInputEvents() const {
193 void MockRenderProcessHost::Cleanup() {
194 if (listeners_
.IsEmpty()) {
195 FOR_EACH_OBSERVER(RenderProcessHostObserver
,
197 RenderProcessHostDestroyed(this));
198 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, this);
199 RenderProcessHostImpl::UnregisterHost(GetID());
200 deletion_callback_called_
= true;
204 void MockRenderProcessHost::AddPendingView() {
207 void MockRenderProcessHost::RemovePendingView() {
210 void MockRenderProcessHost::SetSuddenTerminationAllowed(bool allowed
) {
213 bool MockRenderProcessHost::SuddenTerminationAllowed() const {
217 BrowserContext
* MockRenderProcessHost::GetBrowserContext() const {
218 return browser_context_
;
221 bool MockRenderProcessHost::InSameStoragePartition(
222 StoragePartition
* partition
) const {
223 // Mock RPHs only have one partition.
227 IPC::ChannelProxy
* MockRenderProcessHost::GetChannel() {
231 void MockRenderProcessHost::AddFilter(BrowserMessageFilter
* filter
) {
234 bool MockRenderProcessHost::FastShutdownForPageCount(size_t count
) {
235 if (static_cast<size_t>(GetActiveViewCount()) == count
)
236 return FastShutdownIfPossible();
240 base::TimeDelta
MockRenderProcessHost::GetChildProcessIdleTime() const {
241 return base::TimeDelta::FromMilliseconds(0);
244 void MockRenderProcessHost::ResumeRequestsForView(int route_id
) {
247 void MockRenderProcessHost::NotifyTimezoneChange() {
250 ServiceRegistry
* MockRenderProcessHost::GetServiceRegistry() {
254 const base::TimeTicks
& MockRenderProcessHost::GetInitTimeForNavigationMetrics()
256 static base::TimeTicks dummy_time
= base::TimeTicks::Now();
260 bool MockRenderProcessHost::SubscribeUniformEnabled() const {
264 void MockRenderProcessHost::OnAddSubscription(unsigned int target
) {
267 void MockRenderProcessHost::OnRemoveSubscription(unsigned int target
) {
270 void MockRenderProcessHost::SendUpdateValueState(
271 unsigned int target
, const gpu::ValueState
& state
) {
274 #if defined(ENABLE_BROWSER_CDMS)
275 media::BrowserCdm
* MockRenderProcessHost::GetBrowserCdm(int render_frame_id
,
281 void MockRenderProcessHost::FilterURL(bool empty_allowed
, GURL
* url
) {
282 RenderProcessHostImpl::FilterURL(this, empty_allowed
, url
);
285 #if defined(ENABLE_WEBRTC)
286 void MockRenderProcessHost::EnableAecDump(const base::FilePath
& file
) {
289 void MockRenderProcessHost::DisableAecDump() {
292 void MockRenderProcessHost::SetWebRtcLogMessageCallback(
293 base::Callback
<void(const std::string
&)> callback
) {
296 RenderProcessHost::WebRtcStopRtpDumpCallback
297 MockRenderProcessHost::StartRtpDump(
300 const WebRtcRtpPacketCallback
& packet_callback
) {
301 return WebRtcStopRtpDumpCallback();
305 void MockRenderProcessHost::ResumeDeferredNavigation(
306 const GlobalRequestID
& request_id
) {}
308 bool MockRenderProcessHost::OnMessageReceived(const IPC::Message
& msg
) {
309 IPC::Listener
* listener
= listeners_
.Lookup(msg
.routing_id());
311 return listener
->OnMessageReceived(msg
);
315 void MockRenderProcessHost::OnChannelConnected(int32 peer_pid
) {
318 MockRenderProcessHostFactory::MockRenderProcessHostFactory() {}
320 MockRenderProcessHostFactory::~MockRenderProcessHostFactory() {
321 // Detach this object from MockRenderProcesses to prevent STLDeleteElements()
322 // from calling MockRenderProcessHostFactory::Remove().
323 for (ScopedVector
<MockRenderProcessHost
>::iterator it
= processes_
.begin();
324 it
!= processes_
.end(); ++it
) {
325 (*it
)->SetFactory(NULL
);
329 RenderProcessHost
* MockRenderProcessHostFactory::CreateRenderProcessHost(
330 BrowserContext
* browser_context
,
331 SiteInstance
* site_instance
) const {
332 MockRenderProcessHost
* host
= new MockRenderProcessHost(browser_context
);
334 processes_
.push_back(host
);
335 host
->SetFactory(this);
340 void MockRenderProcessHostFactory::Remove(MockRenderProcessHost
* host
) const {
341 for (ScopedVector
<MockRenderProcessHost
>::iterator it
= processes_
.begin();
342 it
!= processes_
.end(); ++it
) {
344 processes_
.weak_erase(it
);