blob: ab24b378c2fe68f353add9ce81ecfe4959fa8e3a [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
[email protected]85b95a2012012-08-07 18:57:277#include <map>
8
[email protected]4ae73292011-11-15 05:20:189#include "base/bind.h"
[email protected]b307bceb2011-11-17 07:49:5510#include "base/stl_util.h"
[email protected]dcad8fc2012-04-30 23:31:3311#include "base/stringprintf.h"
[email protected]4ae73292011-11-15 05:20:1812#include "dbus/bus.h"
13#include "dbus/message.h"
[email protected]216ed0b2012-02-14 21:29:0614#include "dbus/object_path.h"
[email protected]4ae73292011-11-15 05:20:1815#include "dbus/object_proxy.h"
16#include "third_party/cros_system_api/dbus/service_constants.h"
17
18namespace chromeos {
19
20namespace {
21
22const char* kDefaultMountOptions[] = {
23 "rw",
24 "nodev",
25 "noexec",
26 "nosuid",
[email protected]4ae73292011-11-15 05:20:1827};
28
29const char* kDefaultUnmountOptions[] = {
30 "force",
31};
32
[email protected]10795ae2012-10-10 07:33:4933const char kLazyUnmountOption[] = "lazy";
34
[email protected]dcad8fc2012-04-30 23:31:3335const char kMountLabelOption[] = "mountlabel";
36
[email protected]2321d282012-01-31 23:06:5937// Checks if retrieved media type is in boundaries of DeviceMediaType.
38bool IsValidMediaType(uint32 type) {
39 return type < static_cast<uint32>(cros_disks::DEVICE_MEDIA_NUM_VALUES);
40}
41
42
43// Translates enum used in cros-disks to enum used in Chrome.
44// Note that we could just do static_cast, but this is less sensitive to
45// changes in cros-disks.
46DeviceType DeviceMediaTypeToDeviceType(uint32 media_type_uint32) {
47 if (!IsValidMediaType(media_type_uint32))
48 return DEVICE_TYPE_UNKNOWN;
49
50 cros_disks::DeviceMediaType media_type =
51 cros_disks::DeviceMediaType(media_type_uint32);
52
53 switch (media_type) {
54 case(cros_disks::DEVICE_MEDIA_UNKNOWN):
55 return DEVICE_TYPE_UNKNOWN;
56 case(cros_disks::DEVICE_MEDIA_USB):
57 return DEVICE_TYPE_USB;
58 case(cros_disks::DEVICE_MEDIA_SD):
59 return DEVICE_TYPE_SD;
60 case(cros_disks::DEVICE_MEDIA_OPTICAL_DISC):
61 return DEVICE_TYPE_OPTICAL_DISC;
62 case(cros_disks::DEVICE_MEDIA_MOBILE):
63 return DEVICE_TYPE_MOBILE;
[email protected]f4ae40ac2012-05-04 21:57:0064 case(cros_disks::DEVICE_MEDIA_DVD):
65 return DEVICE_TYPE_DVD;
[email protected]2321d282012-01-31 23:06:5966 default:
67 return DEVICE_TYPE_UNKNOWN;
68 }
[email protected]4ae73292011-11-15 05:20:1869}
70
71// Pops a bool value when |reader| is not NULL.
72// Returns true when a value is popped, false otherwise.
73bool MaybePopBool(dbus::MessageReader* reader, bool* value) {
74 if (!reader)
75 return false;
76 return reader->PopBool(value);
77}
78
79// Pops a string value when |reader| is not NULL.
80// Returns true when a value is popped, false otherwise.
81bool MaybePopString(dbus::MessageReader* reader, std::string* value) {
82 if (!reader)
83 return false;
84 return reader->PopString(value);
85}
86
[email protected]2321d282012-01-31 23:06:5987// Pops a uint32 value when |reader| is not NULL.
88// Returns true when a value is popped, false otherwise.
89bool MaybePopUint32(dbus::MessageReader* reader, uint32* value) {
90 if (!reader)
91 return false;
92
93 return reader->PopUint32(value);
94}
95
[email protected]4ae73292011-11-15 05:20:1896// Pops a uint64 value when |reader| is not NULL.
97// Returns true when a value is popped, false otherwise.
98bool MaybePopUint64(dbus::MessageReader* reader, uint64* value) {
99 if (!reader)
100 return false;
101 return reader->PopUint64(value);
102}
103
104// Pops an array of strings when |reader| is not NULL.
105// Returns true when an array is popped, false otherwise.
106bool MaybePopArrayOfStrings(dbus::MessageReader* reader,
107 std::vector<std::string>* value) {
108 if (!reader)
109 return false;
110 return reader->PopArrayOfStrings(value);
111}
112
113// The CrosDisksClient implementation.
114class CrosDisksClientImpl : public CrosDisksClient {
115 public:
116 explicit CrosDisksClientImpl(dbus::Bus* bus)
[email protected]216ed0b2012-02-14 21:29:06117 : proxy_(bus->GetObjectProxy(
118 cros_disks::kCrosDisksServiceName,
119 dbus::ObjectPath(cros_disks::kCrosDisksServicePath))),
[email protected]4ae73292011-11-15 05:20:18120 weak_ptr_factory_(this) {
121 }
122
123 // CrosDisksClient override.
124 virtual void Mount(const std::string& source_path,
[email protected]b9f22d12012-04-25 21:46:48125 const std::string& source_format,
[email protected]dcad8fc2012-04-30 23:31:33126 const std::string& mount_label,
[email protected]4ae73292011-11-15 05:20:18127 MountType type,
[email protected]4a404e52012-04-11 02:25:35128 const MountCallback& callback,
129 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18130 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
131 cros_disks::kMount);
132 dbus::MessageWriter writer(&method_call);
133 writer.AppendString(source_path);
[email protected]b9f22d12012-04-25 21:46:48134 writer.AppendString(source_format);
[email protected]4ae73292011-11-15 05:20:18135 std::vector<std::string> mount_options(kDefaultMountOptions,
136 kDefaultMountOptions +
137 arraysize(kDefaultMountOptions));
[email protected]dcad8fc2012-04-30 23:31:33138 if (!mount_label.empty()) {
139 std::string mount_label_option = base::StringPrintf("%s=%s",
140 kMountLabelOption,
141 mount_label.c_str());
142 mount_options.push_back(mount_label_option);
143 }
[email protected]4ae73292011-11-15 05:20:18144 writer.AppendArrayOfStrings(mount_options);
145 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
146 base::Bind(&CrosDisksClientImpl::OnMount,
147 weak_ptr_factory_.GetWeakPtr(),
148 callback,
149 error_callback));
150 }
151
152 // CrosDisksClient override.
153 virtual void Unmount(const std::string& device_path,
[email protected]10795ae2012-10-10 07:33:49154 UnmountOptions options,
[email protected]4a404e52012-04-11 02:25:35155 const UnmountCallback& callback,
[email protected]10795ae2012-10-10 07:33:49156 const UnmountCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18157 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
158 cros_disks::kUnmount);
159 dbus::MessageWriter writer(&method_call);
160 writer.AppendString(device_path);
[email protected]10795ae2012-10-10 07:33:49161
162 std::vector<std::string> unmount_options(
163 kDefaultUnmountOptions,
164 kDefaultUnmountOptions + arraysize(kDefaultUnmountOptions));
165 if (options == UNMOUNT_OPTIONS_LAZY)
166 unmount_options.push_back(kLazyUnmountOption);
167
[email protected]4ae73292011-11-15 05:20:18168 writer.AppendArrayOfStrings(unmount_options);
169 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
170 base::Bind(&CrosDisksClientImpl::OnUnmount,
171 weak_ptr_factory_.GetWeakPtr(),
172 device_path,
173 callback,
174 error_callback));
175 }
176
177 // CrosDisksClient override.
178 virtual void EnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35179 const EnumerateAutoMountableDevicesCallback& callback,
180 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18181 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
182 cros_disks::kEnumerateAutoMountableDevices);
183 proxy_->CallMethod(
184 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
185 base::Bind(&CrosDisksClientImpl::OnEnumerateAutoMountableDevices,
186 weak_ptr_factory_.GetWeakPtr(),
187 callback,
188 error_callback));
189 }
190
191 // CrosDisksClient override.
192 virtual void FormatDevice(const std::string& device_path,
193 const std::string& filesystem,
[email protected]4a404e52012-04-11 02:25:35194 const FormatDeviceCallback& callback,
195 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18196 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
197 cros_disks::kFormatDevice);
198 dbus::MessageWriter writer(&method_call);
199 writer.AppendString(device_path);
200 writer.AppendString(filesystem);
201 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
202 base::Bind(&CrosDisksClientImpl::OnFormatDevice,
203 weak_ptr_factory_.GetWeakPtr(),
204 device_path,
205 callback,
206 error_callback));
207 }
208
209 // CrosDisksClient override.
[email protected]4a404e52012-04-11 02:25:35210 virtual void GetDeviceProperties(
211 const std::string& device_path,
212 const GetDevicePropertiesCallback& callback,
213 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18214 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
215 cros_disks::kGetDeviceProperties);
216 dbus::MessageWriter writer(&method_call);
217 writer.AppendString(device_path);
218 proxy_->CallMethod(&method_call,
219 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
220 base::Bind(&CrosDisksClientImpl::OnGetDeviceProperties,
221 weak_ptr_factory_.GetWeakPtr(),
222 device_path,
223 callback,
224 error_callback));
225 }
226
227 // CrosDisksClient override.
228 virtual void SetUpConnections(
[email protected]4a404e52012-04-11 02:25:35229 const MountEventHandler& mount_event_handler,
230 const MountCompletedHandler& mount_completed_handler) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18231 static const SignalEventTuple kSignalEventTuples[] = {
[email protected]e3c1fc92012-11-15 00:56:46232 { cros_disks::kDeviceAdded, CROS_DISKS_DEVICE_ADDED },
233 { cros_disks::kDeviceScanned, CROS_DISKS_DEVICE_SCANNED },
234 { cros_disks::kDeviceRemoved, CROS_DISKS_DEVICE_REMOVED },
235 { cros_disks::kDiskAdded, CROS_DISKS_DISK_ADDED },
236 { cros_disks::kDiskChanged, CROS_DISKS_DISK_CHANGED },
237 { cros_disks::kDiskRemoved, CROS_DISKS_DISK_REMOVED },
238 { cros_disks::kFormattingFinished, CROS_DISKS_FORMATTING_FINISHED },
[email protected]4ae73292011-11-15 05:20:18239 };
240 const size_t kNumSignalEventTuples = arraysize(kSignalEventTuples);
241
242 for (size_t i = 0; i < kNumSignalEventTuples; ++i) {
243 proxy_->ConnectToSignal(
244 cros_disks::kCrosDisksInterface,
245 kSignalEventTuples[i].signal_name,
246 base::Bind(&CrosDisksClientImpl::OnMountEvent,
247 weak_ptr_factory_.GetWeakPtr(),
248 kSignalEventTuples[i].event_type,
249 mount_event_handler),
250 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
251 weak_ptr_factory_.GetWeakPtr()));
252 }
253 proxy_->ConnectToSignal(
254 cros_disks::kCrosDisksInterface,
[email protected]b3e3f492011-11-18 18:46:00255 cros_disks::kMountCompleted,
[email protected]4ae73292011-11-15 05:20:18256 base::Bind(&CrosDisksClientImpl::OnMountCompleted,
257 weak_ptr_factory_.GetWeakPtr(),
[email protected]85b95a2012012-08-07 18:57:27258 mount_completed_handler),
[email protected]4ae73292011-11-15 05:20:18259 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
260 weak_ptr_factory_.GetWeakPtr()));
261 }
262
263 private:
264 // A struct to contain a pair of signal name and mount event type.
265 // Used by SetUpConnections.
266 struct SignalEventTuple {
267 const char *signal_name;
268 MountEventType event_type;
269 };
270
271 // Handles the result of Mount and calls |callback| or |error_callback|.
[email protected]4a404e52012-04-11 02:25:35272 void OnMount(const MountCallback& callback,
273 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18274 dbus::Response* response) {
275 if (!response) {
276 error_callback.Run();
277 return;
278 }
279 callback.Run();
280 }
281
282 // Handles the result of Unount and calls |callback| or |error_callback|.
283 void OnUnmount(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35284 const UnmountCallback& callback,
[email protected]10795ae2012-10-10 07:33:49285 const UnmountCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18286 dbus::Response* response) {
287 if (!response) {
[email protected]10795ae2012-10-10 07:33:49288 error_callback.Run(device_path);
[email protected]4ae73292011-11-15 05:20:18289 return;
290 }
291 callback.Run(device_path);
292 }
293
294 // Handles the result of EnumerateAutoMountableDevices and calls |callback| or
295 // |error_callback|.
296 void OnEnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35297 const EnumerateAutoMountableDevicesCallback& callback,
298 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18299 dbus::Response* response) {
300 if (!response) {
301 error_callback.Run();
302 return;
303 }
304 dbus::MessageReader reader(response);
305 std::vector<std::string> device_paths;
306 if (!reader.PopArrayOfStrings(&device_paths)) {
307 LOG(ERROR) << "Invalid response: " << response->ToString();
308 error_callback.Run();
309 return;
310 }
311 callback.Run(device_paths);
312 }
313
314 // Handles the result of FormatDevice and calls |callback| or
315 // |error_callback|.
316 void OnFormatDevice(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35317 const FormatDeviceCallback& callback,
318 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18319 dbus::Response* response) {
320 if (!response) {
321 error_callback.Run();
322 return;
323 }
324 dbus::MessageReader reader(response);
325 bool success = false;
326 if (!reader.PopBool(&success)) {
327 LOG(ERROR) << "Invalid response: " << response->ToString();
328 error_callback.Run();
329 return;
330 }
331 callback.Run(device_path, success);
332 }
333
334 // Handles the result of GetDeviceProperties and calls |callback| or
335 // |error_callback|.
336 void OnGetDeviceProperties(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35337 const GetDevicePropertiesCallback& callback,
338 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18339 dbus::Response* response) {
340 if (!response) {
341 error_callback.Run();
342 return;
343 }
344 DiskInfo disk(device_path, response);
345 callback.Run(disk);
346 }
347
348 // Handles mount event signals and calls |handler|.
349 void OnMountEvent(MountEventType event_type,
350 MountEventHandler handler,
351 dbus::Signal* signal) {
352 dbus::MessageReader reader(signal);
353 std::string device;
354 if (!reader.PopString(&device)) {
355 LOG(ERROR) << "Invalid signal: " << signal->ToString();
356 return;
357 }
358 handler.Run(event_type, device);
359 }
360
361 // Handles MountCompleted signal and calls |handler|.
362 void OnMountCompleted(MountCompletedHandler handler, dbus::Signal* signal) {
363 dbus::MessageReader reader(signal);
364 unsigned int error_code = 0;
365 std::string source_path;
366 unsigned int mount_type = 0;
367 std::string mount_path;
368 if (!reader.PopUint32(&error_code) ||
369 !reader.PopString(&source_path) ||
370 !reader.PopUint32(&mount_type) ||
371 !reader.PopString(&mount_path)) {
372 LOG(ERROR) << "Invalid signal: " << signal->ToString();
373 return;
374 }
375 handler.Run(static_cast<MountError>(error_code), source_path,
376 static_cast<MountType>(mount_type), mount_path);
377 }
378
379 // Handles the result of signal connection setup.
380 void OnSignalConnected(const std::string& interface,
381 const std::string& signal,
[email protected]d6311dcb2012-10-22 03:40:43382 bool succeeded) {
383 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
[email protected]4ae73292011-11-15 05:20:18384 signal << " failed.";
385 }
386
387 dbus::ObjectProxy* proxy_;
[email protected]926957b2012-09-07 05:34:16388
389 // Note: This should remain the last member so it'll be destroyed and
390 // invalidate its weak pointers before any other members are destroyed.
[email protected]4ae73292011-11-15 05:20:18391 base::WeakPtrFactory<CrosDisksClientImpl> weak_ptr_factory_;
392
393 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl);
394};
395
396// A stub implementaion of CrosDisksClient.
397class CrosDisksClientStubImpl : public CrosDisksClient {
398 public:
399 CrosDisksClientStubImpl() {}
400 virtual ~CrosDisksClientStubImpl() {}
401
402 virtual void Mount(const std::string& source_path,
[email protected]b9f22d12012-04-25 21:46:48403 const std::string& source_format,
[email protected]dcad8fc2012-04-30 23:31:33404 const std::string& mount_label,
[email protected]4ae73292011-11-15 05:20:18405 MountType type,
[email protected]4a404e52012-04-11 02:25:35406 const MountCallback& callback,
407 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18408 virtual void Unmount(const std::string& device_path,
[email protected]10795ae2012-10-10 07:33:49409 UnmountOptions options,
[email protected]4a404e52012-04-11 02:25:35410 const UnmountCallback& callback,
[email protected]10795ae2012-10-10 07:33:49411 const UnmountCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18412 virtual void EnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35413 const EnumerateAutoMountableDevicesCallback& callback,
414 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18415 virtual void FormatDevice(const std::string& device_path,
416 const std::string& filesystem,
[email protected]4a404e52012-04-11 02:25:35417 const FormatDeviceCallback& callback,
418 const ErrorCallback& error_callback) OVERRIDE {}
419 virtual void GetDeviceProperties(
420 const std::string& device_path,
421 const GetDevicePropertiesCallback& callback,
422 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18423 virtual void SetUpConnections(
[email protected]4a404e52012-04-11 02:25:35424 const MountEventHandler& mount_event_handler,
425 const MountCompletedHandler& mount_completed_handler) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18426
427 private:
428 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientStubImpl);
429};
430
[email protected]85b95a2012012-08-07 18:57:27431} // namespace
[email protected]4ae73292011-11-15 05:20:18432
433////////////////////////////////////////////////////////////////////////////////
434// DiskInfo
435
436DiskInfo::DiskInfo(const std::string& device_path, dbus::Response* response)
437 : device_path_(device_path),
438 is_drive_(false),
439 has_media_(false),
440 on_boot_device_(false),
[email protected]2321d282012-01-31 23:06:59441 device_type_(DEVICE_TYPE_UNKNOWN),
[email protected]4ae73292011-11-15 05:20:18442 total_size_in_bytes_(0),
443 is_read_only_(false),
444 is_hidden_(true) {
445 InitializeFromResponse(response);
446}
447
448DiskInfo::~DiskInfo() {
449}
450
[email protected]85b95a2012012-08-07 18:57:27451// Initializes |this| from |response| given by the cros-disks service.
[email protected]4ae73292011-11-15 05:20:18452// Below is an example of |response|'s raw message (long string is ellipsized).
453//
454//
455// message_type: MESSAGE_METHOD_RETURN
456// destination: :1.8
457// sender: :1.16
458// signature: a{sv}
459// serial: 96
460// reply_serial: 267
461//
462// array [
463// dict entry {
464// string "DeviceFile"
465// variant string "/dev/sdb"
466// }
467// dict entry {
468// string "DeviceIsDrive"
469// variant bool true
470// }
471// dict entry {
472// string "DeviceIsMediaAvailable"
473// variant bool true
474// }
475// dict entry {
476// string "DeviceIsMounted"
477// variant bool false
478// }
479// dict entry {
480// string "DeviceIsOnBootDevice"
481// variant bool false
482// }
483// dict entry {
[email protected]4ae73292011-11-15 05:20:18484// string "DeviceIsReadOnly"
485// variant bool false
486// }
487// dict entry {
488// string "DeviceIsVirtual"
489// variant bool false
490// }
491// dict entry {
492// string "DeviceMediaType"
493// variant uint32 1
494// }
495// dict entry {
496// string "DeviceMountPaths"
497// variant array [
498// ]
499// }
500// dict entry {
501// string "DevicePresentationHide"
502// variant bool true
503// }
504// dict entry {
505// string "DeviceSize"
506// variant uint64 7998537728
507// }
508// dict entry {
509// string "DriveIsRotational"
510// variant bool false
511// }
512// dict entry {
[email protected]202e9fee2012-09-13 20:21:29513// string "VendorId"
514// variant string "18d1"
515// }
516// dict entry {
517// string "VendorName"
518// variant string "Google Inc."
519// }
520// dict entry {
521// string "ProductId"
522// variant string "4e11"
523// }
524// dict entry {
525// string "ProductName"
526// variant string "Nexus One"
527// }
528// dict entry {
[email protected]4ae73292011-11-15 05:20:18529// string "DriveModel"
530// variant string "TransMemory"
531// }
532// dict entry {
533// string "IdLabel"
534// variant string ""
535// }
536// dict entry {
537// string "IdUuid"
538// variant string ""
539// }
540// dict entry {
541// string "NativePath"
542// variant string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
543// }
544// ]
545void DiskInfo::InitializeFromResponse(dbus::Response* response) {
546 dbus::MessageReader response_reader(response);
547 dbus::MessageReader array_reader(response);
548 if (!response_reader.PopArray(&array_reader)) {
549 LOG(ERROR) << "Invalid response: " << response->ToString();
550 return;
551 }
552 // TODO(satorux): Rework this code using Protocol Buffers. crosbug.com/22626
[email protected]b307bceb2011-11-17 07:49:55553 typedef std::map<std::string, dbus::MessageReader*> PropertiesMap;
554 PropertiesMap properties;
555 STLValueDeleter<PropertiesMap> properties_value_deleter(&properties);
[email protected]4ae73292011-11-15 05:20:18556 while (array_reader.HasMoreData()) {
[email protected]4ae73292011-11-15 05:20:18557 dbus::MessageReader* value_reader = new dbus::MessageReader(response);
[email protected]4ae73292011-11-15 05:20:18558 dbus::MessageReader dict_entry_reader(response);
559 std::string key;
560 if (!array_reader.PopDictEntry(&dict_entry_reader) ||
561 !dict_entry_reader.PopString(&key) ||
562 !dict_entry_reader.PopVariant(value_reader)) {
563 LOG(ERROR) << "Invalid response: " << response->ToString();
564 return;
565 }
566 properties[key] = value_reader;
567 }
568 MaybePopBool(properties[cros_disks::kDeviceIsDrive], &is_drive_);
569 MaybePopBool(properties[cros_disks::kDeviceIsReadOnly], &is_read_only_);
570 MaybePopBool(properties[cros_disks::kDevicePresentationHide], &is_hidden_);
571 MaybePopBool(properties[cros_disks::kDeviceIsMediaAvailable], &has_media_);
572 MaybePopBool(properties[cros_disks::kDeviceIsOnBootDevice],
573 &on_boot_device_);
574 MaybePopString(properties[cros_disks::kNativePath], &system_path_);
575 MaybePopString(properties[cros_disks::kDeviceFile], &file_path_);
[email protected]202e9fee2012-09-13 20:21:29576 MaybePopString(properties[cros_disks::kVendorId], &vendor_id_);
577 MaybePopString(properties[cros_disks::kVendorName], &vendor_name_);
578 MaybePopString(properties[cros_disks::kProductId], &product_id_);
579 MaybePopString(properties[cros_disks::kProductName], &product_name_);
[email protected]4ae73292011-11-15 05:20:18580 MaybePopString(properties[cros_disks::kDriveModel], &drive_model_);
581 MaybePopString(properties[cros_disks::kIdLabel], &label_);
[email protected]9c5620d32012-07-31 01:00:38582 MaybePopString(properties[cros_disks::kIdUuid], &uuid_);
[email protected]4ae73292011-11-15 05:20:18583 MaybePopUint64(properties[cros_disks::kDeviceSize], &total_size_in_bytes_);
584
[email protected]2321d282012-01-31 23:06:59585 uint32 media_type_uint32 = 0;
586 if (MaybePopUint32(properties[cros_disks::kDeviceMediaType],
587 &media_type_uint32)) {
588 device_type_ = DeviceMediaTypeToDeviceType(media_type_uint32);
589 }
590
[email protected]4ae73292011-11-15 05:20:18591 std::vector<std::string> mount_paths;
592 if (MaybePopArrayOfStrings(properties[cros_disks::kDeviceMountPaths],
593 &mount_paths) && !mount_paths.empty())
594 mount_path_ = mount_paths[0];
[email protected]4ae73292011-11-15 05:20:18595}
596
597////////////////////////////////////////////////////////////////////////////////
598// CrosDisksClient
599
600CrosDisksClient::CrosDisksClient() {}
601
602CrosDisksClient::~CrosDisksClient() {}
603
604// static
[email protected]e8db03d62012-03-31 04:08:38605CrosDisksClient* CrosDisksClient::Create(DBusClientImplementationType type,
606 dbus::Bus* bus) {
607 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
[email protected]4ae73292011-11-15 05:20:18608 return new CrosDisksClientImpl(bus);
[email protected]e8db03d62012-03-31 04:08:38609 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
610 return new CrosDisksClientStubImpl();
[email protected]4ae73292011-11-15 05:20:18611}
612
613} // namespace chromeos