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
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_HOST_MAC_AGENT_PROCESS_BROKER_H_
#define REMOTING_HOST_MAC_AGENT_PROCESS_BROKER_H_
#include <mach/message.h>
#include <memory>
#include <string_view>
#include <utility>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/process/process_handle.h"
#include "base/sequence_checker.h"
#include "components/named_mojo_ipc_server/named_mojo_ipc_server.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "remoting/host/chromoting_host_services_server.h"
#include "remoting/host/mojom/agent_process_broker.mojom.h"
#include "remoting/host/mojom/chromoting_host_services.mojom.h"
#include "remoting/host/mojom/remoting_host.mojom.h"
namespace remoting {
class AgentProcessBroker final : public mojom::AgentProcessBroker {
public:
AgentProcessBroker();
AgentProcessBroker(const AgentProcessBroker&) = delete;
AgentProcessBroker& operator=(const AgentProcessBroker&) = delete;
~AgentProcessBroker() override;
void Start();
void OnAgentProcessLaunched(
mojo::PendingRemote<mojom::AgentProcess> pending_agent_process) override;
private:
friend class AgentProcessBrokerTest;
struct AgentProcess {
AgentProcess(
size_t reference_id,
base::ProcessId pid,
mojo::Remote<mojom::AgentProcess> agent_process_remote,
mojo::Remote<mojom::RemotingHostControl> remoting_host_control_remote,
bool is_root,
bool is_active);
AgentProcess(AgentProcess&&);
~AgentProcess();
AgentProcess& operator=(AgentProcess&&);
void ResumeProcess();
void SuspendProcess();
void TerminateProcess();
std::string GetAgentProcessLogString(std::string_view state) const;
size_t reference_id; // For reverse lookup in `agent_processes_`.
base::ProcessId pid; // For logging only. Not for book keeping.
mojo::Remote<mojom::AgentProcess> agent_process_remote;
mojo::Remote<mojom::RemotingHostControl> remoting_host_control_remote;
bool is_root;
bool is_active;
};
using Validator = base::RepeatingCallback<bool(
const named_mojo_ipc_server::ConnectionInfo&)>;
// Interface to allow tests to fake the root-ness/non-root-ness of a process,
// since tests can't launch process as root.
using IsRootProcessGetter = base::RepeatingCallback<bool(audit_token_t)>;
AgentProcessBroker(const mojo::NamedPlatformChannel::ServerName& server_name,
Validator validator,
IsRootProcessGetter is_root_process);
void BindChromotingHostServices(
mojo::PendingReceiver<mojom::ChromotingHostServices> receiver,
base::ProcessId peer_pid);
void OnAgentProcessDisconnected(size_t reference_id);
void BrokerAgentProcesses();
// Closes all processes except one. If there are active processes in
// |processes|, then the one not being closed is guaranteed to be active.
// Other than that, the process being left over is arbitrary.
void TrimProcessList(std::vector<AgentProcess*>& processes);
void set_on_agent_process_launched_for_testing(
base::OnceClosure on_agent_process_launched) {
on_agent_process_launched_ = std::move(on_agent_process_launched);
}
SEQUENCE_CHECKER(sequence_checker_);
named_mojo_ipc_server::NamedMojoIpcServer<mojom::AgentProcessBroker> server_;
std::unique_ptr<ChromotingHostServicesServer>
chromoting_host_services_server_;
IsRootProcessGetter is_root_process_;
base::flat_map<size_t /* reference_id */, AgentProcess> agent_processes_;
// We use our own reference ID for book keeping. While unlikely, the OS is
// free to immediately reuse the PID after a process has exited. This might
// cause race conditions since the disconnect callback might be called after
// the new process is spawned.
size_t next_reference_id_ = 0u;
base::OnceClosure on_agent_process_launched_;
};
} // namespace remoting
#endif // REMOTING_HOST_MAC_AGENT_PROCESS_BROKER_H_
|