| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/test/mock_render_process_host.h" |
| |
| #include "base/lazy_instance.h" |
| #include "base/message_loop.h" |
| #include "base/time.h" |
| #include "content/browser/child_process_security_policy_impl.h" |
| #include "content/browser/renderer_host/render_process_host_impl.h" |
| #include "content/common/child_process_host_impl.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_types.h" |
| |
| namespace content { |
| |
| MockRenderProcessHost::MockRenderProcessHost( |
| BrowserContext* browser_context) |
| : transport_dib_(NULL), |
| bad_msg_count_(0), |
| factory_(NULL), |
| id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), |
| browser_context_(browser_context), |
| fast_shutdown_started_(false) { |
| // Child process security operations can't be unit tested unless we add |
| // ourselves as an existing child process. |
| ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID()); |
| |
| RenderProcessHostImpl::RegisterHost(GetID(), this); |
| } |
| |
| MockRenderProcessHost::~MockRenderProcessHost() { |
| ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID()); |
| delete transport_dib_; |
| if (factory_) |
| factory_->Remove(this); |
| // In unit tests, Release() might not have been called. |
| RenderProcessHostImpl::UnregisterHost(GetID()); |
| } |
| |
| void MockRenderProcessHost::EnableSendQueue() { |
| } |
| |
| bool MockRenderProcessHost::Init() { |
| return true; |
| } |
| |
| int MockRenderProcessHost::GetNextRoutingID() { |
| static int prev_routing_id = 0; |
| return ++prev_routing_id; |
| } |
| |
| void MockRenderProcessHost::CancelResourceRequests(int render_widget_id) { |
| } |
| |
| void MockRenderProcessHost::SimulateSwapOutACK( |
| const ViewMsg_SwapOut_Params& params) { |
| } |
| |
| bool MockRenderProcessHost::WaitForUpdateMsg(int render_widget_id, |
| const base::TimeDelta& max_delay, |
| IPC::Message* msg) { |
| return false; |
| } |
| |
| void MockRenderProcessHost::ReceivedBadMessage() { |
| ++bad_msg_count_; |
| } |
| |
| void MockRenderProcessHost::WidgetRestored() { |
| } |
| |
| void MockRenderProcessHost::WidgetHidden() { |
| } |
| |
| int MockRenderProcessHost::VisibleWidgetCount() const { |
| return 1; |
| } |
| |
| void MockRenderProcessHost::AddWord(const string16& word) { |
| } |
| |
| bool MockRenderProcessHost::FastShutdownIfPossible() { |
| // We aren't actually going to do anything, but set |fast_shutdown_started_| |
| // to true so that tests know we've been called. |
| fast_shutdown_started_ = true; |
| return true; |
| } |
| |
| bool MockRenderProcessHost::FastShutdownStarted() const { |
| return fast_shutdown_started_; |
| } |
| |
| void MockRenderProcessHost::DumpHandles() { |
| } |
| |
| base::ProcessHandle MockRenderProcessHost::GetHandle() { |
| return base::kNullProcessHandle; |
| } |
| |
| bool MockRenderProcessHost::Send(IPC::Message* msg) { |
| // Save the message in the sink. |
| sink_.OnMessageReceived(*msg); |
| delete msg; |
| return true; |
| } |
| |
| TransportDIB* MockRenderProcessHost::GetTransportDIB(TransportDIB::Id dib_id) { |
| if (transport_dib_) |
| return transport_dib_; |
| #if defined(OS_WIN) |
| HANDLE duped; |
| DuplicateHandle(GetCurrentProcess(), dib_id.handle, GetCurrentProcess(), |
| &duped, 0, TRUE, DUPLICATE_SAME_ACCESS); |
| transport_dib_ = TransportDIB::Map(duped); |
| #elif defined(OS_MACOSX) |
| // On Mac, TransportDIBs are always created in the browser, so we cannot map |
| // one from a dib_id. |
| transport_dib_ = TransportDIB::Create(100 * 100 * 4, 0); |
| #elif defined(OS_ANDROID) |
| // On Android, Handles and Ids are the same underlying type. |
| transport_dib_ = TransportDIB::Map(dib_id); |
| #elif defined(OS_POSIX) |
| transport_dib_ = TransportDIB::Map(dib_id.shmkey); |
| #endif |
| |
| return transport_dib_; |
| } |
| |
| int MockRenderProcessHost::GetID() const { |
| return id_; |
| } |
| |
| bool MockRenderProcessHost::HasConnection() const { |
| return true; |
| } |
| |
| void MockRenderProcessHost::SetIgnoreInputEvents(bool ignore_input_events) { |
| } |
| |
| bool MockRenderProcessHost::IgnoreInputEvents() const { |
| return false; |
| } |
| |
| void MockRenderProcessHost::Attach(RenderWidgetHost* host, |
| int routing_id) { |
| render_widget_hosts_.AddWithID(host, routing_id); |
| } |
| |
| void MockRenderProcessHost::Release(int routing_id) { |
| render_widget_hosts_.Remove(routing_id); |
| Cleanup(); |
| } |
| |
| void MockRenderProcessHost::Cleanup() { |
| if (render_widget_hosts_.IsEmpty()) { |
| NotificationService::current()->Notify( |
| NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| Source<RenderProcessHost>(this), |
| NotificationService::NoDetails()); |
| MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| RenderProcessHostImpl::UnregisterHost(GetID()); |
| } |
| } |
| |
| void MockRenderProcessHost::AddPendingView() { |
| } |
| |
| void MockRenderProcessHost::RemovePendingView() { |
| } |
| |
| void MockRenderProcessHost::SetSuddenTerminationAllowed(bool allowed) { |
| } |
| |
| bool MockRenderProcessHost::SuddenTerminationAllowed() const { |
| return true; |
| } |
| |
| content::RenderWidgetHost* MockRenderProcessHost::GetRenderWidgetHostByID( |
| int routing_id) { |
| return render_widget_hosts_.Lookup(routing_id); |
| } |
| |
| BrowserContext* MockRenderProcessHost::GetBrowserContext() const { |
| return browser_context_; |
| } |
| |
| IPC::ChannelProxy* MockRenderProcessHost::GetChannel() { |
| return NULL; |
| } |
| |
| bool MockRenderProcessHost::FastShutdownForPageCount(size_t count) { |
| if (render_widget_hosts_.size() == count) |
| return FastShutdownIfPossible(); |
| return false; |
| } |
| |
| base::TimeDelta MockRenderProcessHost::GetChildProcessIdleTime() const { |
| return base::TimeDelta::FromMilliseconds(0); |
| } |
| |
| void MockRenderProcessHost::SurfaceUpdated(int32 surface_id) { |
| } |
| |
| RenderProcessHost::RenderWidgetHostsIterator |
| MockRenderProcessHost::GetRenderWidgetHostsIterator() { |
| return RenderWidgetHostsIterator(&render_widget_hosts_); |
| } |
| |
| bool MockRenderProcessHost::OnMessageReceived(const IPC::Message& msg) { |
| return false; |
| } |
| |
| void MockRenderProcessHost::OnChannelConnected(int32 peer_pid) { |
| } |
| |
| MockRenderProcessHostFactory::MockRenderProcessHostFactory() {} |
| |
| MockRenderProcessHostFactory::~MockRenderProcessHostFactory() { |
| // Detach this object from MockRenderProcesses to prevent STLDeleteElements() |
| // from calling MockRenderProcessHostFactory::Remove(). |
| for (ScopedVector<MockRenderProcessHost>::iterator it = processes_.begin(); |
| it != processes_.end(); ++it) { |
| (*it)->SetFactory(NULL); |
| } |
| } |
| |
| RenderProcessHost* MockRenderProcessHostFactory::CreateRenderProcessHost( |
| BrowserContext* browser_context) const { |
| MockRenderProcessHost* host = new MockRenderProcessHost(browser_context); |
| if (host) { |
| processes_.push_back(host); |
| host->SetFactory(this); |
| } |
| return host; |
| } |
| |
| void MockRenderProcessHostFactory::Remove(MockRenderProcessHost* host) const { |
| for (ScopedVector<MockRenderProcessHost>::iterator it = processes_.begin(); |
| it != processes_.end(); ++it) { |
| if (*it == host) { |
| processes_.weak_erase(it); |
| break; |
| } |
| } |
| } |
| |
| } // content |