blob: 885f9d62f690bd6bd6c541660cd480337d39f9e6 [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
149 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50150 void EnumerateAutoMountableDevices(
Aga Wronskaddc1a752017-12-01 19:44:02151 const EnumerateDevicesCallback& callback,
mostynb4f4cf142014-10-06 13:57:52152 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18153 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
154 cros_disks::kEnumerateAutoMountableDevices);
Aga Wronskaddc1a752017-12-01 19:44:02155 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
156 base::BindOnce(&CrosDisksClientImpl::OnEnumerateDevices,
157 weak_ptr_factory_.GetWeakPtr(), callback,
158 error_callback));
159 }
160
161 void EnumerateDevices(const EnumerateDevicesCallback& callback,
162 const base::Closure& error_callback) override {
163 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
164 cros_disks::kEnumerateDevices);
165 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
166 base::BindOnce(&CrosDisksClientImpl::OnEnumerateDevices,
167 weak_ptr_factory_.GetWeakPtr(), callback,
168 error_callback));
[email protected]4ae73292011-11-15 05:20:18169 }
170
171 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50172 void EnumerateMountEntries(const EnumerateMountEntriesCallback& callback,
173 const base::Closure& error_callback) override {
[email protected]d7760592014-05-16 07:57:52174 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
175 cros_disks::kEnumerateMountEntries);
176 proxy_->CallMethod(
177 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
Hidehiko Abed62ed3e2017-09-05 05:16:56178 base::BindOnce(&CrosDisksClientImpl::OnEnumerateMountEntries,
179 weak_ptr_factory_.GetWeakPtr(), callback,
180 error_callback));
[email protected]d7760592014-05-16 07:57:52181 }
182
183 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50184 void Format(const std::string& device_path,
185 const std::string& filesystem,
Hidehiko Abec293cdcf2018-02-08 02:10:45186 VoidDBusMethodCallback callback) override {
[email protected]4ae73292011-11-15 05:20:18187 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
[email protected]f026c0f2014-05-06 21:52:35188 cros_disks::kFormat);
[email protected]4ae73292011-11-15 05:20:18189 dbus::MessageWriter writer(&method_call);
190 writer.AppendString(device_path);
191 writer.AppendString(filesystem);
[email protected]f026c0f2014-05-06 21:52:35192 // No format option is currently specified, but we can later use this
193 // argument to specify options for the format operation.
194 std::vector<std::string> format_options;
195 writer.AppendArrayOfStrings(format_options);
Hidehiko Abec293cdcf2018-02-08 02:10:45196 proxy_->CallMethod(
197 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
198 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
199 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
[email protected]4ae73292011-11-15 05:20:18200 }
201
Klemen Kozjekbf5610f2017-08-25 20:20:09202 void Rename(const std::string& device_path,
203 const std::string& volume_name,
Hidehiko Abec293cdcf2018-02-08 02:10:45204 VoidDBusMethodCallback callback) override {
Klemen Kozjekbf5610f2017-08-25 20:20:09205 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
206 cros_disks::kRename);
207 dbus::MessageWriter writer(&method_call);
208 writer.AppendString(device_path);
209 writer.AppendString(volume_name);
Hidehiko Abec293cdcf2018-02-08 02:10:45210 proxy_->CallMethod(
211 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
212 base::BindOnce(&CrosDisksClientImpl::OnVoidMethod,
213 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
Klemen Kozjekbf5610f2017-08-25 20:20:09214 }
215
[email protected]4ae73292011-11-15 05:20:18216 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50217 void GetDeviceProperties(const std::string& device_path,
218 const GetDevicePropertiesCallback& callback,
219 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18220 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
221 cros_disks::kGetDeviceProperties);
222 dbus::MessageWriter writer(&method_call);
223 writer.AppendString(device_path);
Hidehiko Abed62ed3e2017-09-05 05:16:56224 proxy_->CallMethod(
225 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
226 base::BindOnce(&CrosDisksClientImpl::OnGetDeviceProperties,
227 weak_ptr_factory_.GetWeakPtr(), device_path, callback,
228 error_callback));
[email protected]4ae73292011-11-15 05:20:18229 }
230
[email protected]c5fd5362013-08-27 12:23:04231 protected:
dcheng0280cb62015-01-16 07:37:50232 void Init(dbus::Bus* bus) override {
[email protected]c5fd5362013-08-27 12:23:04233 proxy_ = bus->GetObjectProxy(
234 cros_disks::kCrosDisksServiceName,
235 dbus::ObjectPath(cros_disks::kCrosDisksServicePath));
Hidehiko Abe06ce6dc2017-12-08 19:32:03236
237 // Register handlers for D-Bus signals.
238 constexpr SignalEventTuple kSignalEventTuples[] = {
239 {cros_disks::kDeviceAdded, CROS_DISKS_DEVICE_ADDED},
240 {cros_disks::kDeviceScanned, CROS_DISKS_DEVICE_SCANNED},
241 {cros_disks::kDeviceRemoved, CROS_DISKS_DEVICE_REMOVED},
242 {cros_disks::kDiskAdded, CROS_DISKS_DISK_ADDED},
243 {cros_disks::kDiskChanged, CROS_DISKS_DISK_CHANGED},
244 {cros_disks::kDiskRemoved, CROS_DISKS_DISK_REMOVED},
245 };
246 for (const auto& entry : kSignalEventTuples) {
247 proxy_->ConnectToSignal(
248 cros_disks::kCrosDisksInterface, entry.signal_name,
249 base::BindRepeating(&CrosDisksClientImpl::OnMountEvent,
250 weak_ptr_factory_.GetWeakPtr(), entry.event_type),
251 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
252 weak_ptr_factory_.GetWeakPtr()));
253 }
254
255 proxy_->ConnectToSignal(
256 cros_disks::kCrosDisksInterface, cros_disks::kMountCompleted,
257 base::BindRepeating(&CrosDisksClientImpl::OnMountCompleted,
258 weak_ptr_factory_.GetWeakPtr()),
259 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
260 weak_ptr_factory_.GetWeakPtr()));
261
262 proxy_->ConnectToSignal(
263 cros_disks::kCrosDisksInterface, cros_disks::kFormatCompleted,
264 base::BindRepeating(&CrosDisksClientImpl::OnFormatCompleted,
265 weak_ptr_factory_.GetWeakPtr()),
266 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
267 weak_ptr_factory_.GetWeakPtr()));
268
269 proxy_->ConnectToSignal(
270 cros_disks::kCrosDisksInterface, cros_disks::kRenameCompleted,
271 base::BindRepeating(&CrosDisksClientImpl::OnRenameCompleted,
272 weak_ptr_factory_.GetWeakPtr()),
273 base::BindOnce(&CrosDisksClientImpl::OnSignalConnected,
274 weak_ptr_factory_.GetWeakPtr()));
[email protected]c5fd5362013-08-27 12:23:04275 }
276
[email protected]4ae73292011-11-15 05:20:18277 private:
278 // A struct to contain a pair of signal name and mount event type.
[email protected]a0278d52014-05-06 03:36:15279 // Used by SetMountEventHandler.
[email protected]4ae73292011-11-15 05:20:18280 struct SignalEventTuple {
281 const char *signal_name;
282 MountEventType event_type;
283 };
284
Hidehiko Abec293cdcf2018-02-08 02:10:45285 // Handles the result of D-Bus method call with no return value.
286 void OnVoidMethod(VoidDBusMethodCallback callback, dbus::Response* response) {
287 std::move(callback).Run(response);
[email protected]4ae73292011-11-15 05:20:18288 }
289
[email protected]d7760592014-05-16 07:57:52290 // Handles the result of Unmount and calls |callback| or |error_callback|.
Hidehiko Abec293cdcf2018-02-08 02:10:45291 void OnUnmount(VoidDBusMethodCallback callback, dbus::Response* response) {
[email protected]4ae73292011-11-15 05:20:18292 if (!response) {
Hidehiko Abec293cdcf2018-02-08 02:10:45293 std::move(callback).Run(false);
[email protected]4ae73292011-11-15 05:20:18294 return;
295 }
[email protected]ddcb18e2013-09-19 07:17:28296
297 // Temporarly allow Unmount method to report failure both by setting dbus
298 // error (in which case response is not set) and by returning mount error
299 // different from MOUNT_ERROR_NONE. This is done so we can change Unmount
300 // method to return mount error (http://crbug.com/288974) without breaking
301 // Chrome.
302 // TODO(tbarzic): When Unmount implementation is changed on cros disks side,
303 // make this fail if reader is not able to read the error code value from
304 // the response.
305 dbus::MessageReader reader(response);
avi6e1a22d2015-12-21 03:43:20306 uint32_t error_code = 0;
[email protected]ddcb18e2013-09-19 07:17:28307 if (reader.PopUint32(&error_code) &&
308 static_cast<MountError>(error_code) != MOUNT_ERROR_NONE) {
Hidehiko Abec293cdcf2018-02-08 02:10:45309 std::move(callback).Run(false);
[email protected]ddcb18e2013-09-19 07:17:28310 return;
311 }
312
Hidehiko Abec293cdcf2018-02-08 02:10:45313 std::move(callback).Run(true);
[email protected]4ae73292011-11-15 05:20:18314 }
315
Aga Wronskaddc1a752017-12-01 19:44:02316 // Handles the result of EnumerateDevices and EnumarateAutoMountableDevices.
317 // Calls |callback| or |error_callback|.
318 void OnEnumerateDevices(const EnumerateDevicesCallback& callback,
319 const base::Closure& error_callback,
320 dbus::Response* response) {
[email protected]4ae73292011-11-15 05:20:18321 if (!response) {
322 error_callback.Run();
323 return;
324 }
325 dbus::MessageReader reader(response);
326 std::vector<std::string> device_paths;
327 if (!reader.PopArrayOfStrings(&device_paths)) {
328 LOG(ERROR) << "Invalid response: " << response->ToString();
329 error_callback.Run();
330 return;
331 }
332 callback.Run(device_paths);
333 }
334
[email protected]d7760592014-05-16 07:57:52335 // Handles the result of EnumerateMountEntries and calls |callback| or
336 // |error_callback|.
337 void OnEnumerateMountEntries(
338 const EnumerateMountEntriesCallback& callback,
339 const base::Closure& error_callback,
340 dbus::Response* response) {
341 if (!response) {
342 error_callback.Run();
343 return;
344 }
345
346 dbus::MessageReader reader(response);
347 dbus::MessageReader array_reader(NULL);
348 if (!reader.PopArray(&array_reader)) {
349 LOG(ERROR) << "Invalid response: " << response->ToString();
350 error_callback.Run();
351 return;
352 }
353
354 std::vector<MountEntry> entries;
355 while (array_reader.HasMoreData()) {
356 MountEntry entry;
357 dbus::MessageReader sub_reader(NULL);
358 if (!array_reader.PopStruct(&sub_reader) ||
359 !ReadMountEntryFromDbus(&sub_reader, &entry)) {
360 LOG(ERROR) << "Invalid response: " << response->ToString();
361 error_callback.Run();
362 return;
363 }
364 entries.push_back(entry);
365 }
366 callback.Run(entries);
367 }
368
[email protected]4ae73292011-11-15 05:20:18369 // Handles the result of GetDeviceProperties and calls |callback| or
370 // |error_callback|.
371 void OnGetDeviceProperties(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35372 const GetDevicePropertiesCallback& callback,
[email protected]5624a252013-07-04 03:17:53373 const base::Closure& error_callback,
[email protected]4ae73292011-11-15 05:20:18374 dbus::Response* response) {
375 if (!response) {
376 error_callback.Run();
377 return;
378 }
379 DiskInfo disk(device_path, response);
380 callback.Run(disk);
381 }
382
Hidehiko Abe06ce6dc2017-12-08 19:32:03383 // Handles mount event signals and notifies observers.
384 void OnMountEvent(MountEventType event_type, dbus::Signal* signal) {
[email protected]4ae73292011-11-15 05:20:18385 dbus::MessageReader reader(signal);
386 std::string device;
387 if (!reader.PopString(&device)) {
388 LOG(ERROR) << "Invalid signal: " << signal->ToString();
389 return;
390 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03391
392 for (auto& observer : observer_list_)
393 observer.OnMountEvent(event_type, device);
[email protected]4ae73292011-11-15 05:20:18394 }
395
Hidehiko Abe06ce6dc2017-12-08 19:32:03396 // Handles MountCompleted signal and notifies observers.
397 void OnMountCompleted(dbus::Signal* signal) {
[email protected]4ae73292011-11-15 05:20:18398 dbus::MessageReader reader(signal);
[email protected]d7760592014-05-16 07:57:52399 MountEntry entry;
400 if (!ReadMountEntryFromDbus(&reader, &entry)) {
[email protected]4ae73292011-11-15 05:20:18401 LOG(ERROR) << "Invalid signal: " << signal->ToString();
402 return;
403 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03404
405 for (auto& observer : observer_list_)
406 observer.OnMountCompleted(entry);
[email protected]4ae73292011-11-15 05:20:18407 }
408
Hidehiko Abe06ce6dc2017-12-08 19:32:03409 // Handles FormatCompleted signal and notifies observers.
410 void OnFormatCompleted(dbus::Signal* signal) {
[email protected]a0278d52014-05-06 03:36:15411 dbus::MessageReader reader(signal);
avi6e1a22d2015-12-21 03:43:20412 uint32_t error_code = 0;
[email protected]a0278d52014-05-06 03:36:15413 std::string device_path;
414 if (!reader.PopUint32(&error_code) || !reader.PopString(&device_path)) {
415 LOG(ERROR) << "Invalid signal: " << signal->ToString();
416 return;
417 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03418
419 for (auto& observer : observer_list_) {
420 observer.OnFormatCompleted(static_cast<FormatError>(error_code),
421 device_path);
422 }
[email protected]a0278d52014-05-06 03:36:15423 }
424
Hidehiko Abe06ce6dc2017-12-08 19:32:03425 // Handles RenameCompleted signal and notifies observers.
426 void OnRenameCompleted(dbus::Signal* signal) {
Klemen Kozjekbf5610f2017-08-25 20:20:09427 dbus::MessageReader reader(signal);
428 uint32_t error_code = 0;
429 std::string device_path;
430 if (!reader.PopUint32(&error_code) || !reader.PopString(&device_path)) {
431 LOG(ERROR) << "Invalid signal: " << signal->ToString();
432 return;
433 }
Hidehiko Abe06ce6dc2017-12-08 19:32:03434
435 for (auto& observer : observer_list_) {
436 observer.OnRenameCompleted(static_cast<RenameError>(error_code),
437 device_path);
438 }
Klemen Kozjekbf5610f2017-08-25 20:20:09439 }
440
[email protected]4ae73292011-11-15 05:20:18441 // Handles the result of signal connection setup.
442 void OnSignalConnected(const std::string& interface,
443 const std::string& signal,
[email protected]d6311dcb2012-10-22 03:40:43444 bool succeeded) {
445 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
[email protected]4ae73292011-11-15 05:20:18446 signal << " failed.";
447 }
448
449 dbus::ObjectProxy* proxy_;
[email protected]926957b2012-09-07 05:34:16450
Hidehiko Abe06ce6dc2017-12-08 19:32:03451 base::ObserverList<Observer> observer_list_;
452
[email protected]926957b2012-09-07 05:34:16453 // Note: This should remain the last member so it'll be destroyed and
454 // invalidate its weak pointers before any other members are destroyed.
[email protected]4ae73292011-11-15 05:20:18455 base::WeakPtrFactory<CrosDisksClientImpl> weak_ptr_factory_;
456
457 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl);
458};
459
[email protected]85b95a2012012-08-07 18:57:27460} // namespace
[email protected]4ae73292011-11-15 05:20:18461
462////////////////////////////////////////////////////////////////////////////////
463// DiskInfo
464
465DiskInfo::DiskInfo(const std::string& device_path, dbus::Response* response)
466 : device_path_(device_path),
467 is_drive_(false),
468 has_media_(false),
469 on_boot_device_(false),
[email protected]79ed457b2014-07-22 04:07:26470 on_removable_device_(false),
[email protected]4ae73292011-11-15 05:20:18471 is_read_only_(false),
Aga Wronskaddc1a752017-12-01 19:44:02472 is_hidden_(true),
473 is_virtual_(false),
474 device_type_(DEVICE_TYPE_UNKNOWN),
475 total_size_in_bytes_(0) {
[email protected]4ae73292011-11-15 05:20:18476 InitializeFromResponse(response);
477}
478
Chris Watkins2c529d62017-11-29 02:14:41479DiskInfo::~DiskInfo() = default;
[email protected]4ae73292011-11-15 05:20:18480
[email protected]85b95a2012012-08-07 18:57:27481// Initializes |this| from |response| given by the cros-disks service.
[email protected]4ae73292011-11-15 05:20:18482// Below is an example of |response|'s raw message (long string is ellipsized).
483//
484//
485// message_type: MESSAGE_METHOD_RETURN
486// destination: :1.8
487// sender: :1.16
488// signature: a{sv}
489// serial: 96
490// reply_serial: 267
491//
492// array [
493// dict entry {
494// string "DeviceFile"
495// variant string "/dev/sdb"
496// }
497// dict entry {
498// string "DeviceIsDrive"
499// variant bool true
500// }
501// dict entry {
502// string "DeviceIsMediaAvailable"
503// variant bool true
504// }
505// dict entry {
506// string "DeviceIsMounted"
507// variant bool false
508// }
509// dict entry {
510// string "DeviceIsOnBootDevice"
511// variant bool false
512// }
513// dict entry {
[email protected]79ed457b2014-07-22 04:07:26514// string "DeviceIsOnRemovableDevice"
515// variant bool true
516// }
517// dict entry {
[email protected]4ae73292011-11-15 05:20:18518// string "DeviceIsReadOnly"
519// variant bool false
520// }
521// dict entry {
522// string "DeviceIsVirtual"
523// variant bool false
524// }
525// dict entry {
526// string "DeviceMediaType"
avi6e1a22d2015-12-21 03:43:20527// variant uint32_t 1
[email protected]4ae73292011-11-15 05:20:18528// }
529// dict entry {
530// string "DeviceMountPaths"
531// variant array [
532// ]
533// }
534// dict entry {
535// string "DevicePresentationHide"
536// variant bool true
537// }
538// dict entry {
539// string "DeviceSize"
avi6e1a22d2015-12-21 03:43:20540// variant uint64_t 7998537728
[email protected]4ae73292011-11-15 05:20:18541// }
542// dict entry {
543// string "DriveIsRotational"
544// variant bool false
545// }
546// dict entry {
[email protected]202e9fee2012-09-13 20:21:29547// string "VendorId"
548// variant string "18d1"
549// }
550// dict entry {
551// string "VendorName"
552// variant string "Google Inc."
553// }
554// dict entry {
555// string "ProductId"
556// variant string "4e11"
557// }
558// dict entry {
559// string "ProductName"
560// variant string "Nexus One"
561// }
562// dict entry {
[email protected]4ae73292011-11-15 05:20:18563// string "DriveModel"
564// variant string "TransMemory"
565// }
566// dict entry {
567// string "IdLabel"
568// variant string ""
569// }
570// dict entry {
571// string "IdUuid"
572// variant string ""
573// }
574// dict entry {
575// string "NativePath"
576// variant string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
577// }
Klemen Kozjek46f1c6192017-08-25 19:20:54578// dict entry {
579// string "FileSystemType"
580// variant string "vfat"
581// }
[email protected]4ae73292011-11-15 05:20:18582// ]
583void DiskInfo::InitializeFromResponse(dbus::Response* response) {
[email protected]81836aed2013-07-09 23:41:12584 dbus::MessageReader reader(response);
dcheng0a6e80c2016-04-08 18:37:38585 std::unique_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
[email protected]81836aed2013-07-09 23:41:12586 base::DictionaryValue* properties = NULL;
587 if (!value || !value->GetAsDictionary(&properties))
[email protected]4ae73292011-11-15 05:20:18588 return;
[email protected]4ae73292011-11-15 05:20:18589
[email protected]81836aed2013-07-09 23:41:12590 properties->GetBooleanWithoutPathExpansion(
591 cros_disks::kDeviceIsDrive, &is_drive_);
592 properties->GetBooleanWithoutPathExpansion(
593 cros_disks::kDeviceIsReadOnly, &is_read_only_);
594 properties->GetBooleanWithoutPathExpansion(
595 cros_disks::kDevicePresentationHide, &is_hidden_);
596 properties->GetBooleanWithoutPathExpansion(
597 cros_disks::kDeviceIsMediaAvailable, &has_media_);
598 properties->GetBooleanWithoutPathExpansion(
599 cros_disks::kDeviceIsOnBootDevice, &on_boot_device_);
[email protected]79ed457b2014-07-22 04:07:26600 properties->GetBooleanWithoutPathExpansion(
601 cros_disks::kDeviceIsOnRemovableDevice, &on_removable_device_);
Aga Wronskaddc1a752017-12-01 19:44:02602 properties->GetBooleanWithoutPathExpansion(cros_disks::kDeviceIsVirtual,
603 &is_virtual_);
[email protected]81836aed2013-07-09 23:41:12604 properties->GetStringWithoutPathExpansion(
605 cros_disks::kNativePath, &system_path_);
606 properties->GetStringWithoutPathExpansion(
607 cros_disks::kDeviceFile, &file_path_);
608 properties->GetStringWithoutPathExpansion(cros_disks::kVendorId, &vendor_id_);
609 properties->GetStringWithoutPathExpansion(
610 cros_disks::kVendorName, &vendor_name_);
611 properties->GetStringWithoutPathExpansion(
612 cros_disks::kProductId, &product_id_);
613 properties->GetStringWithoutPathExpansion(
614 cros_disks::kProductName, &product_name_);
615 properties->GetStringWithoutPathExpansion(
616 cros_disks::kDriveModel, &drive_model_);
617 properties->GetStringWithoutPathExpansion(cros_disks::kIdLabel, &label_);
618 properties->GetStringWithoutPathExpansion(cros_disks::kIdUuid, &uuid_);
Klemen Kozjek46f1c6192017-08-25 19:20:54619 properties->GetStringWithoutPathExpansion(cros_disks::kFileSystemType,
620 &file_system_type_);
[email protected]2321d282012-01-31 23:06:59621
avi6e1a22d2015-12-21 03:43:20622 // dbus::PopDataAsValue() pops uint64_t as double.
623 // The top 11 bits of uint64_t are dropped by the use of double. But, this
624 // works
[email protected]81836aed2013-07-09 23:41:12625 // unless the size exceeds 8 PB.
626 double device_size_double = 0;
627 if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceSize,
628 &device_size_double))
629 total_size_in_bytes_ = device_size_double;
630
avi6e1a22d2015-12-21 03:43:20631 // dbus::PopDataAsValue() pops uint32_t as double.
[email protected]81836aed2013-07-09 23:41:12632 double media_type_double = 0;
633 if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceMediaType,
634 &media_type_double))
635 device_type_ = DeviceMediaTypeToDeviceType(media_type_double);
636
637 base::ListValue* mount_paths = NULL;
638 if (properties->GetListWithoutPathExpansion(cros_disks::kDeviceMountPaths,
639 &mount_paths))
640 mount_paths->GetString(0, &mount_path_);
[email protected]4ae73292011-11-15 05:20:18641}
642
643////////////////////////////////////////////////////////////////////////////////
644// CrosDisksClient
645
Chris Watkins2c529d62017-11-29 02:14:41646CrosDisksClient::CrosDisksClient() = default;
[email protected]4ae73292011-11-15 05:20:18647
Chris Watkins2c529d62017-11-29 02:14:41648CrosDisksClient::~CrosDisksClient() = default;
[email protected]4ae73292011-11-15 05:20:18649
650// static
[email protected]c5fd5362013-08-27 12:23:04651CrosDisksClient* CrosDisksClient::Create(DBusClientImplementationType type) {
[email protected]e8db03d62012-03-31 04:08:38652 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
[email protected]c5fd5362013-08-27 12:23:04653 return new CrosDisksClientImpl();
jamescook2b590992016-09-14 15:28:45654 DCHECK_EQ(FAKE_DBUS_CLIENT_IMPLEMENTATION, type);
satorux8fd293802014-10-30 08:23:12655 return new FakeCrosDisksClient();
[email protected]4ae73292011-11-15 05:20:18656}
657
[email protected]a5a8b412013-03-04 15:03:11658// static
659base::FilePath CrosDisksClient::GetArchiveMountPoint() {
[email protected]49c4cf852013-09-27 19:28:24660 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
[email protected]a5a8b412013-03-04 15:03:11661 FILE_PATH_LITERAL("/media/archive") :
662 FILE_PATH_LITERAL("/tmp/chromeos/media/archive"));
663}
664
665// static
666base::FilePath CrosDisksClient::GetRemovableDiskMountPoint() {
[email protected]49c4cf852013-09-27 19:28:24667 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
[email protected]a5a8b412013-03-04 15:03:11668 FILE_PATH_LITERAL("/media/removable") :
669 FILE_PATH_LITERAL("/tmp/chromeos/media/removable"));
670}
671
yamaguchi585d5402016-08-02 09:27:36672// static
673std::vector<std::string> CrosDisksClient::ComposeMountOptions(
Sergei Datsenkod19248182018-05-11 01:52:56674 const std::vector<std::string>& options,
yamaguchi585d5402016-08-02 09:27:36675 const std::string& mount_label,
yamaguchifa8efc72016-10-21 15:05:51676 MountAccessMode access_mode,
677 RemountOption remount) {
Sergei Datsenkod19248182018-05-11 01:52:56678 std::vector<std::string> mount_options = options;
yamaguchi585d5402016-08-02 09:27:36679 switch (access_mode) {
680 case MOUNT_ACCESS_MODE_READ_ONLY:
681 mount_options.push_back(kReadOnlyOption);
682 break;
683 case MOUNT_ACCESS_MODE_READ_WRITE:
684 mount_options.push_back(kReadWriteOption);
685 break;
686 }
yamaguchifa8efc72016-10-21 15:05:51687 if (remount == REMOUNT_OPTION_REMOUNT_EXISTING_DEVICE) {
688 mount_options.push_back(kRemountOption);
689 }
yamaguchi585d5402016-08-02 09:27:36690
691 if (!mount_label.empty()) {
692 std::string mount_label_option =
693 base::StringPrintf("%s=%s", kMountLabelOption, mount_label.c_str());
694 mount_options.push_back(mount_label_option);
695 }
Sergei Datsenkod19248182018-05-11 01:52:56696
yamaguchi585d5402016-08-02 09:27:36697 return mount_options;
698}
699
[email protected]4ae73292011-11-15 05:20:18700} // namespace chromeos