Commit a1ea0d7a authored by Timothy Loh's avatar Timothy Loh Committed by Commit Bot

Make Plugin VM installer check for existing VM

The Plugin VM installer currently fails if a VM already exists. This can
happen if the user manually sets up a VM via vmc. This CL updates the
installer so that it first checks whether a VM exists, and proceeds to
the finished state immediately if so.

Bug: 1038816
Change-Id: I19381288c7fd2f2beaa82ffdb72ae5102d1f4c0d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2014203
Commit-Queue: Timothy Loh <timloh@chromium.org>
Reviewed-by: default avatarJulian Watson <juwa@google.com>
Cr-Commit-Position: refs/heads/master@{#733911}
parent 57093a57
......@@ -69,7 +69,13 @@ void PluginVmInstaller::Start() {
return;
}
StartDlcDownload();
// If there's an existing VM, we can complete without running the install
// flow.
PluginVmManager::GetForProfile(profile_)->UpdateVmState(
base::BindOnce(&PluginVmInstaller::OnUpdateVmState,
weak_ptr_factory_.GetWeakPtr()),
base::BindOnce(&PluginVmInstaller::StartDlcDownload,
weak_ptr_factory_.GetWeakPtr()));
}
void PluginVmInstaller::Cancel() {
......@@ -90,6 +96,18 @@ void PluginVmInstaller::Cancel() {
}
}
void PluginVmInstaller::OnUpdateVmState(bool default_vm_exists) {
if (default_vm_exists) {
if (observer_)
observer_->OnVmExists();
profile_->GetPrefs()->SetBoolean(plugin_vm::prefs::kPluginVmImageExists,
true);
state_ = State::CONFIGURED;
return;
}
StartDlcDownload();
}
void PluginVmInstaller::StartDlcDownload() {
state_ = State::DOWNLOADING_DLC;
dlc_download_start_tick_ = base::TimeTicks::Now();
......
......@@ -66,6 +66,10 @@ class PluginVmInstaller : public KeyedService,
class Observer {
public:
virtual ~Observer() = default;
// If a VM already exists, we call this and abort the installation process.
virtual void OnVmExists() = 0;
virtual void OnDlcDownloadProgressUpdated(double progress,
base::TimeDelta elapsed_time) = 0;
virtual void OnDlcDownloadCompleted() = 0;
......@@ -129,6 +133,7 @@ class PluginVmInstaller : public KeyedService,
std::string GetCurrentDownloadGuidForTesting();
private:
void OnUpdateVmState(bool default_vm_exists);
void StartDlcDownload();
void StartDownload();
void StartImport();
......
......@@ -29,6 +29,7 @@
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/dlcservice/fake_dlcservice_client.h"
#include "chromeos/dbus/fake_concierge_client.h"
#include "chromeos/dbus/fake_vm_plugin_dispatcher_client.h"
#include "components/account_id/account_id.h"
#include "components/download/public/background_service/test/test_download_service.h"
#include "components/drive/service/dummy_drive_service.h"
......@@ -70,6 +71,7 @@ const int kDownloadedPluginVmImageSizeInMb = 123456789u / (1024 * 1024);
class MockObserver : public PluginVmInstaller::Observer {
public:
MOCK_METHOD0(OnVmExists, void());
MOCK_METHOD2(OnDlcDownloadProgressUpdated,
void(double progress, base::TimeDelta elapsed_time));
MOCK_METHOD0(OnDlcDownloadCompleted, void());
......@@ -380,6 +382,19 @@ class PluginVmInstallerDriveTest : public PluginVmInstallerTestBase {
DISALLOW_COPY_AND_ASSIGN(PluginVmInstallerDriveTest);
};
TEST_F(PluginVmInstallerDownloadServiceTest, VmExists) {
vm_tools::plugin_dispatcher::ListVmResponse list_vms_response;
list_vms_response.add_vm_info()->set_state(
vm_tools::plugin_dispatcher::VmState::VM_STATE_STOPPED);
static_cast<chromeos::FakeVmPluginDispatcherClient*>(
chromeos::DBusThreadManager::Get()->GetVmPluginDispatcherClient())
->set_list_vms_response(list_vms_response);
EXPECT_CALL(*observer_, OnVmExists());
EXPECT_CALL(*observer_, OnDlcDownloadCompleted()).Times(0);
StartAndRunToCompletion();
}
TEST_F(PluginVmInstallerDownloadServiceTest, DownloadPluginVmImageParamsTest) {
SetupConciergeForSuccessfulDiskImageImport(fake_concierge_client_);
......
......@@ -44,7 +44,9 @@ enum class PluginVmSetupResult {
kErrorDownloadingPluginVmDlc = 6,
kUserCancelledDownloadingPluginVmDlc = 7,
kMaxValue = kUserCancelledDownloadingPluginVmDlc,
kVmAlreadyExists = 8,
kMaxValue = kVmAlreadyExists,
};
enum class PluginVmDlcUseResult {
......
......@@ -222,6 +222,19 @@ gfx::Size PluginVmInstallerView::CalculatePreferredSize() const {
return gfx::Size(kWindowWidth, kWindowHeight);
}
void PluginVmInstallerView::OnVmExists() {
// This case should only occur if the user manually installed a VM via vmc,
// which is rare enough so we just re-use the regular success strings.
DCHECK_EQ(state_, State::DOWNLOADING_DLC);
state_ = State::FINISHED;
OnStateUpdated();
plugin_vm::RecordPluginVmSetupResultHistogram(
plugin_vm::PluginVmSetupResult::kVmAlreadyExists);
plugin_vm::RecordPluginVmSetupTimeHistogram(base::TimeTicks::Now() -
setup_start_tick_);
}
void PluginVmInstallerView::OnDlcDownloadProgressUpdated(
double progress,
base::TimeDelta elapsed_time) {
......
......@@ -33,6 +33,7 @@ class PluginVmInstallerView : public views::BubbleDialogDelegateView,
gfx::Size CalculatePreferredSize() const override;
// plugin_vm::PluginVmImageDownload::Observer implementation.
void OnVmExists() override;
void OnDlcDownloadProgressUpdated(double progress,
base::TimeDelta elapsed_time) override;
void OnDlcDownloadCompleted() override;
......
......@@ -50768,6 +50768,7 @@ Called by update_net_trust_anchors.py.-->
<int value="5" label="User cancelled setup while importing Plugin VM image"/>
<int value="6" label="Error while downloading Plugin VM DLC"/>
<int value="7" label="User cancelled setup while downloading Plugin VM DLC"/>
<int value="8" label="Plugin VM was already installed"/>
</enum>
<enum name="PNaClOptionsOptLevelEnum">
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment