// 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/public/test/mock_render_process_host.h"

#include <algorithm>
#include <utility>
#include <vector>

#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/process/process_handle.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/token.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/frame_messages.h"
#include "content/common/input_messages.h"
#include "content/common/renderer.mojom.h"
#include "content/public/browser/android/child_process_importance.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
#include "content/test/not_implemented_network_url_loader_factory.h"
#include "media/media_buildflags.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"

namespace content {

MockRenderProcessHost::MockRenderProcessHost(BrowserContext* browser_context)
    : bad_msg_count_(0),
      factory_(nullptr),
      id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
      has_connection_(false),
      browser_context_(browser_context),
      prev_routing_id_(0),
      fast_shutdown_started_(false),
      deletion_callback_called_(false),
      is_for_guests_only_(false),
      is_never_suitable_for_reuse_(false),
      is_process_backgrounded_(false),
      is_unused_(true),
      keep_alive_ref_count_(0),
      child_identity_(
          mojom::kRendererServiceName,
          BrowserContext::GetServiceInstanceGroupFor(browser_context),
          base::Token::CreateRandom(),
          base::Token::CreateRandom()),
      url_loader_factory_(nullptr),
      weak_ptr_factory_(this) {
  // 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());
  if (factory_)
    factory_->Remove(this);

  // In unit tests, Cleanup() might not have been called.
  if (!deletion_callback_called_) {
    for (auto& observer : observers_)
      observer.RenderProcessHostDestroyed(this);
    RenderProcessHostImpl::UnregisterHost(GetID());
  }
}

void MockRenderProcessHost::SimulateCrash() {
  SimulateRenderProcessExit(base::TERMINATION_STATUS_PROCESS_CRASHED, 0);
}

void MockRenderProcessHost::SimulateRenderProcessExit(
    base::TerminationStatus status,
    int exit_code) {
  has_connection_ = false;
  ChildProcessTerminationInfo termination_info{status, exit_code};
  NotificationService::current()->Notify(
      NOTIFICATION_RENDERER_PROCESS_CLOSED, Source<RenderProcessHost>(this),
      Details<ChildProcessTerminationInfo>(&termination_info));

  for (auto& observer : observers_)
    observer.RenderProcessExited(this, termination_info);

  // Send every routing ID a FrameHostMsg_RenderProcessGone message. To ensure a
  // predictable order for unittests which may assert against the order, we sort
  // the listeners by descending routing ID, instead of using the arbitrary
  // hash-map order like RenderProcessHostImpl.
  std::vector<std::pair<int32_t, IPC::Listener*>> sorted_listeners_;
  base::IDMap<IPC::Listener*>::iterator iter(&listeners_);
  while (!iter.IsAtEnd()) {
    sorted_listeners_.push_back(
        std::make_pair(iter.GetCurrentKey(), iter.GetCurrentValue()));
    iter.Advance();
  }
  std::sort(sorted_listeners_.rbegin(), sorted_listeners_.rend());

  for (auto& entry_pair : sorted_listeners_) {
    entry_pair.second->OnMessageReceived(FrameHostMsg_RenderProcessGone(
        entry_pair.first, static_cast<int>(termination_info.status),
        termination_info.exit_code));
  }
}

bool MockRenderProcessHost::Init() {
  has_connection_ = true;
  return true;
}

void MockRenderProcessHost::EnableSendQueue() {}

int MockRenderProcessHost::GetNextRoutingID() {
  return ++prev_routing_id_;
}

void MockRenderProcessHost::AddRoute(int32_t routing_id,
                                     IPC::Listener* listener) {
  listeners_.AddWithID(listener, routing_id);
}

void MockRenderProcessHost::RemoveRoute(int32_t routing_id) {
  DCHECK(listeners_.Lookup(routing_id) != nullptr);
  listeners_.Remove(routing_id);
  Cleanup();
}

void MockRenderProcessHost::AddObserver(RenderProcessHostObserver* observer) {
  observers_.AddObserver(observer);
}

void MockRenderProcessHost::RemoveObserver(
    RenderProcessHostObserver* observer) {
  observers_.RemoveObserver(observer);
}

void MockRenderProcessHost::ShutdownForBadMessage(
    CrashReportMode crash_report_mode) {
  ++bad_msg_count_;
}

void MockRenderProcessHost::UpdateClientPriority(PriorityClient* client) {}

int MockRenderProcessHost::VisibleClientCount() {
  int count = 0;
  for (auto* client : priority_clients_) {
    const Priority priority = client->GetPriority();
    if (!priority.is_hidden) {
      count++;
    }
  }
  return count;
}

unsigned int MockRenderProcessHost::GetFrameDepth() {
  NOTIMPLEMENTED();
  return 0u;
}

bool MockRenderProcessHost::GetIntersectsViewport() {
  NOTIMPLEMENTED();
  return true;
}

bool MockRenderProcessHost::IsForGuestsOnly() {
  return is_for_guests_only_;
}

RendererAudioOutputStreamFactoryContext*
MockRenderProcessHost::GetRendererAudioOutputStreamFactoryContext() {
  return nullptr;
}

void MockRenderProcessHost::OnMediaStreamAdded() {}

void MockRenderProcessHost::OnMediaStreamRemoved() {}

StoragePartition* MockRenderProcessHost::GetStoragePartition() {
  return BrowserContext::GetDefaultStoragePartition(browser_context_);
}

void MockRenderProcessHost::AddWord(const base::string16& word) {
}

bool MockRenderProcessHost::Shutdown(int exit_code) {
  return true;
}

bool MockRenderProcessHost::FastShutdownIfPossible(size_t page_count,
                                                   bool skip_unload_handlers) {
  if (GetActiveViewCount() != page_count)
    return false;
  // 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() {
  return fast_shutdown_started_;
}

const base::Process& MockRenderProcessHost::GetProcess() {
  // Return the current-process handle for the IPC::GetPlatformFileForTransit
  // function.
  if (process.IsValid())
    return process;

  static const base::Process current_process(base::Process::Current());
  return current_process;
}

bool MockRenderProcessHost::IsReady() {
  return false;
}

bool MockRenderProcessHost::Send(IPC::Message* msg) {
  // Save the message in the sink.
  sink_.OnMessageReceived(*msg);
  delete msg;
  return true;
}

int MockRenderProcessHost::GetID() {
  return id_;
}

bool MockRenderProcessHost::IsInitializedAndNotDead() {
  return has_connection_;
}

void MockRenderProcessHost::SetBlocked(bool blocked) {}

bool MockRenderProcessHost::IsBlocked() {
  return false;
}

std::unique_ptr<base::CallbackList<void(bool)>::Subscription>
MockRenderProcessHost::RegisterBlockStateChangedCallback(
    const base::RepeatingCallback<void(bool)>& cb) {
  return nullptr;
}

static void DeleteIt(base::WeakPtr<MockRenderProcessHost> h) {
  if (h)
    delete h.get();
}

void MockRenderProcessHost::Cleanup() {
  if (listeners_.IsEmpty()) {
    for (auto& observer : observers_)
      observer.RenderProcessHostDestroyed(this);
    // Post the delete of |this| as a WeakPtr so that if |this| is deleted by a
    // test directly, we don't double free.
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(&DeleteIt, weak_ptr_factory_.GetWeakPtr()));
    RenderProcessHostImpl::UnregisterHost(GetID());
    deletion_callback_called_ = true;
  }
}

