blob: 6e12575bafa6c0ed12d03255ad6a311997a10370 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/settings/chromeos/crostini_handler.h"
#include <string>
#include <utility>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/metrics/histogram_functions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/crostini/crostini_disk.h"
#include "chrome/browser/chromeos/crostini/crostini_features.h"
#include "chrome/browser/chromeos/crostini/crostini_installer.h"
#include "chrome/browser/chromeos/crostini/crostini_port_forwarder.h"
#include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
#include "chrome/browser/chromeos/crostini/crostini_types.mojom.h"
#include "chrome/browser/chromeos/crostini/crostini_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_dialog.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_thread.h"
#include "ui/display/screen.h"
namespace chromeos {
namespace settings {
namespace {
// These values are used for metrics and should not change.
enum class CrostiniSettingsEvent {
kEnableAdbSideloading = 0,
kDisableAdbSideloading = 1,
kMaxValue = kDisableAdbSideloading,
};
void LogEvent(CrostiniSettingsEvent action) {
base::UmaHistogramEnumeration("Crostini.SettingsEvent", action);
}
} // namespace
CrostiniHandler::CrostiniHandler(Profile* profile) : profile_(profile) {}
CrostiniHandler::~CrostiniHandler() {
DisallowJavascript();
}
void CrostiniHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"requestCrostiniInstallerView",
base::BindRepeating(&CrostiniHandler::HandleRequestCrostiniInstallerView,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"requestRemoveCrostini",
base::BindRepeating(&CrostiniHandler::HandleRequestRemoveCrostini,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"exportCrostiniContainer",
base::BindRepeating(&CrostiniHandler::HandleExportCrostiniContainer,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"importCrostiniContainer",
base::BindRepeating(&CrostiniHandler::HandleImportCrostiniContainer,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"requestCrostiniInstallerStatus",
base::BindRepeating(
&CrostiniHandler::HandleCrostiniInstallerStatusRequest,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"requestCrostiniExportImportOperationStatus",
base::BindRepeating(
&CrostiniHandler::HandleCrostiniExportImportOperationStatusRequest,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"requestArcAdbSideloadStatus",
base::BindRepeating(&CrostiniHandler::HandleQueryArcAdbRequest,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"getCanChangeArcAdbSideloading",
base::BindRepeating(
&CrostiniHandler::HandleCanChangeArcAdbSideloadingRequest,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"enableArcAdbSideload",
base::BindRepeating(&CrostiniHandler::HandleEnableArcAdbRequest,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"disableArcAdbSideload",
base::BindRepeating(&CrostiniHandler::HandleDisableArcAdbRequest,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"requestCrostiniContainerUpgradeView",
base::BindRepeating(&CrostiniHandler::HandleRequestContainerUpgradeView,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"requestCrostiniUpgraderDialogStatus",
base::BindRepeating(
&CrostiniHandler::HandleCrostiniUpgraderDialogStatusRequest,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"requestCrostiniContainerUpgradeAvailable",
base::BindRepeating(
&CrostiniHandler::HandleCrostiniContainerUpgradeAvailableRequest,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"addCrostiniPortForward",
base::BindRepeating(&CrostiniHandler::HandleAddCrostiniPortForward,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"getCrostiniDiskInfo",
base::BindRepeating(&CrostiniHandler::HandleGetCrostiniDiskInfo,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"resizeCrostiniDisk",
base::BindRepeating(&CrostiniHandler::HandleResizeCrostiniDisk,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"checkCrostiniMicSharingStatus",
base::BindRepeating(&CrostiniHandler::HandleCheckCrostiniMicSharingStatus,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"removeCrostiniPortForward",
base::BindRepeating(&CrostiniHandler::HandleRemoveCrostiniPortForward,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"removeAllCrostiniPortForwards",
base::BindRepeating(&CrostiniHandler::HandleRemoveAllCrostiniPortForwards,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"activateCrostiniPortForward",
base::BindRepeating(&CrostiniHandler::HandleActivateCrostiniPortForward,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"deactivateCrostiniPortForward",
base::BindRepeating(&CrostiniHandler::HandleDeactivateCrostiniPortForward,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"getCrostiniActivePorts",
base::BindRepeating(&CrostiniHandler::HandleGetCrostiniActivePorts,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"checkCrostiniIsRunning",
base::BindRepeating(&CrostiniHandler::HandleCheckCrostiniIsRunning,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"shutdownCrostini",
base::BindRepeating(&CrostiniHandler::HandleShutdownCrostini,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"setCrostiniMicSharingEnabled",
base::BindRepeating(&CrostiniHandler::HandleSetCrostiniMicSharingEnabled,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"getCrostiniMicSharingEnabled",
base::BindRepeating(&CrostiniHandler::HandleGetCrostiniMicSharingEnabled,
weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::OnJavascriptAllowed() {
auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile_);
crostini_manager->AddCrostiniDialogStatusObserver(this);
crostini_manager->AddCrostiniContainerPropertiesObserver(this);
crostini_manager->AddContainerStartedObserver(this);
crostini_manager->AddContainerShutdownObserver(this);
crostini_manager->AddCrostiniMicSharingEnabledObserver(this);
crostini::CrostiniExportImport::GetForProfile(profile_)->AddObserver(this);
crostini::CrostiniPortForwarder::GetForProfile(profile_)->AddObserver(this);
// Observe ADB sideloading device policy and react to its changes
adb_sideloading_device_policy_subscription_ =
chromeos::CrosSettings::Get()->AddSettingsObserver(
chromeos::kDeviceCrostiniArcAdbSideloadingAllowed,
base::BindRepeating(&CrostiniHandler::FetchCanChangeAdbSideloading,
weak_ptr_factory_.GetWeakPtr()));
// Observe ADB sideloading user policy and react to its changes
pref_change_registrar_.Init(profile_->GetPrefs());
pref_change_registrar_.Add(
crostini::prefs::kCrostiniArcAdbSideloadingUserPref,
base::BindRepeating(&CrostiniHandler::FetchCanChangeAdbSideloading,
weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::OnJavascriptDisallowed() {
auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile_);
crostini_manager->RemoveCrostiniDialogStatusObserver(this);
crostini_manager->RemoveCrostiniContainerPropertiesObserver(this);
crostini_manager->RemoveContainerStartedObserver(this);
crostini_manager->RemoveContainerShutdownObserver(this);
crostini_manager->RemoveCrostiniMicSharingEnabledObserver(this);
crostini::CrostiniExportImport::GetForProfile(profile_)->RemoveObserver(this);
crostini::CrostiniPortForwarder::GetForProfile(profile_)->RemoveObserver(
this);
adb_sideloading_device_policy_subscription_ = {};
pref_change_registrar_.RemoveAll();
}
void CrostiniHandler::HandleRequestCrostiniInstallerView(
const base::ListValue* args) {
AllowJavascript();
crostini::CrostiniInstaller::GetForProfile(Profile::FromWebUI(web_ui()))
->ShowDialog(crostini::CrostiniUISurface::kSettings);
}
void CrostiniHandler::HandleRequestRemoveCrostini(const base::ListValue* args) {
AllowJavascript();
ShowCrostiniUninstallerView(Profile::FromWebUI(web_ui()),
crostini::CrostiniUISurface::kSettings);
}
namespace {
base::Value CrostiniDiskInfoToValue(
std::unique_ptr<crostini::CrostiniDiskInfo> disk_info) {
base::Value disk_value(base::Value::Type::DICTIONARY);
if (!disk_info) {
disk_value.SetBoolKey("succeeded", false);
return disk_value;
}
disk_value.SetBoolKey("succeeded", true);
disk_value.SetBoolKey("canResize", disk_info->can_resize);
disk_value.SetBoolKey("isUserChosenSize", disk_info->is_user_chosen_size);
disk_value.SetBoolKey("isLowSpaceAvailable",
disk_info->is_low_space_available);
disk_value.SetIntKey("defaultIndex", disk_info->default_index);
base::Value ticks(base::Value::Type::LIST);
for (const auto& tick : disk_info->ticks) {
base::Value t(base::Value::Type::DICTIONARY);
t.SetDoubleKey("value", static_cast<double>(tick->value));
t.SetStringKey("ariaValue", tick->aria_value);
t.SetStringKey("label", tick->label);
ticks.Append(std::move(t));
}
disk_value.SetKey("ticks", std::move(ticks));
return disk_value;
}
} // namespace
void CrostiniHandler::HandleExportCrostiniContainer(
const base::ListValue* args) {
CHECK_EQ(0U, args->GetList().size());
crostini::CrostiniExportImport::GetForProfile(profile_)->ExportContainer(
web_ui()->GetWebContents());
}
void CrostiniHandler::HandleImportCrostiniContainer(
const base::ListValue* args) {
CHECK_EQ(0U, args->GetList().size());
crostini::CrostiniExportImport::GetForProfile(profile_)->ImportContainer(
web_ui()->GetWebContents());
}
void CrostiniHandler::HandleCrostiniInstallerStatusRequest(
const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(0U, args->GetList().size());
bool status = crostini::CrostiniManager::GetForProfile(profile_)
->GetCrostiniDialogStatus(crostini::DialogType::INSTALLER);
OnCrostiniDialogStatusChanged(crostini::DialogType::INSTALLER, status);
}
void CrostiniHandler::HandleCrostiniExportImportOperationStatusRequest(
const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(0U, args->GetList().size());
bool in_progress = crostini::CrostiniExportImport::GetForProfile(profile_)
->GetExportImportOperationStatus();
OnCrostiniExportImportOperationStatusChanged(in_progress);
}
void CrostiniHandler::OnCrostiniDialogStatusChanged(
crostini::DialogType dialog_type,
bool status) {
// It's technically possible for this to be called before Javascript is
// enabled, in which case we must not call FireWebUIListener
if (IsJavascriptAllowed()) {
// Other side listens with cr.addWebUIListener
switch (dialog_type) {
case crostini::DialogType::INSTALLER:
FireWebUIListener("crostini-installer-status-changed",
base::Value(status));
break;
case crostini::DialogType::UPGRADER:
FireWebUIListener("crostini-upgrader-status-changed",
base::Value(status));
break;
case crostini::DialogType::REMOVER:
FireWebUIListener("crostini-remover-status-changed",
base::Value(status));
break;
default:
NOTREACHED();
break;
}
}
}
void CrostiniHandler::OnContainerOsReleaseChanged(
const crostini::ContainerId& container_id,
bool can_upgrade) {
if (crostini::CrostiniFeatures::Get()->IsContainerUpgradeUIAllowed(
profile_) &&
container_id == crostini::DefaultContainerId()) {
FireWebUIListener("crostini-container-upgrade-available-changed",
base::Value(can_upgrade));
}
}
void CrostiniHandler::OnQueryAdbSideload(
SessionManagerClient::AdbSideloadResponseCode response_code,
bool enabled) {
if (response_code != SessionManagerClient::AdbSideloadResponseCode::SUCCESS) {
LOG(ERROR) << "Failed to query adb sideload status";
enabled = false;
}
bool need_powerwash =
response_code ==
SessionManagerClient::AdbSideloadResponseCode::NEED_POWERWASH;
// Other side listens with cr.addWebUIListener
FireWebUIListener("crostini-arc-adb-sideload-status-changed",
base::Value(enabled), base::Value(need_powerwash));
}
void CrostiniHandler::HandleEnableArcAdbRequest(const base::ListValue* args) {
CHECK_EQ(0U, args->GetList().size());
crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(
profile_, base::BindOnce(&CrostiniHandler::OnCanEnableArcAdbSideloading,
weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::OnCanEnableArcAdbSideloading(
bool can_change_adb_sideloading) {
if (!can_change_adb_sideloading)
return;
LogEvent(CrostiniSettingsEvent::kEnableAdbSideloading);
PrefService* prefs = g_browser_process->local_state();
prefs->SetBoolean(prefs::kEnableAdbSideloadingRequested, true);
prefs->CommitPendingWrite();
chrome::AttemptRelaunch();
}
void CrostiniHandler::HandleDisableArcAdbRequest(const base::ListValue* args) {
CHECK_EQ(0U, args->GetList().size());
crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(
profile_, base::BindOnce(&CrostiniHandler::OnCanDisableArcAdbSideloading,
weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::OnCanDisableArcAdbSideloading(
bool can_change_adb_sideloading) {
if (!can_change_adb_sideloading)
return;
LogEvent(CrostiniSettingsEvent::kDisableAdbSideloading);
PrefService* prefs = g_browser_process->local_state();
prefs->SetBoolean(prefs::kFactoryResetRequested, true);
prefs->CommitPendingWrite();
chromeos::PowerManagerClient::Get()->RequestRestart(
power_manager::REQUEST_RESTART_FOR_USER, "disable adb sideloading");
}
void CrostiniHandler::LaunchTerminal() {
crostini::LaunchCrostiniApp(
profile_, crostini::kCrostiniTerminalSystemAppId,
display::Screen::GetScreen()->GetPrimaryDisplay().id());
}
void CrostiniHandler::HandleRequestContainerUpgradeView(
const base::ListValue* args) {
CHECK_EQ(0U, args->GetList().size());
chromeos::CrostiniUpgraderDialog::Show(
profile_,
base::BindOnce(&CrostiniHandler::LaunchTerminal,
weak_ptr_factory_.GetWeakPtr()),
// If the user cancels the upgrade, we won't need to restart Crostini and
// we don't want to run the launch closure which would launch Terminal.
/*only_run_launch_closure_on_restart=*/true);
}
void CrostiniHandler::OnCrostiniExportImportOperationStatusChanged(
bool in_progress) {
// Other side listens with cr.addWebUIListener
FireWebUIListener("crostini-export-import-operation-status-changed",
base::Value(in_progress));
}
void CrostiniHandler::HandleQueryArcAdbRequest(const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(0U, args->GetList().size());
chromeos::SessionManagerClient* client =
chromeos::SessionManagerClient::Get();
client->QueryAdbSideload(base::BindOnce(&CrostiniHandler::OnQueryAdbSideload,
weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::HandleCanChangeArcAdbSideloadingRequest(
const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(0U, args->GetList().size());
FetchCanChangeAdbSideloading();
}
void CrostiniHandler::FetchCanChangeAdbSideloading() {
crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(
profile_, base::BindOnce(&CrostiniHandler::OnCanChangeArcAdbSideloading,
weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::OnCanChangeArcAdbSideloading(
bool can_change_arc_adb_sideloading) {
FireWebUIListener("crostini-can-change-arc-adb-sideload-changed",
base::Value(can_change_arc_adb_sideloading));
}
void CrostiniHandler::HandleCrostiniUpgraderDialogStatusRequest(
const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(0U, args->GetList().size());
bool is_open = crostini::CrostiniManager::GetForProfile(profile_)
->GetCrostiniDialogStatus(crostini::DialogType::UPGRADER);
OnCrostiniDialogStatusChanged(crostini::DialogType::UPGRADER, is_open);
}
void CrostiniHandler::HandleCrostiniContainerUpgradeAvailableRequest(
const base::ListValue* args) {
AllowJavascript();
bool can_upgrade = crostini::ShouldAllowContainerUpgrade(profile_);
OnContainerOsReleaseChanged(crostini::DefaultContainerId(), can_upgrade);
}
void CrostiniHandler::OnActivePortsChanged(const base::ListValue& activePorts) {
// Other side listens with cr.addWebUIListener
FireWebUIListener("crostini-port-forwarder-active-ports-changed",
activePorts);
}
void CrostiniHandler::HandleAddCrostiniPortForward(
const base::ListValue* args) {
CHECK_EQ(6U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
std::string vm_name = args->GetList()[1].GetString();
std::string container_name = args->GetList()[2].GetString();
int port_number = args->GetList()[3].GetInt();
int protocol_type = args->GetList()[4].GetInt();
std::string label = args->GetList()[5].GetString();
if (!crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile_)) {
OnPortForwardComplete(callback_id, false);
return;
}
crostini::CrostiniPortForwarder::GetForProfile(profile_)->AddPort(
crostini::ContainerId(std::move(vm_name), std::move(container_name)),
port_number,
static_cast<crostini::CrostiniPortForwarder::Protocol>(protocol_type),
std::move(label),
base::BindOnce(&CrostiniHandler::OnPortForwardComplete,
weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)));
}
void CrostiniHandler::HandleRemoveCrostiniPortForward(
const base::ListValue* args) {
CHECK_EQ(5U, args->GetSize());
std::string callback_id;
CHECK(args->GetString(0, &callback_id));
std::string vm_name;
CHECK(args->GetString(1, &vm_name));
std::string container_name;
CHECK(args->GetString(2, &container_name));
int port_number;
CHECK(args->GetInteger(3, &port_number));
int protocol_type;
CHECK(args->GetInteger(4, &protocol_type));
if (!crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile_)) {
OnPortForwardComplete(callback_id, false);
return;
}
crostini::CrostiniPortForwarder::GetForProfile(profile_)->RemovePort(
crostini::ContainerId(std::move(vm_name), std::move(container_name)),
port_number,
static_cast<crostini::CrostiniPortForwarder::Protocol>(protocol_type),
base::BindOnce(&CrostiniHandler::OnPortForwardComplete,
weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)));
}
void CrostiniHandler::HandleRemoveAllCrostiniPortForwards(
const base::ListValue* args) {
CHECK_EQ(2U, args->GetSize());
const auto& args_list = args->GetList();
std::string vm_name = args_list[0].GetString();
std::string container_name = args_list[1].GetString();
if (!crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile_)) {
return;
}
crostini::CrostiniPortForwarder::GetForProfile(profile_)->RemoveAllPorts(
crostini::ContainerId(std::move(vm_name), std::move(container_name)));
}
void CrostiniHandler::HandleActivateCrostiniPortForward(
const base::ListValue* args) {
CHECK_EQ(5U, args->GetSize());
std::string callback_id;
CHECK(args->GetString(0, &callback_id));
std::string vm_name;
CHECK(args->GetString(1, &vm_name));
std::string container_name;
CHECK(args->GetString(2, &container_name));
int port_number;
CHECK(args->GetInteger(3, &port_number));
int protocol_type;
CHECK(args->GetInteger(4, &protocol_type));
if (!crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile_)) {
OnPortForwardComplete(callback_id, false);
return;
}
crostini::CrostiniPortForwarder::GetForProfile(profile_)->ActivatePort(
crostini::ContainerId(std::move(vm_name), std::move(container_name)),
port_number,
static_cast<crostini::CrostiniPortForwarder::Protocol>(protocol_type),
base::BindOnce(&CrostiniHandler::OnPortForwardComplete,
weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)));
}
void CrostiniHandler::HandleDeactivateCrostiniPortForward(
const base::ListValue* args) {
CHECK_EQ(5U, args->GetSize());
std::string callback_id;
CHECK(args->GetString(0, &callback_id));
std::string vm_name;
CHECK(args->GetString(1, &vm_name));
std::string container_name;
CHECK(args->GetString(2, &container_name));
int port_number;
CHECK(args->GetInteger(3, &port_number));
int protocol_type;
CHECK(args->GetInteger(4, &protocol_type));
if (!crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile_)) {
OnPortForwardComplete(callback_id, false);
return;
}
crostini::CrostiniPortForwarder::GetForProfile(profile_)->DeactivatePort(
crostini::ContainerId(std::move(vm_name), std::move(container_name)),
port_number,
static_cast<crostini::CrostiniPortForwarder::Protocol>(protocol_type),
base::BindOnce(&CrostiniHandler::OnPortForwardComplete,
weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)));
}
void CrostiniHandler::OnPortForwardComplete(std::string callback_id,
bool success) {
ResolveJavascriptCallback(base::Value(callback_id), base::Value(success));
}
void CrostiniHandler::ResolveGetCrostiniDiskInfoCallback(
const std::string& callback_id,
std::unique_ptr<crostini::CrostiniDiskInfo> disk_info) {
ResolveJavascriptCallback(base::Value(std::move(callback_id)),
CrostiniDiskInfoToValue(std::move(disk_info)));
}
void CrostiniHandler::HandleGetCrostiniDiskInfo(const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(3U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
std::string vm_name = args->GetList()[1].GetString();
bool full_info = args->GetList()[2].GetBool();
crostini::disk::GetDiskInfo(
base::BindOnce(&CrostiniHandler::ResolveGetCrostiniDiskInfoCallback,
weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)),
profile_, std::move(vm_name), full_info);
}
void CrostiniHandler::HandleResizeCrostiniDisk(const base::ListValue* args) {
CHECK_EQ(3U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
std::string vm_name = args->GetList()[1].GetString();
double bytes = args->GetList()[2].GetDouble();
crostini::disk::ResizeCrostiniDisk(
profile_, std::move(vm_name), bytes,
base::BindOnce(&CrostiniHandler::ResolveResizeCrostiniDiskCallback,
weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)));
}
void CrostiniHandler::ResolveResizeCrostiniDiskCallback(
const std::string& callback_id,
bool succeeded) {
ResolveJavascriptCallback(base::Value(std::move(callback_id)),
base::Value(succeeded));
}
void CrostiniHandler::HandleCheckCrostiniMicSharingStatus(
const base::ListValue* args) {
CHECK_EQ(2U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
bool proposed_value = args->GetList()[1].GetBool();
bool requiresRestart =
crostini::IsCrostiniRunning(profile_) &&
crostini::CrostiniManager::GetForProfile(profile_)
->crostini_mic_sharing_enabled() != proposed_value;
ResolveJavascriptCallback(base::Value(std::move(callback_id)),
base::Value(requiresRestart));
}
void CrostiniHandler::HandleGetCrostiniActivePorts(
const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(1U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
ResolveJavascriptCallback(
base::Value(callback_id),
crostini::CrostiniPortForwarder::GetForProfile(profile_)
->GetActivePorts());
}
void CrostiniHandler::HandleCheckCrostiniIsRunning(
const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(1U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
ResolveJavascriptCallback(base::Value(callback_id),
base::Value(crostini::IsCrostiniRunning(profile_)));
}
void CrostiniHandler::OnContainerStarted(
const crostini::ContainerId& container_id) {
FireWebUIListener("crostini-status-changed", base::Value(true));
}
void CrostiniHandler::OnContainerShutdown(
const crostini::ContainerId& container_id) {
FireWebUIListener("crostini-status-changed", base::Value(false));
}
void CrostiniHandler::HandleShutdownCrostini(const base::ListValue* args) {
CHECK_EQ(0U, args->GetList().size());
const std::string vm_name = "termina";
crostini::CrostiniManager::GetForProfile(profile_)->StopVm(
std::move(vm_name), std::move(base::DoNothing()));
}
void CrostiniHandler::OnCrostiniMicSharingEnabledChanged(bool enabled) {
FireWebUIListener("crostini-mic-sharing-enabled-changed",
base::Value(enabled));
}
void CrostiniHandler::HandleSetCrostiniMicSharingEnabled(
const base::ListValue* args) {
CHECK_EQ(1U, args->GetList().size());
bool enabled = args->GetList()[0].GetBool();
crostini::CrostiniManager::GetForProfile(profile_)
->SetCrostiniMicSharingEnabled(enabled);
}
void CrostiniHandler::HandleGetCrostiniMicSharingEnabled(
const base::ListValue* args) {
CHECK_EQ(1U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
ResolveJavascriptCallback(
base::Value(callback_id),
base::Value(crostini::CrostiniManager::GetForProfile(profile_)
->crostini_mic_sharing_enabled()));
}
} // namespace settings
} // namespace chromeos