blob: a44017ed68fc91a41f174db81e97cfec0f24f64b [file] [log] [blame]
// Copyright 2019 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.
#ifndef CHROME_BROWSER_CHROMEOS_PLUGIN_VM_PLUGIN_VM_IMAGE_MANAGER_H_
#define CHROME_BROWSER_CHROMEOS_PLUGIN_VM_PLUGIN_VM_IMAGE_MANAGER_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "chromeos/dbus/concierge/service.pb.h"
#include "chromeos/dbus/concierge_client.h"
#include "components/download/public/background_service/download_params.h"
#include "components/keyed_service/core/keyed_service.h"
namespace download {
class DownloadService;
struct CompletionInfo;
} // namespace download
class Profile;
namespace plugin_vm {
// PluginVmImageManager is responsible for management of PluginVm image
// including downloading this image from url specified by the user policy,
// and importing the downloaded image archive using concierge D-Bus services.
//
// Only one PluginVm image at a time is allowed to be processed.
// Methods StartDownload() and StartImport() should be
// called in this order. Image processing might be interrupted by
// calling the corresponding cancel methods. If one of the methods mentioned is
// called not in the correct order or before the previous state is finished then
// associated fail method will be called by the manager and image processing
// will be interrupted.
class PluginVmImageManager
: public KeyedService,
public chromeos::ConciergeClient::DiskImageObserver {
public:
// Observer class for the PluginVm image related events.
class Observer {
public:
virtual ~Observer() = default;
virtual void OnDownloadStarted() = 0;
virtual void OnDownloadProgressUpdated(uint64_t bytes_downloaded,
int64_t content_length,
base::TimeDelta elapsed_time) = 0;
virtual void OnDownloadCompleted() = 0;
virtual void OnDownloadCancelled() = 0;
// TODO(https://crbug.com/904851): Add failure reasons.
virtual void OnDownloadFailed() = 0;
virtual void OnImportProgressUpdated(int percent_completed,
base::TimeDelta elapsed_time) = 0;
virtual void OnImported() = 0;
virtual void OnImportCancelled() = 0;
virtual void OnImportFailed() = 0;
};
explicit PluginVmImageManager(Profile* profile);
// Returns true if manager is processing PluginVm image at the moment.
bool IsProcessingImage();
void StartDownload();
// Cancels the download of PluginVm image finishing the image processing.
// Downloaded PluginVm image archive is being deleted.
void CancelDownload();
// Proceed with importing (unzipping and registering) of the VM image.
// Should be called when download of PluginVm image is successfully completed.
// If called in other cases - importing is not started and
// OnImported(false /* success */) is called.
void StartImport();
// Makes a call to concierge to cancel the import.
void CancelImport();
void SetObserver(Observer* observer);
void RemoveObserver();
// Called by PluginVmImageDownloadClient, are not supposed to be used by other
// classes.
void OnDownloadStarted();
void OnDownloadProgressUpdated(uint64_t bytes_downloaded,
int64_t content_length);
void OnDownloadCompleted(const download::CompletionInfo& info);
void OnDownloadCancelled();
void OnDownloadFailed();
// ConciergeClient::DiskImageObserver:
void OnDiskImageProgress(
const vm_tools::concierge::DiskImageStatusResponse& signal) override;
// Helper function that returns true in case downloaded PluginVm image
// archive passes hash verification and false otherwise.
// Public for testing purposes.
bool VerifyDownload(const std::string& downloaded_archive_hash);
void SetDownloadServiceForTesting(
download::DownloadService* download_service);
void SetDownloadedPluginVmImageArchiveForTesting(
const base::FilePath& downloaded_plugin_vm_image_archive);
std::string GetCurrentDownloadGuidForTesting();
private:
enum class State {
NOT_STARTED,
DOWNLOADING,
DOWNLOAD_CANCELLED,
DOWNLOADED,
IMPORTING,
IMPORT_CANCELLED,
CONFIGURED,
DOWNLOAD_FAILED,
IMPORT_FAILED,
};
Profile* profile_ = nullptr;
Observer* observer_ = nullptr;
download::DownloadService* download_service_ = nullptr;
State state_ = State::NOT_STARTED;
std::string current_download_guid_;
base::FilePath downloaded_plugin_vm_image_archive_;
// Used to identify our running import with concierge:
std::string current_import_command_uuid_;
// -1 when is not yet determined.
int64_t downloaded_plugin_vm_image_size_ = -1;
base::TimeTicks download_start_tick_;
base::TimeTicks import_start_tick_;
~PluginVmImageManager() override;
// Get string representation of state for logging purposes.
std::string GetStateName(State state);
GURL GetPluginVmImageDownloadUrl();
download::DownloadParams GetDownloadParams(const GURL& url);
void OnStartDownload(const std::string& download_guid,
download::DownloadParams::StartResult start_result);
// Callback when PluginVm dispatcher is started (together with supporting
// services such as concierge). This will then make the call to concierge's
// ImportDiskImage.
void OnPluginVmDispatcherStarted(bool success);
// Callback which is called once we know if concierge is available.
void OnConciergeAvailable(bool success);
// Ran as a blocking task preparing the FD for the ImportDiskImage call.
base::Optional<base::ScopedFD> PrepareFD();
// Callback when the FD is prepared. Makes the call to ImportDiskImage.
void OnFDPrepared(base::Optional<base::ScopedFD> maybeFd);
// Callback for the concierge DiskImageImport call.
void OnImportDiskImage(
base::Optional<vm_tools::concierge::ImportDiskImageResponse> reply);
// After we get a signal that the import is finished successfully, we
// make one final call to concierge's DiskImageStatus method to get a
// final resolution.
void RequestFinalStatus();
// Callback for the final call to concierge's DiskImageStatus to
// get the final result of the disk import operation. This moves
// the manager to a finishing state, depending on the result of the
// query. Called when the signal for the command indicates that we
// are done with importing.
void OnFinalDiskImageStatus(
base::Optional<vm_tools::concierge::DiskImageStatusResponse> reply);
// Finishes the processing of PluginVm image.
void OnImported(bool success);
// Callback for the concierge CancelDiskImageOperation call.
void OnImportDiskImageCancelled(
base::Optional<vm_tools::concierge::CancelDiskImageResponse> reply);
void RemoveTemporaryPluginVmImageArchiveIfExists();
void OnTemporaryPluginVmImageArchiveRemoved(bool success);
base::WeakPtrFactory<PluginVmImageManager> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(PluginVmImageManager);
};
} // namespace plugin_vm
#endif // CHROME_BROWSER_CHROMEOS_PLUGIN_VM_PLUGIN_VM_IMAGE_MANAGER_H_