File: plugin_vm_manager_impl.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (208 lines) | stat: -rw-r--r-- 8,578 bytes parent folder | download | duplicates (6)
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
204
205
206
207
208
// 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 CHROME_BROWSER_ASH_PLUGIN_VM_PLUGIN_VM_MANAGER_IMPL_H_
#define CHROME_BROWSER_ASH_PLUGIN_VM_PLUGIN_VM_MANAGER_IMPL_H_

#include <memory>
#include <optional>

#include "base/files/file_path.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/ash/guest_os/guest_os_dlc_helper.h"
#include "chrome/browser/ash/guest_os/vm_starting_observer.h"
#include "chrome/browser/ash/plugin_vm/plugin_vm_manager.h"
#include "chrome/browser/ash/plugin_vm/plugin_vm_metrics_util.h"
#include "chrome/browser/ash/plugin_vm/plugin_vm_uninstaller_notification.h"
#include "chrome/browser/ash/plugin_vm/plugin_vm_util.h"
#include "chromeos/ash/components/dbus/vm_concierge/concierge_service.pb.h"
#include "chromeos/ash/components/dbus/vm_plugin_dispatcher/vm_plugin_dispatcher.pb.h"
#include "chromeos/ash/components/dbus/vm_plugin_dispatcher/vm_plugin_dispatcher_client.h"

class Profile;

