blob: 3b7d4ad267c34dad6b313ed9d4486aadd83ea555 [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,
yamaguchi585d5402016-08-02 09:27:36115 MountAccessMode access_mode,
yamaguchifa8efc72016-10-21 15:05:51116 RemountOption remount,
Hidehiko Abec293cdcf2018-02-08 02:10:45117 VoidDBusMethodCallback callback) override {
[email protected]4ae73292011-11-15 05:20:18118 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
119 cros_disks::kMount);
120 dbus::MessageWriter writer(&method_call);
121 writer.AppendString(source_path);
[email protected]b9f22d12012-04-25 21:46:48122 writer.AppendString(source_format);
yamaguchi585d5402016-08-02 09:27:36123 std::vector<std::string> mount_options =
yamaguchifa8efc72016-10-21 15:05:51124 ComposeMountOptions(mount_label, access_mode, remount);
[email protected]4ae73292011-11-15 05:20:18125 writer.AppendArrayOfStrings(mount_options);
Hidehiko Abec293cdcf2018-02-08 02:10:45126 proxy_->CallMethod(
127 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
128 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
129 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
[email protected]4ae73292011-11-15 05:20:18130 }
131
132 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50133 void Unmount(const std::string& device_path,
134 UnmountOptions options,
Hidehiko Abec293cdcf2018-02-08 02:10:45135 VoidDBusMethodCallback callback) override {
[email protected]4ae73292011-11-15 05:20:18136 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
137 cros_disks::kUnmount);
138 dbus::MessageWriter writer(&method_call);
139 writer.AppendString(device_path);
[email protected]10795ae2012-10-10 07:33:49140
benchan8bcaea12017-03-11 00:26:50141 std::vector<std::string> unmount_options;
[email protected]10795ae2012-10-10 07:33:49142 if (options == UNMOUNT_OPTIONS_LAZY)
143 unmount_options.push_back(kLazyUnmountOption);
144
[email protected]4ae73292011-11-15 05:20:18145 writer.AppendArrayOfStrings(unmount_options);
Hidehiko Abec293cdcf2018-02-08 02:10:45146 proxy_->CallMethod(
147 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
148 base::BindOnce(&CrosDisksClientImpl::OnUnmount,
149 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
[email protected]4ae73292011-11-15 05:20:18150 }
151
152 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50153 void EnumerateAutoMountableDevices(
Aga Wronskaddc1a752017-12-01 19:44:02154 const EnumerateDevicesCallback& callback,
mostynb4f4cf142014-10-06 13:57:52155 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18156 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
157 cros_disks::kEnumerateAutoMountableDevices);
Aga Wronskaddc1a752017-12-01 19:44:02158 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
159 base::BindOnce(&CrosDisksClientImpl::OnEnumerateDevices,
160 weak_ptr_factory_.GetWeakPtr(), callback,
161 error_callback));
162 }
163
164 void EnumerateDevices(const EnumerateDevicesCallback& callback,
165 const base::Closure& error_callback) override {
166 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
167 cros_disks::kEnumerateDevices);
168 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
169 base::BindOnce(&CrosDisksClientImpl::OnEnumerateDevices,
170 weak_ptr_factory_.GetWeakPtr(), callback,
171 error_callback));
[email protected]4ae73292011-11-15 05:20:18172 }
173
174 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50175 void EnumerateMountEntries(const EnumerateMountEntriesCallback& callback,
176 const base::Closure& error_callback) override {
[email protected]d7760592014-05-16 07:57:52177 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
178 cros_disks::kEnumerateMountEntries);
179 proxy_->CallMethod(
180 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
Hidehiko Abed62ed3e2017-09-05 05:16:56181 base::BindOnce(&CrosDisksClientImpl::OnEnumerateMountEntries,
182 weak_ptr_factory_.GetWeakPtr(), callback,
183 error_callback));
[email protected]d7760592014-05-16 07:57:52184 }
185
186 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50187 void Format(const std::string& device_path,
188 const std::string& filesystem,
Hidehiko Abec293cdcf2018-02-08 02:10:45189 VoidDBusMethodCallback callback) override {
[email protected]4ae73292011-11-15 05:20:18190 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
[email protected]f026c0f2014-05-06 21:52:35191 cros_disks::kFormat);
[email protected]4ae73292011-11-15 05:20:18192 dbus::MessageWriter writer(&method_call);
193 writer.AppendString(device_path);
194 writer.AppendString(filesystem);
[email protected]f026c0f2014-05-06 21:52:35195 // No format option is currently specified, but we can later use this
196 // argument to specify options for the format operation.
197 std::vector<std::string> format_options;
198 writer.AppendArrayOfStrings(format_options);
Hidehiko Abec293cdcf2018-02-08 02:10:45199 proxy_->CallMethod(
200 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
201 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
202 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
[email protected]4ae73292011-11-15 05:20:18203 }
204
Klemen Kozjekbf5610f2017-08-25 20:20:09205 void Rename(const std::string& device_path,
206 const std::string& volume_name,
Hidehiko Abec293cdcf2018-02-08 02:10:45207 VoidDBusMethodCallback callback) override {
Klemen Kozjekbf5610f2017-08-25 20:20:09208 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
209 cros_disks::kRename);
210 dbus::MessageWriter writer(&method_call);
211 writer.AppendString(device_path);
212 writer.AppendString(volume_name);
Hidehiko Abec293cdcf2018-02-08 02:10:45213 proxy_->CallMethod(
214 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
215 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
216 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
Klemen Kozjekbf5610f2017-08-25 20:20:09217 }
218
[email protected]4ae73292011-11-15 05:20:18219 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50220 void GetDeviceProperties(const std::string& device_path,
221 const GetDevicePropertiesCallback& callback,
222 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18223 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
224 cros_disks::kGetDeviceProperties);
225 dbus::MessageWriter writer(&method_call);
226 writer.AppendString(device_path);
Hidehiko Abed62ed3e2017-09-05 05:16:56227 proxy_->CallMethod(
228 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
229 base::BindOnce(&CrosDisksClientImpl::OnGetDeviceProperties,
230 weak_ptr_factory_.GetWeakPtr(), device_path, callback,
231 error_callback));
[email protected]4ae73292011-11-15 05:20:18232 }
233
[email protected]c5fd5362013-08-27 12:23:04234 protected:
dcheng0280cb62015-01-16 07:37:50235 void Init(dbus::Bus* bus) override {
[email protected]c5fd5362013-08-27 12:23:04236 proxy_ = bus->GetObjectProxy(
237 cros_disks::kCrosDisksServiceName,
238 dbus::ObjectPath(cros_disks::kCrosDisksServicePath));
Hidehiko Abe06ce6dc2017-12-08 19:32:03239
240 // Register handlers for D-Bus signals.
241 constexpr SignalEventTuple kSignalEventTuples[] = {
242 {cros_disks::kDeviceAdded, CROS_DISKS_DEVICE_ADDED},
243 {cros_disks::kDeviceScanned, CROS_DISKS_DEVICE_SCANNED},
244 {cros_disks::kDeviceRemoved, CROS_DISKS_DEVICE_REMOVED},
245 {cros_disks::kDiskAdded, CROS_DISKS_DISK_ADDED},
246 {cros_disks::kDiskChanged, CROS_DISKS_DISK_CHANGED},
247 {cros_disks::kDiskRemoved, CROS_DISKS_DISK_REMOVED},
248 };
249 for (const auto& entry : kSignalEventTuples) {
250 proxy_->ConnectToSignal(
251 cros_disks::kCrosDisksInterface, entry.signal_name,
252 base::BindRepeating(&CrosDisksClientImpl::OnMountEvent,
253 weak_ptr_factory_.GetWeakPtr(), entry.event_type),
254 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
255 weak_ptr_factory_.GetWeakPtr()));
256 }
257
258 proxy_->ConnectToSignal(
259 cros_disks::kCrosDisksInterface, cros_disks::kMountCompleted,
260 base::BindRepeating(&CrosDisksClientImpl::OnMountCompleted,
261 weak_ptr_factory_.GetWeakPtr()),
262 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
263 weak_ptr_factory_.GetWeakPtr()));
264
265 proxy_->ConnectToSignal(
266 cros_disks::kCrosDisksInterface, cros_disks::kFormatCompleted,
267 base::BindRepeating(&CrosDisksClientImpl::OnFormatCompleted,
268 weak_ptr_factory_.GetWeakPtr()),
269 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
270 weak_ptr_factory_.GetWeakPtr()));
271
272 proxy_->ConnectToSignal(
273 cros_disks::kCrosDisksInterface, cros_disks::kRenameCompleted,
274 base::BindRepeating(&CrosDisksClientImpl::OnRenameCompleted,
275 weak_ptr_factory_.GetWeakPtr()),
276 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
277 weak_ptr_factory_.GetWeakPtr()));
[email protected]c5fd5362013-08-27 12:23:04278 }
279
[email protected]4ae73292011-11-15 05:20:18280 private:
281 // A struct to contain a pair of signal name and mount event type.
[email protected]a0278d52014-05-06 03:36:15282 // Used by SetMountEventHandler.
[email protected]4ae73292011-11-15 05:20:18283 struct SignalEventTuple {
284 const char *signal_name;
285 MountEventType event_type;
286 };
287
Hidehiko Abec293cdcf2018-02-08 02:10:45288 // Handles the result of D-Bus method call with no return value.
289 void OnVoidMethod(VoidDBusMethodCallback callback, dbus::Response* response) {
290 std::move(callback).Run(response);
[email protected]4ae73292011-11-15 05:20:18291 }
292
[email protected]d7760592014-05-16 07:57:52293 // Handles the result of Unmount and calls |callback| or |error_callback|.
Hidehiko Abec293cdcf2018-02-08 02:10:45294 void OnUnmount(VoidDBusMethodCallback callback, dbus::Response* response) {
[email protected]4ae73292011-11-15 05:20:18295 if (!response) {
Hidehiko Abec293cdcf2018-02-08 02:10:45296 std::move(callback).Run(false);
[email protected]4ae73292011-11-15 05:20:18297 return;
298 }
[email protected]ddcb18e2013-09-19 07:17:28299
300 // Temporarly allow Unmount method to report failure both by setting dbus
301 // error (in which case response is not set) and by returning mount error
302 // different from MOUNT_ERROR_NONE. This is done so we can change Unmount
303 // method to return mount error (http://crbug.com/288974) without breaking
304 // Chrome.
305 // TODO(tbarzic): When Unmount implementation is changed on cros disks side,
306 // make this fail if reader is not able to read the error code value from
307 // the response.
308 dbus::MessageReader reader(response);
avi6e1a22d2015-12-21 03:43:20309 uint32_t error_code = 0;
[email protected]ddcb18e2013-09-19 07:17:28310 if (reader.PopUint32(&error_code) &&
311 static_cast<MountError>(error_code) != MOUNT_ERROR_NONE) {
Hidehiko Abec293cdcf2018-02-08 02:10:45312 std::move(callback).Run(false);
[email protected]ddcb18e2013-09-19 07:17:28313 return;
314 }
315
Hidehiko Abec293cdcf2018-02-08 02:10:45316 std::move(callback).Run(true);
[email protected]4ae73292011-11-15 05:20:18317 }
318
Aga Wronskaddc1a752017-12-01 19:44:02319 // Handles the result of EnumerateDevices and EnumarateAutoMountableDevices.
320 // Calls |callback| or |error_callback|.
321 void OnEnumerateDevices(const EnumerateDevicesCallback& callback,
322 const base::Closure& error_callback,
323 dbus::Response* response) {
[email protected]4ae73292011-11-15 05:20:18324 if (!response) {
325 error_callback.Run();
326 return;
327 }
328 dbus::MessageReader reader(response);
329 std::vector<std::string> device_paths;
330 if (!reader.PopArrayOfStrings(&device_paths)) {
331 LOG(ERROR) << "Invalid response: " << response->ToString();
332 error_callback.Run();
333 return;
334 }
335 callback.Run(device_paths);
336 }
337
[email protected]d7760592014-05-16 07:57:52338 // Handles the result of EnumerateMountEntries and calls |callback| or
339 // |error_callback|.
340 void OnEnumerateMountEntries(
341 const EnumerateMountEntriesCallback& callback,
342 const base::Closure& error_callback,
343 dbus::Response* response) {
344 if (!response) {
345 error_callback.Run();
346 return;
347 }
348
349 dbus::MessageReader reader(response);
350 dbus::MessageReader array_reader(NULL);
351 if (!reader.PopArray(&array_reader)) {
352 LOG(ERROR) << "Invalid response: " << response->ToString();
353 error_callback.Run();
354 return;
355 }
356
357 std::vector<MountEntry> entries;
358 while (array_reader.HasMoreData()) {
359 MountEntry entry;
360 dbus::MessageReader sub_reader(NULL);
361 if (!array_reader.PopStruct(&sub_reader) ||
362 !ReadMountEntryFromDbus(&sub_reader, &entry)) {
363 LOG(ERROR) << "Invalid response: " << response->ToString();
364 error_callback.Run();
365 return;
366 }
367 entries.push_back(entry);
368 }
369 callback.Run(entries);
370 }
371
[email protected]4ae73292011-11-15 05:20:18372 // Handles the result of GetDeviceProperties and calls |callback| or
373 // |error_callback|.
374 void OnGetDeviceProperties(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35375 const GetDevicePropertiesCallback& callback,
[email protected]5624a252013-07-04 03:17:53376 const base::Closure& error_callback,
[email protected]4ae73292011-11-15 05:20:18377 dbus::Response* response) {
378 if (!response) {
379 error_callback.Run();
380 return;
381 }
382 DiskInfo disk(device_path, response);
383 callback.Run(disk);
384 }
385
Hidehiko Abe06ce6dc2017-12-08 19:32:03386 // Handles mount event signals and notifies observers.
387 void OnMountEvent(MountEventType event_type, dbus::Signal* signal) {
[email protected]4ae73292011-11-15 05:20:18388 dbus::MessageReader reader(signal);
389 std::string device;
390 if (!reader.PopString(&device)) {
391 LOG(ERROR) << "Invalid signal: " << signal->ToString();
392 return;
393 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03394
395 for (auto& observer : observer_list_)
396 observer.OnMountEvent(event_type, device);
[email protected]4ae73292011-11-15 05:20:18397 }
398
Hidehiko Abe06ce6dc2017-12-08 19:32:03399 // Handles MountCompleted signal and notifies observers.
400 void OnMountCompleted(dbus::Signal* signal) {
[email protected]4ae73292011-11-15 05:20:18401 dbus::MessageReader reader(signal);
[email protected]d7760592014-05-16 07:57:52402 MountEntry entry;
403 if (!ReadMountEntryFromDbus(&reader, &entry)) {
[email protected]4ae73292011-11-15 05:20:18404 LOG(ERROR) << "Invalid signal: " << signal->ToString();
405 return;
406 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03407
408 for (auto& observer : observer_list_)
409 observer.OnMountCompleted(entry);
[email protected]4ae73292011-11-15 05:20:18410 }
411
Hidehiko Abe06ce6dc2017-12-08 19:32:03412 // Handles FormatCompleted signal and notifies observers.
413 void OnFormatCompleted(dbus::Signal* signal) {
[email protected]a0278d52014-05-06 03:36:15414 dbus::MessageReader reader(signal);
avi6e1a22d2015-12-21 03:43:20415 uint32_t error_code = 0;
[email protected]a0278d52014-05-06 03:36:15416 std::string device_path;
417 if (!reader.PopUint32(&error_code) || !reader.PopString(&device_path)) {
418 LOG(ERROR) << "Invalid signal: " << signal->ToString();
419 return;
420 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03421
422 for (auto& observer : observer_list_) {
423 observer.OnFormatCompleted(static_cast<FormatError>(error_code),
424 device_path);
425 }
[email protected]a0278d52014-05-06 03:36:15426 }
427
Hidehiko Abe06ce6dc2017-12-08 19:32:03428 // Handles RenameCompleted signal and notifies observers.
429 void OnRenameCompleted(dbus::Signal* signal) {
Klemen Kozjekbf5610f2017-08-25 20:20:09430 dbus::MessageReader reader(signal);
431 uint32_t error_code = 0;
432 std::string device_path;
433 if (!reader.PopUint32(&error_code) || !reader.PopString(&device_path)) {
434 LOG(ERROR) << "Invalid signal: " << signal->ToString();
435 return;
436 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03437
438 for (auto& observer : observer_list_) {
439 observer.OnRenameCompleted(static_cast<RenameError>(error_code),
440 device_path);
441 }
Klemen Kozjekbf5610f2017-08-25 20:20:09442 }
443
[email protected]4ae73292011-11-15 05:20:18444 // Handles the result of signal connection setup.
445 void OnSignalConnected(const std::string& interface,
446 const std::string& signal,
[email protected]d6311dcb2012-10-22 03:40:43447 bool succeeded) {
448 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
[email protected]4ae73292011-11-15 05:20:18449 signal << " failed.";
450 }
451
452 dbus::ObjectProxy* proxy_;
[email protected]926957b2012-09-07 05:34:16453
Hidehiko Abe06ce6dc2017-12-08 19:32:03454 base::ObserverList<Observer> observer_list_;
455
[email protected]926957b2012-09-07 05:34:16456 // Note: This should remain the last member so it'll be destroyed and
457 // invalidate its weak pointers before any other members are destroyed.
[email protected]4ae73292011-11-15 05:20:18458 base::WeakPtrFactory<CrosDisksClientImpl> weak_ptr_factory_;
459
460 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl);
461};
462
[email protected]85b95a2012012-08-07 18:57:27463} // namespace
[email protected]4ae73292011-11-15 05:20:18464
465////////////////////////////////////////////////////////////////////////////////
466// DiskInfo
467
468DiskInfo::DiskInfo(const std::string& device_path, dbus::Response* response)
469 : device_path_(device_path),
470 is_drive_(false),
471 has_media_(false),
472 on_boot_device_(false),
[email protected]79ed457b2014-07-22 04:07:26473 on_removable_device_(false),
[email protected]4ae73292011-11-15 05:20:18474 is_read_only_(false),
Aga Wronskaddc1a752017-12-01 19:44:02475 is_hidden_(true),
476 is_virtual_(false),
477 device_type_(DEVICE_TYPE_UNKNOWN),
478 total_size_in_bytes_(0) {
[email protected]4ae73292011-11-15 05:20:18479 InitializeFromResponse(response);
480}
481
Chris Watkins2c529d62017-11-29 02:14:41482DiskInfo::~DiskInfo() = default;
[email protected]4ae73292011-11-15 05:20:18483
[email protected]85b95a2012012-08-07 18:57:27484// Initializes |this| from |response| given by the cros-disks service.
[email protected]4ae73292011-11-15 05:20:18485// Below is an example of |response|'s raw message (long string is ellipsized).
486//
487//
488// message_type: MESSAGE_METHOD_RETURN
489// destination: :1.8
490// sender: :1.16
491// signature: a{sv}
492// serial: 96
493// reply_serial: 267
494//
495// array [
496// dict entry {
497// string "DeviceFile"
498// variant string "/dev/sdb"
499// }
500// dict entry {
501// string "DeviceIsDrive"
502// variant bool true
503// }
504// dict entry {
505// string "DeviceIsMediaAvailable"
506// variant bool true
507// }
508// dict entry {
509// string "DeviceIsMounted"
510// variant bool false
511// }
512// dict entry {
513// string "DeviceIsOnBootDevice"
514// variant bool false
515// }
516// dict entry {
[email protected]79ed457b2014-07-22 04:07:26517// string "DeviceIsOnRemovableDevice"
518// variant bool true
519// }
520// dict entry {
[email protected]4ae73292011-11-15 05:20:18521// string "DeviceIsReadOnly"
522// variant bool false
523// }
524// dict entry {
525// string "DeviceIsVirtual"
526// variant bool false
527// }
528// dict entry {
529// string "DeviceMediaType"
avi6e1a22d2015-12-21 03:43:20530// variant uint32_t 1
[email protected]4ae73292011-11-15 05:20:18531// }
532// dict entry {
533// string "DeviceMountPaths"
534// variant array [
535// ]
536// }
537// dict entry {
538// string "DevicePresentationHide"
539// variant bool true
540// }
541// dict entry {
542// string "DeviceSize"
avi6e1a22d2015-12-21 03:43:20543// variant uint64_t 7998537728
[email protected]4ae73292011-11-15 05:20:18544// }
545// dict entry {
546// string "DriveIsRotational"
547// variant bool false
548// }
549// dict entry {
[email protected]202e9fee2012-09-13 20:21:29550// string "VendorId"
551// variant string "18d1"
552// }
553// dict entry {
554// string "VendorName"
555// variant string "Google Inc."
556// }
557// dict entry {
558// string "ProductId"
559// variant string "4e11"
560// }
561// dict entry {
562// string "ProductName"
563// variant string "Nexus One"
564// }
565// dict entry {
[email protected]4ae73292011-11-15 05:20:18566// string "DriveModel"
567// variant string "TransMemory"
568// }
569// dict entry {
570// string "IdLabel"
571// variant string ""
572// }
573// dict entry {
574// string "IdUuid"
575// variant string ""
576// }
577// dict entry {
578// string "NativePath"
579// variant string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
580// }
Klemen Kozjek46f1c6192017-08-25 19:20:54581// dict entry {
582// string "FileSystemType"
583// variant string "vfat"
584// }
[email protected]4ae73292011-11-15 05:20:18585// ]
586void DiskInfo::InitializeFromResponse(dbus::Response* response) {
[email protected]81836aed2013-07-09 23:41:12587 dbus::MessageReader reader(response);
dcheng0a6e80c2016-04-08 18:37:38588 std::unique_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
[email protected]81836aed2013-07-09 23:41:12589 base::DictionaryValue* properties = NULL;
590 if (!value || !value->GetAsDictionary(&properties))
[email protected]4ae73292011-11-15 05:20:18591 return;
[email protected]4ae73292011-11-15 05:20:18592
[email protected]81836aed2013-07-09 23:41:12593 properties->GetBooleanWithoutPathExpansion(
594 cros_disks::kDeviceIsDrive, &is_drive_);
595 properties->GetBooleanWithoutPathExpansion(
596 cros_disks::kDeviceIsReadOnly, &is_read_only_);
597 properties->GetBooleanWithoutPathExpansion(
598 cros_disks::kDevicePresentationHide, &is_hidden_);
599 properties->GetBooleanWithoutPathExpansion(
600 cros_disks::kDeviceIsMediaAvailable, &has_media_);
601 properties->GetBooleanWithoutPathExpansion(
602 cros_disks::kDeviceIsOnBootDevice, &on_boot_device_);
[email protected]79ed457b2014-07-22 04:07:26603 properties->GetBooleanWithoutPathExpansion(
604 cros_disks::kDeviceIsOnRemovableDevice, &on_removable_device_);
Aga Wronskaddc1a752017-12-01 19:44:02605 properties->GetBooleanWithoutPathExpansion(cros_disks::kDeviceIsVirtual,
606 &is_virtual_);
[email protected]81836aed2013-07-09 23:41:12607 properties->GetStringWithoutPathExpansion(
608 cros_disks::kNativePath, &system_path_);
609 properties->GetStringWithoutPathExpansion(
610 cros_disks::kDeviceFile, &file_path_);
611 properties->GetStringWithoutPathExpansion(cros_disks::kVendorId, &vendor_id_);
612 properties->GetStringWithoutPathExpansion(
613 cros_disks::kVendorName, &vendor_name_);
614 properties->GetStringWithoutPathExpansion(
615 cros_disks::kProductId, &product_id_);
616 properties->GetStringWithoutPathExpansion(
617 cros_disks::kProductName, &product_name_);
618 properties->GetStringWithoutPathExpansion(
619 cros_disks::kDriveModel, &drive_model_);
620 properties->GetStringWithoutPathExpansion(cros_disks::kIdLabel, &label_);
621 properties->GetStringWithoutPathExpansion(cros_disks::kIdUuid, &uuid_);
Klemen Kozjek46f1c6192017-08-25 19:20:54622 properties->GetStringWithoutPathExpansion(cros_disks::kFileSystemType,
623 &file_system_type_);
[email protected]2321d282012-01-31 23:06:59624
avi6e1a22d2015-12-21 03:43:20625 // dbus::PopDataAsValue() pops uint64_t as double.
626 // The top 11 bits of uint64_t are dropped by the use of double. But, this
627 // works
[email protected]81836aed2013-07-09 23:41:12628 // unless the size exceeds 8 PB.
629 double device_size_double = 0;
630 if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceSize,
631 &device_size_double))
632 total_size_in_bytes_ = device_size_double;
633
avi6e1a22d2015-12-21 03:43:20634 // dbus::PopDataAsValue() pops uint32_t as double.
[email protected]81836aed2013-07-09 23:41:12635 double media_type_double = 0;
636 if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceMediaType,
637 &media_type_double))
638 device_type_ = DeviceMediaTypeToDeviceType(media_type_double);
639
640 base::ListValue* mount_paths = NULL;
641 if (properties->GetListWithoutPathExpansion(cros_disks::kDeviceMountPaths,
642 &mount_paths))
643 mount_paths->GetString(0, &mount_path_);
[email protected]4ae73292011-11-15 05:20:18644}
645
646////////////////////////////////////////////////////////////////////////////////
647// CrosDisksClient
648
Chris Watkins2c529d62017-11-29 02:14:41649CrosDisksClient::CrosDisksClient() = default;
[email protected]4ae73292011-11-15 05:20:18650
Chris Watkins2c529d62017-11-29 02:14:41651CrosDisksClient::~CrosDisksClient() = default;
[email protected]4ae73292011-11-15 05:20:18652
653// static
[email protected]c5fd5362013-08-27 12:23:04654CrosDisksClient* CrosDisksClient::Create(DBusClientImplementationType type) {
[email protected]e8db03d62012-03-31 04:08:38655 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
[email protected]c5fd5362013-08-27 12:23:04656 return new CrosDisksClientImpl();
jamescook2b590992016-09-14 15:28:45657 DCHECK_EQ(FAKE_DBUS_CLIENT_IMPLEMENTATION, type);
satorux8fd293802014-10-30 08:23:12658 return new FakeCrosDisksClient();
[email protected]4ae73292011-11-15 05:20:18659}
660
[email protected]a5a8b412013-03-04 15:03:11661// static
662base::FilePath CrosDisksClient::GetArchiveMountPoint() {
[email protected]49c4cf852013-09-27 19:28:24663 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
[email protected]a5a8b412013-03-04 15:03:11664 FILE_PATH_LITERAL("/media/archive") :
665 FILE_PATH_LITERAL("/tmp/chromeos/media/archive"));
666}
667
668// static
669base::FilePath CrosDisksClient::GetRemovableDiskMountPoint() {
[email protected]49c4cf852013-09-27 19:28:24670 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
[email protected]a5a8b412013-03-04 15:03:11671 FILE_PATH_LITERAL("/media/removable") :
672 FILE_PATH_LITERAL("/tmp/chromeos/media/removable"));
673}
674
yamaguchi585d5402016-08-02 09:27:36675// static
676std::vector<std::string> CrosDisksClient::ComposeMountOptions(
677 const std::string& mount_label,
yamaguchifa8efc72016-10-21 15:05:51678 MountAccessMode access_mode,
679 RemountOption remount) {
yamaguchi585d5402016-08-02 09:27:36680 std::vector<std::string> mount_options(
681 kDefaultMountOptions,
682 kDefaultMountOptions + arraysize(kDefaultMountOptions));
683 switch (access_mode) {
684 case MOUNT_ACCESS_MODE_READ_ONLY:
685 mount_options.push_back(kReadOnlyOption);
686 break;
687 case MOUNT_ACCESS_MODE_READ_WRITE:
688 mount_options.push_back(kReadWriteOption);
689 break;
690 }
yamaguchifa8efc72016-10-21 15:05:51691 if (remount == REMOUNT_OPTION_REMOUNT_EXISTING_DEVICE) {
692 mount_options.push_back(kRemountOption);
693 }
yamaguchi585d5402016-08-02 09:27:36694
695 if (!mount_label.empty()) {
696 std::string mount_label_option =
697 base::StringPrintf("%s=%s", kMountLabelOption, mount_label.c_str());
698 mount_options.push_back(mount_label_option);
699 }
700 return mount_options;
701}
702
[email protected]4ae73292011-11-15 05:20:18703} // namespace chromeos