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
|
// Copyright 2019 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_CROSTINI_CROSTINI_INSTALLER_H_
#define CHROME_BROWSER_ASH_CROSTINI_CROSTINI_INSTALLER_H_
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ash/crostini/ansible/ansible_management_service.h"
#include "chrome/browser/ash/crostini/crostini_installer_ui_delegate.h"
#include "chrome/browser/ash/crostini/crostini_manager.h"
#include "chrome/browser/ash/crostini/crostini_types.mojom-forward.h"
#include "components/keyed_service/core/keyed_service.h"
class Profile;
namespace crostini {
class CrostiniInstaller : public KeyedService,
public CrostiniManager::RestartObserver,
public CrostiniInstallerUIDelegate {
public:
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
// When you add entries to this enum don't forget to update enums.xml and the
// plx scripts in
// https://plx.corp.google.com/home2/home/collections/c16e3c1474497b821
enum class SetupResult {
kNotStarted = 0,
// kUserCancelled = 1,
kSuccess = 2,
kErrorLoadingTermina = 3,
// kErrorStartingConcierge = 4,
kErrorCreatingDiskImage = 5,
kErrorStartingTermina = 6,
kErrorStartingContainer = 7,
kErrorOffline = 8,
// kErrorFetchingSshKeys = 9,
// kErrorMountingContainer = 10,
kErrorSettingUpContainer = 11,
kUserCancelledStart = 12,
kUserCancelledInstallImageLoader = 13,
// kUserCancelledStartConcierge = 14,
kUserCancelledCreateDiskImage = 15,
kUserCancelledStartTerminaVm = 16,
kUserCancelledCreateContainer = 17,
kUserCancelledStartContainer = 18,
kUserCancelledSetupContainer = 19,
// kUserCancelledFetchSshKeys = 20,
// kUserCancelledMountContainer = 21,
kErrorInsufficientDiskSpace = 22,
kErrorConfiguringContainer = 23,
kUserCancelledConfiguringContainer = 24,
kErrorCreateContainer = 25,
kErrorUnknown = 26,
kUserCancelledStartLxd = 27,
kErrorStartingLxd = 28,
kNeedUpdate = 29,
kMaxValue = kNeedUpdate,
// When adding a new value, check you've followed the steps in the comment
// at the top of this enum.
};
explicit CrostiniInstaller(Profile* profile);
CrostiniInstaller(const CrostiniInstaller&) = delete;
CrostiniInstaller& operator=(const CrostiniInstaller&) = delete;
~CrostiniInstaller() override;
void Shutdown() override;
void ShowDialog(CrostiniUISurface ui_surface);
// CrostiniInstallerUIDelegate:
void Install(CrostiniManager::RestartOptions options,
ProgressCallback progress_callback,
ResultCallback result_callback) override;
void Cancel(base::OnceClosure callback) override;
void CancelBeforeStart() override;
// CrostiniManager::RestartObserver:
void OnStageStarted(crostini::mojom::InstallerState stage) override;
void OnDiskImageCreated(bool success,
CrostiniResult result,
int64_t disk_size_available) override;
void OnContainerDownloading(int32_t download_percent) override;
// Return true if internal state allows starting installation.
bool CanInstall();
void set_require_cleanup_for_testing(bool require_cleanup) {
require_cleanup_ = require_cleanup;
}
void set_skip_launching_terminal_for_testing() {
skip_launching_terminal_for_testing_ = true;
}
private:
enum class State {
IDLE,
INSTALLING,
ERROR, // Something unexpected happened.
CANCEL_CLEANUP, // Deleting a partial installation.
CANCEL_ABORT_CHECK_DISK, // Don't proceed after checking disk.
};
void RunProgressCallback();
void UpdateState(State new_state);
void UpdateInstallingState(
crostini::mojom::InstallerState new_installing_state,
bool run_callback = true);
void HandleError(crostini::mojom::InstallerError error);
void FinishCleanup(crostini::CrostiniResult result);
void RecordSetupResult(SetupResult result);
void OnCrostiniRestartFinished(crostini::CrostiniResult result);
void OnAvailableDiskSpace(std::optional<int64_t> bytes);
void OnCrostiniRemovedAfterConfigurationFailed(
crostini::CrostiniResult result);
raw_ptr<Profile> profile_;
State state_ = State::IDLE;
crostini::mojom::InstallerState installing_state_;
base::TimeTicks install_start_time_;
base::Time installing_state_start_time_;
base::RepeatingTimer state_progress_timer_;
bool require_cleanup_;
int64_t free_disk_space_;
int32_t container_download_percent_;
crostini::CrostiniManager::RestartId restart_id_ =
crostini::CrostiniManager::kUninitializedRestartId;
CrostiniManager::RestartOptions restart_options_;
bool skip_launching_terminal_for_testing_ = false;
ProgressCallback progress_callback_;
ResultCallback result_callback_;
base::OnceClosure cancel_callback_;
base::WeakPtrFactory<CrostiniInstaller> weak_ptr_factory_{this};
};
} // namespace crostini
#endif // CHROME_BROWSER_ASH_CROSTINI_CROSTINI_INSTALLER_H_
|