Commit 756b7be7 authored by Olya Kalitova's avatar Olya Kalitova Committed by Commit Bot

Add progress reporting for unzipping of downloaded PluginVm image

Add progress reporting for unzipping of downloaded PluginVm image
archive.
This CL also changes signature of OnProgressUpdated method so this
method is consistent with the new OnUnzippingProgressUpdated method and
not only fraction complete could be reported, but the number of bytes
processed as well.

Test: unit_tests --gtest_filter="PluginVmImageManager*"
Bug: 904851
Change-Id: I66333f3e31ee339673889e39fab7c5da59303142
Reviewed-on: https://chromium-review.googlesource.com/c/1484097
Commit-Queue: Olya Kalitova <okalitova@chromium.org>
Reviewed-by: default avatarIgor <igorcov@chromium.org>
Reviewed-by: default avatarTimothy Loh <timloh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635584}
parent fcffa40b
......@@ -5,7 +5,6 @@
#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.h"
#include "base/bind.h"
#include "base/optional.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h"
#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.h"
......@@ -58,7 +57,7 @@ void PluginVmImageDownloadClient::OnDownloadUpdated(const std::string& guid,
uint64_t bytes_downloaded) {
VLOG(1) << __func__ << " called";
VLOG(1) << bytes_downloaded << " bytes downloaded";
GetManager()->OnProgressUpdated(GetFractionComplete(bytes_downloaded));
GetManager()->OnDownloadProgressUpdated(bytes_downloaded, content_length_);
}
void PluginVmImageDownloadClient::OnDownloadFailed(
......@@ -116,14 +115,4 @@ void PluginVmImageDownloadClient::GetUploadData(
FROM_HERE, base::BindOnce(std::move(callback), nullptr));
}
base::Optional<double> PluginVmImageDownloadClient::GetFractionComplete(
int64_t bytes_downloaded) {
if (content_length_ == -1 || content_length_ == 0)
return base::nullopt;
if (bytes_downloaded > content_length_)
return base::nullopt;
return base::make_optional(static_cast<double>(bytes_downloaded) /
content_length_);
}
} // namespace plugin_vm
......@@ -11,7 +11,6 @@
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/guid.h"
#include "base/optional.h"
#include "base/strings/string_util.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
......@@ -21,6 +20,8 @@
#include "components/download/public/background_service/download_metadata.h"
#include "components/download/public/background_service/download_service.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "third_party/zlib/google/zip.h"
......@@ -83,10 +84,10 @@ void PluginVmImageManager::OnDownloadStarted() {
observer_->OnDownloadStarted();
}
void PluginVmImageManager::OnProgressUpdated(
base::Optional<double> fraction_complete) {
void PluginVmImageManager::OnDownloadProgressUpdated(uint64_t bytes_downloaded,
int64_t content_length) {
if (observer_)
observer_->OnProgressUpdated(fraction_complete);
observer_->OnDownloadProgressUpdated(bytes_downloaded, content_length);
}
void PluginVmImageManager::OnDownloadCompleted(
......@@ -121,6 +122,32 @@ void PluginVmImageManager::OnDownloadFailed() {
observer_->OnDownloadFailed();
}
void PluginVmImageManager::OnUnzippingProgressUpdated(int new_unzipped_bytes) {
plugin_vm_image_bytes_unzipped_ += new_unzipped_bytes;
if (observer_)
observer_->OnUnzippingProgressUpdated(plugin_vm_image_bytes_unzipped_,
plugin_vm_image_size_);
}
void PluginVmImageManager::OnUnzipped(bool success) {
unzipping_cancelled_ = false;
plugin_vm_image_size_ = -1;
plugin_vm_image_bytes_unzipped_ = 0;
RemoveTemporaryPluginVmImageArchiveIfExists();
if (!success) {
if (observer_)
observer_->OnUnzippingFailed();
RemovePluginVmImageDirectoryIfExists();
processing_image_ = false;
return;
}
if (observer_)
observer_->OnUnzipped();
processing_image_ = false;
// TODO(okalitova): Populate necessary preferences with information about
// PluginVm image that has been successfully downloaded and extracted.
}
void PluginVmImageManager::SetDownloadServiceForTesting(
download::DownloadService* download_service) {
download_service_ = download_service;
......@@ -223,6 +250,32 @@ bool PluginVmImageManager::VerifyDownload(
downloaded_archive_hash);
}
void PluginVmImageManager::CalculatePluginVmImageSize() {
plugin_vm_image_size_ = 0;
zip::ZipReader reader;
if (!reader.Open(downloaded_plugin_vm_image_archive_)) {
LOG(ERROR) << downloaded_plugin_vm_image_archive_.value()
<< " cannot be opened by ZipReader";
plugin_vm_image_size_ = -1;
return;
}
while (reader.HasMore()) {
if (!reader.OpenCurrentEntryInZip()) {
LOG(ERROR) << "One of zip entries cannot be opened";
plugin_vm_image_size_ = -1;
return;
}
plugin_vm_image_size_ += reader.current_entry_info()->original_size();
if (!reader.AdvanceToNextEntry()) {
LOG(ERROR) << "ZipReader failed to advance to the next entry";
plugin_vm_image_size_ = -1;
return;
}
}
}
bool PluginVmImageManager::UnzipDownloadedPluginVmImageArchive() {
if (!EnsureDirectoryForPluginVmImageIsPresent() ||
!EnsureDownloadedPluginVmImageArchiveIsPresent()) {
......@@ -230,6 +283,8 @@ bool PluginVmImageManager::UnzipDownloadedPluginVmImageArchive() {
return false;
}
CalculatePluginVmImageSize();
base::File file(downloaded_plugin_vm_image_archive_,
base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!file.IsValid()) {
......@@ -238,6 +293,7 @@ bool PluginVmImageManager::UnzipDownloadedPluginVmImageArchive() {
return false;
}
plugin_vm_image_bytes_unzipped_ = 0;
bool success = zip::UnzipWithFilterAndWriters(
file.GetPlatformFile(),
base::BindRepeating(
......@@ -275,8 +331,14 @@ bool PluginVmImageManager::PluginVmImageWriterDelegate::PrepareOutput() {
bool PluginVmImageManager::PluginVmImageWriterDelegate::WriteBytes(
const char* data,
int num_bytes) {
return !manager_->IsUnzippingCancelled() &&
num_bytes == output_file_.WriteAtCurrentPos(data, num_bytes);
bool success = num_bytes == output_file_.WriteAtCurrentPos(data, num_bytes);
if (success) {
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&PluginVmImageManager::OnUnzippingProgressUpdated,
base::Unretained(manager_), num_bytes));
}
return !manager_->IsUnzippingCancelled() && success;
}
void PluginVmImageManager::PluginVmImageWriterDelegate::SetTimeModified(
......@@ -301,23 +363,6 @@ bool PluginVmImageManager::FilterFilesInPluginVmImageArchive(
return true;
}
void PluginVmImageManager::OnUnzipped(bool success) {
unzipping_cancelled_ = false;
RemoveTemporaryPluginVmImageArchiveIfExists();
if (!success) {
if (observer_)
observer_->OnUnzippingFailed();
RemovePluginVmImageDirectoryIfExists();
processing_image_ = false;
return;
}
if (observer_)
observer_->OnUnzipped();
processing_image_ = false;
// TODO(okalitova): Populate necessary preferences with information about
// PluginVm image that has been successfully downloaded and extracted.
}
bool PluginVmImageManager::EnsureDownloadedPluginVmImageArchiveIsPresent() {
return !downloaded_plugin_vm_image_archive_.empty();
}
......
......@@ -14,11 +14,6 @@
#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;
struct CompletionInfo;
......@@ -46,12 +41,14 @@ class PluginVmImageManager : public KeyedService {
public:
virtual ~Observer() = default;
virtual void OnDownloadStarted() = 0;
virtual void OnProgressUpdated(
base::Optional<double> fraction_complete) = 0;
virtual void OnDownloadProgressUpdated(uint64_t bytes_downloaded,
int64_t content_length) = 0;
virtual void OnDownloadCompleted() = 0;
virtual void OnDownloadCancelled() = 0;
// TODO(https://crbug.com/904851): Add failure reasons.
virtual void OnDownloadFailed() = 0;
virtual void OnUnzippingProgressUpdated(int64_t bytes_unzipped,
int64_t plugin_vm_image_size) = 0;
virtual void OnUnzipped() = 0;
virtual void OnUnzippingFailed() = 0;
};
......@@ -82,11 +79,13 @@ class PluginVmImageManager : public KeyedService {
// Called by PluginVmImageDownloadClient.
void OnDownloadStarted();
void OnProgressUpdated(base::Optional<double> fraction_complete);
void OnDownloadProgressUpdated(uint64_t bytes_downloaded,
int64_t content_length);
void OnDownloadCompleted(const download::CompletionInfo& info);
void OnDownloadCancelled();
void OnDownloadFailed();
void OnUnzippingProgressUpdated(int new_bytes_unzipped);
// Finishes the processing of PluginVm image. Deletes downloaded PluginVm
// image archive. In case |success| is false also deletes PluginVm image.
void OnUnzipped(bool success);
......@@ -110,6 +109,9 @@ class PluginVmImageManager : public KeyedService {
std::string current_download_guid_;
base::FilePath downloaded_plugin_vm_image_archive_;
base::FilePath plugin_vm_image_dir_;
// -1 when is not yet determined.
int64_t plugin_vm_image_size_ = -1;
int64_t plugin_vm_image_bytes_unzipped_ = 0;
class PluginVmImageWriterDelegate : public zip::WriterDelegate {
public:
......@@ -140,6 +142,7 @@ class PluginVmImageManager : public KeyedService {
download::DownloadParams::StartResult start_result);
bool IsDownloading();
void CalculatePluginVmImageSize();
bool UnzipDownloadedPluginVmImageArchive();
bool IsUnzippingCancelled();
// Callback arguments for unzipping function.
......
......@@ -39,19 +39,24 @@ const char kHash2[] =
const char kPluginVmImageUnzipped[] = "plugin_vm_image_unzipped";
const char kPluginVmImageFile1[] = "plugin_vm_image_file_1";
const char kContent1[] = "This is content #1.";
const int kContent1Size = strlen(kContent1);
const char kPluginVmImageFile2[] = "plugin_vm_image_file_2";
const char kContent2[] = "This is content #2.";
const int kContent2Size = strlen(kContent2);
const int kContentSize = kContent1Size + kContent2Size;
} // namespace
class MockObserver : public PluginVmImageManager::Observer {
public:
MOCK_METHOD0(OnDownloadStarted, void());
MOCK_METHOD1(OnProgressUpdated,
void(base::Optional<double> fraction_complete));
MOCK_METHOD2(OnDownloadProgressUpdated,
void(uint64_t bytes_downloaded, int64_t content_length));
MOCK_METHOD0(OnDownloadCompleted, void());
MOCK_METHOD0(OnDownloadCancelled, void());
MOCK_METHOD0(OnDownloadFailed, void());
MOCK_METHOD2(OnUnzippingProgressUpdated,
void(int64_t unzipped_bytes, int64_t plugin_vm_image_size));
MOCK_METHOD0(OnUnzipped, void());
MOCK_METHOD0(OnUnzippingFailed, void());
};
......@@ -148,6 +153,10 @@ class PluginVmImageManagerTest : public testing::Test {
TEST_F(PluginVmImageManagerTest, DownloadPluginVmImageParamsTest) {
EXPECT_CALL(*download_observer_, OnDownloadCompleted());
EXPECT_CALL(*download_observer_,
OnUnzippingProgressUpdated(kContent1Size, kContentSize));
EXPECT_CALL(*download_observer_,
OnUnzippingProgressUpdated(kContentSize, kContentSize));
EXPECT_CALL(*download_observer_, OnUnzipped());
manager_->StartDownload();
......@@ -171,6 +180,10 @@ TEST_F(PluginVmImageManagerTest, DownloadPluginVmImageParamsTest) {
TEST_F(PluginVmImageManagerTest, OnlyOneImageIsProcessedTest) {
EXPECT_CALL(*download_observer_, OnDownloadCompleted());
EXPECT_CALL(*download_observer_,
OnUnzippingProgressUpdated(kContent1Size, kContentSize));
EXPECT_CALL(*download_observer_,
OnUnzippingProgressUpdated(kContentSize, kContentSize));
EXPECT_CALL(*download_observer_, OnUnzipped());
manager_->StartDownload();
......@@ -191,6 +204,12 @@ TEST_F(PluginVmImageManagerTest, OnlyOneImageIsProcessedTest) {
TEST_F(PluginVmImageManagerTest, CanProceedWithANewImageWhenSucceededTest) {
EXPECT_CALL(*download_observer_, OnDownloadCompleted()).Times(2);
EXPECT_CALL(*download_observer_,
OnUnzippingProgressUpdated(kContent1Size, kContentSize))
.Times(2);
EXPECT_CALL(*download_observer_,
OnUnzippingProgressUpdated(kContentSize, kContentSize))
.Times(2);
EXPECT_CALL(*download_observer_, OnUnzipped()).Times(2);
ProcessImage();
......@@ -205,6 +224,10 @@ TEST_F(PluginVmImageManagerTest, CanProceedWithANewImageWhenSucceededTest) {
TEST_F(PluginVmImageManagerTest, CanProceedWithANewImageWhenFailedTest) {
EXPECT_CALL(*download_observer_, OnDownloadFailed());
EXPECT_CALL(*download_observer_, OnDownloadCompleted());
EXPECT_CALL(*download_observer_,
OnUnzippingProgressUpdated(kContent1Size, kContentSize));
EXPECT_CALL(*download_observer_,
OnUnzippingProgressUpdated(kContentSize, kContentSize));
EXPECT_CALL(*download_observer_, OnUnzipped());
manager_->StartDownload();
......@@ -230,6 +253,10 @@ TEST_F(PluginVmImageManagerTest, CancelledDownloadTest) {
TEST_F(PluginVmImageManagerTest, UnzipDownloadedImageTest) {
EXPECT_CALL(*download_observer_, OnDownloadCompleted());
EXPECT_CALL(*download_observer_,
OnUnzippingProgressUpdated(kContent1Size, kContentSize));
EXPECT_CALL(*download_observer_,
OnUnzippingProgressUpdated(kContentSize, kContentSize));
EXPECT_CALL(*download_observer_, OnUnzipped());
ProcessImage();
......
......@@ -6,6 +6,7 @@
#include <memory>
#include "base/optional.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager.h"
#include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_manager_factory.h"
......@@ -28,6 +29,17 @@ namespace {
PluginVmLauncherView* g_plugin_vm_launcher_view = nullptr;
base::Optional<double> GetFractionComplete(int64_t bytes_processed,
int64_t bytes_to_be_processed) {
if (bytes_to_be_processed == -1 || bytes_to_be_processed == 0)
return base::nullopt;
double fraction_complete =
static_cast<double>(bytes_processed) / bytes_to_be_processed;
if (fraction_complete < 0.0 || fraction_complete > 1.0)
return base::nullopt;
return base::make_optional(fraction_complete);
}
} // namespace
void plugin_vm::ShowPluginVmLauncherView(Profile* profile) {
......@@ -153,9 +165,12 @@ PluginVmLauncherView::~PluginVmLauncherView() {
void PluginVmLauncherView::OnDownloadStarted() {}
void PluginVmLauncherView::OnProgressUpdated(
base::Optional<double> fraction_complete) {
void PluginVmLauncherView::OnDownloadProgressUpdated(uint64_t bytes_downloaded,
int64_t content_length) {
DCHECK_EQ(state_, State::DOWNLOADING);
base::Optional<double> fraction_complete =
GetFractionComplete(bytes_downloaded, content_length);
if (fraction_complete.has_value())
progress_bar_->SetValue(fraction_complete.value());
else
......@@ -177,6 +192,18 @@ void PluginVmLauncherView::OnDownloadFailed() {
OnStateUpdated();
}
void PluginVmLauncherView::OnUnzippingProgressUpdated(
int64_t bytes_unzipped,
int64_t plugin_vm_image_size) {
DCHECK_EQ(state_, State::UNZIPPING);
base::Optional<double> fraction_complete =
GetFractionComplete(bytes_unzipped, plugin_vm_image_size);
if (fraction_complete.has_value())
progress_bar_->SetValue(fraction_complete.value());
else
progress_bar_->SetValue(-1);
}
void PluginVmLauncherView::OnUnzipped() {
DCHECK_EQ(state_, State::UNZIPPING);
state_ = State::FINISHED;
......
......@@ -36,10 +36,13 @@ class PluginVmLauncherView : public views::BubbleDialogDelegateView,
// plugin_vm::PluginVmImageDownloadObserver implementation.
void OnDownloadStarted() override;
void OnProgressUpdated(base::Optional<double> fraction_complete) override;
void OnDownloadProgressUpdated(uint64_t bytes_downloaded,
int64_t content_length) override;
void OnDownloadCompleted() override;
void OnDownloadCancelled() override;
void OnDownloadFailed() override;
void OnUnzippingProgressUpdated(int64_t bytes_unzipped,
int64_t plugin_vm_image_size) override;
void OnUnzipped() override;
void OnUnzippingFailed() override;
......
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