forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfake_cros_disks_client.cc
237 lines (200 loc) · 8.56 KB
/
fake_cros_disks_client.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
// Copyright (c) 2013 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.
#include "chromeos/dbus/fake_cros_disks_client.h"
#include <utility>
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "url/gurl.h"
namespace chromeos {
namespace {
// Performs fake mounting by creating a directory with a dummy file.
MountError PerformFakeMount(const std::string& source_path,
const base::FilePath& mounted_path,
MountType type) {
if (mounted_path.empty())
return MOUNT_ERROR_INVALID_ARGUMENT;
// Just create an empty directory and shows it as the mounted directory.
if (!base::CreateDirectory(mounted_path)) {
DLOG(ERROR) << "Failed to create directory at " << mounted_path.value();
return MOUNT_ERROR_DIRECTORY_CREATION_FAILED;
}
// Fake network mounts are responsible for populating their mount paths so
// don't need a dummy file.
if (type == MOUNT_TYPE_NETWORK_STORAGE)
return MOUNT_ERROR_NONE;
// Put a dummy file.
const base::FilePath dummy_file_path =
mounted_path.Append("SUCCESSFULLY_PERFORMED_FAKE_MOUNT.txt");
const std::string dummy_file_content = "This is a dummy file.";
const int write_result = base::WriteFile(
dummy_file_path, dummy_file_content.data(), dummy_file_content.size());
if (write_result != static_cast<int>(dummy_file_content.size())) {
DLOG(ERROR) << "Failed to put a dummy file at "
<< dummy_file_path.value();
return MOUNT_ERROR_MOUNT_PROGRAM_FAILED;
}
return MOUNT_ERROR_NONE;
}
} // namespace
FakeCrosDisksClient::FakeCrosDisksClient()
: unmount_call_count_(0),
unmount_error_(MOUNT_ERROR_NONE),
format_call_count_(0),
format_success_(true),
rename_call_count_(0),
rename_success_(true),
weak_ptr_factory_(this) {}
FakeCrosDisksClient::~FakeCrosDisksClient() = default;
void FakeCrosDisksClient::Init(dbus::Bus* bus) {
}
void FakeCrosDisksClient::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
void FakeCrosDisksClient::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
}
void FakeCrosDisksClient::Mount(const std::string& source_path,
const std::string& source_format,
const std::string& mount_label,
const std::vector<std::string>& mount_options,
MountAccessMode access_mode,
RemountOption remount,
VoidDBusMethodCallback callback) {
// This fake implementation assumes mounted path is device when source_format
// is empty, or an archive otherwise.
MountType type =
source_format.empty() ? MOUNT_TYPE_DEVICE : MOUNT_TYPE_ARCHIVE;
// Network storage source paths are URIs.
if (GURL(source_path).is_valid())
type = MOUNT_TYPE_NETWORK_STORAGE;
base::FilePath mounted_path;
switch (type) {
case MOUNT_TYPE_ARCHIVE:
mounted_path = GetArchiveMountPoint().Append(
base::FilePath::FromUTF8Unsafe(mount_label));
break;
case MOUNT_TYPE_DEVICE:
mounted_path = GetRemovableDiskMountPoint().Append(
base::FilePath::FromUTF8Unsafe(mount_label));
break;
case MOUNT_TYPE_NETWORK_STORAGE:
// Call all registered callbacks until mounted_path is non-empty.
for (auto const& callback : custom_mount_point_callbacks_) {
mounted_path = callback.Run(source_path, mount_options);
if (!mounted_path.empty()) {
break;
}
}
break;
case MOUNT_TYPE_INVALID:
NOTREACHED();
return;
}
mounted_paths_.insert(mounted_path);
base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&PerformFakeMount, source_path, mounted_path, type),
base::BindOnce(&FakeCrosDisksClient::DidMount,
weak_ptr_factory_.GetWeakPtr(), source_path, type,
mounted_path, std::move(callback)));
}
void FakeCrosDisksClient::DidMount(const std::string& source_path,
MountType type,
const base::FilePath& mounted_path,
VoidDBusMethodCallback callback,
MountError mount_error) {
// Tell the caller of Mount() that the mount request was accepted.
// Note that even if PerformFakeMount fails, this calls with |true| to
// emulate the situation that 1) Mount operation is _successfully_ started,
// 2) then failed for some reason.
std::move(callback).Run(true);
// Notify observers that the mount is completed.
NotifyMountCompleted(mount_error, source_path, type,
mounted_path.AsUTF8Unsafe());
}
void FakeCrosDisksClient::Unmount(const std::string& device_path,
UnmountOptions options,
UnmountCallback callback) {
DCHECK(!callback.is_null());
unmount_call_count_++;
last_unmount_device_path_ = device_path;
last_unmount_options_ = options;
// Remove the dummy mounted directory if it exists.
if (mounted_paths_.erase(base::FilePath::FromUTF8Unsafe(device_path))) {
base::PostTaskWithTraitsAndReply(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(base::IgnoreResult(&base::DeleteFile),
base::FilePath::FromUTF8Unsafe(device_path),
true /* recursive */),
base::BindOnce(std::move(callback), unmount_error_));
} else {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), unmount_error_));
}
if (!unmount_listener_.is_null())
unmount_listener_.Run();
}
void FakeCrosDisksClient::EnumerateDevices(EnumerateDevicesCallback callback,
base::OnceClosure error_callback) {}
void FakeCrosDisksClient::EnumerateMountEntries(
EnumerateMountEntriesCallback callback,
base::OnceClosure error_callback) {}
void FakeCrosDisksClient::Format(const std::string& device_path,
const std::string& filesystem,
VoidDBusMethodCallback callback) {
DCHECK(!callback.is_null());
format_call_count_++;
last_format_device_path_ = device_path;
last_format_filesystem_ = filesystem;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), format_success_));
}
void FakeCrosDisksClient::Rename(const std::string& device_path,
const std::string& volume_name,
VoidDBusMethodCallback callback) {
DCHECK(!callback.is_null());
rename_call_count_++;
last_rename_device_path_ = device_path;
last_rename_volume_name_ = volume_name;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), rename_success_));
}
void FakeCrosDisksClient::GetDeviceProperties(
const std::string& device_path,
GetDevicePropertiesCallback callback,
base::OnceClosure error_callback) {}
void FakeCrosDisksClient::NotifyMountCompleted(MountError error_code,
const std::string& source_path,
MountType mount_type,
const std::string& mount_path) {
for (auto& observer : observer_list_) {
observer.OnMountCompleted(
MountEntry(error_code, source_path, mount_type, mount_path));
}
}
void FakeCrosDisksClient::NotifyFormatCompleted(
FormatError error_code,
const std::string& device_path) {
for (auto& observer : observer_list_)
observer.OnFormatCompleted(error_code, device_path);
}
void FakeCrosDisksClient::NotifyRenameCompleted(
RenameError error_code,
const std::string& device_path) {
for (auto& observer : observer_list_)
observer.OnRenameCompleted(error_code, device_path);
}
void FakeCrosDisksClient::AddCustomMountPointCallback(
FakeCrosDisksClient::CustomMountPointCallback custom_mount_point_callback) {
custom_mount_point_callbacks_.emplace_back(custom_mount_point_callback);
}
} // namespace chromeos