diff --git a/content/browser/renderer_host/agent_scheduling_group_host.cc b/content/browser/renderer_host/agent_scheduling_group_host.cc index 337b39f0c4d2f0..c12ef12de61ad0 100644 --- a/content/browser/renderer_host/agent_scheduling_group_host.cc +++ b/content/browser/renderer_host/agent_scheduling_group_host.cc @@ -199,10 +199,6 @@ bool AgentSchedulingGroupHost::InitProcessAndMojos() { } ChannelProxy* AgentSchedulingGroupHost::GetChannel() { - // TODO(crbug.com/1111231): If the process is not initialized, it also implies - // that it is not Ready, meaning the channel we return here will not be valid. - // In that case we should return |nullptr|, but that causes certain tests to - // fail. This should be changed once those tests are fixed. if (process_.IsInitializedAndNotDead()) SetUpMojoIfNeeded(); @@ -232,11 +228,8 @@ void AgentSchedulingGroupHost::RemoveRoute(int32_t routing_id) { } mojom::RouteProvider* AgentSchedulingGroupHost::GetRemoteRouteProvider() { - // TODO(domfarolino): Remove `GetRemoteRouteProvider` from `RenderProcessHost` - // and make `AgentSchedulingGroupHost` a fully-fledged RouteProvider. - RenderProcessHostImpl& process = - static_cast(process_); - return process.GetRemoteRouteProvider(PassKey()); + SetUpMojoIfNeeded(); + return remote_route_provider_.get(); } void AgentSchedulingGroupHost::CreateFrame(mojom::CreateFrameParamsPtr params) { @@ -277,34 +270,52 @@ void AgentSchedulingGroupHost::GetRoute( int32_t routing_id, mojo::PendingAssociatedReceiver receiver) { - // TODO(crbug.com/1111231): Make AgentSchedulingGroupHost a fully-fledged - // RouteProvider, so we can register routes directly with an - // AgentSchedulingGroupHost rather than RenderProcessHostImpl. - static_cast(process_).GetRoute(routing_id, - std::move(receiver)); + DCHECK(receiver.is_valid()); + associated_interface_provider_receivers_.Add(this, std::move(receiver), + routing_id); } void AgentSchedulingGroupHost::GetAssociatedInterface( const std::string& name, mojo::PendingAssociatedReceiver receiver) { - // TODO(crbug.com/1111231): Make AgentSchedulingGroupHost a fully-fledged - // AssociatedInterfaceProvider, so we can start associating interfaces - // directly with the AgentSchedulingGroupHost interface. - static_cast(process_).GetAssociatedInterface( - name, std::move(receiver)); + int32_t routing_id = + associated_interface_provider_receivers_.current_context(); + IPC::Listener* listener = + static_cast(process_).GetListener(PassKey(), + routing_id); + if (listener) + listener->OnAssociatedInterfaceRequest(name, receiver.PassHandle()); } void AgentSchedulingGroupHost::ResetMojo() { receiver_.reset(); mojo_remote_.reset(); + remote_route_provider_.reset(); + route_provider_receiver_.reset(); + associated_interface_provider_receivers_.Clear(); + // TODO(domfarolino): Move the SetUpMojoIfNeeded() logic to this method, along + // with invoking RenderProcessHostImpl::EnableSendQueue(), so that upon + // renderer process crash, we immediately reset our mojos. } void AgentSchedulingGroupHost::SetUpMojoIfNeeded() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(process_.IsInitializedAndNotDead()); + // We don't DCHECK |process_.IsInitializedAndNotDead()| here because we may + // end up here after the render process has died but before the + // RenderProcessHostImpl is re-initialized (and thus not considered dead + // anymore). + + // The bind states of all of |AgentSchedulingGroupHost|'s remotes and + // receivers are expected to be equivalent. + DCHECK(process_.GetRendererInterface()); + + // Make sure that the bind state of all mojos are equivalent. + DCHECK_EQ(mojo_remote_.is_bound(), receiver_.is_bound()); + DCHECK_EQ(receiver_.is_bound(), remote_route_provider_.is_bound()); + DCHECK_EQ(remote_route_provider_.is_bound(), + route_provider_receiver_.is_bound()); - DCHECK_EQ(receiver_.is_bound(), mojo_remote_.is_bound()); if (receiver_.is_bound()) return; @@ -317,6 +328,10 @@ void AgentSchedulingGroupHost::SetUpMojoIfNeeded() { receiver_.BindNewPipeAndPassRemote(), mojo_remote_.BindNewPipeAndPassReceiver()); } + + mojo_remote_.get()->BindAssociatedRouteProvider( + route_provider_receiver_.BindNewEndpointAndPassRemote(), + remote_route_provider_.BindNewEndpointAndPassReceiver()); } } // namespace content diff --git a/content/browser/renderer_host/agent_scheduling_group_host.h b/content/browser/renderer_host/agent_scheduling_group_host.h index 3a3a2fd43fc3bb..ef475d956f2cae 100644 --- a/content/browser/renderer_host/agent_scheduling_group_host.h +++ b/content/browser/renderer_host/agent_scheduling_group_host.h @@ -13,6 +13,7 @@ #include "content/common/renderer.mojom-forward.h" #include "content/public/browser/render_process_host_observer.h" #include "mojo/public/cpp/bindings/associated_receiver.h" +#include "mojo/public/cpp/bindings/associated_receiver_set.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -188,6 +189,20 @@ class CONTENT_EXPORT AgentSchedulingGroupHost // Remote stub of `mojom::AgentSchedulingGroup`, used for sending calls to the // (renderer-side) `AgentSchedulingGroup`. MaybeAssociatedRemote mojo_remote_; + + // The `mojom::RouteProvider` mojo pair to setup + // `blink::AssociatedInterfaceProvider` routes between this and the + // renderer-side `AgentSchedulingGroup`. + mojo::AssociatedRemote remote_route_provider_; + mojo::AssociatedReceiver route_provider_receiver_{this}; + + // The `blink::mojom::AssociatedInterfaceProvider` receiver set that *all* + // renderer-side `blink::AssociatedInterfaceProvider` objects own a remote to. + // `AgentSchedulingGroupHost` will be responsible for routing each associated + // interface request to the appropriate renderer host object. + mojo::AssociatedReceiverSet + associated_interface_provider_receivers_; }; } // namespace content diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 6c1bfb9731ae1f..b596fff0c3679b 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -1947,8 +1947,6 @@ void RenderProcessHostImpl::InitializeChannelProxy() { // // See OnProcessLaunched() for some additional details of this somewhat // surprising behavior. - remote_route_provider_.reset(); - channel_->GetRemoteAssociatedInterface(&remote_route_provider_); renderer_interface_.reset(); channel_->GetRemoteAssociatedInterface(&renderer_interface_); @@ -2482,8 +2480,6 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() { // This base::Unretained() usage is safe since the associated_registry is // owned by this RPHI. - associated_registry->AddInterface(base::BindRepeating( - &RenderProcessHostImpl::BindRouteProvider, base::Unretained(this))); associated_registry->AddInterface(base::BindRepeating( &RenderProcessHostImpl::CreateRendererHost, base::Unretained(this))); @@ -2537,31 +2533,10 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() { std::move(registry), std::move(child_host_pending_receiver_)); } -void RenderProcessHostImpl::BindRouteProvider( - mojo::PendingAssociatedReceiver receiver) { - if (route_provider_receiver_.is_bound()) - return; - route_provider_receiver_.Bind(std::move(receiver)); -} - -void RenderProcessHostImpl::GetRoute( - int32_t routing_id, - mojo::PendingAssociatedReceiver - receiver) { - DCHECK(receiver.is_valid()); - associated_interface_provider_receivers_.Add(this, std::move(receiver), - routing_id); -} - -void RenderProcessHostImpl::GetAssociatedInterface( - const std::string& name, - mojo::PendingAssociatedReceiver - receiver) { - int32_t routing_id = - associated_interface_provider_receivers_.current_context(); - IPC::Listener* listener = listeners_.Lookup(routing_id); - if (listener) - listener->OnAssociatedInterfaceRequest(name, receiver.PassHandle()); +IPC::Listener* RenderProcessHostImpl::GetListener( + util::PassKey, + int32_t routing_id) { + return listeners_.Lookup(routing_id); } void RenderProcessHostImpl::CreateEmbeddedFrameSinkProvider( @@ -2856,11 +2831,6 @@ void RenderProcessHostImpl::SetIsUsed() { is_unused_ = false; } -mojom::RouteProvider* RenderProcessHostImpl::GetRemoteRouteProvider( - util::PassKey) { - return remote_route_provider_.get(); -} - void RenderProcessHostImpl::AddRoute(int32_t routing_id, IPC::Listener* listener) { TRACE_EVENT2("shutdown", "RenderProcessHostImpl::AddRoute", @@ -4634,8 +4604,6 @@ void RenderProcessHostImpl::ProcessDied( void RenderProcessHostImpl::ResetIPC() { renderer_host_receiver_.reset(); io_thread_host_impl_.reset(); - route_provider_receiver_.reset(); - associated_interface_provider_receivers_.Clear(); associated_interfaces_.reset(); coordinator_connector_receiver_.reset(); tracing_registration_.reset(); diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 52ac9a368d1c1f..8fa93de30c565a 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h @@ -29,6 +29,7 @@ #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/threading/sequence_bound.h" +#include "base/util/type_safety/pass_key.h" #include "build/build_config.h" #include "content/browser/child_process_launcher.h" #include "content/browser/dom_storage/session_storage_namespace_impl.h" @@ -159,8 +160,6 @@ typedef base::Thread* (*RendererMainThreadFactoryFunction)( class CONTENT_EXPORT RenderProcessHostImpl : public RenderProcessHost, public ChildProcessLauncher::Client, - public mojom::RouteProvider, - public blink::mojom::AssociatedInterfaceProvider, public mojom::RendererHost, public blink::mojom::DomStorageProvider, public memory_instrumentation::mojom::CoordinatorConnector { @@ -273,9 +272,6 @@ class CONTENT_EXPORT RenderProcessHostImpl void DumpProfilingData(base::OnceClosure callback) override; #endif - mojom::RouteProvider* GetRemoteRouteProvider( - util::PassKey); - // IPC::Sender via RenderProcessHost. bool Send(IPC::Message* msg) override; @@ -747,17 +743,11 @@ class CONTENT_EXPORT RenderProcessHostImpl // Registers Mojo interfaces to be exposed to the renderer. void RegisterMojoInterfaces(); - // mojom::RouteProvider: - void GetRoute( - int32_t routing_id, - mojo::PendingAssociatedReceiver - receiver) override; - - // blink::mojom::AssociatedInterfaceProvider: - void GetAssociatedInterface( - const std::string& name, - mojo::PendingAssociatedReceiver - receiver) override; + // TODO(crbug.com/1132901): We'll be able to remove this method once + // `AgentSchedulingGroupHost` maintains its own map of IPC::Listeners, but for + // now we'll let it delegate to this class. + IPC::Listener* GetListener(util::PassKey, + int32_t routing_id); // mojom::RendererHost using BrowserHistogramCallback = @@ -770,9 +760,6 @@ class CONTENT_EXPORT RenderProcessHostImpl const GURL& url, mojom::RendererHost::ResolveProxyCallback callback) override; - void BindRouteProvider( - mojo::PendingAssociatedReceiver receiver); - void CreateEmbeddedFrameSinkProvider( mojo::PendingReceiver receiver); void BindCompositingModeReporter( @@ -986,11 +973,6 @@ class CONTENT_EXPORT RenderProcessHostImpl // nature (e.g. metrics, memory usage). std::unique_ptr associated_interfaces_; - mojo::AssociatedReceiver route_provider_receiver_{this}; - mojo::AssociatedReceiverSet - associated_interface_provider_receivers_; - // These fields are cached values that are updated in // UpdateProcessPriorityInputs, and are used to compute priority sent to // ChildProcessLauncher. @@ -1169,7 +1151,6 @@ class CONTENT_EXPORT RenderProcessHostImpl mojo::Remote child_process_; // This will be bound to |io_thread_host_impl_|. mojo::PendingReceiver child_host_pending_receiver_; - mojo::AssociatedRemote remote_route_provider_; mojo::AssociatedRemote renderer_interface_; mojo::AssociatedReceiver renderer_host_receiver_{this}; mojo::Receiver diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index 2a5eaf61305c06..fac5956ca25d9f 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc @@ -843,14 +843,8 @@ bool ChildThreadImpl::IsInBrowserProcess() const { return static_cast(browser_process_io_runner_); } -void ChildThreadImpl::GetAssociatedInterface( - int32_t routing_id, - const std::string& name, - mojo::PendingAssociatedReceiver - receiver) { - Listener* route = router_.GetRoute(routing_id); - if (route) - route->OnAssociatedInterfaceRequest(name, receiver.PassHandle()); +IPC::Listener* ChildThreadImpl::GetListener(int32_t routing_id) { + return router_.GetRoute(routing_id); } } // namespace content diff --git a/content/child/child_thread_impl.h b/content/child/child_thread_impl.h index bd07f46554dc4f..664efd0fc43472 100644 --- a/content/child/child_thread_impl.h +++ b/content/child/child_thread_impl.h @@ -161,11 +161,10 @@ class CONTENT_EXPORT ChildThreadImpl : public IPC::Listener, bool IsInBrowserProcess() const; - void GetAssociatedInterface( - int32_t routing_id, - const std::string& name, - mojo::PendingAssociatedReceiver - receiver); + // TODO(1132901) We'll be able to move this method once |AgentSchedulingGroup| + // maintains its own map of IPC::Listeners, but for now we'll let it delegate + // to this class. + virtual IPC::Listener* GetListener(int32_t routing_id); private: // TODO(crbug.com/1111231): This class is a friend so that it can call our diff --git a/content/common/agent_scheduling_group.mojom b/content/common/agent_scheduling_group.mojom index 132ea76f6bd570..da2309b53257ba 100644 --- a/content/common/agent_scheduling_group.mojom +++ b/content/common/agent_scheduling_group.mojom @@ -4,6 +4,7 @@ module content.mojom; +import "content/common/associated_interfaces.mojom"; import "content/common/document_scoped_interface_bundle.mojom"; import "content/common/native_types.mojom"; import "ipc/constants.mojom"; @@ -206,6 +207,21 @@ interface AgentSchedulingGroupHost { // AgentSchedulingGroupHost and the renderer process's AgentSchedulingGroup. // Implemented by content::AgentSchedulingGroup (in the renderer process). interface AgentSchedulingGroup { + // Tells the renderer to bind the receiver to a backing RouteProvider + // implementation, which in practice is itself. Also passes a remote to the + // RouteProvider interface owned by AgentSchedulingGroupHost so that we + // immediately have bidirectional RouteProvider communication between + // AgentSchedulingGroup <=> AgentSchedulingGroupHost. We have this as a + // method on this interface, as opposed to passing this remote/receiver pair + // over the method that creates the remote AgentSchedulingGroup. This is + // because we need the RouteProvider remote/receiver pair to be associated + // with the message pipe that the AgentSchedulingGroup is associated with, + // which may be different than the message pipe that we create the + // AgentSchedulingGroup over. + BindAssociatedRouteProvider( + pending_associated_remote remote, + pending_associated_receiver receiver); + // Tells the renderer to create a new view. CreateView(CreateViewParams params); diff --git a/content/public/renderer/render_thread.h b/content/public/renderer/render_thread.h index 4f0fbe630acd54..78039470a475d3 100644 --- a/content/public/renderer/render_thread.h +++ b/content/public/renderer/render_thread.h @@ -12,7 +12,6 @@ #include "base/callback.h" #include "base/metrics/user_metrics_action.h" #include "base/single_thread_task_runner.h" -#include "base/util/type_safety/pass_key.h" #include "content/common/content_export.h" #include "content/public/child/child_thread.h" #include "ipc/ipc_channel_proxy.h" @@ -43,12 +42,6 @@ class Extension; } // namespace v8 namespace content { -class AgentSchedulingGroup; - -namespace mojom { -class RouteProvider; -} // namespace mojom - class RenderThreadObserver; class ResourceDispatcherDelegate; @@ -82,9 +75,6 @@ class CONTENT_EXPORT RenderThread : virtual public ChildThread { virtual void AddObserver(RenderThreadObserver* observer) = 0; virtual void RemoveObserver(RenderThreadObserver* observer) = 0; - virtual mojom::RouteProvider* GetRemoteRouteProvider( - util::PassKey) = 0; - // Set the ResourceDispatcher delegate object for this process. virtual void SetResourceDispatcherDelegate( ResourceDispatcherDelegate* delegate) = 0; diff --git a/content/public/test/mock_render_thread.cc b/content/public/test/mock_render_thread.cc index 6d3ebe88641f03..f4f66903c4a1f2 100644 --- a/content/public/test/mock_render_thread.cc +++ b/content/public/test/mock_render_thread.cc @@ -58,18 +58,6 @@ class MockRenderMessageFilterImpl : public mojom::RenderMessageFilter { #endif }; -// Some tests require that a valid mojo::RouteProvider* be accessed to send -// messages over. The RouteProvider does not need to be bound to any real -// implementation, so we simply bind it to a pipe that we'll forget about, as to -// drain all messages sent over the remote. -mojom::RouteProvider* GetStaticRemoteRouteProvider() { - static mojo::Remote remote; - if (!remote) { - ignore_result(remote.BindNewPipeAndPassReceiver()); - } - return remote.get(); -} - } // namespace MockRenderThread::MockRenderThread() @@ -171,11 +159,6 @@ void MockRenderThread::RemoveObserver(RenderThreadObserver* observer) { observers_.RemoveObserver(observer); } -mojom::RouteProvider* MockRenderThread::GetRemoteRouteProvider( - util::PassKey) { - return GetStaticRemoteRouteProvider(); -} - void MockRenderThread::SetResourceDispatcherDelegate( ResourceDispatcherDelegate* delegate) { } diff --git a/content/public/test/mock_render_thread.h b/content/public/test/mock_render_thread.h index 822d0512ab66c4..110c379c329749 100644 --- a/content/public/test/mock_render_thread.h +++ b/content/public/test/mock_render_thread.h @@ -11,7 +11,6 @@ #include "base/observer_list.h" #include "base/single_thread_task_runner.h" #include "base/strings/string16.h" -#include "base/util/type_safety/pass_key.h" #include "build/build_config.h" #include "content/public/common/widget_type.h" #include "content/public/renderer/render_thread.h" @@ -41,7 +40,6 @@ namespace mojom { class CreateNewWindowParams; class CreateNewWindowReply; class RenderMessageFilter; -class RouteProvider; } // This class is a very simple mock of RenderThread. It simulates an IPC channel @@ -70,8 +68,6 @@ class MockRenderThread : public RenderThread { void RemoveFilter(IPC::MessageFilter* filter) override; void AddObserver(RenderThreadObserver* observer) override; void RemoveObserver(RenderThreadObserver* observer) override; - mojom::RouteProvider* GetRemoteRouteProvider( - util::PassKey) override; void SetResourceDispatcherDelegate( ResourceDispatcherDelegate* delegate) override; void RecordAction(const base::UserMetricsAction& action) override; diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index 91bf3e5fd61966..02f113f5850541 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc @@ -29,8 +29,8 @@ #include "content/public/renderer/render_view_visitor.h" #include "content/public/test/fake_render_widget_host.h" #include "content/public/test/frame_load_waiter.h" -#include "content/renderer/agent_scheduling_group.h" #include "content/renderer/loader/resource_dispatcher.h" +#include "content/renderer/mock_agent_scheduling_group.h" #include "content/renderer/render_process.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_view_impl.h" @@ -226,15 +226,17 @@ bool GetWindowsKeyCode(char ascii_character, int* key_code) { std::unique_ptr CreateAgentSchedulingGroup( RenderThread& render_thread) { + // Fake mojos for the AgentSchedulingGroupHost interface. mojo::PendingAssociatedRemote agent_scheduling_group_host; ignore_result( agent_scheduling_group_host.InitWithNewEndpointAndPassReceiver()); mojo::PendingAssociatedReceiver - agent_scheduling_group_mojo; - return std::make_unique( + agent_scheduling_group_receiver; + + return std::make_unique( render_thread, std::move(agent_scheduling_group_host), - std::move(agent_scheduling_group_mojo), + std::move(agent_scheduling_group_receiver), base::OnceCallback()); } diff --git a/content/renderer/agent_scheduling_group.cc b/content/renderer/agent_scheduling_group.cc index 0b54d6dbbf7c58..e0dd2a3ea5ca50 100644 --- a/content/renderer/agent_scheduling_group.cc +++ b/content/renderer/agent_scheduling_group.cc @@ -74,6 +74,11 @@ AgentSchedulingGroup::MaybeAssociatedRemote::MaybeAssociatedRemote( AgentSchedulingGroup::MaybeAssociatedRemote::~MaybeAssociatedRemote() = default; +mojom::AgentSchedulingGroupHost* +AgentSchedulingGroup::MaybeAssociatedRemote::get() { + return absl::visit([](auto& r) { return r.get(); }, remote_); +} + // AgentSchedulingGroup: AgentSchedulingGroup::AgentSchedulingGroup( RenderThread& render_thread, @@ -140,7 +145,8 @@ void AgentSchedulingGroup::RemoveRoute(int32_t routing_id) { } mojom::RouteProvider* AgentSchedulingGroup::GetRemoteRouteProvider() { - return render_thread_.GetRemoteRouteProvider(PassKey()); + DCHECK(remote_route_provider_); + return remote_route_provider_.get(); } void AgentSchedulingGroup::CreateView(mojom::CreateViewParamsPtr params) { @@ -170,24 +176,34 @@ void AgentSchedulingGroup::CreateFrameProxy( devtools_frame_token, PassKey()); } +void AgentSchedulingGroup::BindAssociatedRouteProvider( + mojo::PendingAssociatedRemote remote, + mojo::PendingAssociatedReceiver receiver) { + remote_route_provider_.Bind(std::move(remote)); + route_provider_receiver_.Bind(std::move(receiver), + ToImpl(render_thread_) + .GetWebMainThreadScheduler() + ->DeprecatedDefaultTaskRunner()); +} + void AgentSchedulingGroup::GetRoute( int32_t routing_id, mojo::PendingAssociatedReceiver receiver) { - // TODO(crbug.com/1111231): Make AgentSchedulingGroup a fully-fledged - // RouteProvider, so we can start registering routes directly with an - // AgentSchedulingGroup rather than ChildThreadImpl. - ToImpl(render_thread_).GetRoute(routing_id, std::move(receiver)); + DCHECK(receiver.is_valid()); + associated_interface_provider_receivers_.Add(this, std::move(receiver), + routing_id); } void AgentSchedulingGroup::GetAssociatedInterface( const std::string& name, mojo::PendingAssociatedReceiver receiver) { - // TODO(crbug.com/1111231): Make AgentSchedulingGroup a fully-fledged - // AssociatedInterfaceProvider, so we can start associating interfaces - // directly with the AgentSchedulingGroup interface. - ToImpl(render_thread_).GetAssociatedInterface(name, std::move(receiver)); + int32_t routing_id = + associated_interface_provider_receivers_.current_context(); + IPC::Listener* listener = ToImpl(render_thread_).GetListener(routing_id); + if (listener) + listener->OnAssociatedInterfaceRequest(name, receiver.PassHandle()); } } // namespace content diff --git a/content/renderer/agent_scheduling_group.h b/content/renderer/agent_scheduling_group.h index 4ae51353ed7a1c..033182afc22906 100644 --- a/content/renderer/agent_scheduling_group.h +++ b/content/renderer/agent_scheduling_group.h @@ -10,6 +10,7 @@ #include "content/common/associated_interfaces.mojom.h" #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/associated_receiver.h" +#include "mojo/public/cpp/bindings/associated_receiver_set.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -61,7 +62,8 @@ class CONTENT_EXPORT AgentSchedulingGroup void AddRoute(int32_t routing_id, IPC::Listener* listener); void RemoveRoute(int32_t routing_id); - mojom::RouteProvider* GetRemoteRouteProvider(); + // This is virtual only for unit tests. + virtual mojom::RouteProvider* GetRemoteRouteProvider(); private: // `MaybeAssociatedReceiver` and `MaybeAssociatedRemote` are temporary helper @@ -99,6 +101,7 @@ class CONTENT_EXPORT AgentSchedulingGroup mojo::PendingAssociatedRemote host_remote); ~MaybeAssociatedRemote(); + mojom::AgentSchedulingGroupHost* get(); private: absl::variant, @@ -118,6 +121,9 @@ class CONTENT_EXPORT AgentSchedulingGroup const FrameReplicationState& replicated_state, const base::UnguessableToken& frame_token, const base::UnguessableToken& devtools_frame_token) override; + void BindAssociatedRouteProvider( + mojo::PendingAssociatedRemote remote, + mojo::PendingAssociatedReceiver receiever) override; // mojom::RouteProvider void GetRoute( @@ -140,6 +146,20 @@ class CONTENT_EXPORT AgentSchedulingGroup // Remote stub of mojom::AgentSchedulingGroupHost, used for sending calls to // the (browser-side) AgentSchedulingGroupHost. MaybeAssociatedRemote host_remote_; + + // The |mojom::RouteProvider| mojo pair to setup + // |blink::AssociatedInterfaceProvider| routes between us and the browser-side + // |AgentSchedulingGroup|. + mojo::AssociatedRemote remote_route_provider_; + mojo::AssociatedReceiver route_provider_receiver_{this}; + + // The `blink::mojom::AssociatedInterfaceProvider` receiver set that *all* + // browser-side `blink::AssociatedInterfaceProvider` objects own a remote to. + // `AgentSchedulingGroupHost` will be responsible for routing each associated + // interface request to the appropriate renderer object. + mojo::AssociatedReceiverSet + associated_interface_provider_receivers_; }; } // namespace content diff --git a/content/renderer/mock_agent_scheduling_group.cc b/content/renderer/mock_agent_scheduling_group.cc new file mode 100644 index 00000000000000..28f240ca06c412 --- /dev/null +++ b/content/renderer/mock_agent_scheduling_group.cc @@ -0,0 +1,33 @@ +// Copyright 2020 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/renderer/mock_agent_scheduling_group.h" + +#include "base/no_destructor.h" +#include "content/renderer/render_thread_impl.h" + +namespace content { + +MockAgentSchedulingGroup::MockAgentSchedulingGroup( + RenderThread& render_thread, + mojo::PendingAssociatedRemote host_remote, + mojo::PendingAssociatedReceiver receiver, + base::OnceCallback + mojo_disconnect_handler) + : AgentSchedulingGroup(render_thread, + std::move(host_remote), + std::move(receiver), + std::move(mojo_disconnect_handler)) {} + +mojom::RouteProvider* MockAgentSchedulingGroup::GetRemoteRouteProvider() { + DCHECK(!RenderThreadImpl::current()); + static base::NoDestructor> static_remote; + if (!static_remote->is_bound()) { + ignore_result(static_remote->BindNewPipeAndPassReceiver()); + } + DCHECK(static_remote->is_bound()); + return static_remote->get(); +} + +} // namespace content diff --git a/content/renderer/mock_agent_scheduling_group.h b/content/renderer/mock_agent_scheduling_group.h new file mode 100644 index 00000000000000..f927d8d7dbaf8d --- /dev/null +++ b/content/renderer/mock_agent_scheduling_group.h @@ -0,0 +1,40 @@ +// Copyright 2020 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. + +#ifndef CONTENT_RENDERER_MOCK_AGENT_SCHEDULING_GROUP_H_ +#define CONTENT_RENDERER_MOCK_AGENT_SCHEDULING_GROUP_H_ + +#include "base/callback.h" +#include "content/common/associated_interfaces.mojom.h" +#include "content/common/content_export.h" +#include "content/renderer/agent_scheduling_group.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" + +namespace content { + +class RenderThread; + +// A mock of `AgentSchedulingGroup`, that exists only to provide some test-only +// overrides of the base class methods. Meant to be used in unit tests, where +// the `AgentSchedulingGroup` is not actually wired up to its corresponding host +// in the browser process. +class MockAgentSchedulingGroup : public AgentSchedulingGroup { + public: + // `mojo_disconnect_handler` is an optional callback that will be called with + // `this` when `receiver` is disconnected. + MockAgentSchedulingGroup( + RenderThread& render_thread, + mojo::PendingAssociatedRemote + host_remote, + mojo::PendingAssociatedReceiver receiver, + base::OnceCallback + mojo_disconnect_handler); + + mojom::RouteProvider* GetRemoteRouteProvider() override; +}; + +} // namespace content + +#endif diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 0998f754068ffe..0a63771586231c 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc @@ -629,8 +629,6 @@ void RenderThreadImpl::Init() { GetContentClient()->renderer()->CreateURLLoaderThrottleProvider( URLLoaderThrottleProviderType::kFrame); - GetAssociatedInterfaceRegistry()->AddInterface(base::BindRepeating( - &RenderThreadImpl::OnRouteProviderReceiver, base::Unretained(this))); GetAssociatedInterfaceRegistry()->AddInterface(base::BindRepeating( &RenderThreadImpl::OnRendererInterfaceReceiver, base::Unretained(this))); @@ -950,16 +948,6 @@ RenderThreadImpl::CreateVideoFrameCompositorTaskRunner() { return video_frame_compositor_task_runner_; } -mojom::RouteProvider* RenderThreadImpl::GetRemoteRouteProvider( - util::PassKey) { - if (!remote_route_provider_) { - DCHECK(GetChannel()); - GetChannel()->GetRemoteAssociatedInterface(&remote_route_provider_); - } - - return remote_route_provider_.get(); -} - void RenderThreadImpl::InitializeWebKit(mojo::BinderMap* binders) { DCHECK(!blink_platform_impl_); @@ -1891,26 +1879,6 @@ void RenderThreadImpl::OnMemoryPressure( } } -void RenderThreadImpl::GetRoute( - int32_t routing_id, - mojo::PendingAssociatedReceiver - receiver) { - associated_interface_provider_receivers_.Add(this, std::move(receiver), - routing_id); -} - -void RenderThreadImpl::GetAssociatedInterface( - const std::string& name, - mojo::PendingAssociatedReceiver - receiver) { - int32_t routing_id = - associated_interface_provider_receivers_.current_context(); - // We delegate to ChildThreadImpl when we actually need to communicate with - // IPC::Listeners, since it owns the router. - ChildThreadImpl::GetAssociatedInterface(routing_id, name, - std::move(receiver)); -} - scoped_refptr RenderThreadImpl::GetMediaThreadTaskRunner() { DCHECK(main_thread_runner()->BelongsToCurrentThread()); @@ -2100,14 +2068,6 @@ void RenderThreadImpl::OnSyncMemoryPressure( v8_memory_pressure_level); } -void RenderThreadImpl::OnRouteProviderReceiver( - mojo::PendingAssociatedReceiver receiver) { - DCHECK(!route_provider_receiver_.is_bound()); - route_provider_receiver_.Bind( - std::move(receiver), - GetWebMainThreadScheduler()->DeprecatedDefaultTaskRunner()); -} - void RenderThreadImpl::OnRendererInterfaceReceiver( mojo::PendingAssociatedReceiver receiver) { DCHECK(!renderer_receiver_.is_bound()); diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index cab50f7e079aa1..b741979ec88506 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h @@ -124,8 +124,6 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread, public ChildThreadImpl, public mojom::Renderer, - public mojom::RouteProvider, - public blink::mojom::AssociatedInterfaceProvider, public viz::mojom::CompositingModeWatcher, public CompositorDependencies { public: @@ -427,9 +425,6 @@ class CONTENT_EXPORT RenderThreadImpl video_frame_compositor_task_runner_ = task_runner; } - mojom::RouteProvider* GetRemoteRouteProvider( - util::PassKey) override; - private: friend class RenderThreadImplBrowserTest; friend class AgentSchedulingGroup; @@ -494,18 +489,6 @@ class CONTENT_EXPORT RenderThreadImpl void OnMemoryPressure( base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); - // mojom::RouteProvider implementation: - void GetRoute( - int32_t routing_id, - mojo::PendingAssociatedReceiver - receiver) override; - - // blink::mojom::AssociatedInterfaceProvider implementation: - void GetAssociatedInterface( - const std::string& name, - mojo::PendingAssociatedReceiver - receiver) override; - bool RendererIsHidden() const; void OnRendererHidden(); void OnRendererVisible(); @@ -528,8 +511,6 @@ class CONTENT_EXPORT RenderThreadImpl std::unique_ptr CreateSyntheticBeginFrameSource(); - void OnRouteProviderReceiver( - mojo::PendingAssociatedReceiver receiver); void OnRendererInterfaceReceiver( mojo::PendingAssociatedReceiver receiver); @@ -631,12 +612,6 @@ class CONTENT_EXPORT RenderThreadImpl mojo::AssociatedRemote renderer_host_; - mojo::AssociatedReceiver route_provider_receiver_{this}; - mojo::AssociatedReceiverSet - associated_interface_provider_receivers_; - mojo::AssociatedRemote remote_route_provider_; - blink::AssociatedInterfaceRegistry associated_interfaces_; mojo::AssociatedReceiver renderer_receiver_{this}; diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 166d63cff22ffb..70670d0d61b6fe 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn @@ -253,6 +253,8 @@ static_library("test_support") { "../public/test/web_contents_tester.h", "../public/test/web_ui_browsertest_util.cc", "../public/test/web_ui_browsertest_util.h", + "../renderer/mock_agent_scheduling_group.cc", + "../renderer/mock_agent_scheduling_group.h", "content_browser_consistency_checker.cc", "content_browser_consistency_checker.h", "content_test_suite.cc",