void MockRenderProcessHost::AddPendingView() {
}

void MockRenderProcessHost::RemovePendingView() {
}

void MockRenderProcessHost::AddPriorityClient(PriorityClient* priority_client) {
  priority_clients_.insert(priority_client);
}

void MockRenderProcessHost::RemovePriorityClient(
    PriorityClient* priority_client) {
  priority_clients_.erase(priority_client);
}

#if defined(OS_ANDROID)
ChildProcessImportance MockRenderProcessHost::GetEffectiveImportance() {
  NOTIMPLEMENTED();
  return ChildProcessImportance::NORMAL;
}
#endif

void MockRenderProcessHost::SetSuddenTerminationAllowed(bool allowed) {
}

bool MockRenderProcessHost::SuddenTerminationAllowed() {
  return true;
}

BrowserContext* MockRenderProcessHost::GetBrowserContext() {
  return browser_context_;
}

bool MockRenderProcessHost::InSameStoragePartition(
    StoragePartition* partition) {
  // Mock RPHs only have one partition.
  return true;
}

IPC::ChannelProxy* MockRenderProcessHost::GetChannel() {
  return nullptr;
}

void MockRenderProcessHost::AddFilter(BrowserMessageFilter* filter) {
}

base::TimeDelta MockRenderProcessHost::GetChildProcessIdleTime() {
  return base::TimeDelta::FromMilliseconds(0);
}

