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
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_GUEST_OS_GUEST_OS_SESSION_TRACKER_H_
#define CHROME_BROWSER_ASH_GUEST_OS_GUEST_OS_SESSION_TRACKER_H_
#include "base/callback_list.h"
#include "base/containers/flat_set.h"
#include "base/files/file_path.h"
#include "base/functional/callback_forward.h"
#include "chrome/browser/ash/guest_os/guest_id.h"
#include "chromeos/ash/components/dbus/cicerone/cicerone_client.h"
#include "chromeos/ash/components/dbus/cicerone/cicerone_service.pb.h"
#include "chromeos/ash/components/dbus/concierge/concierge_client.h"
#include "chromeos/ash/components/dbus/vm_concierge/concierge_service.pb.h"
#include "components/keyed_service/core/keyed_service.h"
namespace guest_os {
struct GuestInfo {
GuestInfo(GuestId guest_id,
int64_t cid,
std::string username,
base::FilePath homedir,
std::string ipv4_address,
uint32_t sftp_vsock_port);
~GuestInfo();
GuestInfo(GuestInfo&&);
GuestInfo(const GuestInfo&);
GuestInfo& operator=(GuestInfo&&);
GuestInfo& operator=(const GuestInfo&);
GuestId guest_id;
int64_t cid;
std::string username;
base::FilePath homedir;
std::string ipv4_address;
uint32_t sftp_vsock_port;
};
class ContainerStartedObserver : public base::CheckedObserver {
public:
// Called when the container has started.
virtual void OnContainerStarted(const guest_os::GuestId& container_id) = 0;
};
class GuestOsSessionTracker : protected ash::ConciergeClient::VmObserver,
protected ash::CiceroneClient::Observer,
public KeyedService {
public:
explicit GuestOsSessionTracker(std::string owner_id);
~GuestOsSessionTracker() override;
// Runs `callback` when the OnContainerStarted signal arrives for the guest
// with the given `id`. To cancel the callback (e.g. upon timeout) destroy the
// returned subscription.
base::CallbackListSubscription RunOnceContainerStarted(
const GuestId& id,
base::OnceCallback<void(GuestInfo)> callback);
// Runs `callback` when the guest identified by `id` shuts down. To cancel the
// callback (e.g. upon timeout) destroy the returned subscription.
base::CallbackListSubscription RunOnShutdown(
const GuestId& id,
base::OnceCallback<void()> callback);
// Returns information about a running guest. Returns nullopt if the guest
// isn't recognised e.g. it's not running. If you just want to check if a
// guest is running or not and don't need the info, use `IsRunning` instead
std::optional<GuestInfo> GetInfo(const GuestId& id);
// Returns information about a running VM. Returns nullopt if the VM
// isn't recognised e.g. it's not running.
std::optional<vm_tools::concierge::VmInfo> GetVmInfo(
const std::string& vm_name);
// Given a container_token for a running guest, returns its GuestId. Returns
// nullopt if the token isn't recognised.
std::optional<GuestId> GetGuestIdForToken(const std::string& container_token);
// Returns true if a guest is running, false otherwise.
bool IsRunning(const GuestId& id);
// Returns true if a VM is known to be shutting down, false for running or
// stopped.
bool IsVmStopping(const std::string& vm_name);
void AddGuestForTesting(const GuestId& id,
const std::string& token = "test_token");
void AddGuestForTesting(const GuestId& id,
const GuestInfo& info,
bool notify = false,
const std::string& token = "test_token");
void AddContainerStartedObserver(ContainerStartedObserver* observer);
void RemoveContainerStartedObserver(ContainerStartedObserver* observer);
protected:
// ash::ConciergeClient::VmObserver overrides.
void OnVmStarted(const vm_tools::concierge::VmStartedSignal& signal) override;
void OnVmStopped(const vm_tools::concierge::VmStoppedSignal& signal) override;
void OnVmStopping(
const vm_tools::concierge::VmStoppingSignal& signal) override;
// ash::CiceroneClient::Observer overrides.
void OnContainerStarted(
const vm_tools::cicerone::ContainerStartedSignal& signal) override;
void OnContainerShutdown(
const vm_tools::cicerone::ContainerShutdownSignal& signal) override;
private:
void OnListVms(std::optional<vm_tools::concierge::ListVmsResponse> response);
void OnListRunningContainers(
std::optional<vm_tools::cicerone::ListRunningContainersResponse>
response);
void OnGetGarconSessionInfo(
std::string vm_name,
std::string container_name,
std::string container_token,
std::optional<vm_tools::cicerone::GetGarconSessionInfoResponse> response);
void HandleNewGuest(const std::string& vm_name,
const std::string& container_name,
const std::string& container_token,
const std::string& username,
const std::string& homedir,
const std::string& ipv4_address,
const uint32_t& sftp_vsock_port);
void HandleContainerShutdown(const std::string& vm_name,
const std::string& container_name);
std::string owner_id_;
base::flat_map<std::string, vm_tools::concierge::VmInfo> vms_;
base::flat_set<std::string> stopping_vms_;
base::flat_map<GuestId, GuestInfo> guests_;
base::flat_map<std::string, GuestId> tokens_to_guests_;
base::flat_map<GuestId,
std::unique_ptr<base::OnceCallbackList<void(GuestInfo)>>>
container_start_callbacks_;
base::flat_map<GuestId, std::unique_ptr<base::OnceCallbackList<void()>>>
container_shutdown_callbacks_;
base::ObserverList<ContainerStartedObserver> container_started_observers_;
base::WeakPtrFactory<GuestOsSessionTracker> weak_ptr_factory_{this};
};
} // namespace guest_os
#endif // CHROME_BROWSER_ASH_GUEST_OS_GUEST_OS_SESSION_TRACKER_H_
|