blob: ece415cfebab8fd4d97bf6e7292c72fde79be731 [file] [log] [blame]
// 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/browser/renderer_host/agent_scheduling_group_host.h"
#include <memory>
#include "base/feature_list.h"
#include "base/supports_user_data.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/common/agent_scheduling_group.mojom.h"
#include "content/common/renderer.mojom.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_features.h"
namespace content {
namespace {
using ::IPC::ChannelProxy;
using ::IPC::Listener;
using ::mojo::AssociatedReceiver;
using ::mojo::AssociatedRemote;
using ::mojo::PendingAssociatedReceiver;
using ::mojo::PendingAssociatedRemote;
using ::mojo::PendingReceiver;
using ::mojo::PendingRemote;
using ::mojo::Receiver;
using ::mojo::Remote;
static constexpr char kAgentGroupHostDataKey[] =
"AgentSchedulingGroupHostUserDataKey";
class AgentGroupHostUserData : public base::SupportsUserData::Data {
public:
explicit AgentGroupHostUserData(
std::unique_ptr<AgentSchedulingGroupHost> agent_group)
: agent_group_(std::move(agent_group)) {
DCHECK(agent_group_);
}
~AgentGroupHostUserData() override = default;
AgentSchedulingGroupHost* agent_group() { return agent_group_.get(); }
private:
std::unique_ptr<AgentSchedulingGroupHost> agent_group_;
};
} // namespace
// MaybeAssociatedReceiver:
AgentSchedulingGroupHost::MaybeAssociatedReceiver::MaybeAssociatedReceiver(
AgentSchedulingGroupHost& host,
bool should_associate) {
if (should_associate) {
receiver_.emplace<AssociatedReceiver<mojom::AgentSchedulingGroupHost>>(
&host);
} else {
receiver_.emplace<Receiver<mojom::AgentSchedulingGroupHost>>(&host);
}
}
AgentSchedulingGroupHost::MaybeAssociatedReceiver::~MaybeAssociatedReceiver() =
default;
PendingRemote<mojom::AgentSchedulingGroupHost>
AgentSchedulingGroupHost::MaybeAssociatedReceiver::BindNewPipeAndPassRemote() {
return absl::get<Receiver<mojom::AgentSchedulingGroupHost>>(receiver_)
.BindNewPipeAndPassRemote();
}
PendingAssociatedRemote<mojom::AgentSchedulingGroupHost>
AgentSchedulingGroupHost::MaybeAssociatedReceiver::
BindNewEndpointAndPassRemote() {
return absl::get<AssociatedReceiver<mojom::AgentSchedulingGroupHost>>(
receiver_)
.BindNewEndpointAndPassRemote();
}
// MaybeAssociatedRemote:
AgentSchedulingGroupHost::MaybeAssociatedRemote::MaybeAssociatedRemote(
bool should_associate) {
if (should_associate) {
remote_ = AssociatedRemote<mojom::AgentSchedulingGroup>();
} else {
remote_ = Remote<mojom::AgentSchedulingGroup>();
}
}
AgentSchedulingGroupHost::MaybeAssociatedRemote::~MaybeAssociatedRemote() =
default;
PendingReceiver<mojom::AgentSchedulingGroup>
AgentSchedulingGroupHost::MaybeAssociatedRemote::BindNewPipeAndPassReceiver() {
return absl::get<Remote<mojom::AgentSchedulingGroup>>(remote_)
.BindNewPipeAndPassReceiver();
}
PendingAssociatedReceiver<mojom::AgentSchedulingGroup>
AgentSchedulingGroupHost::MaybeAssociatedRemote::
BindNewEndpointAndPassReceiver() {
return absl::get<AssociatedRemote<mojom::AgentSchedulingGroup>>(remote_)
.BindNewEndpointAndPassReceiver();
}
// AgentSchedulingGroupHost:
// static
AgentSchedulingGroupHost* AgentSchedulingGroupHost::Get(
const SiteInstance& instance,
RenderProcessHost& process) {
AgentGroupHostUserData* data = static_cast<AgentGroupHostUserData*>(
process.GetUserData(kAgentGroupHostDataKey));
if (data != nullptr)
return data->agent_group();
auto agent_group_data = std::make_unique<AgentGroupHostUserData>(
std::make_unique<AgentSchedulingGroupHost>(process));
AgentSchedulingGroupHost* agent_group = agent_group_data->agent_group();
process.SetUserData(kAgentGroupHostDataKey, std::move(agent_group_data));
return agent_group;
}
AgentSchedulingGroupHost::AgentSchedulingGroupHost(RenderProcessHost& process)
: AgentSchedulingGroupHost(
process,
!base::FeatureList::IsEnabled(
features::kMbiDetachAgentSchedulingGroupFromChannel)) {}
AgentSchedulingGroupHost::AgentSchedulingGroupHost(RenderProcessHost& process,
bool should_associate)
: process_(process),
receiver_(*this, should_associate),
mojo_remote_(should_associate) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (should_associate) {
process_.GetRendererInterface()->CreateAssociatedAgentSchedulingGroup(
receiver_.BindNewEndpointAndPassRemote(),
mojo_remote_.BindNewEndpointAndPassReceiver());
} else {
process_.GetRendererInterface()->CreateAgentSchedulingGroup(
receiver_.BindNewPipeAndPassRemote(),
mojo_remote_.BindNewPipeAndPassReceiver());
}
}
// DO NOT USE |process_| HERE! At this point it (or at least parts of it) is no
// longer valid.
AgentSchedulingGroupHost::~AgentSchedulingGroupHost() = default;
RenderProcessHost* AgentSchedulingGroupHost::GetProcess() {
return &process_;
}
ChannelProxy* AgentSchedulingGroupHost::GetChannel() {
return process_.GetChannel();
}
bool AgentSchedulingGroupHost::Send(IPC::Message* message) {
return process_.Send(message);
}
void AgentSchedulingGroupHost::AddRoute(int32_t routing_id,
Listener* listener) {
process_.AddRoute(routing_id, listener);
}
void AgentSchedulingGroupHost::RemoveRoute(int32_t routing_id) {
process_.RemoveRoute(routing_id);
}
mojom::RouteProvider* AgentSchedulingGroupHost::GetRemoteRouteProvider() {
RenderProcessHostImpl& process =
static_cast<RenderProcessHostImpl&>(process_);
return process.GetRemoteRouteProvider();
}
void AgentSchedulingGroupHost::CreateFrame(mojom::CreateFrameParamsPtr params) {
process_.GetRendererInterface()->CreateFrame(std::move(params));
}
void AgentSchedulingGroupHost::CreateView(mojom::CreateViewParamsPtr params) {
// TODO(crbug.com/1111231): Ensure that the mojo endpoints are still connected
// (once crrev.com/c/2397057 is submitted).
process_.GetRendererInterface()->CreateView(std::move(params));
}
void AgentSchedulingGroupHost::DestroyView(int32_t routing_id) {
process_.GetRendererInterface()->DestroyView(routing_id);
}
} // namespace content