1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/dbus/cros_disks_client.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/location.h"
13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/stl_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/sys_info.h"
17 #include "base/task_runner_util.h"
18 #include "base/threading/worker_pool.h"
19 #include "base/values.h"
21 #include "dbus/message.h"
22 #include "dbus/object_path.h"
23 #include "dbus/object_proxy.h"
24 #include "dbus/values_util.h"
25 #include "third_party/cros_system_api/dbus/service_constants.h"
31 const char* kDefaultMountOptions
[] = {
38 const char* kDefaultUnmountOptions
[] = {
42 const char kLazyUnmountOption
[] = "lazy";
44 const char kMountLabelOption
[] = "mountlabel";
46 // Checks if retrieved media type is in boundaries of DeviceMediaType.
47 bool IsValidMediaType(uint32 type
) {
48 return type
< static_cast<uint32
>(cros_disks::DEVICE_MEDIA_NUM_VALUES
);
51 // Translates enum used in cros-disks to enum used in Chrome.
52 // Note that we could just do static_cast, but this is less sensitive to
53 // changes in cros-disks.
54 DeviceType
DeviceMediaTypeToDeviceType(uint32 media_type_uint32
) {
55 if (!IsValidMediaType(media_type_uint32
))
56 return DEVICE_TYPE_UNKNOWN
;
58 cros_disks::DeviceMediaType media_type
=
59 cros_disks::DeviceMediaType(media_type_uint32
);
62 case(cros_disks::DEVICE_MEDIA_UNKNOWN
):
63 return DEVICE_TYPE_UNKNOWN
;
64 case(cros_disks::DEVICE_MEDIA_USB
):
65 return DEVICE_TYPE_USB
;
66 case(cros_disks::DEVICE_MEDIA_SD
):
67 return DEVICE_TYPE_SD
;
68 case(cros_disks::DEVICE_MEDIA_OPTICAL_DISC
):
69 return DEVICE_TYPE_OPTICAL_DISC
;
70 case(cros_disks::DEVICE_MEDIA_MOBILE
):
71 return DEVICE_TYPE_MOBILE
;
72 case(cros_disks::DEVICE_MEDIA_DVD
):
73 return DEVICE_TYPE_DVD
;
75 return DEVICE_TYPE_UNKNOWN
;
79 bool ReadMountEntryFromDbus(dbus::MessageReader
* reader
, MountEntry
* entry
) {
80 uint32 error_code
= 0;
81 std::string source_path
;
82 uint32 mount_type
= 0;
83 std::string mount_path
;
84 if (!reader
->PopUint32(&error_code
) ||
85 !reader
->PopString(&source_path
) ||
86 !reader
->PopUint32(&mount_type
) ||
87 !reader
->PopString(&mount_path
)) {
90 *entry
= MountEntry(static_cast<MountError
>(error_code
), source_path
,
91 static_cast<MountType
>(mount_type
), mount_path
);
95 // The CrosDisksClient implementation.
96 class CrosDisksClientImpl
: public CrosDisksClient
{
98 CrosDisksClientImpl() : proxy_(NULL
), weak_ptr_factory_(this) {}
100 // CrosDisksClient override.
101 virtual void Mount(const std::string
& source_path
,
102 const std::string
& source_format
,
103 const std::string
& mount_label
,
104 const base::Closure
& callback
,
105 const base::Closure
& error_callback
) OVERRIDE
{
106 dbus::MethodCall
method_call(cros_disks::kCrosDisksInterface
,
108 dbus::MessageWriter
writer(&method_call
);
109 writer
.AppendString(source_path
);
110 writer
.AppendString(source_format
);
111 std::vector
<std::string
> mount_options(kDefaultMountOptions
,
112 kDefaultMountOptions
+
113 arraysize(kDefaultMountOptions
));
114 if (!mount_label
.empty()) {
115 std::string mount_label_option
= base::StringPrintf("%s=%s",
117 mount_label
.c_str());
118 mount_options
.push_back(mount_label_option
);
120 writer
.AppendArrayOfStrings(mount_options
);
121 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
122 base::Bind(&CrosDisksClientImpl::OnMount
,
123 weak_ptr_factory_
.GetWeakPtr(),
128 // CrosDisksClient override.
129 virtual void Unmount(const std::string
& device_path
,
130 UnmountOptions options
,
131 const base::Closure
& callback
,
132 const base::Closure
& error_callback
) OVERRIDE
{
133 dbus::MethodCall
method_call(cros_disks::kCrosDisksInterface
,
134 cros_disks::kUnmount
);
135 dbus::MessageWriter
writer(&method_call
);
136 writer
.AppendString(device_path
);
138 std::vector
<std::string
> unmount_options(
139 kDefaultUnmountOptions
,
140 kDefaultUnmountOptions
+ arraysize(kDefaultUnmountOptions
));
141 if (options
== UNMOUNT_OPTIONS_LAZY
)
142 unmount_options
.push_back(kLazyUnmountOption
);
144 writer
.AppendArrayOfStrings(unmount_options
);
145 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
146 base::Bind(&CrosDisksClientImpl::OnUnmount
,
147 weak_ptr_factory_
.GetWeakPtr(),
152 // CrosDisksClient override.
153 virtual void EnumerateAutoMountableDevices(
154 const EnumerateAutoMountableDevicesCallback
& callback
,
155 const base::Closure
& error_callback
) OVERRIDE
{
156 dbus::MethodCall
method_call(cros_disks::kCrosDisksInterface
,
157 cros_disks::kEnumerateAutoMountableDevices
);
159 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
160 base::Bind(&CrosDisksClientImpl::OnEnumerateAutoMountableDevices
,
161 weak_ptr_factory_
.GetWeakPtr(),
166 // CrosDisksClient override.
167 virtual void EnumerateMountEntries(
168 const EnumerateMountEntriesCallback
& callback
,
169 const base::Closure
& error_callback
) OVERRIDE
{
170 dbus::MethodCall
method_call(cros_disks::kCrosDisksInterface
,
171 cros_disks::kEnumerateMountEntries
);
173 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
174 base::Bind(&CrosDisksClientImpl::OnEnumerateMountEntries
,
175 weak_ptr_factory_
.GetWeakPtr(),
180 // CrosDisksClient override.
181 virtual void Format(const std::string
& device_path
,
182 const std::string
& filesystem
,
183 const base::Closure
& callback
,
184 const base::Closure
& error_callback
) OVERRIDE
{
185 dbus::MethodCall
method_call(cros_disks::kCrosDisksInterface
,
186 cros_disks::kFormat
);
187 dbus::MessageWriter
writer(&method_call
);
188 writer
.AppendString(device_path
);
189 writer
.AppendString(filesystem
);
190 // No format option is currently specified, but we can later use this
191 // argument to specify options for the format operation.
192 std::vector
<std::string
> format_options
;
193 writer
.AppendArrayOfStrings(format_options
);
194 proxy_
->CallMethod(&method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
195 base::Bind(&CrosDisksClientImpl::OnFormat
,
196 weak_ptr_factory_
.GetWeakPtr(),
201 // CrosDisksClient override.
202 virtual void GetDeviceProperties(
203 const std::string
& device_path
,
204 const GetDevicePropertiesCallback
& callback
,
205 const base::Closure
& error_callback
) OVERRIDE
{
206 dbus::MethodCall
method_call(cros_disks::kCrosDisksInterface
,
207 cros_disks::kGetDeviceProperties
);
208 dbus::MessageWriter
writer(&method_call
);
209 writer
.AppendString(device_path
);
210 proxy_
->CallMethod(&method_call
,
211 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
212 base::Bind(&CrosDisksClientImpl::OnGetDeviceProperties
,
213 weak_ptr_factory_
.GetWeakPtr(),
219 // CrosDisksClient override.
220 virtual void SetMountEventHandler(
221 const MountEventHandler
& mount_event_handler
) OVERRIDE
{
222 static const SignalEventTuple kSignalEventTuples
[] = {
223 { cros_disks::kDeviceAdded
, CROS_DISKS_DEVICE_ADDED
},
224 { cros_disks::kDeviceScanned
, CROS_DISKS_DEVICE_SCANNED
},
225 { cros_disks::kDeviceRemoved
, CROS_DISKS_DEVICE_REMOVED
},
226 { cros_disks::kDiskAdded
, CROS_DISKS_DISK_ADDED
},
227 { cros_disks::kDiskChanged
, CROS_DISKS_DISK_CHANGED
},
228 { cros_disks::kDiskRemoved
, CROS_DISKS_DISK_REMOVED
},
230 const size_t kNumSignalEventTuples
= arraysize(kSignalEventTuples
);
232 for (size_t i
= 0; i
< kNumSignalEventTuples
; ++i
) {
233 proxy_
->ConnectToSignal(
234 cros_disks::kCrosDisksInterface
,
235 kSignalEventTuples
[i
].signal_name
,
236 base::Bind(&CrosDisksClientImpl::OnMountEvent
,
237 weak_ptr_factory_
.GetWeakPtr(),
238 kSignalEventTuples
[i
].event_type
,
239 mount_event_handler
),
240 base::Bind(&CrosDisksClientImpl::OnSignalConnected
,
241 weak_ptr_factory_
.GetWeakPtr()));
245 // CrosDisksClient override.
246 virtual void SetMountCompletedHandler(
247 const MountCompletedHandler
& mount_completed_handler
) OVERRIDE
{
248 proxy_
->ConnectToSignal(
249 cros_disks::kCrosDisksInterface
,
250 cros_disks::kMountCompleted
,
251 base::Bind(&CrosDisksClientImpl::OnMountCompleted
,
252 weak_ptr_factory_
.GetWeakPtr(),
253 mount_completed_handler
),
254 base::Bind(&CrosDisksClientImpl::OnSignalConnected
,
255 weak_ptr_factory_
.GetWeakPtr()));
258 // CrosDisksClient override.
259 virtual void SetFormatCompletedHandler(
260 const FormatCompletedHandler
& format_completed_handler
) OVERRIDE
{
261 proxy_
->ConnectToSignal(
262 cros_disks::kCrosDisksInterface
,
263 cros_disks::kFormatCompleted
,
264 base::Bind(&CrosDisksClientImpl::OnFormatCompleted
,
265 weak_ptr_factory_
.GetWeakPtr(),
266 format_completed_handler
),
267 base::Bind(&CrosDisksClientImpl::OnSignalConnected
,
268 weak_ptr_factory_
.GetWeakPtr()));
272 virtual void Init(dbus::Bus
* bus
) OVERRIDE
{
273 proxy_
= bus
->GetObjectProxy(
274 cros_disks::kCrosDisksServiceName
,
275 dbus::ObjectPath(cros_disks::kCrosDisksServicePath
));
279 // A struct to contain a pair of signal name and mount event type.
280 // Used by SetMountEventHandler.
281 struct SignalEventTuple
{
282 const char *signal_name
;
283 MountEventType event_type
;
286 // Handles the result of Mount and calls |callback| or |error_callback|.
287 void OnMount(const base::Closure
& callback
,
288 const base::Closure
& error_callback
,
289 dbus::Response
* response
) {
291 error_callback
.Run();
297 // Handles the result of Unmount and calls |callback| or |error_callback|.
298 void OnUnmount(const base::Closure
& callback
,
299 const base::Closure
& error_callback
,
300 dbus::Response
* response
) {
302 error_callback
.Run();
306 // Temporarly allow Unmount method to report failure both by setting dbus
307 // error (in which case response is not set) and by returning mount error
308 // different from MOUNT_ERROR_NONE. This is done so we can change Unmount
309 // method to return mount error (http://crbug.com/288974) without breaking
311 // TODO(tbarzic): When Unmount implementation is changed on cros disks side,
312 // make this fail if reader is not able to read the error code value from
314 dbus::MessageReader
reader(response
);
315 uint32 error_code
= 0;
316 if (reader
.PopUint32(&error_code
) &&
317 static_cast<MountError
>(error_code
) != MOUNT_ERROR_NONE
) {
318 error_callback
.Run();
325 // Handles the result of EnumerateAutoMountableDevices and calls |callback| or
327 void OnEnumerateAutoMountableDevices(
328 const EnumerateAutoMountableDevicesCallback
& callback
,
329 const base::Closure
& error_callback
,
330 dbus::Response
* response
) {
332 error_callback
.Run();
335 dbus::MessageReader
reader(response
);
336 std::vector
<std::string
> device_paths
;
337 if (!reader
.PopArrayOfStrings(&device_paths
)) {
338 LOG(ERROR
) << "Invalid response: " << response
->ToString();
339 error_callback
.Run();
342 callback
.Run(device_paths
);
345 // Handles the result of EnumerateMountEntries and calls |callback| or
347 void OnEnumerateMountEntries(
348 const EnumerateMountEntriesCallback
& callback
,
349 const base::Closure
& error_callback
,
350 dbus::Response
* response
) {
352 error_callback
.Run();
356 dbus::MessageReader
reader(response
);
357 dbus::MessageReader
array_reader(NULL
);
358 if (!reader
.PopArray(&array_reader
)) {
359 LOG(ERROR
) << "Invalid response: " << response
->ToString();
360 error_callback
.Run();
364 std::vector
<MountEntry
> entries
;
365 while (array_reader
.HasMoreData()) {
367 dbus::MessageReader
sub_reader(NULL
);
368 if (!array_reader
.PopStruct(&sub_reader
) ||
369 !ReadMountEntryFromDbus(&sub_reader
, &entry
)) {
370 LOG(ERROR
) << "Invalid response: " << response
->ToString();
371 error_callback
.Run();
374 entries
.push_back(entry
);
376 callback
.Run(entries
);
379 // Handles the result of Format and calls |callback| or |error_callback|.
380 void OnFormat(const base::Closure
& callback
,
381 const base::Closure
& error_callback
,
382 dbus::Response
* response
) {
384 error_callback
.Run();
390 // Handles the result of GetDeviceProperties and calls |callback| or
392 void OnGetDeviceProperties(const std::string
& device_path
,
393 const GetDevicePropertiesCallback
& callback
,
394 const base::Closure
& error_callback
,
395 dbus::Response
* response
) {
397 error_callback
.Run();
400 DiskInfo
disk(device_path
, response
);
404 // Handles mount event signals and calls |handler|.
405 void OnMountEvent(MountEventType event_type
,
406 MountEventHandler handler
,
407 dbus::Signal
* signal
) {
408 dbus::MessageReader
reader(signal
);
410 if (!reader
.PopString(&device
)) {
411 LOG(ERROR
) << "Invalid signal: " << signal
->ToString();
414 handler
.Run(event_type
, device
);
417 // Handles MountCompleted signal and calls |handler|.
418 void OnMountCompleted(MountCompletedHandler handler
, dbus::Signal
* signal
) {
419 dbus::MessageReader
reader(signal
);
421 if (!ReadMountEntryFromDbus(&reader
, &entry
)) {
422 LOG(ERROR
) << "Invalid signal: " << signal
->ToString();
428 // Handles FormatCompleted signal and calls |handler|.
429 void OnFormatCompleted(FormatCompletedHandler handler
, dbus::Signal
* signal
) {
430 dbus::MessageReader
reader(signal
);
431 uint32 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();
437 handler
.Run(static_cast<FormatError
>(error_code
), device_path
);
440 // Handles the result of signal connection setup.
441 void OnSignalConnected(const std::string
& interface
,
442 const std::string
& signal
,
444 LOG_IF(ERROR
, !succeeded
) << "Connect to " << interface
<< " " <<
445 signal
<< " failed.";
448 dbus::ObjectProxy
* proxy_
;
450 // Note: This should remain the last member so it'll be destroyed and
451 // invalidate its weak pointers before any other members are destroyed.
452 base::WeakPtrFactory
<CrosDisksClientImpl
> weak_ptr_factory_
;
454 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl
);
457 // A stub implementaion of CrosDisksClient.
458 class CrosDisksClientStubImpl
: public CrosDisksClient
{
460 CrosDisksClientStubImpl()
461 : weak_ptr_factory_(this) {}
463 virtual ~CrosDisksClientStubImpl() {}
465 // CrosDisksClient overrides:
466 virtual void Init(dbus::Bus
* bus
) OVERRIDE
{}
467 virtual void Mount(const std::string
& source_path
,
468 const std::string
& source_format
,
469 const std::string
& mount_label
,
470 const base::Closure
& callback
,
471 const base::Closure
& error_callback
) OVERRIDE
{
472 // This stub implementation only accepts archive mount requests.
473 const MountType type
= MOUNT_TYPE_ARCHIVE
;
475 const base::FilePath mounted_path
= GetArchiveMountPoint().Append(
476 base::FilePath::FromUTF8Unsafe(mount_label
));
478 // Already mounted path.
479 if (mounted_to_source_path_map_
.count(mounted_path
.value()) != 0) {
480 FinishMount(MOUNT_ERROR_PATH_ALREADY_MOUNTED
, source_path
, type
,
481 std::string(), callback
);
485 // Perform fake mount.
486 base::PostTaskAndReplyWithResult(
487 base::WorkerPool::GetTaskRunner(true /* task_is_slow */).get(),
489 base::Bind(&PerformFakeMount
, source_path
, mounted_path
),
490 base::Bind(&CrosDisksClientStubImpl::ContinueMount
,
491 weak_ptr_factory_
.GetWeakPtr(),
498 virtual void Unmount(const std::string
& device_path
,
499 UnmountOptions options
,
500 const base::Closure
& callback
,
501 const base::Closure
& error_callback
) OVERRIDE
{
503 if (mounted_to_source_path_map_
.count(device_path
) == 0) {
504 base::MessageLoopProxy::current()->PostTask(FROM_HERE
, error_callback
);
508 mounted_to_source_path_map_
.erase(device_path
);
510 // Remove the directory created in Mount().
511 base::WorkerPool::PostTaskAndReply(
513 base::Bind(base::IgnoreResult(&base::DeleteFile
),
514 base::FilePath::FromUTF8Unsafe(device_path
),
515 true /* recursive */),
517 true /* task_is_slow */);
520 virtual void EnumerateAutoMountableDevices(
521 const EnumerateAutoMountableDevicesCallback
& callback
,
522 const base::Closure
& error_callback
) OVERRIDE
{
523 std::vector
<std::string
> device_paths
;
524 base::MessageLoopProxy::current()->PostTask(
525 FROM_HERE
, base::Bind(callback
, device_paths
));
528 virtual void EnumerateMountEntries(
529 const EnumerateMountEntriesCallback
& callback
,
530 const base::Closure
& error_callback
) OVERRIDE
{
531 std::vector
<MountEntry
> entries
;
532 base::MessageLoopProxy::current()->PostTask(
533 FROM_HERE
, base::Bind(callback
, entries
));
536 virtual void Format(const std::string
& device_path
,
537 const std::string
& filesystem
,
538 const base::Closure
& callback
,
539 const base::Closure
& error_callback
) OVERRIDE
{
540 base::MessageLoopProxy::current()->PostTask(FROM_HERE
, error_callback
);
543 virtual void GetDeviceProperties(
544 const std::string
& device_path
,
545 const GetDevicePropertiesCallback
& callback
,
546 const base::Closure
& error_callback
) OVERRIDE
{
547 base::MessageLoopProxy::current()->PostTask(FROM_HERE
, error_callback
);
550 virtual void SetMountEventHandler(
551 const MountEventHandler
& mount_event_handler
) OVERRIDE
{
552 mount_event_handler_
= mount_event_handler
;
555 virtual void SetMountCompletedHandler(
556 const MountCompletedHandler
& mount_completed_handler
) OVERRIDE
{
557 mount_completed_handler_
= mount_completed_handler
;
560 virtual void SetFormatCompletedHandler(
561 const FormatCompletedHandler
& format_completed_handler
) OVERRIDE
{
562 format_completed_handler_
= format_completed_handler
;
566 // Performs file actions for Mount().
567 static MountError
PerformFakeMount(const std::string
& source_path
,
568 const base::FilePath
& mounted_path
) {
569 // Check the source path exists.
570 if (!base::PathExists(base::FilePath::FromUTF8Unsafe(source_path
))) {
571 DLOG(ERROR
) << "Source does not exist at " << source_path
;
572 return MOUNT_ERROR_INVALID_PATH
;
575 // Just create an empty directory and shows it as the mounted directory.
576 if (!base::CreateDirectory(mounted_path
)) {
577 DLOG(ERROR
) << "Failed to create directory at " << mounted_path
.value();
578 return MOUNT_ERROR_DIRECTORY_CREATION_FAILED
;
582 const base::FilePath dummy_file_path
=
583 mounted_path
.Append("SUCCESSFULLY_PERFORMED_FAKE_MOUNT.txt");
584 const std::string dummy_file_content
= "This is a dummy file.";
585 const int write_result
= base::WriteFile(
586 dummy_file_path
, dummy_file_content
.data(), dummy_file_content
.size());
587 if (write_result
!= static_cast<int>(dummy_file_content
.size())) {
588 DLOG(ERROR
) << "Failed to put a dummy file at "
589 << dummy_file_path
.value();
590 return MOUNT_ERROR_MOUNT_PROGRAM_FAILED
;
593 return MOUNT_ERROR_NONE
;
596 // Part of Mount() implementation.
597 void ContinueMount(const std::string
& source_path
,
599 const base::Closure
& callback
,
600 const base::FilePath
& mounted_path
,
601 MountError mount_error
) {
602 if (mount_error
!= MOUNT_ERROR_NONE
) {
603 FinishMount(mount_error
, source_path
, type
, std::string(), callback
);
606 mounted_to_source_path_map_
[mounted_path
.value()] = source_path
;
607 FinishMount(MOUNT_ERROR_NONE
, source_path
, type
,
608 mounted_path
.AsUTF8Unsafe(), callback
);
611 // Runs |callback| and sends MountCompleted signal.
612 // Part of Mount() implementation.
613 void FinishMount(MountError error
,
614 const std::string
& source_path
,
616 const std::string
& mounted_path
,
617 const base::Closure
& callback
) {
618 base::MessageLoopProxy::current()->PostTask(FROM_HERE
, callback
);
619 if (!mount_completed_handler_
.is_null()) {
620 base::MessageLoopProxy::current()->PostTask(
622 base::Bind(mount_completed_handler_
,
623 MountEntry(error
, source_path
, type
, mounted_path
)));
627 // Mounted path to source path map.
628 std::map
<std::string
, std::string
> mounted_to_source_path_map_
;
630 MountEventHandler mount_event_handler_
;
631 MountCompletedHandler mount_completed_handler_
;
632 FormatCompletedHandler format_completed_handler_
;
634 base::WeakPtrFactory
<CrosDisksClientStubImpl
> weak_ptr_factory_
;
636 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientStubImpl
);
641 ////////////////////////////////////////////////////////////////////////////////
644 DiskInfo::DiskInfo(const std::string
& device_path
, dbus::Response
* response
)
645 : device_path_(device_path
),
648 on_boot_device_(false),
649 on_removable_device_(false),
650 device_type_(DEVICE_TYPE_UNKNOWN
),
651 total_size_in_bytes_(0),
652 is_read_only_(false),
654 InitializeFromResponse(response
);
657 DiskInfo::~DiskInfo() {
660 // Initializes |this| from |response| given by the cros-disks service.
661 // Below is an example of |response|'s raw message (long string is ellipsized).
664 // message_type: MESSAGE_METHOD_RETURN
673 // string "DeviceFile"
674 // variant string "/dev/sdb"
677 // string "DeviceIsDrive"
681 // string "DeviceIsMediaAvailable"
685 // string "DeviceIsMounted"
686 // variant bool false
689 // string "DeviceIsOnBootDevice"
690 // variant bool false
693 // string "DeviceIsOnRemovableDevice"
697 // string "DeviceIsReadOnly"
698 // variant bool false
701 // string "DeviceIsVirtual"
702 // variant bool false
705 // string "DeviceMediaType"
709 // string "DeviceMountPaths"
714 // string "DevicePresentationHide"
718 // string "DeviceSize"
719 // variant uint64 7998537728
722 // string "DriveIsRotational"
723 // variant bool false
727 // variant string "18d1"
730 // string "VendorName"
731 // variant string "Google Inc."
734 // string "ProductId"
735 // variant string "4e11"
738 // string "ProductName"
739 // variant string "Nexus One"
742 // string "DriveModel"
743 // variant string "TransMemory"
754 // string "NativePath"
755 // variant string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
758 void DiskInfo::InitializeFromResponse(dbus::Response
* response
) {
759 dbus::MessageReader
reader(response
);
760 scoped_ptr
<base::Value
> value(dbus::PopDataAsValue(&reader
));
761 base::DictionaryValue
* properties
= NULL
;
762 if (!value
|| !value
->GetAsDictionary(&properties
))
765 properties
->GetBooleanWithoutPathExpansion(
766 cros_disks::kDeviceIsDrive
, &is_drive_
);
767 properties
->GetBooleanWithoutPathExpansion(
768 cros_disks::kDeviceIsReadOnly
, &is_read_only_
);
769 properties
->GetBooleanWithoutPathExpansion(
770 cros_disks::kDevicePresentationHide
, &is_hidden_
);
771 properties
->GetBooleanWithoutPathExpansion(
772 cros_disks::kDeviceIsMediaAvailable
, &has_media_
);
773 properties
->GetBooleanWithoutPathExpansion(
774 cros_disks::kDeviceIsOnBootDevice
, &on_boot_device_
);
775 properties
->GetBooleanWithoutPathExpansion(
776 cros_disks::kDeviceIsOnRemovableDevice
, &on_removable_device_
);
777 properties
->GetStringWithoutPathExpansion(
778 cros_disks::kNativePath
, &system_path_
);
779 properties
->GetStringWithoutPathExpansion(
780 cros_disks::kDeviceFile
, &file_path_
);
781 properties
->GetStringWithoutPathExpansion(cros_disks::kVendorId
, &vendor_id_
);
782 properties
->GetStringWithoutPathExpansion(
783 cros_disks::kVendorName
, &vendor_name_
);
784 properties
->GetStringWithoutPathExpansion(
785 cros_disks::kProductId
, &product_id_
);
786 properties
->GetStringWithoutPathExpansion(
787 cros_disks::kProductName
, &product_name_
);
788 properties
->GetStringWithoutPathExpansion(
789 cros_disks::kDriveModel
, &drive_model_
);
790 properties
->GetStringWithoutPathExpansion(cros_disks::kIdLabel
, &label_
);
791 properties
->GetStringWithoutPathExpansion(cros_disks::kIdUuid
, &uuid_
);
793 // dbus::PopDataAsValue() pops uint64 as double.
794 // The top 11 bits of uint64 are dropped by the use of double. But, this works
795 // unless the size exceeds 8 PB.
796 double device_size_double
= 0;
797 if (properties
->GetDoubleWithoutPathExpansion(cros_disks::kDeviceSize
,
798 &device_size_double
))
799 total_size_in_bytes_
= device_size_double
;
801 // dbus::PopDataAsValue() pops uint32 as double.
802 double media_type_double
= 0;
803 if (properties
->GetDoubleWithoutPathExpansion(cros_disks::kDeviceMediaType
,
805 device_type_
= DeviceMediaTypeToDeviceType(media_type_double
);
807 base::ListValue
* mount_paths
= NULL
;
808 if (properties
->GetListWithoutPathExpansion(cros_disks::kDeviceMountPaths
,
810 mount_paths
->GetString(0, &mount_path_
);
813 ////////////////////////////////////////////////////////////////////////////////
816 CrosDisksClient::CrosDisksClient() {}
818 CrosDisksClient::~CrosDisksClient() {}
821 CrosDisksClient
* CrosDisksClient::Create(DBusClientImplementationType type
) {
822 if (type
== REAL_DBUS_CLIENT_IMPLEMENTATION
)
823 return new CrosDisksClientImpl();
824 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION
, type
);
825 return new CrosDisksClientStubImpl();
829 base::FilePath
CrosDisksClient::GetArchiveMountPoint() {
830 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
831 FILE_PATH_LITERAL("/media/archive") :
832 FILE_PATH_LITERAL("/tmp/chromeos/media/archive"));
836 base::FilePath
CrosDisksClient::GetRemovableDiskMountPoint() {
837 return base::FilePath(base::SysInfo::IsRunningOnChromeOS() ?
838 FILE_PATH_LITERAL("/media/removable") :
839 FILE_PATH_LITERAL("/tmp/chromeos/media/removable"));
842 } // namespace chromeos