| Index: content/browser/renderer_host/render_process_host_impl.cc
|
| diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
|
| index 231e10b44f1916751e021d182e16a07690a7a8c1..cf1e0068043ec0f4b66eaea59d07da30f7851874 100644
|
| --- a/content/browser/renderer_host/render_process_host_impl.cc
|
| +++ b/content/browser/renderer_host/render_process_host_impl.cc
|
| @@ -675,6 +675,9 @@ RenderProcessHostImpl::RenderProcessHostImpl(
|
| child_token_(mojo::edk::GenerateRandomToken()),
|
| service_worker_ref_count_(0),
|
| shared_worker_ref_count_(0),
|
| + route_provider_binding_(this),
|
| + associated_interface_provider_bindings_(
|
| + mojo::BindingSetDispatchMode::WITH_CONTEXT),
|
| visible_widgets_(0),
|
| is_process_backgrounded_(false),
|
| is_initialized_(false),
|
| @@ -841,10 +844,7 @@ RenderProcessHostImpl::~RenderProcessHostImpl() {
|
| #endif
|
| // We may have some unsent messages at this point, but that's OK.
|
| channel_.reset();
|
| - while (!queued_messages_.empty()) {
|
| - delete queued_messages_.front();
|
| - queued_messages_.pop();
|
| - }
|
| + queued_messages_ = MessageQueue{};
|
|
|
| UnregisterHost(GetID());
|
|
|
| @@ -967,10 +967,19 @@ bool RenderProcessHostImpl::Init() {
|
| base::Bind(&RenderProcessHostImpl::OnMojoError,
|
| weak_factory_.GetWeakPtr(),
|
| base::ThreadTaskRunnerHandle::Get())));
|
| + channel_->Pause();
|
|
|
| fast_shutdown_started_ = false;
|
| }
|
|
|
| + // Push any pending messages to the channel now. Note that if the child
|
| + // process is still launching, the channel will be paused and outgoing
|
| + // messages will be queued internally by the channel.
|
| + while (!queued_messages_.empty()) {
|
| + channel_->Send(queued_messages_.front().release());
|
| + queued_messages_.pop();
|
| + }
|
| +
|
| if (!gpu_observer_registered_) {
|
| gpu_observer_registered_ = true;
|
| ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
|
| @@ -993,24 +1002,23 @@ std::unique_ptr<IPC::ChannelProxy> RenderProcessHostImpl::CreateChannelProxy(
|
| IPC::ChannelMojo::CreateServerFactory(
|
| bootstrap.PassInterface().PassHandle(), runner);
|
|
|
| + std::unique_ptr<IPC::ChannelProxy> channel;
|
| // Do NOT expand ifdef or run time condition checks here! Synchronous
|
| // IPCs from browser process are banned. It is only narrowly allowed
|
| // for Android WebView to maintain backward compatibility.
|
| // See crbug.com/526842 for details.
|
| #if defined(OS_ANDROID)
|
| - if (GetContentClient()->UsingSynchronousCompositing()) {
|
| - return IPC::SyncChannel::Create(
|
| - std::move(channel_factory), this, runner.get(), true, &never_signaled_);
|
| - }
|
| + if (GetContentClient()->UsingSynchronousCompositing())
|
| + channel = IPC::SyncChannel::Create(this, runner.get(), &never_signaled_);
|
| #endif // OS_ANDROID
|
| -
|
| - std::unique_ptr<IPC::ChannelProxy> channel(
|
| - new IPC::ChannelProxy(this, runner.get()));
|
| + if (!channel)
|
| + channel.reset(new IPC::ChannelProxy(this, runner.get()));
|
| #if USE_ATTACHMENT_BROKER
|
| IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel(
|
| channel.get(), runner);
|
| #endif
|
| - channel->Init(std::move(channel_factory), true);
|
| + channel->Init(std::move(channel_factory), true /* create_pipe_now */);
|
| +
|
| return channel;
|
| }
|
|
|
| @@ -1212,6 +1220,10 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
|
| interface_registry_android_.get());
|
| #endif
|
|
|
| + channel_->AddAssociatedInterface(
|
| + base::Bind(&RenderProcessHostImpl::OnRouteProviderRequest,
|
| + base::Unretained(this)));
|
| +
|
| #if !defined(OS_ANDROID)
|
| AddUIThreadInterface(
|
| registry.get(), base::Bind(&device::BatteryMonitorImpl::Create));
|
| @@ -1287,6 +1299,25 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
|
| mojo_shell_connection->AddConnectionFilter(std::move(connection_filter));
|
| }
|
|
|
| +void RenderProcessHostImpl::GetRoute(
|
| + int32_t routing_id,
|
| + mojom::AssociatedInterfaceProviderAssociatedRequest request) {
|
| + DCHECK(request.is_pending());
|
| + associated_interface_provider_bindings_.AddBinding(
|
| + this, std::move(request),
|
| + reinterpret_cast<void*>(static_cast<uintptr_t>(routing_id)));
|
| +}
|
| +
|
| +void RenderProcessHostImpl::GetAssociatedInterface(
|
| + const std::string& name,
|
| + mojom::AssociatedInterfaceAssociatedRequest request) {
|
| + int32_t routing_id = static_cast<int32_t>(reinterpret_cast<uintptr_t>(
|
| + associated_interface_provider_bindings_.dispatch_context()));
|
| + IPC::Listener* listener = listeners_.Lookup(routing_id);
|
| + if (listener)
|
| + listener->OnAssociatedInterfaceRequest(name, request.PassHandle());
|
| +}
|
| +
|
| void RenderProcessHostImpl::CreateStoragePartitionService(
|
| mojo::InterfaceRequest<mojom::StoragePartitionService> request) {
|
| // DO NOT REMOVE THIS COMMAND LINE CHECK WITHOUT SECURITY REVIEW!
|
| @@ -1373,6 +1404,14 @@ void RenderProcessHostImpl::PurgeAndSuspend() {
|
| Send(new ChildProcessMsg_PurgeAndSuspend());
|
| }
|
|
|
| +mojom::RouteProvider* RenderProcessHostImpl::GetRemoteRouteProvider() {
|
| + if (!remote_route_provider_) {
|
| + DCHECK(channel_);
|
| + channel_->GetRemoteAssociatedInterface(&remote_route_provider_);
|
| + }
|
| + return remote_route_provider_.get();
|
| +}
|
| +
|
| void RenderProcessHostImpl::AddRoute(int32_t routing_id,
|
| IPC::Listener* listener) {
|
| CHECK(!listeners_.Lookup(routing_id)) << "Found Routing ID Conflict: "
|
| @@ -1381,7 +1420,7 @@ void RenderProcessHostImpl::AddRoute(int32_t routing_id,
|
| }
|
|
|
| void RenderProcessHostImpl::RemoveRoute(int32_t routing_id) {
|
| - DCHECK(listeners_.Lookup(routing_id) != NULL);
|
| + DCHECK(listeners_.Lookup(routing_id) != nullptr);
|
| listeners_.Remove(routing_id);
|
| Cleanup();
|
| }
|
| @@ -1886,38 +1925,33 @@ bool RenderProcessHostImpl::FastShutdownIfPossible() {
|
|
|
| bool RenderProcessHostImpl::Send(IPC::Message* msg) {
|
| TRACE_EVENT0("renderer_host", "RenderProcessHostImpl::Send");
|
| +
|
| + std::unique_ptr<IPC::Message> message(msg);
|
| +
|
| #if !defined(OS_ANDROID)
|
| - DCHECK(!msg->is_sync());
|
| + DCHECK(!message->is_sync());
|
| #endif
|
|
|
| if (!channel_) {
|
| #if defined(OS_ANDROID)
|
| - if (msg->is_sync()) {
|
| - delete msg;
|
| + if (message->is_sync())
|
| return false;
|
| - }
|
| #endif
|
| if (!is_initialized_) {
|
| - queued_messages_.push(msg);
|
| + queued_messages_.emplace(std::move(message));
|
| return true;
|
| - } else {
|
| - delete msg;
|
| - return false;
|
| }
|
| + return false;
|
| }
|
|
|
| - if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) {
|
| #if defined(OS_ANDROID)
|
| - if (msg->is_sync()) {
|
| - delete msg;
|
| - return false;
|
| - }
|
| -#endif
|
| - queued_messages_.push(msg);
|
| - return true;
|
| + if (child_process_launcher_.get() && child_process_launcher_->IsStarting() &&
|
| + message->is_sync()) {
|
| + return false;
|
| }
|
| +#endif
|
|
|
| - return channel_->Send(msg);
|
| + return channel_->Send(message.release());
|
| }
|
|
|
| bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
|
| @@ -2573,6 +2607,13 @@ void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() {
|
| shm_handle, metrics_allocator_->shared_memory()->mapped_size()));
|
| }
|
|
|
| +void RenderProcessHostImpl::OnRouteProviderRequest(
|
| + mojom::RouteProviderAssociatedRequest request) {
|
| + if (route_provider_binding_.is_bound())
|
| + return;
|
| + route_provider_binding_.Bind(std::move(request));
|
| +}
|
| +
|
| void RenderProcessHostImpl::ProcessDied(bool already_dead,
|
| RendererClosedDetails* known_details) {
|
| // Our child process has died. If we didn't expect it, it's a crash.
|
| @@ -2617,10 +2658,8 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead,
|
| channel_.get());
|
| #endif
|
| channel_.reset();
|
| - while (!queued_messages_.empty()) {
|
| - delete queued_messages_.front();
|
| - queued_messages_.pop();
|
| - }
|
| + queued_messages_ = MessageQueue{};
|
| +
|
| UpdateProcessPriority();
|
| DCHECK(!is_process_backgrounded_);
|
|
|
| @@ -2771,6 +2810,12 @@ void RenderProcessHostImpl::OnProcessLaunched() {
|
| DCHECK(child_process_launcher_->GetProcess().IsValid());
|
| DCHECK(!is_process_backgrounded_);
|
|
|
| + // Unpause the channel now that the process is launched. We don't flush it
|
| + // yet to ensure that any initialization messages sent here (e.g., things
|
| + // done in response to NOTIFICATION_RENDER_PROCESS_CREATED; see below)
|
| + // preempt already queued messages.
|
| + channel_->Unpause(false /* flush */);
|
| +
|
| if (mojo_child_connection_) {
|
| mojo_child_connection_->SetProcessHandle(
|
| child_process_launcher_->GetProcess().Handle());
|
| @@ -2795,7 +2840,7 @@ void RenderProcessHostImpl::OnProcessLaunched() {
|
| CreateSharedRendererHistogramAllocator();
|
| }
|
|
|
| - // NOTE: This needs to be before sending queued messages because
|
| + // NOTE: This needs to be before flushing queued messages, because
|
| // ExtensionService uses this notification to initialize the renderer process
|
| // with state that must be there before any JavaScript executes.
|
| //
|
| @@ -2806,10 +2851,8 @@ void RenderProcessHostImpl::OnProcessLaunched() {
|
| Source<RenderProcessHost>(this),
|
| NotificationService::NoDetails());
|
|
|
| - while (!queued_messages_.empty()) {
|
| - Send(queued_messages_.front());
|
| - queued_messages_.pop();
|
| - }
|
| + if (child_process_launcher_)
|
| + channel_->Flush();
|
|
|
| if (IsReady()) {
|
| DCHECK(!sent_render_process_ready_);
|
|
|