namespace plugin_vm {

// Native Parallels error codes.
constexpr int PRL_ERR_SUCCESS = 0;
constexpr int PRL_ERR_DISP_SHUTDOWN_IN_PROCESS = 0x80000404;
constexpr int PRL_ERR_LICENSE_NOT_VALID = 0x80011000;
constexpr int PRL_ERR_LICENSE_EXPIRED = 0x80011001;
constexpr int PRL_ERR_LICENSE_WRONG_VERSION = 0x80011002;
constexpr int PRL_ERR_LICENSE_WRONG_PLATFORM = 0x80011004;
constexpr int PRL_ERR_LICENSE_BETA_KEY_RELEASE_PRODUCT = 0x80011011;
constexpr int PRL_ERR_LICENSE_RELEASE_KEY_BETA_PRODUCT = 0x80011013;
constexpr int PRL_ERR_LICENSE_SUBSCR_EXPIRED = 0x80011074;
constexpr int PRL_ERR_JLIC_WRONG_HWID = 0x80057005;
constexpr int PRL_ERR_JLIC_LICENSE_DISABLED = 0x80057010;
constexpr int PRL_ERR_JLIC_WEB_PORTAL_ACCESS_REQUIRED = 0x80057012;
constexpr int PRL_ERR_NOT_ENOUGH_DISK_SPACE_TO_START_VM = 0x80000456;

// The PluginVmManagerImpl is responsible for connecting to the D-Bus services
// to manage the Plugin Vm.

class PluginVmManagerImpl : public PluginVmManager,
                            public ash::VmPluginDispatcherClient::Observer {
 public:
  using LaunchPluginVmCallback = base::OnceCallback<void(bool success)>;

  explicit PluginVmManagerImpl(Profile* profile);

  PluginVmManagerImpl(const PluginVmManagerImpl&) = delete;
  PluginVmManagerImpl& operator=(const PluginVmManagerImpl&) = delete;

  ~PluginVmManagerImpl() override;

  void OnPrimaryUserSessionStarted() override;

  // TODO(juwa): Don't allow launch/stop/uninstall to run simultaneously.
  // |callback| is called either when VM tools are ready or if an error occurs.
  void LaunchPluginVm(LaunchPluginVmCallback callback) override;
  void RelaunchPluginVm() override;
  void StopPluginVm(const std::string& name, bool force) override;
  void UninstallPluginVm() override;

  uint64_t seneschal_server_handle() const override;

  // ash::VmPluginDispatcherClient::Observer:
  void OnVmToolsStateChanged(
      const vm_tools::plugin_dispatcher::VmToolsStateChangedSignal& signal)
      override;
  void OnVmStateChanged(
      const vm_tools::plugin_dispatcher::VmStateChangedSignal& signal) override;

  void StartDispatcher(
      base::OnceCallback<void(bool success)> callback) const override;

  vm_tools::plugin_dispatcher::VmState vm_state() const override;

  bool IsRelaunchNeededForNewPermissions() const override;

  void AddVmStartingObserver(ash::VmStartingObserver* observer) override;
  void RemoveVmStartingObserver(ash::VmStartingObserver* observer) override;

  PluginVmUninstallerNotification* uninstaller_notification_for_testing()
      const {
    return uninstaller_notification_.get();
  }

 private:
  void InstallDlcAndUpdateVmState(
      base::OnceCallback<void(bool default_vm_exists)> success_callback,
      base::OnceClosure error_callback);
  void OnInstallPluginVmDlc(
      base::OnceCallback<void(bool default_vm_exists)> success_callback,
      base::OnceClosure error_callback,
      guest_os::GuestOsDlcInstallation::Result install_result);
  void OnStartDispatcher(
      base::OnceCallback<void(bool default_vm_exists)> success_callback,
      base::OnceClosure error_callback,
      bool success);
  void OnListVms(
      base::OnceCallback<void(bool default_vm_exists)> success_callback,
      base::OnceClosure error_callback,
      std::optional<vm_tools::plugin_dispatcher::ListVmResponse> reply);

  // The flow to launch a Plugin Vm. We'll probably want to add additional
  // abstraction around starting the services in the future but this is
  // sufficient for now.
  void OnListVmsForLaunch(bool default_vm_exists);
  void StartVm();
  void OnStartVm(
      std::optional<vm_tools::plugin_dispatcher::StartVmResponse> reply);
  void ShowVm();
  void OnShowVm(
      std::optional<vm_tools::plugin_dispatcher::ShowVmResponse> reply);
  void OnGetVmInfoForSharing(
      std::optional<vm_tools::concierge::GetVmInfoResponse> reply);
  void OnDefaultSharedDirExists(const base::FilePath& dir, bool exists);
  void UninstallSucceeded();

  // Called when LaunchPluginVm() is successful.
  void LaunchSuccessful();
  // Called when LaunchPluginVm() is unsuccessful.
  void LaunchFailed(PluginVmLaunchResult result = PluginVmLaunchResult::kError);

  // The flow to relaunch Plugin Vm.
  void OnSuspendVmForRelaunch(
      std::optional<vm_tools::plugin_dispatcher::SuspendVmResponse> reply);
  void OnRelaunchVmComplete(bool success);

  // The flow to uninstall Plugin Vm.
  void OnListVmsForUninstall(bool default_vm_exists);
  void StopVmForUninstall();
  void OnStopVmForUninstall(
      std::optional<vm_tools::plugin_dispatcher::StopVmResponse> reply);
  void DestroyDiskImage();
  void OnDestroyDiskImage(
      std::optional<vm_tools::concierge::DestroyDiskImageResponse> response);

  // Called when UninstallPluginVm() is unsuccessful.
  void UninstallFailed(
      PluginVmUninstallerNotification::FailedReason reason =
          PluginVmUninstallerNotification::FailedReason::kUnknown);

  // Called when Plugin VM changes availability e.g. installed, uninstalled,
  // policy changes.
  void OnAvailabilityChanged(bool is_allowed, bool is_configured);

  raw_ptr<Profile> profile_;
  std::string owner_id_;
  uint64_t seneschal_server_handle_ = 0;

  // State of the default VM's tools, kept up-to-date by signals from the
  // dispatcher.
  vm_tools::plugin_dispatcher::VmToolsState vm_tools_state_ =
      vm_tools::plugin_dispatcher::VmToolsState::VM_TOOLS_STATE_UNKNOWN;
  // State of the default VM, kept up-to-date by signals from the dispatcher.
  vm_tools::plugin_dispatcher::VmState vm_state_ =
      vm_tools::plugin_dispatcher::VmState::VM_STATE_UNKNOWN;

  base::ObserverList<ash::VmStartingObserver> vm_starting_observers_;

  std::unique_ptr<guest_os::GuestOsDlcInstallation> in_progress_installation_;

  // Members used in the launch flow.

  std::vector<LaunchPluginVmCallback> launch_vm_callbacks_;
  // We can't immediately start the VM when it is in states like suspending, so
  // delay until an in progress operation finishes.
  bool pending_start_vm_ = false;
  // |launch_vm_callbacks_| cannot be run before the vm tools are installed, so
  // delay until the tools are installed. This is set only after StartVm() runs
  // successfully.
  bool pending_vm_tools_installed_ = false;

  // Members used in the relaunch flow.

  // Indicates that we are attempting to start the VM. This fact may not yet
  // be reflected in VM state as the dispatcher may not have had a chance
  // to update it, or maybe it even is not yet aware that we issued StartVm
  // request.
  bool vm_is_starting_ = false;
  // Indicates that we are executing VM relaunch.
  bool relaunch_in_progress_ = false;
  // If we receive second or third relaunch request while already in the middle
  // of relaunch, we need to repeat it to ensure that privileges are set up
  // according to the latest settings.
  bool pending_relaunch_vm_ = false;

  // Members used in the uninstall flow

  std::unique_ptr<PluginVmUninstallerNotification> uninstaller_notification_;
  // We can't immediately destroy the VM when it is in states like
  // suspending, so delay until an in progress operation finishes.
  bool pending_destroy_disk_image_ = false;

  // For notifying the GuestOsSharePath.
  std::unique_ptr<PluginVmAvailabilitySubscription> availability_subscription_;

  base::WeakPtrFactory<PluginVmManagerImpl> weak_ptr_factory_{this};
};

}  // namespace plugin_vm

#endif  // CHROME_BROWSER_ASH_PLUGIN_VM_PLUGIN_VM_MANAGER_IMPL_H_