blob: 81f7958272e334ccc289f0c7a97f36ece4e5575f [file] [log] [blame]
[email protected]2321d282012-01-31 23:06:591// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]4ae73292011-11-15 05:20:182// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]64e199252012-04-06 01:54:365#include "chromeos/dbus/cros_disks_client.h"
[email protected]4ae73292011-11-15 05:20:186
avi6e1a22d2015-12-21 03:43:207#include <stddef.h>
8#include <stdint.h>
9
[email protected]85b95a2012012-08-07 18:57:2710#include <map>
Hidehiko Abe5a138a22017-10-05 16:22:2111#include <memory>
Hidehiko Abec293cdcf2018-02-08 02:10:4512#include <utility>
[email protected]85b95a2012012-08-07 18:57:2713
[email protected]4ae73292011-11-15 05:20:1814#include "base/bind.h"
[email protected]a5a8b412013-03-04 15:03:1115#include "base/files/file_path.h"
thestigb44bd352014-09-10 01:47:0616#include "base/files/file_util.h"
[email protected]593cf3b2013-03-05 04:16:5217#include "base/location.h"
avi6e1a22d2015-12-21 03:43:2018#include "base/macros.h"
Hidehiko Abe06ce6dc2017-12-08 19:32:0319#include "base/observer_list.h"
[email protected]b307bceb2011-11-17 07:49:5520#include "base/stl_util.h"
[email protected]afa339d72013-06-11 06:32:5121#include "base/strings/stringprintf.h"
[email protected]49c4cf852013-09-27 19:28:2422#include "base/sys_info.h"
[email protected]593cf3b2013-03-05 04:16:5223#include "base/task_runner_util.h"
[email protected]81836aed2013-07-09 23:41:1224#include "base/values.h"
satorux8fd293802014-10-30 08:23:1225#include "chromeos/dbus/fake_cros_disks_client.h"
[email protected]4ae73292011-11-15 05:20:1826#include "dbus/bus.h"
27#include "dbus/message.h"
[email protected]216ed0b2012-02-14 21:29:0628#include "dbus/object_path.h"
[email protected]4ae73292011-11-15 05:20:1829#include "dbus/object_proxy.h"
[email protected]81836aed2013-07-09 23:41:1230#include "dbus/values_util.h"
[email protected]4ae73292011-11-15 05:20:1831#include "third_party/cros_system_api/dbus/service_constants.h"
32
33namespace chromeos {
34
35namespace {
36
37const char* kDefaultMountOptions[] = {
yamaguchi585d5402016-08-02 09:27:3638 "nodev", "noexec", "nosuid",
[email protected]4ae73292011-11-15 05:20:1839};
yamaguchi585d5402016-08-02 09:27:3640const char kReadOnlyOption[] = "ro";
41const char kReadWriteOption[] = "rw";
yamaguchifa8efc72016-10-21 15:05:5142const char kRemountOption[] = "remount";
yamaguchi585d5402016-08-02 09:27:3643const char kMountLabelOption[] = "mountlabel";
[email protected]4ae73292011-11-15 05:20:1844
[email protected]10795ae2012-10-10 07:33:4945const char kLazyUnmountOption[] = "lazy";
46
[email protected]2321d282012-01-31 23:06:5947// Checks if retrieved media type is in boundaries of DeviceMediaType.
avi6e1a22d2015-12-21 03:43:2048bool IsValidMediaType(uint32_t type) {
49 return type < static_cast<uint32_t>(cros_disks::DEVICE_MEDIA_NUM_VALUES);
[email protected]2321d282012-01-31 23:06:5950}
51
[email protected]2321d282012-01-31 23:06:5952// Translates enum used in cros-disks to enum used in Chrome.
53// Note that we could just do static_cast, but this is less sensitive to
54// changes in cros-disks.
avi6e1a22d2015-12-21 03:43:2055DeviceType DeviceMediaTypeToDeviceType(uint32_t media_type_uint32) {
[email protected]2321d282012-01-31 23:06:5956 if (!IsValidMediaType(media_type_uint32))
57 return DEVICE_TYPE_UNKNOWN;
58
59 cros_disks::DeviceMediaType media_type =
60 cros_disks::DeviceMediaType(media_type_uint32);
61
62 switch (media_type) {
63 case(cros_disks::DEVICE_MEDIA_UNKNOWN):
64 return DEVICE_TYPE_UNKNOWN;
65 case(cros_disks::DEVICE_MEDIA_USB):
66 return DEVICE_TYPE_USB;
67 case(cros_disks::DEVICE_MEDIA_SD):
68 return DEVICE_TYPE_SD;
69 case(cros_disks::DEVICE_MEDIA_OPTICAL_DISC):
70 return DEVICE_TYPE_OPTICAL_DISC;
71 case(cros_disks::DEVICE_MEDIA_MOBILE):
72 return DEVICE_TYPE_MOBILE;
[email protected]f4ae40ac2012-05-04 21:57:0073 case(cros_disks::DEVICE_MEDIA_DVD):
74 return DEVICE_TYPE_DVD;
[email protected]2321d282012-01-31 23:06:5975 default:
76 return DEVICE_TYPE_UNKNOWN;
77 }
[email protected]4ae73292011-11-15 05:20:1878}
79
[email protected]d7760592014-05-16 07:57:5280bool ReadMountEntryFromDbus(dbus::MessageReader* reader, MountEntry* entry) {
avi6e1a22d2015-12-21 03:43:2081 uint32_t error_code = 0;
[email protected]d7760592014-05-16 07:57:5282 std::string source_path;
avi6e1a22d2015-12-21 03:43:2083 uint32_t mount_type = 0;
[email protected]d7760592014-05-16 07:57:5284 std::string mount_path;
85 if (!reader->PopUint32(&error_code) ||
86 !reader->PopString(&source_path) ||
87 !reader->PopUint32(&mount_type) ||
88 !reader->PopString(&mount_path)) {
89 return false;
90 }
91 *entry = MountEntry(static_cast<MountError>(error_code), source_path,
92 static_cast<MountType>(mount_type), mount_path);
93 return true;
94}
95
[email protected]4ae73292011-11-15 05:20:1896// The CrosDisksClient implementation.
97class CrosDisksClientImpl : public CrosDisksClient {
98 public:
Hidehiko Abe06ce6dc2017-12-08 19:32:0399 CrosDisksClientImpl() : proxy_(nullptr), weak_ptr_factory_(this) {}
100
101 // CrosDisksClient override.
102 void AddObserver(Observer* observer) override {
103 observer_list_.AddObserver(observer);
104 }
105
106 // CrosDisksClient override.
107 void RemoveObserver(Observer* observer) override {
108 observer_list_.RemoveObserver(observer);
109 }
[email protected]4ae73292011-11-15 05:20:18110
111 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50112 void Mount(const std::string& source_path,
113 const std::string& source_format,
114 const std::string& mount_label,
Sergei Datsenkod19248182018-05-11 01:52:56115 const std::vector<std::string>& mount_options,
yamaguchi585d5402016-08-02 09:27:36116 MountAccessMode access_mode,
yamaguchifa8efc72016-10-21 15:05:51117 RemountOption remount,
Hidehiko Abec293cdcf2018-02-08 02:10:45118 VoidDBusMethodCallback callback) override {
[email protected]4ae73292011-11-15 05:20:18119 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
120 cros_disks::kMount);
121 dbus::MessageWriter writer(&method_call);
122 writer.AppendString(source_path);
[email protected]b9f22d12012-04-25 21:46:48123 writer.AppendString(source_format);
Sergei Datsenkod19248182018-05-11 01:52:56124 std::vector<std::string> options =
125 ComposeMountOptions(mount_options, mount_label, access_mode, remount);
126 writer.AppendArrayOfStrings(options);
Hidehiko Abec293cdcf2018-02-08 02:10:45127 proxy_->CallMethod(
128 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
129 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
130 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
[email protected]4ae73292011-11-15 05:20:18131 }
132
133 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50134 void Unmount(const std::string& device_path,
135 UnmountOptions options,
Hidehiko Abec293cdcf2018-02-08 02:10:45136 VoidDBusMethodCallback callback) override {
[email protected]4ae73292011-11-15 05:20:18137 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
138 cros_disks::kUnmount);
139 dbus::MessageWriter writer(&method_call);
140 writer.AppendString(device_path);
[email protected]10795ae2012-10-10 07:33:49141
benchan8bcaea12017-03-11 00:26:50142 std::vector<std::string> unmount_options;
[email protected]10795ae2012-10-10 07:33:49143 if (options == UNMOUNT_OPTIONS_LAZY)
144 unmount_options.push_back(kLazyUnmountOption);
145
[email protected]4ae73292011-11-15 05:20:18146 writer.AppendArrayOfStrings(unmount_options);
Hidehiko Abec293cdcf2018-02-08 02:10:45147 proxy_->CallMethod(
148 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
149 base::BindOnce(&CrosDisksClientImpl::OnUnmount,
150 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
[email protected]4ae73292011-11-15 05:20:18151 }
152
153 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50154 void EnumerateAutoMountableDevices(
Aga Wronskaddc1a752017-12-01 19:44:02155 const EnumerateDevicesCallback& callback,
mostynb4f4cf142014-10-06 13:57:52156 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18157 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
158 cros_disks::kEnumerateAutoMountableDevices);
Aga Wronskaddc1a752017-12-01 19:44:02159 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
160 base::BindOnce(&CrosDisksClientImpl::OnEnumerateDevices,
161 weak_ptr_factory_.GetWeakPtr(), callback,
162 error_callback));
163 }
164
165 void EnumerateDevices(const EnumerateDevicesCallback& callback,
166 const base::Closure& error_callback) override {
167 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
168 cros_disks::kEnumerateDevices);
169 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
170 base::BindOnce(&CrosDisksClientImpl::OnEnumerateDevices,
171 weak_ptr_factory_.GetWeakPtr(), callback,
172 error_callback));
[email protected]4ae73292011-11-15 05:20:18173 }
174
175 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50176 void EnumerateMountEntries(const EnumerateMountEntriesCallback& callback,
177 const base::Closure& error_callback) override {
[email protected]d7760592014-05-16 07:57:52178 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
179 cros_disks::kEnumerateMountEntries);
180 proxy_->CallMethod(
181 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
Hidehiko Abed62ed3e2017-09-05 05:16:56182 base::BindOnce(&CrosDisksClientImpl::OnEnumerateMountEntries,
183 weak_ptr_factory_.GetWeakPtr(), callback,
184 error_callback));
[email protected]d7760592014-05-16 07:57:52185 }
186
187 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50188 void Format(const std::string& device_path,
189 const std::string& filesystem,
Hidehiko Abec293cdcf2018-02-08 02:10:45190 VoidDBusMethodCallback callback) override {
[email protected]4ae73292011-11-15 05:20:18191 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
[email protected]f026c0f2014-05-06 21:52:35192 cros_disks::kFormat);
[email protected]4ae73292011-11-15 05:20:18193 dbus::MessageWriter writer(&method_call);
194 writer.AppendString(device_path);
195 writer.AppendString(filesystem);
[email protected]f026c0f2014-05-06 21:52:35196 // No format option is currently specified, but we can later use this
197 // argument to specify options for the format operation.
198 std::vector<std::string> format_options;
199 writer.AppendArrayOfStrings(format_options);
Hidehiko Abec293cdcf2018-02-08 02:10:45200 proxy_->CallMethod(
201 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
202 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
203 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
[email protected]4ae73292011-11-15 05:20:18204 }
205
Klemen Kozjekbf5610f2017-08-25 20:20:09206 void Rename(const std::string& device_path,
207 const std::string& volume_name,
Hidehiko Abec293cdcf2018-02-08 02:10:45208 VoidDBusMethodCallback callback) override {
Klemen Kozjekbf5610f2017-08-25 20:20:09209 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
210 cros_disks::kRename);
211 dbus::MessageWriter writer(&method_call);
212 writer.AppendString(device_path);
213 writer.AppendString(volume_name);
Hidehiko Abec293cdcf2018-02-08 02:10:45214 proxy_->CallMethod(
215 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
216 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
217 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
Klemen Kozjekbf5610f2017-08-25 20:20:09218 }
219
[email protected]4ae73292011-11-15 05:20:18220 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50221 void GetDeviceProperties(const std::string& device_path,
222 const GetDevicePropertiesCallback& callback,
223 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18224 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
225 cros_disks::kGetDeviceProperties);
226 dbus::MessageWriter writer(&method_call);
227 writer.AppendString(device_path);
Hidehiko Abed62ed3e2017-09-05 05:16:56228 proxy_->CallMethod(
229 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
230 base::BindOnce(&CrosDisksClientImpl::OnGetDeviceProperties,
231 weak_ptr_factory_.GetWeakPtr(), device_path, callback,
232 error_callback));
[email protected]4ae73292011-11-15 05:20:18233 }
234
[email protected]c5fd5362013-08-27 12:23:04235 protected:
dcheng0280cb62015-01-16 07:37:50236 void Init(dbus::Bus* bus) override {
[email protected]c5fd5362013-08-27 12:23:04237 proxy_ = bus->GetObjectProxy(
238 cros_disks::kCrosDisksServiceName,
239 dbus::ObjectPath(cros_disks::kCrosDisksServicePath));
Hidehiko Abe06ce6dc2017-12-08 19:32:03240
241 // Register handlers for D-Bus signals.
242 constexpr SignalEventTuple kSignalEventTuples[] = {
243 {cros_disks::kDeviceAdded, CROS_DISKS_DEVICE_ADDED},
244 {cros_disks::kDeviceScanned, CROS_DISKS_DEVICE_SCANNED},
245 {cros_disks::kDeviceRemoved, CROS_DISKS_DEVICE_REMOVED},
246 {cros_disks::kDiskAdded, CROS_DISKS_DISK_ADDED},
247 {cros_disks::kDiskChanged, CROS_DISKS_DISK_CHANGED},
248 {cros_disks::kDiskRemoved, CROS_DISKS_DISK_REMOVED},
249 };
250 for (const auto& entry : kSignalEventTuples) {
251 proxy_->ConnectToSignal(
252 cros_disks::kCrosDisksInterface, entry.signal_name,
253 base::BindRepeating(&CrosDisksClientImpl::OnMountEvent,
254 weak_ptr_factory_.GetWeakPtr(), entry.event_type),
255 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
256 weak_ptr_factory_.GetWeakPtr()));
257 }
258
259 proxy_->ConnectToSignal(
260 cros_disks::kCrosDisksInterface, cros_disks::kMountCompleted,
261 base::BindRepeating(&CrosDisksClientImpl::OnMountCompleted,
262 weak_ptr_factory_.GetWeakPtr()),
263 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
264 weak_ptr_factory_.GetWeakPtr()));
265
266 proxy_->ConnectToSignal(
267 cros_disks::kCrosDisksInterface, cros_disks::kFormatCompleted,
268 base::BindRepeating(&CrosDisksClientImpl::OnFormatCompleted,
269 weak_ptr_factory_.GetWeakPtr()),
270 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
271 weak_ptr_factory_.GetWeakPtr()));
272
273 proxy_->ConnectToSignal(
274 cros_disks::kCrosDisksInterface, cros_disks::kRenameCompleted,
275 base::BindRepeating(&CrosDisksClientImpl::OnRenameCompleted,
276 weak_ptr_factory_.GetWeakPtr()),
277 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
278 weak_ptr_factory_.GetWeakPtr()));
[email protected]c5fd5362013-08-27 12:23:04279 }
280
[email protected]4ae73292011-11-15 05:20:18281 private:
282 // A struct to contain a pair of signal name and mount event type.
[email protected]a0278d52014-05-06 03:36:15283 // Used by SetMountEventHandler.
[email protected]4ae73292011-11-15 05:20:18284 struct SignalEventTuple {
285 const char *signal_name;
286 MountEventType event_type;
287 };
288
Hidehiko Abec293cdcf2018-02-08 02:10:45289 // Handles the result of D-Bus method call with no return value.
290 void OnVoidMethod(VoidDBusMethodCallback callback, dbus::Response* response) {
291 std::move(callback).Run(response);
[email protected]4ae73292011-11-15 05:20:18292 }
293
[email protected]d7760592014-05-16 07:57:52294 // Handles the result of Unmount and calls |callback| or |error_callback|.
Hidehiko Abec293cdcf2018-02-08 02:10:45295 void OnUnmount(VoidDBusMethodCallback callback, dbus::Response* response) {
[email protected]4ae73292011-11-15 05:20:18296 if (!response) {
Hidehiko Abec293cdcf2018-02-08 02:10:45297 std::move(callback).Run(false);
[email protected]4ae73292011-11-15 05:20:18298 return;
299 }
[email protected]ddcb18e2013-09-19 07:17:28300
301 // Temporarly allow Unmount method to report failure both by setting dbus
302 // error (in which case response is not set) and by returning mount error
303 // different from MOUNT_ERROR_NONE. This is done so we can change Unmount
304 // method to return mount error (http://crbug.com/288974) without breaking
305 // Chrome.
306 // TODO(tbarzic): When Unmount implementation is changed on cros disks side,
307 // make this fail if reader is not able to read the error code value from
308 // the response.
309 dbus::MessageReader reader(response);
avi6e1a22d2015-12-21 03:43:20310 uint32_t error_code = 0;
[email protected]ddcb18e2013-09-19 07:17:28311 if (reader.PopUint32(&error_code) &&
312 static_cast<MountError>(error_code) != MOUNT_ERROR_NONE) {
Hidehiko Abec293cdcf2018-02-08 02:10:45313 std::move(callback).Run(false);
[email protected]ddcb18e2013-09-19 07:17:28314 return;
315 }
316
Hidehiko Abec293cdcf2018-02-08 02:10:45317 std::move(callback).Run(true);
[email protected]4ae73292011-11-15 05:20:18318 }
319
Aga Wronskaddc1a752017-12-01 19:44:02320 // Handles the result of EnumerateDevices and EnumarateAutoMountableDevices.
321 // Calls |callback| or |error_callback|.
322 void OnEnumerateDevices(const EnumerateDevicesCallback& callback,
323 const base::Closure& error_callback,
324 dbus::Response* response) {
[email protected]4ae73292011-11-15 05:20:18325 if (!response) {
326 error_callback.Run();
327 return;
328 }
329 dbus::MessageReader reader(response);
330 std::vector<std::string> device_paths;
331 if (!reader.PopArrayOfStrings(&device_paths)) {
332 LOG(ERROR) << "Invalid response: " << response->ToString();
333 error_callback.Run();
334 return;
335 }
336 callback.Run(device_paths);
337 }
338
[email protected]d7760592014-05-16 07:57:52339 // Handles the result of EnumerateMountEntries and calls |callback| or
340 // |error_callback|.
341 void OnEnumerateMountEntries(
342 const EnumerateMountEntriesCallback& callback,
343 const base::Closure& error_callback,
344 dbus::Response* response) {
345 if (!response) {
346 error_callback.Run();
347 return;
348 }
349
350 dbus::MessageReader reader(response);
351 dbus::MessageReader array_reader(NULL);
352 if (!reader.PopArray(&array_reader)) {
353 LOG(ERROR) << "Invalid response: " << response->ToString();
354 error_callback.Run();
355 return;
356 }
357
358 std::vector<MountEntry> entries;
359 while (array_reader.HasMoreData()) {
360 MountEntry entry;
361 dbus::MessageReader sub_reader(NULL);
362 if (!array_reader.PopStruct(&sub_reader) ||
363 !ReadMountEntryFromDbus(&sub_reader, &entry)) {
364 LOG(ERROR) << "Invalid response: " << response->ToString();
365 error_callback.Run();
366 return;
367 }
368 entries.push_back(entry);
369 }
370 callback.Run(entries);
371 }
372
[email protected]4ae73292011-11-15 05:20:18373 // Handles the result of GetDeviceProperties and calls |callback| or
374 // |error_callback|.
375 void OnGetDeviceProperties(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35376 const GetDevicePropertiesCallback& callback,
[email protected]5624a252013-07-04 03:17:53377 const base::Closure& error_callback,
[email protected]4ae73292011-11-15 05:20:18378 dbus::Response* response) {
379 if (!response) {
380 error_callback.Run();
381 return;
382 }
383 DiskInfo disk(device_path, response);
384 callback.Run(disk);
385 }
386
Hidehiko Abe06ce6dc2017-12-08 19:32:03387 // Handles mount event signals and notifies observers.
388 void OnMountEvent(MountEventType event_type, dbus::Signal* signal) {
[email protected]4ae73292011-11-15 05:20:18389 dbus::MessageReader reader(signal);
390 std::string device;
391 if (!reader.PopString(&device)) {
392 LOG(ERROR) << "Invalid signal: " << signal->ToString();
393 return;
394 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03395
396 for (auto& observer : observer_list_)
397 observer.OnMountEvent(event_type, device);
[email protected]4ae73292011-11-15 05:20:18398 }
399
Hidehiko Abe06ce6dc2017-12-08 19:32:03400 // Handles MountCompleted signal and notifies observers.
401 void OnMountCompleted(dbus::Signal* signal) {
[email protected]4ae73292011-11-15 05:20:18402 dbus::MessageReader reader(signal);
[email protected]d7760592014-05-16 07:57:52403 MountEntry entry;
404 if (!ReadMountEntryFromDbus(&reader, &entry)) {
[email protected]4ae73292011-11-15 05:20:18405 LOG(ERROR) << "Invalid signal: " << signal->ToString();
406 return;
407 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03408
409 for (auto& observer : observer_list_)
410 observer.OnMountCompleted(entry);
[email protected]4ae73292011-11-15 05:20:18411 }
412
Hidehiko Abe06ce6dc2017-12-08 19:32:03413 // Handles FormatCompleted signal and notifies observers.
414 void OnFormatCompleted(dbus::Signal* signal) {
[email protected]a0278d52014-05-06 03:36:15415 dbus::MessageReader reader(signal);
avi6e1a22d2015-12-21 03:43:20416 uint32_t error_code = 0;
[email protected]a0278d52014-05-06 03:36:15417 std::string device_path;
418 if (!reader.PopUint32(&error_code) || !reader.PopString(&device_path)) {
419 LOG(ERROR) << "Invalid signal: " << signal->ToString();
420 return;
421 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03422
423 for (auto& observer : observer_list_) {
424 observer.OnFormatCompleted(static_cast<FormatError>(error_code),
425 device_path);
426 }
[email protected]a0278d52014-05-06 03:36:15427 }
428
Hidehiko Abe06ce6dc2017-12-08 19:32:03429 // Handles RenameCompleted signal and notifies observers.
430 void OnRenameCompleted(dbus::Signal* signal) {
Klemen Kozjekbf5610f2017-08-25 20:20:09431 dbus::MessageReader reader(signal);
432 uint32_t error_code = 0;
433 std::string device_path;
434 if (!reader.PopUint32(&error_code) || !reader.PopString(&device_path)) {
435 LOG(ERROR) << "Invalid signal: " << signal->ToString();
436 return;
437 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03438
439 for (auto& observer : observer_list_) {
440 observer.OnRenameCompleted(static_cast<RenameError>(error_code),
441 device_path);
442 }
Klemen Kozjekbf5610f2017-08-25 20:20:09443 }
444
[email protected]4ae73292011-11-15 05:20:18445 // Handles the result of signal connection setup.
446 void OnSignalConnected(const std::string& interface,
447 const std::string& signal,
[email protected]d6311dcb2012-10-22 03:40:43448 bool succeeded) {
449 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
[email protected]4ae73292011-11-15 05:20:18450 signal << " failed.";
451 }
452
453 dbus::ObjectProxy* proxy_;
[email protected]926957b2012-09-07 05:34:16454
Hidehiko Abe06ce6dc2017-12-08 19:32:03455 base::ObserverList<Observer> observer_list_;
456
[email protected]926957b2012-09-07 05:34:16457 // Note: This should remain the last member so it'll be destroyed and
458 // invalidate its weak pointers before any other members are destroyed.
[email protected]4ae73292011-11-15 05:20:18459 base::WeakPtrFactory<CrosDisksClientImpl> weak_ptr_factory_;
460
461 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl);
462};
463
[email protected]85b95a2012012-08-07 18:57:27464} // namespace
[email protected]4ae73292011-11-15 05:20:18465
466////////////////////////////////////////////////////////////////////////////////
467// DiskInfo
468
469DiskInfo::DiskInfo(const std::string& device_path, dbus::Response* response)
470 : device_path_(device_path),
471 is_drive_(false),
472 has_media_(false),
473 on_boot_device_(false),
[email protected]79ed457b2014-07-22 04:07:26474 on_removable_device_(false),
[email protected]4ae73292011-11-15 05:20:18475 is_read_only_(false),
Aga Wronskaddc1a752017-12-01 19:44:02476 is_hidden_(true),
477 is_virtual_(false),
478 device_type_(DEVICE_TYPE_UNKNOWN),
479 total_size_in_bytes_(0) {
[email protected]4ae73292011-11-15 05:20:18480 InitializeFromResponse(response);
481}
482
Chris Watkins2c529d62017-11-29 02:14:41483DiskInfo::~DiskInfo() = default;
[email protected]4ae73292011-11-15 05:20:18484
[email protected]85b95a2012012-08-07 18:57:27485// Initializes |this| from |response| given by the cros-disks service.
[email protected]4ae73292011-11-15 05:20:18486// Below is an example of |response|'s raw message (long string is ellipsized).
487//
488//
489// message_type: MESSAGE_METHOD_RETURN
490// destination: :1.8
491// sender: :1.16
492// signature: a{sv}
493// serial: 96
494// reply_serial: 267
495//
496// array [
497// dict entry {
498// string "DeviceFile"
499// variant string "/dev/sdb"
500// }
501// dict entry {
502// string "DeviceIsDrive"
503// variant bool true
504// }
505// dict entry {
506// string "DeviceIsMediaAvailable"
507// variant bool true
508// }
509// dict entry {
510// string "DeviceIsMounted"
511// variant bool false
512// }
513// dict entry {
514// string "DeviceIsOnBootDevice"
515// variant bool false
516// }
517// dict entry {
[email protected]79ed457b2014-07-22 04:07:26518// string "DeviceIsOnRemovableDevice"
519// variant bool true
520// }
521// dict entry {
[email protected]4ae73292011-11-15 05:20:18522// string "DeviceIsReadOnly"
523// variant bool false
524// }
525// dict entry {
526// string "DeviceIsVirtual"
527// variant bool false
528// }
529// dict entry {
530// string "DeviceMediaType"
avi6e1a22d2015-12-21 03:43:20531// variant uint32_t 1
[email protected]4ae73292011-11-15 05:20:18532// }
533// dict entry {
534// string "DeviceMountPaths"
535// variant array [
536// ]
537// }
538// dict entry {
539// string "DevicePresentationHide"
540// variant bool true
541// }
542// dict entry {
543// string "DeviceSize"
avi6e1a22d2015-12-21 03:43:20544// variant uint64_t 7998537728
[email protected]4ae73292011-11-15 05:20:18545// }
546// dict entry {
547// string "DriveIsRotational"
548// variant bool false
549// }
550// dict entry {
[email protected]202e9fee2012-09-13 20:21:29551// string "VendorId"
552// variant string "18d1"
553// }
554// dict entry {
555// string "VendorName"
556// variant string "Google Inc."
557// }
558// dict entry {
559// string "ProductId"
560// variant string "4e11"
561// }
562// dict entry {
563// string "ProductName"
564// variant string "Nexus One"
565// }
566// dict entry {
[email protected]4ae73292011-11-15 05:20:18567// string "DriveModel"
568// variant string "TransMemory"
569// }
570// dict entry {
571// string "IdLabel"
572// variant string ""
573// }
574// dict entry {
575// string "IdUuid"
576// variant string ""
577// }
578// dict entry {
579// string "NativePath"
580// variant string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
581// }
Klemen Kozjek46f1c6192017-08-25 19:20:54582// dict entry {
583// string "FileSystemType"
584// variant string "vfat"
585// }
[email protected]4ae73292011-11-15 05:20:18586// ]
587void DiskInfo::InitializeFromResponse(dbus::Response* response) {
[email protected]81836aed2013-07-09 23:41:12588 dbus::MessageReader reader(response);
dcheng0a6e80c2016-04-08 18:37:38589 std::unique_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
[email protected]81836aed2013-07-09 23:41:12590 base::DictionaryValue* properties = NULL;
591 if (!value || !value->GetAsDictionary(&properties))
[email protected]4ae73292011-11-15 05:20:18592 return;
[email protected]4ae73292011-11-15 05:20:18593
[email protected]81836aed2013-07-09 23:41:12594 properties->GetBooleanWithoutPathExpansion(
595 cros_disks::kDeviceIsDrive, &is_drive_);
596 properties->GetBooleanWithoutPathExpansion(
597 cros_disks::kDeviceIsReadOnly, &is_read_only_);
598 properties->GetBooleanWithoutPathExpansion(
599 cros_disks::kDevicePresentationHide, &is_hidden_);
600 properties->GetBooleanWithoutPathExpansion(
601 cros_disks::kDeviceIsMediaAvailable, &has_media_);
602 properties->GetBooleanWithoutPathExpansion(
603 cros_disks::kDeviceIsOnBootDevice, &on_boot_device_);
[email protected]79ed457b2014-07-22 04:07:26604 properties->GetBooleanWithoutPathExpansion(
605 cros_disks::kDeviceIsOnRemovableDevice, &on_removable_device_);
Aga Wronskaddc1a752017-12-01 19:44:02606 properties->GetBooleanWithoutPathExpansion(cros_disks::kDeviceIsVirtual,
607 &is_virtual_);
[email protected]81836aed2013-07-09 23:41:12608 properties->GetStringWithoutPathExpansion(
609 cros_disks::kNativePath, &system_path_);
610 properties->GetStringWithoutPathExpansion(
611 cros_disks::kDeviceFile, &file_path_);
612 properties->GetStringWithoutPathExpansion(cros_disks::kVendorId, &vendor_id_);
613 properties->GetStringWithoutPathExpansion(
614 cros_disks::kVendorName, &vendor_name_);
615 properties->GetStringWithoutPathExpansion(
616 cros_disks::kProductId, &product_id_);
617 properties->GetStringWithoutPathExpansion(
618 cros_disks::kProductName, &product_name_);
619 properties->GetStringWithoutPathExpansion(
620 cros_disks::kDriveModel, &drive_model_);
621 properties->GetStringWithoutPathExpansion(cros_disks::kIdLabel, &label_);
622 properties->GetStringWithoutPathExpansion(cros_disks::kIdUuid, &uuid_);
Klemen Kozjek46f1c6192017-08-25 19:20:54623 properties->GetStringWithoutPathExpansion(cros_disks::kFileSystemType,
624 &file_system_type_);
[email protected]2321d282012-01-31 23:06:59625
avi6e1a22d2015-12-21 03:43:20626 // dbus::PopDataAsValue() pops uint64_t as double.
627 // The top 11 bits of uint64_t are dropped by the use of double. But, this
628 // works
[email protected]81836aed2013-07-09 23:41:12629 // unless the size exceeds 8 PB.
630 double device_size_double = 0;
631 if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceSize,
632 &device_size_double))
633 total_size_in_bytes_ = device_size_double;
634
avi6e1a22d2015-12-21 03:43:20635 // dbus::PopDataAsValue() pops uint32_t as double.
[email protected]81836aed2013-07-09 23:41:12636 double media_type_double = 0;
637 if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceMediaType,
638 &media_type_double))
639 device_type_ = DeviceMediaTypeToDeviceType(media_type_double);
640
641 base::ListValue* mount_paths = NULL;
642 if (properties->GetListWithoutPathExpansion(cros_disks::kDeviceMountPaths,
643 &mount_paths))
644 mount_paths->GetString(0, &mount_path_);
[email protected]4ae73292011-11-15 05:20:18645}
646
647////////////////////////////////////////////////////////////////////////////////
648// CrosDisksClient
649
Chris Watkins2c529d62017-11-29 02:14:41650CrosDisksClient::CrosDisksClient() = default;
[email protected]4ae73292011-11-15 05:20:18651
Chris Watkins2c529d62017-11-29 02:14:41652CrosDisksClient::~CrosDisksClient() = default;
[email protected]4ae73292011-11-15 05:20:18653
654// static
[email protected]c5fd5362013-08-27 12:23:04655CrosDisksClient* CrosDisksClient::Create(DBusClientImplementationType type) {
[email protected]e8db03d62012-03-31 04:08:38656 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
[email protected]c5fd5362013-08-27 12:23:04657 return new CrosDisksClientImpl();
jamescook2b590992016-09-14 15:28:45658 DCHECK_EQ(FAKE_DBUS_CLIENT_IMPLEMENTATION, type);
satorux8fd293802014-10-30 08:23:12659 return new FakeCrosDisksClient();
[email protected]4ae73292011-11-15 05:20:18660}
661
[email protected]a5a8b412013-03-04 15:03:11662// static
663base::FilePath CrosDisksClient::GetArchiveMountPoint() {
[email protected]49c4cf852013-09-27 19:28:24664 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
[email protected]a5a8b412013-03-04 15:03:11665 FILE_PATH_LITERAL("/media/archive") :
666 FILE_PATH_LITERAL("/tmp/chromeos/media/archive"));
667}
668
669// static
670base::FilePath CrosDisksClient::GetRemovableDiskMountPoint() {
[email protected]49c4cf852013-09-27 19:28:24671 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
[email protected]a5a8b412013-03-04 15:03:11672 FILE_PATH_LITERAL("/media/removable") :
673 FILE_PATH_LITERAL("/tmp/chromeos/media/removable"));
674}
675
yamaguchi585d5402016-08-02 09:27:36676// static
677std::vector<std::string> CrosDisksClient::ComposeMountOptions(
Sergei Datsenkod19248182018-05-11 01:52:56678 const std::vector<std::string>& options,
yamaguchi585d5402016-08-02 09:27:36679 const std::string& mount_label,
yamaguchifa8efc72016-10-21 15:05:51680 MountAccessMode access_mode,
681 RemountOption remount) {
Sergei Datsenkod19248182018-05-11 01:52:56682 std::vector<std::string> mount_options = options;
683 mount_options.insert(mount_options.end(), kDefaultMountOptions,
684 kDefaultMountOptions + base::size(kDefaultMountOptions));
yamaguchi585d5402016-08-02 09:27:36685 switch (access_mode) {
686 case MOUNT_ACCESS_MODE_READ_ONLY:
687 mount_options.push_back(kReadOnlyOption);
688 break;
689 case MOUNT_ACCESS_MODE_READ_WRITE:
690 mount_options.push_back(kReadWriteOption);
691 break;
692 }
yamaguchifa8efc72016-10-21 15:05:51693 if (remount == REMOUNT_OPTION_REMOUNT_EXISTING_DEVICE) {
694 mount_options.push_back(kRemountOption);
695 }
yamaguchi585d5402016-08-02 09:27:36696
697 if (!mount_label.empty()) {
698 std::string mount_label_option =
699 base::StringPrintf("%s=%s", kMountLabelOption, mount_label.c_str());
700 mount_options.push_back(mount_label_option);
701 }
Sergei Datsenkod19248182018-05-11 01:52:56702
yamaguchi585d5402016-08-02 09:27:36703 return mount_options;
704}
705
[email protected]4ae73292011-11-15 05:20:18706} // namespace chromeos