1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_RENDERER_AGENT_SCHEDULING_GROUP_H_
#define CONTENT_RENDERER_AGENT_SCHEDULING_GROUP_H_
#include "base/containers/id_map.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/task/single_thread_task_runner.h"
#include "content/common/agent_scheduling_group.mojom.h"
#include "content/common/associated_interfaces.mojom.h"
#include "content/common/buildflags.h"
#include "content/common/content_export.h"
#include "content/public/common/content_features.h"
#include "ipc/ipc.mojom.h"
#include "ipc/ipc_listener.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"
#include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/mojom/associated_interfaces/associated_interfaces.mojom.h"
#include "third_party/blink/public/mojom/frame/frame_replication_state.mojom-forward.h"
#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-forward.h"
#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-forward.h"
#include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
namespace IPC {
class Message;
class SyncChannel;
} // namespace IPC
namespace blink {
class WebURL;
class WebView;
} // namespace blink
namespace content {
class RenderFrameImpl;
class RenderThread;
// Renderer-side representation of AgentSchedulingGroup, used for communication
// with the (browser-side) AgentSchedulingGroupHost. AgentSchedulingGroup is
// Blink's unit of scheduling and performance isolation, which is the only way
// to obtain ordering guarantees between different Mojo (associated) interfaces
// and legacy IPC messages.
class CONTENT_EXPORT AgentSchedulingGroup
: public IPC::Listener,
public mojom::AgentSchedulingGroup,
public mojom::RouteProvider,
public blink::mojom::AssociatedInterfaceProvider {
public:
AgentSchedulingGroup(
RenderThread& render_thread,
mojo::PendingReceiver<IPC::mojom::ChannelBootstrap> bootstrap);
AgentSchedulingGroup(
RenderThread& render_thread,
mojo::PendingAssociatedReceiver<mojom::AgentSchedulingGroup> receiver);
~AgentSchedulingGroup() override;
AgentSchedulingGroup(const AgentSchedulingGroup&) = delete;
AgentSchedulingGroup& operator=(const AgentSchedulingGroup&) = delete;
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
bool Send(IPC::Message* message);
#endif
void AddFrameRoute(const blink::LocalFrameToken& frame_token,
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
int routing_id,
#endif
RenderFrameImpl* render_frame,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
void RemoveFrameRoute(const blink::LocalFrameToken& frame_token
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
,
int routing_id
#endif
);
void DidUnloadRenderFrame(const blink::LocalFrameToken& frame_token);
mojom::RouteProvider* GetRemoteRouteProvider();
blink::scheduler::WebAgentGroupScheduler& agent_group_scheduler() {
return *agent_group_scheduler_;
}
// Create a new WebView in this AgentSchedulingGroup.
blink::WebView* CreateWebView(mojom::CreateViewParamsPtr params,
bool was_created_by_renderer,
const blink::WebURL& base_url);
protected:
// mojom::AgentSchedulingGroup:
void BindAssociatedInterfaces(
mojo::PendingAssociatedRemote<mojom::AgentSchedulingGroupHost>
remote_host,
mojo::PendingAssociatedReceiver<mojom::RouteProvider>
route_provider_receiever) override;
private:
// IPC::Listener:
bool OnMessageReceived(const IPC::Message& message) override;
void OnBadMessageReceived(const IPC::Message& message) override;
void OnAssociatedInterfaceRequest(
const std::string& interface_name,
mojo::ScopedInterfaceEndpointHandle handle) override;
// mojom::AgentSchedulingGroup:
void CreateView(mojom::CreateViewParamsPtr params) override;
void CreateFrame(mojom::CreateFrameParamsPtr params) override;
void CreateSharedStorageWorkletService(
mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService> receiver,
blink::mojom::WorkletGlobalScopeCreationParamsPtr
global_scope_creation_params) override;
// mojom::RouteProvider
void GetRoute(
const blink::LocalFrameToken& frame_token,
mojo::PendingAssociatedReceiver<blink::mojom::AssociatedInterfaceProvider>
receiver) override;
// blink::mojom::AssociatedInterfaceProvider
void GetAssociatedInterface(
const std::string& name,
mojo::PendingAssociatedReceiver<blink::mojom::AssociatedInterface>
receiver) override;
RenderFrameImpl* GetListener(const blink::LocalFrameToken& frame_token);
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
RenderFrameImpl* GetListener(int32_t routing_id);
#endif
// Map of registered RenderFrames.
absl::flat_hash_map<blink::LocalFrameToken,
raw_ptr<RenderFrameImpl, CtnExperimental>>
listener_map_;
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
absl::flat_hash_map<int32_t, raw_ptr<RenderFrameImpl, CtnExperimental>>
routing_id_map_;
#endif
// A dedicated scheduler for this AgentSchedulingGroup.
std::unique_ptr<blink::scheduler::WebAgentGroupScheduler>
agent_group_scheduler_;
// This AgentSchedulingGroup's legacy IPC channel. Will only be used in
// `features::MBIMode::kEnabledPerRenderProcessHost` or
// `features::MBIMode::kEnabledPerSiteInstance` mode.
std::unique_ptr<IPC::SyncChannel> channel_;
const raw_ref<RenderThread> render_thread_;
// Implementation of `mojom::AgentSchedulingGroup`, used for responding to
// calls from the (browser-side) `AgentSchedulingGroupHost`.
mojo::AssociatedReceiver<mojom::AgentSchedulingGroup> receiver_;
// Remote stub of mojom::AgentSchedulingGroupHost, used for sending calls to
// the (browser-side) AgentSchedulingGroupHost.
mojo::AssociatedRemote<mojom::AgentSchedulingGroupHost> host_remote_;
// The `mojom::RouteProvider` mojo receiver that the browser uses to establish
// a `blink::AssociatedInterfaceProvider` route between `this` and a
// `RenderFrameHostImpl`. See documentation above
// `associated_interface_provider_receivers_`.
mojo::AssociatedReceiver<mojom::RouteProvider> route_provider_receiver_{this};
// The `blink::mojom::AssociatedInterfaceProvider` receiver set that *all*
// `RenderFrameHostImpl`s associated with this agent scheduling group own a
// remote to. `this` handles each of their associated interface requests. If
// we have an associated `RenderFrameImpl` that we can forward the request to,
// we do. Otherwise, we "queue" these requests in `pending_receivers_`. This
// is really bad though; see the documentation there.
mojo::AssociatedReceiverSet<blink::mojom::AssociatedInterfaceProvider,
blink::LocalFrameToken>
associated_interface_provider_receivers_;
struct ReceiverData {
ReceiverData(
const std::string& name,
mojo::PendingAssociatedReceiver<blink::mojom::AssociatedInterface>
receiver);
ReceiverData(ReceiverData&& other);
~ReceiverData();
std::string name;
mojo::PendingAssociatedReceiver<blink::mojom::AssociatedInterface> receiver;
};
// See warning in `GetAssociatedInterface`.
// Map from `blink::LocalFrameToken` to pending receivers that have not had
// their route added. Note this is unsafe and can lead to message drops.
std::multimap<blink::LocalFrameToken, ReceiverData> pending_receivers_;
};
} // namespace content
#endif // CONTENT_RENDERER_AGENT_SCHEDULING_GROUP_H_
|