void MockRenderProcessHost::BindInterface(
    const std::string& interface_name,
    mojo::ScopedMessagePipeHandle interface_pipe) {
  if (binder_overrides_.count(interface_name) > 0)
    binder_overrides_[interface_name].Run(std::move(interface_pipe));
}

const service_manager::Identity& MockRenderProcessHost::GetChildIdentity() {
  return child_identity_;
}

std::unique_ptr<base::SharedPersistentMemoryAllocator>
MockRenderProcessHost::TakeMetricsAllocator() {
  return nullptr;
}

const base::TimeTicks&
MockRenderProcessHost::GetInitTimeForNavigationMetrics() {
  static base::TimeTicks dummy_time = base::TimeTicks::Now();
  return dummy_time;
}

bool MockRenderProcessHost::IsProcessBackgrounded() {
  return is_process_backgrounded_;
}

size_t MockRenderProcessHost::GetKeepAliveRefCount() const {
  return keep_alive_ref_count_;
}

void MockRenderProcessHost::IncrementKeepAliveRefCount(
    KeepAliveClientType client) {
  ++keep_alive_ref_count_;
}

void MockRenderProcessHost::DecrementKeepAliveRefCount(
    KeepAliveClientType client) {
  --keep_alive_ref_count_;
}

void MockRenderProcessHost::DisableKeepAliveRefCount() {
  keep_alive_ref_count_ = 0;

  // RenderProcessHost::DisableKeepAliveRefCount() virtual method gets called as
  // part of BrowserContext::NotifyWillBeDestroyed(...).  Normally
  // MockRenderProcessHost::DisableKeepAliveRefCount doesn't call Cleanup,
  // because the MockRenderProcessHost might be owned by a test.  However, when
  // the MockRenderProcessHost is the spare RenderProcessHost, we know that it
  // is owned by the SpareRenderProcessHostManager and we need to delete the
  // spare to avoid reports/DCHECKs about memory leaks.
  if (this == RenderProcessHostImpl::GetSpareRenderProcessHostForTesting())
    Cleanup();
}

bool MockRenderProcessHost::IsKeepAliveRefCountDisabled() {
  return false;
}

void MockRenderProcessHost::PurgeAndSuspend() {}

void MockRenderProcessHost::Resume() {}

mojom::Renderer* MockRenderProcessHost::GetRendererInterface() {
  if (!renderer_interface_) {
    renderer_interface_.reset(new mojom::RendererAssociatedPtr);
    mojo::MakeRequestAssociatedWithDedicatedPipe(renderer_interface_.get());
  }
  return renderer_interface_->get();
}

resource_coordinator::ProcessResourceCoordinator*
MockRenderProcessHost::GetProcessResourceCoordinator() {
  if (!process_resource_coordinator_) {
    content::ServiceManagerConnection* connection =
        content::ServiceManagerConnection::GetForProcess();
    // Tests may not set up a connection.
    service_manager::Connector* connector =
        connection ? connection->GetConnector() : nullptr;
    process_resource_coordinator_ =
        std::make_unique<resource_coordinator::ProcessResourceCoordinator>(
            connector);
  }
  return process_resource_coordinator_.get();
}

void MockRenderProcessHost::CreateURLLoaderFactory(
    const base::Optional<url::Origin>& origin,
    network::mojom::TrustedURLLoaderHeaderClientPtrInfo header_client,
    network::mojom::URLLoaderFactoryRequest request) {
  url_loader_factory_->Clone(std::move(request));
}

void MockRenderProcessHost::SetIsNeverSuitableForReuse() {
  is_never_suitable_for_reuse_ = true;
}

bool MockRenderProcessHost::MayReuseHost() {
  return !is_never_suitable_for_reuse_;
}

bool MockRenderProcessHost::IsUnused() {
  return is_unused_;
}

