blob: 3e2eb86a89d1dd72b93a4687f9e58687494c2cf8 [file]
// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/peer_connection_process_handler.h"
#include <utility>
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/task/single_thread_task_runner.h"
namespace remoting {
PeerConnectionProcessHandler::PeerConnectionProcessHandler(
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
std::unique_ptr<WorkerProcessLauncher::Delegate> launcher_delegate,
StoppedCallback stopped_callback)
: caller_task_runner_(caller_task_runner),
stopped_callback_(std::move(stopped_callback)) {
launcher_ = std::make_unique<WorkerProcessLauncher>(
std::move(launcher_delegate), this);
}
PeerConnectionProcessHandler::~PeerConnectionProcessHandler() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
void PeerConnectionProcessHandler::BindPeerSession(
mojo::PendingReceiver<mojom::PeerSession> receiver) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (pc_process_control_.is_bound()) {
pc_process_control_->BindPeerSession(std::move(receiver));
} else {
CHECK(!pending_session_receiver_) << "Only one peer session receiver can "
"be buffered prior to connection.";
pending_session_receiver_ = std::move(receiver);
}
}
void PeerConnectionProcessHandler::Crash(const base::Location& location) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (launcher_) {
launcher_->Crash(location);
}
}
void PeerConnectionProcessHandler::OnChannelConnected(int32_t peer_pid) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
pc_process_control_.reset();
launcher_->GetRemoteAssociatedInterface(
pc_process_control_.BindNewEndpointAndPassReceiver());
if (pending_session_receiver_) {
pc_process_control_->BindPeerSession(std::move(pending_session_receiver_));
}
}
void PeerConnectionProcessHandler::OnPermanentError(int exit_code) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
LOG(ERROR) << "Peer Connection process permanent error, exit code: "
<< exit_code;
OnWorkerProcessStopped();
}
void PeerConnectionProcessHandler::OnWorkerProcessStopped() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// We do not attempt to restart the Peer Connection process because WebRTC
// connection state is lost on crash (requiring a client reconnect), and the
// desktop pipe cannot be recovered. Thus, we tear down the handler and the
// session.
caller_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&PeerConnectionProcessHandler::CloseSelf,
weak_factory_.GetWeakPtr()));
}
void PeerConnectionProcessHandler::OnAssociatedInterfaceRequest(
const std::string& interface_name,
mojo::ScopedInterfaceEndpointHandle handle) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
LOG(ERROR) << "Unexpected associated interface request: " << interface_name;
}
void PeerConnectionProcessHandler::CloseSelf() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (stopped_callback_) {
caller_task_runner_->PostTask(FROM_HERE,
base::BindOnce(std::move(stopped_callback_),
weak_factory_.GetWeakPtr()));
}
}
} // namespace remoting