blob: 1ba007ce1e90d7b394076b0e1ff2123126070ab8 [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
Peter Boström924f8032021-04-02 20:36:027#include <memory>
Henrique Ferreiro0b26f34d2019-10-03 08:36:228#include <utility>
9
noel6b03ae82017-02-09 15:28:1710#include "base/bind.h"
[email protected]3d78cbe2014-02-27 13:19:3011#include "base/files/file_path.h"
Ken Rockot2ad4db32018-02-10 16:24:1012#include "chrome/services/removable_storage_writer/public/mojom/removable_storage_writer.mojom.h"
Avi Drissmaneb17c632020-07-28 14:57:0013#include "chrome/utility/image_writer/error_message_strings.h"
Anton Bikineev46bbb972021-05-15 17:53:5314#include "third_party/abseil-cpp/absl/types/optional.h"
noel6b03ae82017-02-09 15:28:1715
16namespace {
17
18bool IsTestDevice(const base::FilePath& device) {
19 return device.AsUTF8Unsafe() ==
Jay Civelli66e0d892017-12-05 01:05:1020 chrome::mojom::RemovableStorageWriter::kTestDevice;
noel6b03ae82017-02-09 15:28:1721}
22
23base::FilePath MakeTestDevicePath(const base::FilePath& image) {
24 return image.ReplaceExtension(FILE_PATH_LITERAL("out"));
25}
26
27} // namespace
[email protected]3d78cbe2014-02-27 13:19:3028
[email protected]3d78cbe2014-02-27 13:19:3029namespace image_writer {
30
noel6b03ae82017-02-09 15:28:1731ImageWriterHandler::ImageWriterHandler() = default;
[email protected]3d78cbe2014-02-27 13:19:3032
noel6b03ae82017-02-09 15:28:1733ImageWriterHandler::~ImageWriterHandler() = default;
[email protected]3d78cbe2014-02-27 13:19:3034
noel6b03ae82017-02-09 15:28:1735void ImageWriterHandler::Write(
36 const base::FilePath& image,
37 const base::FilePath& device,
Henrique Ferreiro0b26f34d2019-10-03 08:36:2238 mojo::PendingRemote<chrome::mojom::RemovableStorageWriterClient> client) {
39 client_.Bind(std::move(client));
40 client_.set_disconnect_handler(
tzikf7d48c73ac2017-06-26 09:27:0441 base::BindOnce(&ImageWriterHandler::Cancel, base::Unretained(this)));
[email protected]3d78cbe2014-02-27 13:19:3042
noel6b03ae82017-02-09 15:28:1743 base::FilePath target_device = device;
44 const bool test_mode = IsTestDevice(device);
45 if (test_mode)
46 target_device = MakeTestDevicePath(image);
[email protected]3d78cbe2014-02-27 13:19:3047
noel4342d3ea2017-03-20 08:08:3248 if (ShouldResetImageWriter(image, target_device))
Peter Boström924f8032021-04-02 20:36:0249 image_writer_ = std::make_unique<ImageWriter>(this, image, target_device);
[email protected]01fe23ce2014-05-07 13:18:5550
51 if (image_writer_->IsRunning()) {
52 SendFailed(error::kOperationAlreadyInProgress);
[email protected]3d78cbe2014-02-27 13:19:3053 return;
54 }
55
noel6b03ae82017-02-09 15:28:1756 if (test_mode) {
57 image_writer_->Write();
58 return;
59 }
60
[email protected]01fe23ce2014-05-07 13:18:5561 if (!image_writer_->IsValidDevice()) {
62 SendFailed(error::kInvalidDevice);
[email protected]3d78cbe2014-02-27 13:19:3063 return;
64 }
[email protected]01fe23ce2014-05-07 13:18:5565
[email protected]4e100e82014-06-18 23:47:2966 image_writer_->UnmountVolumes(
Anand K. Mistry902a75dc2019-11-26 00:29:2567 base::BindOnce(&ImageWriter::Write, image_writer_->AsWeakPtr()));
[email protected]3d78cbe2014-02-27 13:19:3068}
69
noel6b03ae82017-02-09 15:28:1770void ImageWriterHandler::Verify(
71 const base::FilePath& image,
72 const base::FilePath& device,
Henrique Ferreiro0b26f34d2019-10-03 08:36:2273 mojo::PendingRemote<chrome::mojom::RemovableStorageWriterClient> client) {
74 client_.Bind(std::move(client));
75 client_.set_disconnect_handler(
tzikf7d48c73ac2017-06-26 09:27:0476 base::BindOnce(&ImageWriterHandler::Cancel, base::Unretained(this)));
noel6b03ae82017-02-09 15:28:1777
78 base::FilePath target_device = device;
79 const bool test_mode = IsTestDevice(device);
80 if (test_mode)
81 target_device = MakeTestDevicePath(image);
82
noel4342d3ea2017-03-20 08:08:3283 if (ShouldResetImageWriter(image, target_device))
Peter Boström924f8032021-04-02 20:36:0284 image_writer_ = std::make_unique<ImageWriter>(this, image, target_device);
[email protected]01fe23ce2014-05-07 13:18:5585
86 if (image_writer_->IsRunning()) {
87 SendFailed(error::kOperationAlreadyInProgress);
[email protected]3d78cbe2014-02-27 13:19:3088 return;
89 }
90
noel6b03ae82017-02-09 15:28:1791 if (test_mode) {
92 image_writer_->Verify();
93 return;
94 }
95
[email protected]01fe23ce2014-05-07 13:18:5596 if (!image_writer_->IsValidDevice()) {
97 SendFailed(error::kInvalidDevice);
[email protected]3d78cbe2014-02-27 13:19:3098 return;
99 }
[email protected]01fe23ce2014-05-07 13:18:55100
101 image_writer_->Verify();
[email protected]3d78cbe2014-02-27 13:19:30102}
103
noel6b03ae82017-02-09 15:28:17104void ImageWriterHandler::SendProgress(int64_t progress) {
105 client_->Progress(progress);
106}
107
108void ImageWriterHandler::SendSucceeded() {
Anton Bikineev46bbb972021-05-15 17:53:53109 client_->Complete(absl::nullopt);
noel6b03ae82017-02-09 15:28:17110 client_.reset();
111}
112
113void ImageWriterHandler::SendFailed(const std::string& error) {
Jay Civelli66e0d892017-12-05 01:05:10114 if (client_) {
115 // client_ may be null as the ImageWriter implementation may have reported
116 // an error already.
117 client_->Complete(error);
118 client_.reset();
119 }
noel6b03ae82017-02-09 15:28:17120}
121
122void ImageWriterHandler::Cancel() {
123 if (image_writer_)
[email protected]01fe23ce2014-05-07 13:18:55124 image_writer_->Cancel();
noel6b03ae82017-02-09 15:28:17125 client_.reset();
[email protected]3d78cbe2014-02-27 13:19:30126}
127
noel4342d3ea2017-03-20 08:08:32128bool ImageWriterHandler::ShouldResetImageWriter(const base::FilePath& image,
129 const base::FilePath& device) {
130 if (!image_writer_)
131 return true;
132 if (image != image_writer_->GetImagePath())
133 return true;
134 if (device != image_writer_->GetDevicePath())
135 return true;
136
137 // When writing and verifying the same file on the same device, keep
138 // the file handles open; do not reset them since that can cause the
139 // operation to fail in unexpected ways: crbug.com/352442#c7
140 return false;
141}
142
[email protected]3d78cbe2014-02-27 13:19:30143} // namespace image_writer