void MockRenderProcessHost::SetIsUsed() {
  is_unused_ = false;
}

bool MockRenderProcessHost::HostHasNotBeenUsed() {
  return IsUnused() && listeners_.IsEmpty() && GetKeepAliveRefCount() == 0;
}

void MockRenderProcessHost::LockToOrigin(const GURL& lock_url) {
  ChildProcessSecurityPolicyImpl::GetInstance()->LockToOrigin(GetID(),
                                                              lock_url);
  if (SiteInstanceImpl::IsOriginLockASite(lock_url))
    is_renderer_locked_to_site_ = true;
}

void MockRenderProcessHost::BindCacheStorage(
    blink::mojom::CacheStorageRequest request,
    const url::Origin& origin) {
  cache_storage_request_ = std::move(request);
}

void MockRenderProcessHost::BindIndexedDB(
    blink::mojom::IDBFactoryRequest request,
    const url::Origin& origin) {
  idb_factory_request_ = std::move(request);
}

void MockRenderProcessHost::CleanupCorbExceptionForPluginUponDestruction() {}

void MockRenderProcessHost::FilterURL(bool empty_allowed, GURL* url) {
  RenderProcessHostImpl::FilterURL(this, empty_allowed, url);
}

void MockRenderProcessHost::EnableAudioDebugRecordings(
    const base::FilePath& file) {
}

void MockRenderProcessHost::DisableAudioDebugRecordings() {}

void MockRenderProcessHost::SetEchoCanceller3(
    bool enable,
    base::OnceCallback<void(bool, const std::string&)> callback) {}

RenderProcessHost::WebRtcStopRtpDumpCallback
MockRenderProcessHost::StartRtpDump(
    bool incoming,
    bool outgoing,
    const WebRtcRtpPacketCallback& packet_callback) {
  return WebRtcStopRtpDumpCallback();
}

void MockRenderProcessHost::EnableWebRtcEventLogOutput(int lid,
                                                       int output_period_ms) {}
void MockRenderProcessHost::DisableWebRtcEventLogOutput(int lid) {}

bool MockRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
  IPC::Listener* listener = listeners_.Lookup(msg.routing_id());
  if (listener)
    return listener->OnMessageReceived(msg);
  return false;
}

void MockRenderProcessHost::OnChannelConnected(int32_t peer_pid) {}

void MockRenderProcessHost::OverrideBinderForTesting(
    const std::string& interface_name,
    const InterfaceBinder& binder) {
  binder_overrides_[interface_name] = binder;
}

void MockRenderProcessHost::OverrideRendererInterfaceForTesting(
    std::unique_ptr<mojo::AssociatedInterfacePtr<mojom::Renderer>>
        renderer_interface) {
  renderer_interface_ = std::move(renderer_interface);
}

void MockRenderProcessHost::OverrideURLLoaderFactory(
    network::mojom::URLLoaderFactory* factory) {
  url_loader_factory_ = factory;
}

MockRenderProcessHostFactory::MockRenderProcessHostFactory()
    : default_mock_url_loader_factory_(
          std::make_unique<NotImplementedNetworkURLLoaderFactory>()) {}

MockRenderProcessHostFactory::~MockRenderProcessHostFactory() {
  // Detach this object from MockRenderProcesses to prevent them from calling
  // MockRenderProcessHostFactory::Remove() when destroyed.
  for (const auto& process : processes_)
    process->SetFactory(nullptr);
}

RenderProcessHost* MockRenderProcessHostFactory::CreateRenderProcessHost(
    BrowserContext* browser_context,
    SiteInstance* site_instance) const {
  std::unique_ptr<MockRenderProcessHost> host =
      std::make_unique<MockRenderProcessHost>(browser_context);
  host->OverrideURLLoaderFactory(default_mock_url_loader_factory_.get());
  processes_.push_back(std::move(host));
  processes_.back()->SetFactory(this);
  return processes_.back().get();
}

void MockRenderProcessHostFactory::Remove(MockRenderProcessHost* host) const {
  for (auto it = processes_.begin(); it != processes_.end(); ++it) {
    if (it->get() == host) {
      it->release();
      processes_.erase(it);
      break;
    }
  }
}

}  // namespace content
