blob: 07fe123be69edc1716b3073a102d148b894b40d4 [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>
[email protected]85b95a2012012-08-07 18:57:2712
[email protected]4ae73292011-11-15 05:20:1813#include "base/bind.h"
[email protected]a5a8b412013-03-04 15:03:1114#include "base/files/file_path.h"
thestigb44bd352014-09-10 01:47:0615#include "base/files/file_util.h"
[email protected]593cf3b2013-03-05 04:16:5216#include "base/location.h"
avi6e1a22d2015-12-21 03:43:2017#include "base/macros.h"
[email protected]b307bceb2011-11-17 07:49:5518#include "base/stl_util.h"
[email protected]afa339d72013-06-11 06:32:5119#include "base/strings/stringprintf.h"
[email protected]49c4cf852013-09-27 19:28:2420#include "base/sys_info.h"
[email protected]593cf3b2013-03-05 04:16:5221#include "base/task_runner_util.h"
[email protected]81836aed2013-07-09 23:41:1222#include "base/values.h"
satorux8fd293802014-10-30 08:23:1223#include "chromeos/dbus/fake_cros_disks_client.h"
[email protected]4ae73292011-11-15 05:20:1824#include "dbus/bus.h"
25#include "dbus/message.h"
[email protected]216ed0b2012-02-14 21:29:0626#include "dbus/object_path.h"
[email protected]4ae73292011-11-15 05:20:1827#include "dbus/object_proxy.h"
[email protected]81836aed2013-07-09 23:41:1228#include "dbus/values_util.h"
[email protected]4ae73292011-11-15 05:20:1829#include "third_party/cros_system_api/dbus/service_constants.h"
30
31namespace chromeos {
32
33namespace {
34
35const char* kDefaultMountOptions[] = {
yamaguchi585d5402016-08-02 09:27:3636 "nodev", "noexec", "nosuid",
[email protected]4ae73292011-11-15 05:20:1837};
yamaguchi585d5402016-08-02 09:27:3638const char kReadOnlyOption[] = "ro";
39const char kReadWriteOption[] = "rw";
yamaguchifa8efc72016-10-21 15:05:5140const char kRemountOption[] = "remount";
yamaguchi585d5402016-08-02 09:27:3641const char kMountLabelOption[] = "mountlabel";
[email protected]4ae73292011-11-15 05:20:1842
[email protected]10795ae2012-10-10 07:33:4943const char kLazyUnmountOption[] = "lazy";
44
[email protected]2321d282012-01-31 23:06:5945// Checks if retrieved media type is in boundaries of DeviceMediaType.
avi6e1a22d2015-12-21 03:43:2046bool IsValidMediaType(uint32_t type) {
47 return type < static_cast<uint32_t>(cros_disks::DEVICE_MEDIA_NUM_VALUES);
[email protected]2321d282012-01-31 23:06:5948}
49
[email protected]2321d282012-01-31 23:06:5950// Translates enum used in cros-disks to enum used in Chrome.
51// Note that we could just do static_cast, but this is less sensitive to
52// changes in cros-disks.
avi6e1a22d2015-12-21 03:43:2053DeviceType DeviceMediaTypeToDeviceType(uint32_t media_type_uint32) {
[email protected]2321d282012-01-31 23:06:5954 if (!IsValidMediaType(media_type_uint32))
55 return DEVICE_TYPE_UNKNOWN;
56
57 cros_disks::DeviceMediaType media_type =
58 cros_disks::DeviceMediaType(media_type_uint32);
59
60 switch (media_type) {
61 case(cros_disks::DEVICE_MEDIA_UNKNOWN):
62 return DEVICE_TYPE_UNKNOWN;
63 case(cros_disks::DEVICE_MEDIA_USB):
64 return DEVICE_TYPE_USB;
65 case(cros_disks::DEVICE_MEDIA_SD):
66 return DEVICE_TYPE_SD;
67 case(cros_disks::DEVICE_MEDIA_OPTICAL_DISC):
68 return DEVICE_TYPE_OPTICAL_DISC;
69 case(cros_disks::DEVICE_MEDIA_MOBILE):
70 return DEVICE_TYPE_MOBILE;
[email protected]f4ae40ac2012-05-04 21:57:0071 case(cros_disks::DEVICE_MEDIA_DVD):
72 return DEVICE_TYPE_DVD;
[email protected]2321d282012-01-31 23:06:5973 default:
74 return DEVICE_TYPE_UNKNOWN;
75 }
[email protected]4ae73292011-11-15 05:20:1876}
77
[email protected]d7760592014-05-16 07:57:5278bool ReadMountEntryFromDbus(dbus::MessageReader* reader, MountEntry* entry) {
avi6e1a22d2015-12-21 03:43:2079 uint32_t error_code = 0;
[email protected]d7760592014-05-16 07:57:5280 std::string source_path;
avi6e1a22d2015-12-21 03:43:2081 uint32_t mount_type = 0;
[email protected]d7760592014-05-16 07:57:5282 std::string mount_path;
83 if (!reader->PopUint32(&error_code) ||
84 !reader->PopString(&source_path) ||
85 !reader->PopUint32(&mount_type) ||
86 !reader->PopString(&mount_path)) {
87 return false;
88 }
89 *entry = MountEntry(static_cast<MountError>(error_code), source_path,
90 static_cast<MountType>(mount_type), mount_path);
91 return true;
92}
93
[email protected]4ae73292011-11-15 05:20:1894// The CrosDisksClient implementation.
95class CrosDisksClientImpl : public CrosDisksClient {
96 public:
[email protected]c5fd5362013-08-27 12:23:0497 CrosDisksClientImpl() : proxy_(NULL), weak_ptr_factory_(this) {}
[email protected]4ae73292011-11-15 05:20:1898
99 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50100 void Mount(const std::string& source_path,
101 const std::string& source_format,
102 const std::string& mount_label,
yamaguchi585d5402016-08-02 09:27:36103 MountAccessMode access_mode,
yamaguchifa8efc72016-10-21 15:05:51104 RemountOption remount,
dcheng0280cb62015-01-16 07:37:50105 const base::Closure& callback,
106 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18107 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
108 cros_disks::kMount);
109 dbus::MessageWriter writer(&method_call);
110 writer.AppendString(source_path);
[email protected]b9f22d12012-04-25 21:46:48111 writer.AppendString(source_format);
yamaguchi585d5402016-08-02 09:27:36112 std::vector<std::string> mount_options =
yamaguchifa8efc72016-10-21 15:05:51113 ComposeMountOptions(mount_label, access_mode, remount);
[email protected]4ae73292011-11-15 05:20:18114 writer.AppendArrayOfStrings(mount_options);
115 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
Hidehiko Abed62ed3e2017-09-05 05:16:56116 base::BindOnce(&CrosDisksClientImpl::OnMount,
117 weak_ptr_factory_.GetWeakPtr(), callback,
118 error_callback));
[email protected]4ae73292011-11-15 05:20:18119 }
120
121 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50122 void Unmount(const std::string& device_path,
123 UnmountOptions options,
124 const base::Closure& callback,
125 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18126 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
127 cros_disks::kUnmount);
128 dbus::MessageWriter writer(&method_call);
129 writer.AppendString(device_path);
[email protected]10795ae2012-10-10 07:33:49130
benchan8bcaea12017-03-11 00:26:50131 std::vector<std::string> unmount_options;
[email protected]10795ae2012-10-10 07:33:49132 if (options == UNMOUNT_OPTIONS_LAZY)
133 unmount_options.push_back(kLazyUnmountOption);
134
[email protected]4ae73292011-11-15 05:20:18135 writer.AppendArrayOfStrings(unmount_options);
136 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
Hidehiko Abed62ed3e2017-09-05 05:16:56137 base::BindOnce(&CrosDisksClientImpl::OnUnmount,
138 weak_ptr_factory_.GetWeakPtr(), callback,
139 error_callback));
[email protected]4ae73292011-11-15 05:20:18140 }
141
142 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50143 void EnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35144 const EnumerateAutoMountableDevicesCallback& callback,
mostynb4f4cf142014-10-06 13:57:52145 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18146 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
147 cros_disks::kEnumerateAutoMountableDevices);
148 proxy_->CallMethod(
149 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
Hidehiko Abed62ed3e2017-09-05 05:16:56150 base::BindOnce(&CrosDisksClientImpl::OnEnumerateAutoMountableDevices,
151 weak_ptr_factory_.GetWeakPtr(), callback,
152 error_callback));
[email protected]4ae73292011-11-15 05:20:18153 }
154
155 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50156 void EnumerateMountEntries(const EnumerateMountEntriesCallback& callback,
157 const base::Closure& error_callback) override {
[email protected]d7760592014-05-16 07:57:52158 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
159 cros_disks::kEnumerateMountEntries);
160 proxy_->CallMethod(
161 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
Hidehiko Abed62ed3e2017-09-05 05:16:56162 base::BindOnce(&CrosDisksClientImpl::OnEnumerateMountEntries,
163 weak_ptr_factory_.GetWeakPtr(), callback,
164 error_callback));
[email protected]d7760592014-05-16 07:57:52165 }
166
167 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50168 void Format(const std::string& device_path,
169 const std::string& filesystem,
170 const base::Closure& callback,
171 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18172 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
[email protected]f026c0f2014-05-06 21:52:35173 cros_disks::kFormat);
[email protected]4ae73292011-11-15 05:20:18174 dbus::MessageWriter writer(&method_call);
175 writer.AppendString(device_path);
176 writer.AppendString(filesystem);
[email protected]f026c0f2014-05-06 21:52:35177 // No format option is currently specified, but we can later use this
178 // argument to specify options for the format operation.
179 std::vector<std::string> format_options;
180 writer.AppendArrayOfStrings(format_options);
[email protected]4ae73292011-11-15 05:20:18181 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
Hidehiko Abed62ed3e2017-09-05 05:16:56182 base::BindOnce(&CrosDisksClientImpl::OnFormat,
183 weak_ptr_factory_.GetWeakPtr(), callback,
184 error_callback));
[email protected]4ae73292011-11-15 05:20:18185 }
186
Klemen Kozjekbf5610f2017-08-25 20:20:09187 void Rename(const std::string& device_path,
188 const std::string& volume_name,
189 const base::Closure& callback,
190 const base::Closure& error_callback) override {
191 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
192 cros_disks::kRename);
193 dbus::MessageWriter writer(&method_call);
194 writer.AppendString(device_path);
195 writer.AppendString(volume_name);
Hidehiko Abed62ed3e2017-09-05 05:16:56196 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
197 base::BindOnce(&CrosDisksClientImpl::OnRename,
198 weak_ptr_factory_.GetWeakPtr(), callback,
199 error_callback));
Klemen Kozjekbf5610f2017-08-25 20:20:09200 }
201
[email protected]4ae73292011-11-15 05:20:18202 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50203 void GetDeviceProperties(const std::string& device_path,
204 const GetDevicePropertiesCallback& callback,
205 const base::Closure& error_callback) override {
[email protected]4ae73292011-11-15 05:20:18206 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
207 cros_disks::kGetDeviceProperties);
208 dbus::MessageWriter writer(&method_call);
209 writer.AppendString(device_path);
Hidehiko Abed62ed3e2017-09-05 05:16:56210 proxy_->CallMethod(
211 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
212 base::BindOnce(&CrosDisksClientImpl::OnGetDeviceProperties,
213 weak_ptr_factory_.GetWeakPtr(), device_path, callback,
214 error_callback));
[email protected]4ae73292011-11-15 05:20:18215 }
216
217 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50218 void SetMountEventHandler(
mostynb4f4cf142014-10-06 13:57:52219 const MountEventHandler& mount_event_handler) override {
[email protected]4ae73292011-11-15 05:20:18220 static const SignalEventTuple kSignalEventTuples[] = {
[email protected]e3c1fc92012-11-15 00:56:46221 { cros_disks::kDeviceAdded, CROS_DISKS_DEVICE_ADDED },
222 { cros_disks::kDeviceScanned, CROS_DISKS_DEVICE_SCANNED },
223 { cros_disks::kDeviceRemoved, CROS_DISKS_DEVICE_REMOVED },
224 { cros_disks::kDiskAdded, CROS_DISKS_DISK_ADDED },
225 { cros_disks::kDiskChanged, CROS_DISKS_DISK_CHANGED },
226 { cros_disks::kDiskRemoved, CROS_DISKS_DISK_REMOVED },
[email protected]4ae73292011-11-15 05:20:18227 };
228 const size_t kNumSignalEventTuples = arraysize(kSignalEventTuples);
229
230 for (size_t i = 0; i < kNumSignalEventTuples; ++i) {
231 proxy_->ConnectToSignal(
232 cros_disks::kCrosDisksInterface,
233 kSignalEventTuples[i].signal_name,
234 base::Bind(&CrosDisksClientImpl::OnMountEvent,
235 weak_ptr_factory_.GetWeakPtr(),
236 kSignalEventTuples[i].event_type,
237 mount_event_handler),
238 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
239 weak_ptr_factory_.GetWeakPtr()));
240 }
[email protected]a0278d52014-05-06 03:36:15241 }
242
243 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50244 void SetMountCompletedHandler(
mostynb4f4cf142014-10-06 13:57:52245 const MountCompletedHandler& mount_completed_handler) override {
[email protected]4ae73292011-11-15 05:20:18246 proxy_->ConnectToSignal(
247 cros_disks::kCrosDisksInterface,
[email protected]b3e3f492011-11-18 18:46:00248 cros_disks::kMountCompleted,
[email protected]4ae73292011-11-15 05:20:18249 base::Bind(&CrosDisksClientImpl::OnMountCompleted,
250 weak_ptr_factory_.GetWeakPtr(),
[email protected]85b95a2012012-08-07 18:57:27251 mount_completed_handler),
[email protected]4ae73292011-11-15 05:20:18252 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
253 weak_ptr_factory_.GetWeakPtr()));
254 }
255
[email protected]a0278d52014-05-06 03:36:15256 // CrosDisksClient override.
dcheng0280cb62015-01-16 07:37:50257 void SetFormatCompletedHandler(
mostynb4f4cf142014-10-06 13:57:52258 const FormatCompletedHandler& format_completed_handler) override {
[email protected]a0278d52014-05-06 03:36:15259 proxy_->ConnectToSignal(
260 cros_disks::kCrosDisksInterface,
261 cros_disks::kFormatCompleted,
262 base::Bind(&CrosDisksClientImpl::OnFormatCompleted,
263 weak_ptr_factory_.GetWeakPtr(),
264 format_completed_handler),
265 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
266 weak_ptr_factory_.GetWeakPtr()));
267 }
268
Klemen Kozjekbf5610f2017-08-25 20:20:09269 // CrosDisksClient override.
270 void SetRenameCompletedHandler(
271 const RenameCompletedHandler& rename_completed_handler) override {
272 proxy_->ConnectToSignal(
273 cros_disks::kCrosDisksInterface, cros_disks::kRenameCompleted,
274 base::Bind(&CrosDisksClientImpl::OnRenameCompleted,
275 weak_ptr_factory_.GetWeakPtr(), rename_completed_handler),
276 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
277 weak_ptr_factory_.GetWeakPtr()));
278 }
279
[email protected]c5fd5362013-08-27 12:23:04280 protected:
dcheng0280cb62015-01-16 07:37:50281 void Init(dbus::Bus* bus) override {
[email protected]c5fd5362013-08-27 12:23:04282 proxy_ = bus->GetObjectProxy(
283 cros_disks::kCrosDisksServiceName,
284 dbus::ObjectPath(cros_disks::kCrosDisksServicePath));
285 }
286
[email protected]4ae73292011-11-15 05:20:18287 private:
288 // A struct to contain a pair of signal name and mount event type.
[email protected]a0278d52014-05-06 03:36:15289 // Used by SetMountEventHandler.
[email protected]4ae73292011-11-15 05:20:18290 struct SignalEventTuple {
291 const char *signal_name;
292 MountEventType event_type;
293 };
294
295 // Handles the result of Mount and calls |callback| or |error_callback|.
[email protected]5624a252013-07-04 03:17:53296 void OnMount(const base::Closure& callback,
297 const base::Closure& error_callback,
[email protected]4ae73292011-11-15 05:20:18298 dbus::Response* response) {
299 if (!response) {
300 error_callback.Run();
301 return;
302 }
303 callback.Run();
304 }
305
[email protected]d7760592014-05-16 07:57:52306 // Handles the result of Unmount and calls |callback| or |error_callback|.
[email protected]ffdcc7a9c2013-07-02 06:59:39307 void OnUnmount(const base::Closure& callback,
308 const base::Closure& error_callback,
[email protected]4ae73292011-11-15 05:20:18309 dbus::Response* response) {
310 if (!response) {
[email protected]ffdcc7a9c2013-07-02 06:59:39311 error_callback.Run();
[email protected]4ae73292011-11-15 05:20:18312 return;
313 }
[email protected]ddcb18e2013-09-19 07:17:28314
315 // Temporarly allow Unmount method to report failure both by setting dbus
316 // error (in which case response is not set) and by returning mount error
317 // different from MOUNT_ERROR_NONE. This is done so we can change Unmount
318 // method to return mount error (http://crbug.com/288974) without breaking
319 // Chrome.
320 // TODO(tbarzic): When Unmount implementation is changed on cros disks side,
321 // make this fail if reader is not able to read the error code value from
322 // the response.
323 dbus::MessageReader reader(response);
avi6e1a22d2015-12-21 03:43:20324 uint32_t error_code = 0;
[email protected]ddcb18e2013-09-19 07:17:28325 if (reader.PopUint32(&error_code) &&
326 static_cast<MountError>(error_code) != MOUNT_ERROR_NONE) {
327 error_callback.Run();
328 return;
329 }
330
[email protected]ffdcc7a9c2013-07-02 06:59:39331 callback.Run();
[email protected]4ae73292011-11-15 05:20:18332 }
333
334 // Handles the result of EnumerateAutoMountableDevices and calls |callback| or
335 // |error_callback|.
336 void OnEnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35337 const EnumerateAutoMountableDevicesCallback& callback,
[email protected]5624a252013-07-04 03:17:53338 const base::Closure& error_callback,
[email protected]4ae73292011-11-15 05:20:18339 dbus::Response* response) {
340 if (!response) {
341 error_callback.Run();
342 return;
343 }
344 dbus::MessageReader reader(response);
345 std::vector<std::string> device_paths;
346 if (!reader.PopArrayOfStrings(&device_paths)) {
347 LOG(ERROR) << "Invalid response: " << response->ToString();
348 error_callback.Run();
349 return;
350 }
351 callback.Run(device_paths);
352 }
353
[email protected]d7760592014-05-16 07:57:52354 // Handles the result of EnumerateMountEntries and calls |callback| or
355 // |error_callback|.
356 void OnEnumerateMountEntries(
357 const EnumerateMountEntriesCallback& callback,
358 const base::Closure& error_callback,
359 dbus::Response* response) {
360 if (!response) {
361 error_callback.Run();
362 return;
363 }
364
365 dbus::MessageReader reader(response);
366 dbus::MessageReader array_reader(NULL);
367 if (!reader.PopArray(&array_reader)) {
368 LOG(ERROR) << "Invalid response: " << response->ToString();
369 error_callback.Run();
370 return;
371 }
372
373 std::vector<MountEntry> entries;
374 while (array_reader.HasMoreData()) {
375 MountEntry entry;
376 dbus::MessageReader sub_reader(NULL);
377 if (!array_reader.PopStruct(&sub_reader) ||
378 !ReadMountEntryFromDbus(&sub_reader, &entry)) {
379 LOG(ERROR) << "Invalid response: " << response->ToString();
380 error_callback.Run();
381 return;
382 }
383 entries.push_back(entry);
384 }
385 callback.Run(entries);
386 }
387
[email protected]f026c0f2014-05-06 21:52:35388 // Handles the result of Format and calls |callback| or |error_callback|.
389 void OnFormat(const base::Closure& callback,
390 const base::Closure& error_callback,
391 dbus::Response* response) {
[email protected]4ae73292011-11-15 05:20:18392 if (!response) {
393 error_callback.Run();
394 return;
395 }
[email protected]f026c0f2014-05-06 21:52:35396 callback.Run();
[email protected]4ae73292011-11-15 05:20:18397 }
398
Klemen Kozjekbf5610f2017-08-25 20:20:09399 // Handles the result of Rename and calls |callback| or |error_callback|.
400 void OnRename(const base::Closure& callback,
401 const base::Closure& error_callback,
402 dbus::Response* response) {
403 if (!response) {
404 error_callback.Run();
405 return;
406 }
407 callback.Run();
408 }
409
[email protected]4ae73292011-11-15 05:20:18410 // Handles the result of GetDeviceProperties and calls |callback| or
411 // |error_callback|.
412 void OnGetDeviceProperties(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35413 const GetDevicePropertiesCallback& callback,
[email protected]5624a252013-07-04 03:17:53414 const base::Closure& error_callback,
[email protected]4ae73292011-11-15 05:20:18415 dbus::Response* response) {
416 if (!response) {
417 error_callback.Run();
418 return;
419 }
420 DiskInfo disk(device_path, response);
421 callback.Run(disk);
422 }
423
424 // Handles mount event signals and calls |handler|.
425 void OnMountEvent(MountEventType event_type,
426 MountEventHandler handler,
427 dbus::Signal* signal) {
428 dbus::MessageReader reader(signal);
429 std::string device;
430 if (!reader.PopString(&device)) {
431 LOG(ERROR) << "Invalid signal: " << signal->ToString();
432 return;
433 }
434 handler.Run(event_type, device);
435 }
436
437 // Handles MountCompleted signal and calls |handler|.
438 void OnMountCompleted(MountCompletedHandler handler, dbus::Signal* signal) {
439 dbus::MessageReader reader(signal);
[email protected]d7760592014-05-16 07:57:52440 MountEntry entry;
441 if (!ReadMountEntryFromDbus(&reader, &entry)) {
[email protected]4ae73292011-11-15 05:20:18442 LOG(ERROR) << "Invalid signal: " << signal->ToString();
443 return;
444 }
[email protected]d7760592014-05-16 07:57:52445 handler.Run(entry);
[email protected]4ae73292011-11-15 05:20:18446 }
447
[email protected]a0278d52014-05-06 03:36:15448 // Handles FormatCompleted signal and calls |handler|.
449 void OnFormatCompleted(FormatCompletedHandler handler, dbus::Signal* signal) {
450 dbus::MessageReader reader(signal);
avi6e1a22d2015-12-21 03:43:20451 uint32_t error_code = 0;
[email protected]a0278d52014-05-06 03:36:15452 std::string device_path;
453 if (!reader.PopUint32(&error_code) || !reader.PopString(&device_path)) {
454 LOG(ERROR) << "Invalid signal: " << signal->ToString();
455 return;
456 }
457 handler.Run(static_cast<FormatError>(error_code), device_path);
458 }
459
Klemen Kozjekbf5610f2017-08-25 20:20:09460 // Handles RenameCompleted signal and calls |handler|.
461 void OnRenameCompleted(RenameCompletedHandler handler, dbus::Signal* signal) {
462 dbus::MessageReader reader(signal);
463 uint32_t error_code = 0;
464 std::string device_path;
465 if (!reader.PopUint32(&error_code) || !reader.PopString(&device_path)) {
466 LOG(ERROR) << "Invalid signal: " << signal->ToString();
467 return;
468 }
469 handler.Run(static_cast<RenameError>(error_code), device_path);
470 }
471
[email protected]4ae73292011-11-15 05:20:18472 // Handles the result of signal connection setup.
473 void OnSignalConnected(const std::string& interface,
474 const std::string& signal,
[email protected]d6311dcb2012-10-22 03:40:43475 bool succeeded) {
476 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
[email protected]4ae73292011-11-15 05:20:18477 signal << " failed.";
478 }
479
480 dbus::ObjectProxy* proxy_;
[email protected]926957b2012-09-07 05:34:16481
482 // Note: This should remain the last member so it'll be destroyed and
483 // invalidate its weak pointers before any other members are destroyed.
[email protected]4ae73292011-11-15 05:20:18484 base::WeakPtrFactory<CrosDisksClientImpl> weak_ptr_factory_;
485
486 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl);
487};
488
[email protected]85b95a2012012-08-07 18:57:27489} // namespace
[email protected]4ae73292011-11-15 05:20:18490
491////////////////////////////////////////////////////////////////////////////////
492// DiskInfo
493
494DiskInfo::DiskInfo(const std::string& device_path, dbus::Response* response)
495 : device_path_(device_path),
496 is_drive_(false),
497 has_media_(false),
498 on_boot_device_(false),
[email protected]79ed457b2014-07-22 04:07:26499 on_removable_device_(false),
[email protected]2321d282012-01-31 23:06:59500 device_type_(DEVICE_TYPE_UNKNOWN),
[email protected]4ae73292011-11-15 05:20:18501 total_size_in_bytes_(0),
502 is_read_only_(false),
503 is_hidden_(true) {
504 InitializeFromResponse(response);
505}
506
507DiskInfo::~DiskInfo() {
508}
509
[email protected]85b95a2012012-08-07 18:57:27510// Initializes |this| from |response| given by the cros-disks service.
[email protected]4ae73292011-11-15 05:20:18511// Below is an example of |response|'s raw message (long string is ellipsized).
512//
513//
514// message_type: MESSAGE_METHOD_RETURN
515// destination: :1.8
516// sender: :1.16
517// signature: a{sv}
518// serial: 96
519// reply_serial: 267
520//
521// array [
522// dict entry {
523// string "DeviceFile"
524// variant string "/dev/sdb"
525// }
526// dict entry {
527// string "DeviceIsDrive"
528// variant bool true
529// }
530// dict entry {
531// string "DeviceIsMediaAvailable"
532// variant bool true
533// }
534// dict entry {
535// string "DeviceIsMounted"
536// variant bool false
537// }
538// dict entry {
539// string "DeviceIsOnBootDevice"
540// variant bool false
541// }
542// dict entry {
[email protected]79ed457b2014-07-22 04:07:26543// string "DeviceIsOnRemovableDevice"
544// variant bool true
545// }
546// dict entry {
[email protected]4ae73292011-11-15 05:20:18547// string "DeviceIsReadOnly"
548// variant bool false
549// }
550// dict entry {
551// string "DeviceIsVirtual"
552// variant bool false
553// }
554// dict entry {
555// string "DeviceMediaType"
avi6e1a22d2015-12-21 03:43:20556// variant uint32_t 1
[email protected]4ae73292011-11-15 05:20:18557// }
558// dict entry {
559// string "DeviceMountPaths"
560// variant array [
561// ]
562// }
563// dict entry {
564// string "DevicePresentationHide"
565// variant bool true
566// }
567// dict entry {
568// string "DeviceSize"
avi6e1a22d2015-12-21 03:43:20569// variant uint64_t 7998537728
[email protected]4ae73292011-11-15 05:20:18570// }
571// dict entry {
572// string "DriveIsRotational"
573// variant bool false
574// }
575// dict entry {
[email protected]202e9fee2012-09-13 20:21:29576// string "VendorId"
577// variant string "18d1"
578// }
579// dict entry {
580// string "VendorName"
581// variant string "Google Inc."
582// }
583// dict entry {
584// string "ProductId"
585// variant string "4e11"
586// }
587// dict entry {
588// string "ProductName"
589// variant string "Nexus One"
590// }
591// dict entry {
[email protected]4ae73292011-11-15 05:20:18592// string "DriveModel"
593// variant string "TransMemory"
594// }
595// dict entry {
596// string "IdLabel"
597// variant string ""
598// }
599// dict entry {
600// string "IdUuid"
601// variant string ""
602// }
603// dict entry {
604// string "NativePath"
605// variant string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
606// }
Klemen Kozjek46f1c6192017-08-25 19:20:54607// dict entry {
608// string "FileSystemType"
609// variant string "vfat"
610// }
[email protected]4ae73292011-11-15 05:20:18611// ]
612void DiskInfo::InitializeFromResponse(dbus::Response* response) {
[email protected]81836aed2013-07-09 23:41:12613 dbus::MessageReader reader(response);
dcheng0a6e80c2016-04-08 18:37:38614 std::unique_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
[email protected]81836aed2013-07-09 23:41:12615 base::DictionaryValue* properties = NULL;
616 if (!value || !value->GetAsDictionary(&properties))
[email protected]4ae73292011-11-15 05:20:18617 return;
[email protected]4ae73292011-11-15 05:20:18618
[email protected]81836aed2013-07-09 23:41:12619 properties->GetBooleanWithoutPathExpansion(
620 cros_disks::kDeviceIsDrive, &is_drive_);
621 properties->GetBooleanWithoutPathExpansion(
622 cros_disks::kDeviceIsReadOnly, &is_read_only_);
623 properties->GetBooleanWithoutPathExpansion(
624 cros_disks::kDevicePresentationHide, &is_hidden_);
625 properties->GetBooleanWithoutPathExpansion(
626 cros_disks::kDeviceIsMediaAvailable, &has_media_);
627 properties->GetBooleanWithoutPathExpansion(
628 cros_disks::kDeviceIsOnBootDevice, &on_boot_device_);
[email protected]79ed457b2014-07-22 04:07:26629 properties->GetBooleanWithoutPathExpansion(
630 cros_disks::kDeviceIsOnRemovableDevice, &on_removable_device_);
[email protected]81836aed2013-07-09 23:41:12631 properties->GetStringWithoutPathExpansion(
632 cros_disks::kNativePath, &system_path_);
633 properties->GetStringWithoutPathExpansion(
634 cros_disks::kDeviceFile, &file_path_);
635 properties->GetStringWithoutPathExpansion(cros_disks::kVendorId, &vendor_id_);
636 properties->GetStringWithoutPathExpansion(
637 cros_disks::kVendorName, &vendor_name_);
638 properties->GetStringWithoutPathExpansion(
639 cros_disks::kProductId, &product_id_);
640 properties->GetStringWithoutPathExpansion(
641 cros_disks::kProductName, &product_name_);
642 properties->GetStringWithoutPathExpansion(
643 cros_disks::kDriveModel, &drive_model_);
644 properties->GetStringWithoutPathExpansion(cros_disks::kIdLabel, &label_);
645 properties->GetStringWithoutPathExpansion(cros_disks::kIdUuid, &uuid_);
Klemen Kozjek46f1c6192017-08-25 19:20:54646 properties->GetStringWithoutPathExpansion(cros_disks::kFileSystemType,
647 &file_system_type_);
[email protected]2321d282012-01-31 23:06:59648
avi6e1a22d2015-12-21 03:43:20649 // dbus::PopDataAsValue() pops uint64_t as double.
650 // The top 11 bits of uint64_t are dropped by the use of double. But, this
651 // works
[email protected]81836aed2013-07-09 23:41:12652 // unless the size exceeds 8 PB.
653 double device_size_double = 0;
654 if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceSize,
655 &device_size_double))
656 total_size_in_bytes_ = device_size_double;
657
avi6e1a22d2015-12-21 03:43:20658 // dbus::PopDataAsValue() pops uint32_t as double.
[email protected]81836aed2013-07-09 23:41:12659 double media_type_double = 0;
660 if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceMediaType,
661 &media_type_double))
662 device_type_ = DeviceMediaTypeToDeviceType(media_type_double);
663
664 base::ListValue* mount_paths = NULL;
665 if (properties->GetListWithoutPathExpansion(cros_disks::kDeviceMountPaths,
666 &mount_paths))
667 mount_paths->GetString(0, &mount_path_);
[email protected]4ae73292011-11-15 05:20:18668}
669
670////////////////////////////////////////////////////////////////////////////////
671// CrosDisksClient
672
673CrosDisksClient::CrosDisksClient() {}
674
675CrosDisksClient::~CrosDisksClient() {}
676
677// static
[email protected]c5fd5362013-08-27 12:23:04678CrosDisksClient* CrosDisksClient::Create(DBusClientImplementationType type) {
[email protected]e8db03d62012-03-31 04:08:38679 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
[email protected]c5fd5362013-08-27 12:23:04680 return new CrosDisksClientImpl();
jamescook2b590992016-09-14 15:28:45681 DCHECK_EQ(FAKE_DBUS_CLIENT_IMPLEMENTATION, type);
satorux8fd293802014-10-30 08:23:12682 return new FakeCrosDisksClient();
[email protected]4ae73292011-11-15 05:20:18683}
684
[email protected]a5a8b412013-03-04 15:03:11685// static
686base::FilePath CrosDisksClient::GetArchiveMountPoint() {
[email protected]49c4cf852013-09-27 19:28:24687 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
[email protected]a5a8b412013-03-04 15:03:11688 FILE_PATH_LITERAL("/media/archive") :
689 FILE_PATH_LITERAL("/tmp/chromeos/media/archive"));
690}
691
692// static
693base::FilePath CrosDisksClient::GetRemovableDiskMountPoint() {
[email protected]49c4cf852013-09-27 19:28:24694 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
[email protected]a5a8b412013-03-04 15:03:11695 FILE_PATH_LITERAL("/media/removable") :
696 FILE_PATH_LITERAL("/tmp/chromeos/media/removable"));
697}
698
yamaguchi585d5402016-08-02 09:27:36699// static
700std::vector<std::string> CrosDisksClient::ComposeMountOptions(
701 const std::string& mount_label,
yamaguchifa8efc72016-10-21 15:05:51702 MountAccessMode access_mode,
703 RemountOption remount) {
yamaguchi585d5402016-08-02 09:27:36704 std::vector<std::string> mount_options(
705 kDefaultMountOptions,
706 kDefaultMountOptions + arraysize(kDefaultMountOptions));
707 switch (access_mode) {
708 case MOUNT_ACCESS_MODE_READ_ONLY:
709 mount_options.push_back(kReadOnlyOption);
710 break;
711 case MOUNT_ACCESS_MODE_READ_WRITE:
712 mount_options.push_back(kReadWriteOption);
713 break;
714 }
yamaguchifa8efc72016-10-21 15:05:51715 if (remount == REMOUNT_OPTION_REMOUNT_EXISTING_DEVICE) {
716 mount_options.push_back(kRemountOption);
717 }
yamaguchi585d5402016-08-02 09:27:36718
719 if (!mount_label.empty()) {
720 std::string mount_label_option =
721 base::StringPrintf("%s=%s", kMountLabelOption, mount_label.c_str());
722 mount_options.push_back(mount_label_option);
723 }
724 return mount_options;
725}
726
[email protected]4ae73292011-11-15 05:20:18727} // namespace chromeos