blob: 69eedbe5384726dfee9847969d97f7264dde6c4e [file] [log] [blame]
[email protected]3d78cbe2014-02-27 13:19:301// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]4e100e82014-06-18 23:47:295#include "chrome/utility/image_writer/image_writer_handler.h"
6
noel6b03ae82017-02-09 15:28:177#include "base/bind.h"
[email protected]3d78cbe2014-02-27 13:19:308#include "base/files/file_path.h"
noel6b03ae82017-02-09 15:28:179#include "base/optional.h"
Ken Rockot2ad4db32018-02-10 16:24:1010#include "chrome/services/removable_storage_writer/public/mojom/removable_storage_writer.mojom.h"
[email protected]3d78cbe2014-02-27 13:19:3011#include "chrome/utility/image_writer/error_messages.h"
noel6b03ae82017-02-09 15:28:1712
13namespace {
14
15bool IsTestDevice(const base::FilePath& device) {
16 return device.AsUTF8Unsafe() ==
Jay Civelli66e0d892017-12-05 01:05:1017 chrome::mojom::RemovableStorageWriter::kTestDevice;
noel6b03ae82017-02-09 15:28:1718}
19
20base::FilePath MakeTestDevicePath(const base::FilePath& image) {
21 return image.ReplaceExtension(FILE_PATH_LITERAL("out"));
22}
23
24} // namespace
[email protected]3d78cbe2014-02-27 13:19:3025
[email protected]3d78cbe2014-02-27 13:19:3026namespace image_writer {
27
noel6b03ae82017-02-09 15:28:1728ImageWriterHandler::ImageWriterHandler() = default;
[email protected]3d78cbe2014-02-27 13:19:3029
noel6b03ae82017-02-09 15:28:1730ImageWriterHandler::~ImageWriterHandler() = default;
[email protected]3d78cbe2014-02-27 13:19:3031
noel6b03ae82017-02-09 15:28:1732void ImageWriterHandler::Write(
33 const base::FilePath& image,
34 const base::FilePath& device,
Jay Civelli66e0d892017-12-05 01:05:1035 chrome::mojom::RemovableStorageWriterClientPtr client) {
noel6b03ae82017-02-09 15:28:1736 client_ = std::move(client);
37 client_.set_connection_error_handler(
tzikf7d48c73ac2017-06-26 09:27:0438 base::BindOnce(&ImageWriterHandler::Cancel, base::Unretained(this)));
[email protected]3d78cbe2014-02-27 13:19:3039
noel6b03ae82017-02-09 15:28:1740 base::FilePath target_device = device;
41 const bool test_mode = IsTestDevice(device);
42 if (test_mode)
43 target_device = MakeTestDevicePath(image);
[email protected]3d78cbe2014-02-27 13:19:3044
noel4342d3ea2017-03-20 08:08:3245 if (ShouldResetImageWriter(image, target_device))
noel6b03ae82017-02-09 15:28:1746 image_writer_.reset(new ImageWriter(this, image, target_device));
[email protected]01fe23ce2014-05-07 13:18:5547
48 if (image_writer_->IsRunning()) {
49 SendFailed(error::kOperationAlreadyInProgress);
[email protected]3d78cbe2014-02-27 13:19:3050 return;
51 }
52
noel6b03ae82017-02-09 15:28:1753 if (test_mode) {
54 image_writer_->Write();
55 return;
56 }
57
[email protected]01fe23ce2014-05-07 13:18:5558 if (!image_writer_->IsValidDevice()) {
59 SendFailed(error::kInvalidDevice);
[email protected]3d78cbe2014-02-27 13:19:3060 return;
61 }
[email protected]01fe23ce2014-05-07 13:18:5562
[email protected]4e100e82014-06-18 23:47:2963 image_writer_->UnmountVolumes(
64 base::Bind(&ImageWriter::Write, image_writer_->AsWeakPtr()));
[email protected]3d78cbe2014-02-27 13:19:3065}
66
noel6b03ae82017-02-09 15:28:1767void ImageWriterHandler::Verify(
68 const base::FilePath& image,
69 const base::FilePath& device,
Jay Civelli66e0d892017-12-05 01:05:1070 chrome::mojom::RemovableStorageWriterClientPtr client) {
noel6b03ae82017-02-09 15:28:1771 client_ = std::move(client);
72 client_.set_connection_error_handler(
tzikf7d48c73ac2017-06-26 09:27:0473 base::BindOnce(&ImageWriterHandler::Cancel, base::Unretained(this)));
noel6b03ae82017-02-09 15:28:1774
75 base::FilePath target_device = device;
76 const bool test_mode = IsTestDevice(device);
77 if (test_mode)
78 target_device = MakeTestDevicePath(image);
79
noel4342d3ea2017-03-20 08:08:3280 if (ShouldResetImageWriter(image, target_device))
noel6b03ae82017-02-09 15:28:1781 image_writer_.reset(new ImageWriter(this, image, target_device));
[email protected]01fe23ce2014-05-07 13:18:5582
83 if (image_writer_->IsRunning()) {
84 SendFailed(error::kOperationAlreadyInProgress);
[email protected]3d78cbe2014-02-27 13:19:3085 return;
86 }
87
noel6b03ae82017-02-09 15:28:1788 if (test_mode) {
89 image_writer_->Verify();
90 return;
91 }
92
[email protected]01fe23ce2014-05-07 13:18:5593 if (!image_writer_->IsValidDevice()) {
94 SendFailed(error::kInvalidDevice);
[email protected]3d78cbe2014-02-27 13:19:3095 return;
96 }
[email protected]01fe23ce2014-05-07 13:18:5597
98 image_writer_->Verify();
[email protected]3d78cbe2014-02-27 13:19:3099}
100
noel6b03ae82017-02-09 15:28:17101void ImageWriterHandler::SendProgress(int64_t progress) {
102 client_->Progress(progress);
103}
104
105void ImageWriterHandler::SendSucceeded() {
106 client_->Complete(base::nullopt);
107 client_.reset();
108}
109
110void ImageWriterHandler::SendFailed(const std::string& error) {
Jay Civelli66e0d892017-12-05 01:05:10111 if (client_) {
112 // client_ may be null as the ImageWriter implementation may have reported
113 // an error already.
114 client_->Complete(error);
115 client_.reset();
116 }
noel6b03ae82017-02-09 15:28:17117}
118
119void ImageWriterHandler::Cancel() {
120 if (image_writer_)
[email protected]01fe23ce2014-05-07 13:18:55121 image_writer_->Cancel();
noel6b03ae82017-02-09 15:28:17122 client_.reset();
[email protected]3d78cbe2014-02-27 13:19:30123}
124
noel4342d3ea2017-03-20 08:08:32125bool ImageWriterHandler::ShouldResetImageWriter(const base::FilePath& image,
126 const base::FilePath& device) {
127 if (!image_writer_)
128 return true;
129 if (image != image_writer_->GetImagePath())
130 return true;
131 if (device != image_writer_->GetDevicePath())
132 return true;
133
134 // When writing and verifying the same file on the same device, keep
135 // the file handles open; do not reset them since that can cause the
136 // operation to fail in unexpected ways: crbug.com/352442#c7
137 return false;
138}
139
[email protected]3d78cbe2014-02-27 13:19:30140} // namespace image_writer