blob: 46cba5abc6ab4b9c872aab57a0c5084cad17bc27 [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 "components/download/public/background_service/download_params.h"
#include "components/keyed_service/core/keyed_service.h"
#include "third_party/zlib/google/zip_reader.h"
namespace base {
template <typename T>
class Optional;
} // namespace base
namespace download {
class DownloadService;
} // namespace download
class Profile;
namespace plugin_vm {
constexpr char kCrosvmDir[] = "crosvm";
constexpr char kPvmDir[] = "pvm";
constexpr char kPluginVmImageDir[] = "default";
// PluginVmImageManager is responsible for management of PluginVm image
// including downloading this image from url specified by user policy and
// unzipping downloaded image archive to the specified location.
//
// Only one PluginVm image at a time is allowed to be processed.
// IsProcessingImage() should be called to check whether any image is being
// processed at the moment.
class PluginVmImageManager : public KeyedService {
public:
// Observer class for the PluginVm image related events.
class Observer {
public:
virtual ~Observer() = default;
virtual void OnDownloadStarted() = 0;
virtual void OnProgressUpdated(
base::Optional<double> fraction_complete) = 0;
virtual void OnDownloadCompleted() = 0;
virtual void OnDownloadCancelled() = 0;
// TODO(https://crbug.com/904851): Add failure reasons.
virtual void OnDownloadFailed() = 0;
virtual void OnUnzipped() = 0;
virtual void OnUnzippingFailed() = 0;
};
explicit PluginVmImageManager(Profile* profile);
// Returns true if manager is processing PluginVm image at the moment.
bool IsProcessingImage();
// Doesn't start to download PluginVm image and calls OnDownloadFailed() in
// case IsProcessingImage() returns true otherwise starts processing PluginVm
// image by downloading it.
void StartDownload();
// Cancels the download of PluginVm image finishing the image processing.
// Downloaded PluginVm image archive is being deleted.
void CancelDownload();
// Should be called when download of PluginVm image has been completed
// successfully. If called in other cases - unzipping is not started
// and OnUnzipped(false /* success */) is called.
void StartUnzipping();
// Sets flag that indicates that unzipping is cancelled. This flag is further
// checked in PluginVmImageWriterDelegate and in cases it is set to true
// OnUnzipped(false /* success */) called.
void CancelUnzipping();
void SetObserver(Observer* observer);
void RemoveObserver();
// Called by PluginVmImageDownloadClient.
void OnDownloadStarted();
void OnProgressUpdated(base::Optional<double> fraction_complete);
void OnDownloadCompleted(base::FilePath file_path);
void OnDownloadCancelled();
void OnDownloadFailed();
// Finishes the processing of PluginVm image. Deletes downloaded PluginVm
// image archive. In case |success| is false also deletes PluginVm image.
void OnUnzipped(bool success);
void SetDownloadServiceForTesting(
download::DownloadService* download_service);
void SetDownloadedPluginVmImageArchiveForTesting(
base::FilePath downloaded_plugin_vm_image_archive);
std::string GetCurrentDownloadGuidForTesting();
private:
Profile* profile_ = nullptr;
Observer* observer_ = nullptr;
download::DownloadService* download_service_ = nullptr;
bool processing_image_ = false;
bool unzipping_cancelled_ = false;
std::string current_download_guid_;
base::FilePath downloaded_plugin_vm_image_archive_;
base::FilePath plugin_vm_image_dir_;
class PluginVmImageWriterDelegate : public zip::WriterDelegate {
public:
explicit PluginVmImageWriterDelegate(
PluginVmImageManager* manager,
const base::FilePath& output_file_path);
// zip::WriterDelegate implementation.
bool PrepareOutput() override;
// If unzipping is cancelled returns false so unzipping would fail.
bool WriteBytes(const char* data, int num_bytes) override;
void SetTimeModified(const base::Time& time) override;
private:
PluginVmImageManager* manager_;
base::FilePath output_file_path_;
base::File output_file_;
DISALLOW_COPY_AND_ASSIGN(PluginVmImageWriterDelegate);
};
~PluginVmImageManager() override;
GURL GetPluginVmImageDownloadUrl();
download::DownloadParams GetDownloadParams(const GURL& url);
void OnStartDownload(const std::string& download_guid,
download::DownloadParams::StartResult start_result);
bool IsDownloading();
// Returns true in case downloaded PluginVm image archive passes verification
// and false otherwise.
bool VerifyDownload(std::string downloaded_archive_hash);
bool UnzipDownloadedPluginVmImageArchive();
bool IsUnzippingCancelled();
// Callback arguments for unzipping function.
std::unique_ptr<zip::WriterDelegate> CreatePluginVmImageWriterDelegate(
const base::FilePath& entry_path);
bool CreateDirectory(const base::FilePath& entry_path);
bool FilterFilesInPluginVmImageArchive(const base::FilePath& file);
bool EnsureDownloadedPluginVmImageArchiveIsPresent();
// Creates directory for PluginVm image if one doesn't exists.
// Returns true in case directory has already existed or was successfully
// created and false otherwise.
bool EnsureDirectoryForPluginVmImageIsPresent();
void RemoveTemporaryPluginVmImageArchiveIfExists();
void OnTemporaryPluginVmImageArchiveRemoved(bool success);
void RemovePluginVmImageDirectoryIfExists();
void OnPluginVmImageDirectoryRemoved(bool success);
base::WeakPtrFactory<PluginVmImageManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PluginVmImageManager);
};
} // namespace plugin_vm
#endif // CHROME_BROWSER_CHROMEOS_PLUGIN_VM_PLUGIN_VM_IMAGE_MANAGER_H_