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