blob: cb30136096dbb220bf0b2187bb3ae0198ddce923 [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
Sergei Datsenko1fadef32018-05-14 02:14:2337constexpr char kReadOnlyOption[] = "ro";
38constexpr char kReadWriteOption[] = "rw";
39constexpr char kRemountOption[] = "remount";
40constexpr char kMountLabelOption[] = "mountlabel";
41constexpr char kLazyUnmountOption[] = "lazy";
[email protected]10795ae2012-10-10 07:33:4942
[email protected]2321d282012-01-31 23:06:5943// Checks if retrieved media type is in boundaries of DeviceMediaType.
avi6e1a22d2015-12-21 03:43:2044bool IsValidMediaType(uint32_t type) {
45 return type < static_cast<uint32_t>(cros_disks::DEVICE_MEDIA_NUM_VALUES);
[email protected]2321d282012-01-31 23:06:5946}
47
[email protected]2321d282012-01-31 23:06:5948// Translates enum used in cros-disks to enum used in Chrome.
49// Note that we could just do static_cast, but this is less sensitive to
50// changes in cros-disks.
avi6e1a22d2015-12-21 03:43:2051DeviceType DeviceMediaTypeToDeviceType(uint32_t media_type_uint32) {
[email protected]2321d282012-01-31 23:06:5952 if (!IsValidMediaType(media_type_uint32))
53 return DEVICE_TYPE_UNKNOWN;
54
55 cros_disks::DeviceMediaType media_type =
56 cros_disks::DeviceMediaType(media_type_uint32);
57
58 switch (media_type) {
59 case(cros_disks::DEVICE_MEDIA_UNKNOWN):
60 return DEVICE_TYPE_UNKNOWN;
61 case(cros_disks::DEVICE_MEDIA_USB):
62 return DEVICE_TYPE_USB;
63 case(cros_disks::DEVICE_MEDIA_SD):
64 return DEVICE_TYPE_SD;
65 case(cros_disks::DEVICE_MEDIA_OPTICAL_DISC):
66 return DEVICE_TYPE_OPTICAL_DISC;
67 case(cros_disks::DEVICE_MEDIA_MOBILE):
68 return DEVICE_TYPE_MOBILE;
[email protected]f4ae40ac2012-05-04 21:57:0069 case(cros_disks::DEVICE_MEDIA_DVD):
70 return DEVICE_TYPE_DVD;
[email protected]2321d282012-01-31 23:06:5971 default:
72 return DEVICE_TYPE_UNKNOWN;
73 }
[email protected]4ae73292011-11-15 05:20:1874}
75
[email protected]d7760592014-05-16 07:57:5276bool ReadMountEntryFromDbus(dbus::MessageReader* reader, MountEntry* entry) {
avi6e1a22d2015-12-21 03:43:2077 uint32_t error_code = 0;
[email protected]d7760592014-05-16 07:57:5278 std::string source_path;
avi6e1a22d2015-12-21 03:43:2079 uint32_t mount_type = 0;
[email protected]d7760592014-05-16 07:57:5280 std::string mount_path;
81 if (!reader->PopUint32(&error_code) ||
82 !reader->PopString(&source_path) ||
83 !reader->PopUint32(&mount_type) ||
84 !reader->PopString(&mount_path)) {
85 return false;
86 }
87 *entry = MountEntry(static_cast<MountError>(error_code), source_path,
88 static_cast<MountType>(mount_type), mount_path);
89 return true;
90}
91
[email protected]4ae73292011-11-15 05:20:1892// The CrosDisksClient implementation.
93class CrosDisksClientImpl : public CrosDisksClient {
94 public:
Hidehiko Abe06ce6dc2017-12-08 19:32:0395 CrosDisksClientImpl() : proxy_(nullptr), weak_ptr_factory_(this) {}
96
97 // CrosDisksClient override.
98 void AddObserver(Observer* observer) override {
99 observer_list_.AddObserver(observer);
100 }
101
102 // CrosDisksClient override.
103 void RemoveObserver(Observer* observer) override {
104 observer_list_.RemoveObserver(observer);
105 }
[email protected]4ae73292011-11-15 05:20:18106
107 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50108 void Mount(const std::string& source_path,
109 const std::string& source_format,
110 const std::string& mount_label,
Sergei Datsenkod19248182018-05-11 01:52:56111 const std::vector<std::string>& mount_options,
yamaguchi585d5402016-08-02 09:27:36112 MountAccessMode access_mode,
yamaguchifa8efc72016-10-21 15:05:51113 RemountOption remount,
Hidehiko Abec293cdcf2018-02-08 02:10:45114 VoidDBusMethodCallback callback) override {
[email protected]4ae73292011-11-15 05:20:18115 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
116 cros_disks::kMount);
117 dbus::MessageWriter writer(&method_call);
118 writer.AppendString(source_path);
[email protected]b9f22d12012-04-25 21:46:48119 writer.AppendString(source_format);
Sergei Datsenkod19248182018-05-11 01:52:56120 std::vector<std::string> options =
121 ComposeMountOptions(mount_options, mount_label, access_mode, remount);
122 writer.AppendArrayOfStrings(options);
Hidehiko Abec293cdcf2018-02-08 02:10:45123 proxy_->CallMethod(
124 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
125 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
126 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
[email protected]4ae73292011-11-15 05:20:18127 }
128
129 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50130 void Unmount(const std::string& device_path,
131 UnmountOptions options,
Hidehiko Abec293cdcf2018-02-08 02:10:45132 VoidDBusMethodCallback callback) override {
[email protected]4ae73292011-11-15 05:20:18133 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
134 cros_disks::kUnmount);
135 dbus::MessageWriter writer(&method_call);
136 writer.AppendString(device_path);
[email protected]10795ae2012-10-10 07:33:49137
benchan8bcaea12017-03-11 00:26:50138 std::vector<std::string> unmount_options;
[email protected]10795ae2012-10-10 07:33:49139 if (options == UNMOUNT_OPTIONS_LAZY)
140 unmount_options.push_back(kLazyUnmountOption);
141
[email protected]4ae73292011-11-15 05:20:18142 writer.AppendArrayOfStrings(unmount_options);
Hidehiko Abec293cdcf2018-02-08 02:10:45143 proxy_->CallMethod(
144 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
145 base::BindOnce(&CrosDisksClientImpl::OnUnmount,
146 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
[email protected]4ae73292011-11-15 05:20:18147 }
148
Aga Wronskaddc1a752017-12-01 19:44:02149 void EnumerateDevices(const EnumerateDevicesCallback& callback,
150 const base::Closure& error_callback) override {
151 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
152 cros_disks::kEnumerateDevices);
153 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
154 base::BindOnce(&CrosDisksClientImpl::OnEnumerateDevices,
155 weak_ptr_factory_.GetWeakPtr(), callback,
156 error_callback));
[email protected]4ae73292011-11-15 05:20:18157 }
158
159 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50160 void EnumerateMountEntries(const EnumerateMountEntriesCallback& callback,
161 const base::Closure& error_callback) override {
[email protected]d7760592014-05-16 07:57:52162 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
163 cros_disks::kEnumerateMountEntries);
164 proxy_->CallMethod(
165 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
Hidehiko Abed62ed3e2017-09-05 05:16:56166 base::BindOnce(&CrosDisksClientImpl::OnEnumerateMountEntries,
167 weak_ptr_factory_.GetWeakPtr(), callback,
168 error_callback));
[email protected]d7760592014-05-16 07:57:52169 }
170
171 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50172 void Format(const std::string& device_path,
173 const std::string& filesystem,
Hidehiko Abec293cdcf2018-02-08 02:10:45174 VoidDBusMethodCallback callback) override {
[email protected]4ae73292011-11-15 05:20:18175 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
[email protected]f026c0f2014-05-06 21:52:35176 cros_disks::kFormat);
[email protected]4ae73292011-11-15 05:20:18177 dbus::MessageWriter writer(&method_call);
178 writer.AppendString(device_path);
179 writer.AppendString(filesystem);
[email protected]f026c0f2014-05-06 21:52:35180 // No format option is currently specified, but we can later use this
181 // argument to specify options for the format operation.
182 std::vector<std::string> format_options;
183 writer.AppendArrayOfStrings(format_options);
Hidehiko Abec293cdcf2018-02-08 02:10:45184 proxy_->CallMethod(
185 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
186 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
187 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
[email protected]4ae73292011-11-15 05:20:18188 }
189
Klemen Kozjekbf5610f2017-08-25 20:20:09190 void Rename(const std::string& device_path,
191 const std::string& volume_name,
Hidehiko Abec293cdcf2018-02-08 02:10:45192 VoidDBusMethodCallback callback) override {
Klemen Kozjekbf5610f2017-08-25 20:20:09193 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
194 cros_disks::kRename);
195 dbus::MessageWriter writer(&method_call);
196 writer.AppendString(device_path);
197 writer.AppendString(volume_name);
Hidehiko Abec293cdcf2018-02-08 02:10:45198 proxy_->CallMethod(
199 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
200 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
201 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
Klemen Kozjekbf5610f2017-08-25 20:20:09202 }
203
[email protected]4ae73292011-11-15 05:20:18204 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50205 void GetDeviceProperties(const std::string& device_path,
206 const GetDevicePropertiesCallback& callback,
207 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18208 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
209 cros_disks::kGetDeviceProperties);
210 dbus::MessageWriter writer(&method_call);
211 writer.AppendString(device_path);
Hidehiko Abed62ed3e2017-09-05 05:16:56212 proxy_->CallMethod(
213 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
214 base::BindOnce(&CrosDisksClientImpl::OnGetDeviceProperties,
215 weak_ptr_factory_.GetWeakPtr(), device_path, callback,
216 error_callback));
[email protected]4ae73292011-11-15 05:20:18217 }
218
[email protected]c5fd5362013-08-27 12:23:04219 protected:
dcheng0280cb62015-01-16 07:37:50220 void Init(dbus::Bus* bus) override {
[email protected]c5fd5362013-08-27 12:23:04221 proxy_ = bus->GetObjectProxy(
222 cros_disks::kCrosDisksServiceName,
223 dbus::ObjectPath(cros_disks::kCrosDisksServicePath));
Hidehiko Abe06ce6dc2017-12-08 19:32:03224
225 // Register handlers for D-Bus signals.
226 constexpr SignalEventTuple kSignalEventTuples[] = {
227 {cros_disks::kDeviceAdded, CROS_DISKS_DEVICE_ADDED},
228 {cros_disks::kDeviceScanned, CROS_DISKS_DEVICE_SCANNED},
229 {cros_disks::kDeviceRemoved, CROS_DISKS_DEVICE_REMOVED},
230 {cros_disks::kDiskAdded, CROS_DISKS_DISK_ADDED},
231 {cros_disks::kDiskChanged, CROS_DISKS_DISK_CHANGED},
232 {cros_disks::kDiskRemoved, CROS_DISKS_DISK_REMOVED},
233 };
234 for (const auto& entry : kSignalEventTuples) {
235 proxy_->ConnectToSignal(
236 cros_disks::kCrosDisksInterface, entry.signal_name,
237 base::BindRepeating(&CrosDisksClientImpl::OnMountEvent,
238 weak_ptr_factory_.GetWeakPtr(), entry.event_type),
239 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
240 weak_ptr_factory_.GetWeakPtr()));
241 }
242
243 proxy_->ConnectToSignal(
244 cros_disks::kCrosDisksInterface, cros_disks::kMountCompleted,
245 base::BindRepeating(&CrosDisksClientImpl::OnMountCompleted,
246 weak_ptr_factory_.GetWeakPtr()),
247 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
248 weak_ptr_factory_.GetWeakPtr()));
249
250 proxy_->ConnectToSignal(
251 cros_disks::kCrosDisksInterface, cros_disks::kFormatCompleted,
252 base::BindRepeating(&CrosDisksClientImpl::OnFormatCompleted,
253 weak_ptr_factory_.GetWeakPtr()),
254 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
255 weak_ptr_factory_.GetWeakPtr()));
256
257 proxy_->ConnectToSignal(
258 cros_disks::kCrosDisksInterface, cros_disks::kRenameCompleted,
259 base::BindRepeating(&CrosDisksClientImpl::OnRenameCompleted,
260 weak_ptr_factory_.GetWeakPtr()),
261 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
262 weak_ptr_factory_.GetWeakPtr()));
[email protected]c5fd5362013-08-27 12:23:04263 }
264
[email protected]4ae73292011-11-15 05:20:18265 private:
266 // A struct to contain a pair of signal name and mount event type.
[email protected]a0278d52014-05-06 03:36:15267 // Used by SetMountEventHandler.
[email protected]4ae73292011-11-15 05:20:18268 struct SignalEventTuple {
269 const char *signal_name;
270 MountEventType event_type;
271 };
272
Hidehiko Abec293cdcf2018-02-08 02:10:45273 // Handles the result of D-Bus method call with no return value.
274 void OnVoidMethod(VoidDBusMethodCallback callback, dbus::Response* response) {
275 std::move(callback).Run(response);
[email protected]4ae73292011-11-15 05:20:18276 }
277
[email protected]d7760592014-05-16 07:57:52278 // Handles the result of Unmount and calls |callback| or |error_callback|.
Hidehiko Abec293cdcf2018-02-08 02:10:45279 void OnUnmount(VoidDBusMethodCallback callback, dbus::Response* response) {
[email protected]4ae73292011-11-15 05:20:18280 if (!response) {
Hidehiko Abec293cdcf2018-02-08 02:10:45281 std::move(callback).Run(false);
[email protected]4ae73292011-11-15 05:20:18282 return;
283 }
[email protected]ddcb18e2013-09-19 07:17:28284
285 // Temporarly allow Unmount method to report failure both by setting dbus
286 // error (in which case response is not set) and by returning mount error
287 // different from MOUNT_ERROR_NONE. This is done so we can change Unmount
288 // method to return mount error (http://crbug.com/288974) without breaking
289 // Chrome.
290 // TODO(tbarzic): When Unmount implementation is changed on cros disks side,
291 // make this fail if reader is not able to read the error code value from
292 // the response.
293 dbus::MessageReader reader(response);
avi6e1a22d2015-12-21 03:43:20294 uint32_t error_code = 0;
[email protected]ddcb18e2013-09-19 07:17:28295 if (reader.PopUint32(&error_code) &&
296 static_cast<MountError>(error_code) != MOUNT_ERROR_NONE) {
Hidehiko Abec293cdcf2018-02-08 02:10:45297 std::move(callback).Run(false);
[email protected]ddcb18e2013-09-19 07:17:28298 return;
299 }
300
Hidehiko Abec293cdcf2018-02-08 02:10:45301 std::move(callback).Run(true);
[email protected]4ae73292011-11-15 05:20:18302 }
303
Aga Wronskaddc1a752017-12-01 19:44:02304 // Handles the result of EnumerateDevices and EnumarateAutoMountableDevices.
305 // Calls |callback| or |error_callback|.
306 void OnEnumerateDevices(const EnumerateDevicesCallback& callback,
307 const base::Closure& error_callback,
308 dbus::Response* response) {
[email protected]4ae73292011-11-15 05:20:18309 if (!response) {
310 error_callback.Run();
311 return;
312 }
313 dbus::MessageReader reader(response);
314 std::vector<std::string> device_paths;
315 if (!reader.PopArrayOfStrings(&device_paths)) {
316 LOG(ERROR) << "Invalid response: " << response->ToString();
317 error_callback.Run();
318 return;
319 }
320 callback.Run(device_paths);
321 }
322
[email protected]d7760592014-05-16 07:57:52323 // Handles the result of EnumerateMountEntries and calls |callback| or
324 // |error_callback|.
325 void OnEnumerateMountEntries(
326 const EnumerateMountEntriesCallback& callback,
327 const base::Closure& error_callback,
328 dbus::Response* response) {
329 if (!response) {
330 error_callback.Run();
331 return;
332 }
333
334 dbus::MessageReader reader(response);
335 dbus::MessageReader array_reader(NULL);
336 if (!reader.PopArray(&array_reader)) {
337 LOG(ERROR) << "Invalid response: " << response->ToString();
338 error_callback.Run();
339 return;
340 }
341
342 std::vector<MountEntry> entries;
343 while (array_reader.HasMoreData()) {
344 MountEntry entry;
345 dbus::MessageReader sub_reader(NULL);
346 if (!array_reader.PopStruct(&sub_reader) ||
347 !ReadMountEntryFromDbus(&sub_reader, &entry)) {
348 LOG(ERROR) << "Invalid response: " << response->ToString();
349 error_callback.Run();
350 return;
351 }
352 entries.push_back(entry);
353 }
354 callback.Run(entries);
355 }
356
[email protected]4ae73292011-11-15 05:20:18357 // Handles the result of GetDeviceProperties and calls |callback| or
358 // |error_callback|.
359 void OnGetDeviceProperties(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35360 const GetDevicePropertiesCallback& callback,
[email protected]5624a252013-07-04 03:17:53361 const base::Closure& error_callback,
[email protected]4ae73292011-11-15 05:20:18362 dbus::Response* response) {
363 if (!response) {
364 error_callback.Run();
365 return;
366 }
367 DiskInfo disk(device_path, response);
368 callback.Run(disk);
369 }
370
Hidehiko Abe06ce6dc2017-12-08 19:32:03371 // Handles mount event signals and notifies observers.
372 void OnMountEvent(MountEventType event_type, dbus::Signal* signal) {
[email protected]4ae73292011-11-15 05:20:18373 dbus::MessageReader reader(signal);
374 std::string device;
375 if (!reader.PopString(&device)) {
376 LOG(ERROR) << "Invalid signal: " << signal->ToString();
377 return;
378 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03379
380 for (auto& observer : observer_list_)
381 observer.OnMountEvent(event_type, device);
[email protected]4ae73292011-11-15 05:20:18382 }
383
Hidehiko Abe06ce6dc2017-12-08 19:32:03384 // Handles MountCompleted signal and notifies observers.
385 void OnMountCompleted(dbus::Signal* signal) {
[email protected]4ae73292011-11-15 05:20:18386 dbus::MessageReader reader(signal);
[email protected]d7760592014-05-16 07:57:52387 MountEntry entry;
388 if (!ReadMountEntryFromDbus(&reader, &entry)) {
[email protected]4ae73292011-11-15 05:20:18389 LOG(ERROR) << "Invalid signal: " << signal->ToString();
390 return;
391 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03392
393 for (auto& observer : observer_list_)
394 observer.OnMountCompleted(entry);
[email protected]4ae73292011-11-15 05:20:18395 }
396
Hidehiko Abe06ce6dc2017-12-08 19:32:03397 // Handles FormatCompleted signal and notifies observers.
398 void OnFormatCompleted(dbus::Signal* signal) {
[email protected]a0278d52014-05-06 03:36:15399 dbus::MessageReader reader(signal);
avi6e1a22d2015-12-21 03:43:20400 uint32_t error_code = 0;
[email protected]a0278d52014-05-06 03:36:15401 std::string device_path;
402 if (!reader.PopUint32(&error_code) || !reader.PopString(&device_path)) {
403 LOG(ERROR) << "Invalid signal: " << signal->ToString();
404 return;
405 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03406
407 for (auto& observer : observer_list_) {
408 observer.OnFormatCompleted(static_cast<FormatError>(error_code),
409 device_path);
410 }
[email protected]a0278d52014-05-06 03:36:15411 }
412
Hidehiko Abe06ce6dc2017-12-08 19:32:03413 // Handles RenameCompleted signal and notifies observers.
414 void OnRenameCompleted(dbus::Signal* signal) {
Klemen Kozjekbf5610f2017-08-25 20:20:09415 dbus::MessageReader reader(signal);
416 uint32_t error_code = 0;
417 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.OnRenameCompleted(static_cast<RenameError>(error_code),
425 device_path);
426 }
Klemen Kozjekbf5610f2017-08-25 20:20:09427 }
428
[email protected]4ae73292011-11-15 05:20:18429 // Handles the result of signal connection setup.
430 void OnSignalConnected(const std::string& interface,
431 const std::string& signal,
[email protected]d6311dcb2012-10-22 03:40:43432 bool succeeded) {
433 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
[email protected]4ae73292011-11-15 05:20:18434 signal << " failed.";
435 }
436
437 dbus::ObjectProxy* proxy_;
[email protected]926957b2012-09-07 05:34:16438
Hidehiko Abe06ce6dc2017-12-08 19:32:03439 base::ObserverList<Observer> observer_list_;
440
[email protected]926957b2012-09-07 05:34:16441 // Note: This should remain the last member so it'll be destroyed and
442 // invalidate its weak pointers before any other members are destroyed.
[email protected]4ae73292011-11-15 05:20:18443 base::WeakPtrFactory<CrosDisksClientImpl> weak_ptr_factory_;
444
445 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl);
446};
447
[email protected]85b95a2012012-08-07 18:57:27448} // namespace
[email protected]4ae73292011-11-15 05:20:18449
450////////////////////////////////////////////////////////////////////////////////
451// DiskInfo
452
453DiskInfo::DiskInfo(const std::string& device_path, dbus::Response* response)
454 : device_path_(device_path),
455 is_drive_(false),
456 has_media_(false),
457 on_boot_device_(false),
[email protected]79ed457b2014-07-22 04:07:26458 on_removable_device_(false),
[email protected]4ae73292011-11-15 05:20:18459 is_read_only_(false),
Aga Wronskaddc1a752017-12-01 19:44:02460 is_hidden_(true),
461 is_virtual_(false),
Anand K. Mistry2a5ed862018-08-08 00:53:31462 is_auto_mountable_(false),
Aga Wronskaddc1a752017-12-01 19:44:02463 device_type_(DEVICE_TYPE_UNKNOWN),
464 total_size_in_bytes_(0) {
[email protected]4ae73292011-11-15 05:20:18465 InitializeFromResponse(response);
466}
467
Chris Watkins2c529d62017-11-29 02:14:41468DiskInfo::~DiskInfo() = default;
[email protected]4ae73292011-11-15 05:20:18469
[email protected]85b95a2012012-08-07 18:57:27470// Initializes |this| from |response| given by the cros-disks service.
[email protected]4ae73292011-11-15 05:20:18471// Below is an example of |response|'s raw message (long string is ellipsized).
472//
473//
474// message_type: MESSAGE_METHOD_RETURN
475// destination: :1.8
476// sender: :1.16
477// signature: a{sv}
478// serial: 96
479// reply_serial: 267
480//
481// array [
482// dict entry {
483// string "DeviceFile"
484// variant string "/dev/sdb"
485// }
486// dict entry {
487// string "DeviceIsDrive"
488// variant bool true
489// }
490// dict entry {
491// string "DeviceIsMediaAvailable"
492// variant bool true
493// }
494// dict entry {
495// string "DeviceIsMounted"
496// variant bool false
497// }
498// dict entry {
499// string "DeviceIsOnBootDevice"
500// variant bool false
501// }
502// dict entry {
[email protected]79ed457b2014-07-22 04:07:26503// string "DeviceIsOnRemovableDevice"
504// variant bool true
505// }
506// dict entry {
[email protected]4ae73292011-11-15 05:20:18507// string "DeviceIsReadOnly"
508// variant bool false
509// }
510// dict entry {
511// string "DeviceIsVirtual"
512// variant bool false
513// }
514// dict entry {
515// string "DeviceMediaType"
avi6e1a22d2015-12-21 03:43:20516// variant uint32_t 1
[email protected]4ae73292011-11-15 05:20:18517// }
518// dict entry {
519// string "DeviceMountPaths"
520// variant array [
521// ]
522// }
523// dict entry {
524// string "DevicePresentationHide"
525// variant bool true
526// }
527// dict entry {
528// string "DeviceSize"
avi6e1a22d2015-12-21 03:43:20529// variant uint64_t 7998537728
[email protected]4ae73292011-11-15 05:20:18530// }
531// dict entry {
532// string "DriveIsRotational"
533// variant bool false
534// }
535// dict entry {
[email protected]202e9fee2012-09-13 20:21:29536// string "VendorId"
537// variant string "18d1"
538// }
539// dict entry {
540// string "VendorName"
541// variant string "Google Inc."
542// }
543// dict entry {
544// string "ProductId"
545// variant string "4e11"
546// }
547// dict entry {
548// string "ProductName"
549// variant string "Nexus One"
550// }
551// dict entry {
[email protected]4ae73292011-11-15 05:20:18552// string "DriveModel"
553// variant string "TransMemory"
554// }
555// dict entry {
556// string "IdLabel"
557// variant string ""
558// }
559// dict entry {
560// string "IdUuid"
561// variant string ""
562// }
563// dict entry {
564// string "NativePath"
565// variant string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
566// }
Klemen Kozjek46f1c6192017-08-25 19:20:54567// dict entry {
568// string "FileSystemType"
569// variant string "vfat"
570// }
[email protected]4ae73292011-11-15 05:20:18571// ]
572void DiskInfo::InitializeFromResponse(dbus::Response* response) {
[email protected]81836aed2013-07-09 23:41:12573 dbus::MessageReader reader(response);
dcheng0a6e80c2016-04-08 18:37:38574 std::unique_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
[email protected]81836aed2013-07-09 23:41:12575 base::DictionaryValue* properties = NULL;
576 if (!value || !value->GetAsDictionary(&properties))
[email protected]4ae73292011-11-15 05:20:18577 return;
[email protected]4ae73292011-11-15 05:20:18578
[email protected]81836aed2013-07-09 23:41:12579 properties->GetBooleanWithoutPathExpansion(
580 cros_disks::kDeviceIsDrive, &is_drive_);
581 properties->GetBooleanWithoutPathExpansion(
582 cros_disks::kDeviceIsReadOnly, &is_read_only_);
583 properties->GetBooleanWithoutPathExpansion(
584 cros_disks::kDevicePresentationHide, &is_hidden_);
585 properties->GetBooleanWithoutPathExpansion(
586 cros_disks::kDeviceIsMediaAvailable, &has_media_);
587 properties->GetBooleanWithoutPathExpansion(
588 cros_disks::kDeviceIsOnBootDevice, &on_boot_device_);
[email protected]79ed457b2014-07-22 04:07:26589 properties->GetBooleanWithoutPathExpansion(
590 cros_disks::kDeviceIsOnRemovableDevice, &on_removable_device_);
Aga Wronskaddc1a752017-12-01 19:44:02591 properties->GetBooleanWithoutPathExpansion(cros_disks::kDeviceIsVirtual,
592 &is_virtual_);
Anand K. Mistry2a5ed862018-08-08 00:53:31593 properties->GetBooleanWithoutPathExpansion(cros_disks::kIsAutoMountable,
594 &is_auto_mountable_);
[email protected]81836aed2013-07-09 23:41:12595 properties->GetStringWithoutPathExpansion(
596 cros_disks::kNativePath, &system_path_);
597 properties->GetStringWithoutPathExpansion(
598 cros_disks::kDeviceFile, &file_path_);
599 properties->GetStringWithoutPathExpansion(cros_disks::kVendorId, &vendor_id_);
600 properties->GetStringWithoutPathExpansion(
601 cros_disks::kVendorName, &vendor_name_);
602 properties->GetStringWithoutPathExpansion(
603 cros_disks::kProductId, &product_id_);
604 properties->GetStringWithoutPathExpansion(
605 cros_disks::kProductName, &product_name_);
606 properties->GetStringWithoutPathExpansion(
607 cros_disks::kDriveModel, &drive_model_);
608 properties->GetStringWithoutPathExpansion(cros_disks::kIdLabel, &label_);
609 properties->GetStringWithoutPathExpansion(cros_disks::kIdUuid, &uuid_);
Klemen Kozjek46f1c6192017-08-25 19:20:54610 properties->GetStringWithoutPathExpansion(cros_disks::kFileSystemType,
611 &file_system_type_);
[email protected]2321d282012-01-31 23:06:59612
avi6e1a22d2015-12-21 03:43:20613 // dbus::PopDataAsValue() pops uint64_t as double.
614 // The top 11 bits of uint64_t are dropped by the use of double. But, this
615 // works
[email protected]81836aed2013-07-09 23:41:12616 // unless the size exceeds 8 PB.
617 double device_size_double = 0;
618 if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceSize,
619 &device_size_double))
620 total_size_in_bytes_ = device_size_double;
621
avi6e1a22d2015-12-21 03:43:20622 // dbus::PopDataAsValue() pops uint32_t as double.
[email protected]81836aed2013-07-09 23:41:12623 double media_type_double = 0;
624 if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceMediaType,
625 &media_type_double))
626 device_type_ = DeviceMediaTypeToDeviceType(media_type_double);
627
628 base::ListValue* mount_paths = NULL;
629 if (properties->GetListWithoutPathExpansion(cros_disks::kDeviceMountPaths,
630 &mount_paths))
631 mount_paths->GetString(0, &mount_path_);
[email protected]4ae73292011-11-15 05:20:18632}
633
634////////////////////////////////////////////////////////////////////////////////
635// CrosDisksClient
636
Chris Watkins2c529d62017-11-29 02:14:41637CrosDisksClient::CrosDisksClient() = default;
[email protected]4ae73292011-11-15 05:20:18638
Chris Watkins2c529d62017-11-29 02:14:41639CrosDisksClient::~CrosDisksClient() = default;
[email protected]4ae73292011-11-15 05:20:18640
641// static
[email protected]c5fd5362013-08-27 12:23:04642CrosDisksClient* CrosDisksClient::Create(DBusClientImplementationType type) {
[email protected]e8db03d62012-03-31 04:08:38643 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
[email protected]c5fd5362013-08-27 12:23:04644 return new CrosDisksClientImpl();
jamescook2b590992016-09-14 15:28:45645 DCHECK_EQ(FAKE_DBUS_CLIENT_IMPLEMENTATION, type);
satorux8fd293802014-10-30 08:23:12646 return new FakeCrosDisksClient();
[email protected]4ae73292011-11-15 05:20:18647}
648
[email protected]a5a8b412013-03-04 15:03:11649// static
650base::FilePath CrosDisksClient::GetArchiveMountPoint() {
[email protected]49c4cf852013-09-27 19:28:24651 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
[email protected]a5a8b412013-03-04 15:03:11652 FILE_PATH_LITERAL("/media/archive") :
653 FILE_PATH_LITERAL("/tmp/chromeos/media/archive"));
654}
655
656// static
657base::FilePath CrosDisksClient::GetRemovableDiskMountPoint() {
[email protected]49c4cf852013-09-27 19:28:24658 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
[email protected]a5a8b412013-03-04 15:03:11659 FILE_PATH_LITERAL("/media/removable") :
660 FILE_PATH_LITERAL("/tmp/chromeos/media/removable"));
661}
662
yamaguchi585d5402016-08-02 09:27:36663// static
664std::vector<std::string> CrosDisksClient::ComposeMountOptions(
Sergei Datsenkod19248182018-05-11 01:52:56665 const std::vector<std::string>& options,
yamaguchi585d5402016-08-02 09:27:36666 const std::string& mount_label,
yamaguchifa8efc72016-10-21 15:05:51667 MountAccessMode access_mode,
668 RemountOption remount) {
Sergei Datsenkod19248182018-05-11 01:52:56669 std::vector<std::string> mount_options = options;
yamaguchi585d5402016-08-02 09:27:36670 switch (access_mode) {
671 case MOUNT_ACCESS_MODE_READ_ONLY:
672 mount_options.push_back(kReadOnlyOption);
673 break;
674 case MOUNT_ACCESS_MODE_READ_WRITE:
675 mount_options.push_back(kReadWriteOption);
676 break;
677 }
yamaguchifa8efc72016-10-21 15:05:51678 if (remount == REMOUNT_OPTION_REMOUNT_EXISTING_DEVICE) {
679 mount_options.push_back(kRemountOption);
680 }
yamaguchi585d5402016-08-02 09:27:36681
682 if (!mount_label.empty()) {
683 std::string mount_label_option =
684 base::StringPrintf("%s=%s", kMountLabelOption, mount_label.c_str());
685 mount_options.push_back(mount_label_option);
686 }
Sergei Datsenkod19248182018-05-11 01:52:56687
yamaguchi585d5402016-08-02 09:27:36688 return mount_options;
689}
690
[email protected]4ae73292011-11-15 05:20:18691} // namespace chromeos