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 has_connection_(false),
37 browser_context_(browser_context
),
39 fast_shutdown_started_(false),
40 deletion_callback_called_(false),
41 is_for_guests_only_(false) {
42 // Child process security operations can't be unit tested unless we add
43 // ourselves as an existing child process.
44 ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID());
46 RenderProcessHostImpl::RegisterHost(GetID(), this);
49 MockRenderProcessHost::~MockRenderProcessHost() {
50 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID());
52 factory_
->Remove(this);
54 // In unit tests, Cleanup() might not have been called.
55 if (!deletion_callback_called_
) {
56 FOR_EACH_OBSERVER(RenderProcessHostObserver
,
58 RenderProcessHostDestroyed(this));
59 RenderProcessHostImpl::UnregisterHost(GetID());
63 void MockRenderProcessHost::SimulateCrash() {
64 has_connection_
= false;
65 RenderProcessHost::RendererClosedDetails
details(
66 base::TERMINATION_STATUS_PROCESS_CRASHED
, 0);
67 NotificationService::current()->Notify(
68 NOTIFICATION_RENDERER_PROCESS_CLOSED
, Source
<RenderProcessHost
>(this),
69 Details
<RenderProcessHost::RendererClosedDetails
>(&details
));
72 RenderProcessHostObserver
, observers_
,
73 RenderProcessExited(this, details
.status
, details
.exit_code
));
75 // Send every routing ID a FrameHostMsg_RenderProcessGone message. To ensure a
76 // predictable order for unittests which may assert against the order, we sort
77 // the listeners by descending routing ID, instead of using the arbitrary
78 // hash-map order like RenderProcessHostImpl.
79 std::vector
<std::pair
<int32
, IPC::Listener
*>> sorted_listeners_
;
80 IDMap
<IPC::Listener
>::iterator
iter(&listeners_
);
81 while (!iter
.IsAtEnd()) {
82 sorted_listeners_
.push_back(
83 std::make_pair(iter
.GetCurrentKey(), iter
.GetCurrentValue()));
86 std::sort(sorted_listeners_
.rbegin(), sorted_listeners_
.rend());
88 for (auto& entry_pair
: sorted_listeners_
) {
89 entry_pair
.second
->OnMessageReceived(FrameHostMsg_RenderProcessGone(
90 entry_pair
.first
, static_cast<int>(details
.status
), details
.exit_code
));
94 void MockRenderProcessHost::EnableSendQueue() {
97 bool MockRenderProcessHost::Init() {
98 has_connection_
= true;
102 int MockRenderProcessHost::GetNextRoutingID() {
103 return ++prev_routing_id_
;
106 void MockRenderProcessHost::AddRoute(
108 IPC::Listener
* listener
) {
109 listeners_
.AddWithID(listener
, routing_id
);
112 void MockRenderProcessHost::RemoveRoute(int32 routing_id
) {
113 DCHECK(listeners_
.Lookup(routing_id
) != NULL
);
114 listeners_
.Remove(routing_id
);
118 void MockRenderProcessHost::AddObserver(RenderProcessHostObserver
* observer
) {
119 observers_
.AddObserver(observer
);
122 void MockRenderProcessHost::RemoveObserver(
123 RenderProcessHostObserver
* observer
) {
124 observers_
.RemoveObserver(observer
);
127 void MockRenderProcessHost::ShutdownForBadMessage() {
131 void MockRenderProcessHost::WidgetRestored() {
134 void MockRenderProcessHost::WidgetHidden() {
137 int MockRenderProcessHost::VisibleWidgetCount() const {
141 bool MockRenderProcessHost::IsForGuestsOnly() const {
142 return is_for_guests_only_
;
145 StoragePartition
* MockRenderProcessHost::GetStoragePartition() const {
146 return BrowserContext::GetDefaultStoragePartition(browser_context_
);
149 void MockRenderProcessHost::AddWord(const base::string16
& word
) {
152 bool MockRenderProcessHost::Shutdown(int exit_code
, bool wait
) {
156 bool MockRenderProcessHost::FastShutdownIfPossible() {
157 // We aren't actually going to do anything, but set |fast_shutdown_started_|
158 // to true so that tests know we've been called.
159 fast_shutdown_started_
= true;
163 bool MockRenderProcessHost::FastShutdownStarted() const {
164 return fast_shutdown_started_
;
167 base::ProcessHandle
MockRenderProcessHost::GetHandle() const {
168 // Return the current-process handle for the IPC::GetFileHandleForProcess
171 return *process_handle
;
172 return base::GetCurrentProcessHandle();
175 bool MockRenderProcessHost::Send(IPC::Message
* msg
) {
176 // Save the message in the sink.
177 sink_
.OnMessageReceived(*msg
);
182 int MockRenderProcessHost::GetID() const {
186 bool MockRenderProcessHost::HasConnection() const {
187 return has_connection_
;
190 void MockRenderProcessHost::SetIgnoreInputEvents(bool ignore_input_events
) {
193 bool MockRenderProcessHost::IgnoreInputEvents() const {
197 void MockRenderProcessHost::Cleanup() {
198 if (listeners_
.IsEmpty()) {
199 FOR_EACH_OBSERVER(RenderProcessHostObserver
,
201 RenderProcessHostDestroyed(this));
202 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, this);
203 RenderProcessHostImpl::UnregisterHost(GetID());
204 deletion_callback_called_
= true;
208 void MockRenderProcessHost::AddPendingView() {
211 void MockRenderProcessHost::RemovePendingView() {
214 void MockRenderProcessHost::SetSuddenTerminationAllowed(bool allowed
) {
217 bool MockRenderProcessHost::SuddenTerminationAllowed() const {
221 BrowserContext
* MockRenderProcessHost::GetBrowserContext() const {
222 return browser_context_
;
225 bool MockRenderProcessHost::InSameStoragePartition(
226 StoragePartition
* partition
) const {
227 // Mock RPHs only have one partition.
231 IPC::ChannelProxy
* MockRenderProcessHost::GetChannel() {
235 void MockRenderProcessHost::AddFilter(BrowserMessageFilter
* filter
) {
238 bool MockRenderProcessHost::FastShutdownForPageCount(size_t count
) {
239 if (GetActiveViewCount() == count
)
240 return FastShutdownIfPossible();
244 base::TimeDelta
MockRenderProcessHost::GetChildProcessIdleTime() const {
245 return base::TimeDelta::FromMilliseconds(0);
248 void MockRenderProcessHost::ResumeRequestsForView(int route_id
) {
251 void MockRenderProcessHost::NotifyTimezoneChange(const std::string
& zone_id
) {
254 ServiceRegistry
* MockRenderProcessHost::GetServiceRegistry() {
258 const base::TimeTicks
& MockRenderProcessHost::GetInitTimeForNavigationMetrics()
260 static base::TimeTicks dummy_time
= base::TimeTicks::Now();
264 bool MockRenderProcessHost::SubscribeUniformEnabled() const {
268 void MockRenderProcessHost::OnAddSubscription(unsigned int target
) {
271 void MockRenderProcessHost::OnRemoveSubscription(unsigned int target
) {
274 void MockRenderProcessHost::SendUpdateValueState(
275 unsigned int target
, const gpu::ValueState
& state
) {
278 #if defined(ENABLE_BROWSER_CDMS)
279 media::BrowserCdm
* MockRenderProcessHost::GetBrowserCdm(int render_frame_id
,
285 void MockRenderProcessHost::FilterURL(bool empty_allowed
, GURL
* url
) {
286 RenderProcessHostImpl::FilterURL(this, empty_allowed
, url
);
289 #if defined(ENABLE_WEBRTC)
290 void MockRenderProcessHost::EnableAudioDebugRecordings(
291 const base::FilePath
& file
) {
294 void MockRenderProcessHost::DisableAudioDebugRecordings() {
297 void MockRenderProcessHost::SetWebRtcLogMessageCallback(
298 base::Callback
<void(const std::string
&)> callback
) {
301 RenderProcessHost::WebRtcStopRtpDumpCallback
302 MockRenderProcessHost::StartRtpDump(
305 const WebRtcRtpPacketCallback
& packet_callback
) {
306 return WebRtcStopRtpDumpCallback();
310 void MockRenderProcessHost::ResumeDeferredNavigation(
311 const GlobalRequestID
& request_id
) {}
313 bool MockRenderProcessHost::OnMessageReceived(const IPC::Message
& msg
) {
314 IPC::Listener
* listener
= listeners_
.Lookup(msg
.routing_id());
316 return listener
->OnMessageReceived(msg
);
320 void MockRenderProcessHost::OnChannelConnected(int32 peer_pid
) {
323 MockRenderProcessHostFactory::MockRenderProcessHostFactory() {}
325 MockRenderProcessHostFactory::~MockRenderProcessHostFactory() {
326 // Detach this object from MockRenderProcesses to prevent STLDeleteElements()
327 // from calling MockRenderProcessHostFactory::Remove().
328 for (ScopedVector
<MockRenderProcessHost
>::iterator it
= processes_
.begin();
329 it
!= processes_
.end(); ++it
) {
330 (*it
)->SetFactory(NULL
);
334 RenderProcessHost
* MockRenderProcessHostFactory::CreateRenderProcessHost(
335 BrowserContext
* browser_context
,
336 SiteInstance
* site_instance
) const {
337 MockRenderProcessHost
* host
= new MockRenderProcessHost(browser_context
);
339 processes_
.push_back(host
);
340 host
->SetFactory(this);
345 void MockRenderProcessHostFactory::Remove(MockRenderProcessHost
* host
) const {
346 for (ScopedVector
<MockRenderProcessHost
>::iterator it
= processes_
.begin();
347 it
!= processes_
.end(); ++it
) {
349 processes_
.weak_erase(it
);
355 } // namespace content