blob: 9f367c247d99290660cdf9d08578a2cfa02d3f46 [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
7#include "base/bind.h"
[email protected]b307bceb2011-11-17 07:49:558#include "base/stl_util.h"
[email protected]dcad8fc2012-04-30 23:31:339#include "base/stringprintf.h"
[email protected]4ae73292011-11-15 05:20:1810#include "dbus/bus.h"
11#include "dbus/message.h"
[email protected]216ed0b2012-02-14 21:29:0612#include "dbus/object_path.h"
[email protected]4ae73292011-11-15 05:20:1813#include "dbus/object_proxy.h"
14#include "third_party/cros_system_api/dbus/service_constants.h"
15
16namespace chromeos {
17
18namespace {
19
20const char* kDefaultMountOptions[] = {
21 "rw",
22 "nodev",
23 "noexec",
24 "nosuid",
[email protected]4ae73292011-11-15 05:20:1825};
26
27const char* kDefaultUnmountOptions[] = {
28 "force",
29};
30
[email protected]dcad8fc2012-04-30 23:31:3331const char kMountLabelOption[] = "mountlabel";
32
[email protected]2321d282012-01-31 23:06:5933// Checks if retrieved media type is in boundaries of DeviceMediaType.
34bool IsValidMediaType(uint32 type) {
35 return type < static_cast<uint32>(cros_disks::DEVICE_MEDIA_NUM_VALUES);
36}
37
38
39// Translates enum used in cros-disks to enum used in Chrome.
40// Note that we could just do static_cast, but this is less sensitive to
41// changes in cros-disks.
42DeviceType DeviceMediaTypeToDeviceType(uint32 media_type_uint32) {
43 if (!IsValidMediaType(media_type_uint32))
44 return DEVICE_TYPE_UNKNOWN;
45
46 cros_disks::DeviceMediaType media_type =
47 cros_disks::DeviceMediaType(media_type_uint32);
48
49 switch (media_type) {
50 case(cros_disks::DEVICE_MEDIA_UNKNOWN):
51 return DEVICE_TYPE_UNKNOWN;
52 case(cros_disks::DEVICE_MEDIA_USB):
53 return DEVICE_TYPE_USB;
54 case(cros_disks::DEVICE_MEDIA_SD):
55 return DEVICE_TYPE_SD;
56 case(cros_disks::DEVICE_MEDIA_OPTICAL_DISC):
57 return DEVICE_TYPE_OPTICAL_DISC;
58 case(cros_disks::DEVICE_MEDIA_MOBILE):
59 return DEVICE_TYPE_MOBILE;
[email protected]f4ae40ac2012-05-04 21:57:0060 case(cros_disks::DEVICE_MEDIA_DVD):
61 return DEVICE_TYPE_DVD;
[email protected]2321d282012-01-31 23:06:5962 default:
63 return DEVICE_TYPE_UNKNOWN;
64 }
[email protected]4ae73292011-11-15 05:20:1865}
66
67// Pops a bool value when |reader| is not NULL.
68// Returns true when a value is popped, false otherwise.
69bool MaybePopBool(dbus::MessageReader* reader, bool* value) {
70 if (!reader)
71 return false;
72 return reader->PopBool(value);
73}
74
75// Pops a string value when |reader| is not NULL.
76// Returns true when a value is popped, false otherwise.
77bool MaybePopString(dbus::MessageReader* reader, std::string* value) {
78 if (!reader)
79 return false;
80 return reader->PopString(value);
81}
82
[email protected]2321d282012-01-31 23:06:5983// Pops a uint32 value when |reader| is not NULL.
84// Returns true when a value is popped, false otherwise.
85bool MaybePopUint32(dbus::MessageReader* reader, uint32* value) {
86 if (!reader)
87 return false;
88
89 return reader->PopUint32(value);
90}
91
[email protected]4ae73292011-11-15 05:20:1892// Pops a uint64 value when |reader| is not NULL.
93// Returns true when a value is popped, false otherwise.
94bool MaybePopUint64(dbus::MessageReader* reader, uint64* value) {
95 if (!reader)
96 return false;
97 return reader->PopUint64(value);
98}
99
100// Pops an array of strings when |reader| is not NULL.
101// Returns true when an array is popped, false otherwise.
102bool MaybePopArrayOfStrings(dbus::MessageReader* reader,
103 std::vector<std::string>* value) {
104 if (!reader)
105 return false;
106 return reader->PopArrayOfStrings(value);
107}
108
109// The CrosDisksClient implementation.
110class CrosDisksClientImpl : public CrosDisksClient {
111 public:
112 explicit CrosDisksClientImpl(dbus::Bus* bus)
[email protected]216ed0b2012-02-14 21:29:06113 : proxy_(bus->GetObjectProxy(
114 cros_disks::kCrosDisksServiceName,
115 dbus::ObjectPath(cros_disks::kCrosDisksServicePath))),
[email protected]4ae73292011-11-15 05:20:18116 weak_ptr_factory_(this) {
117 }
118
119 // CrosDisksClient override.
120 virtual void Mount(const std::string& source_path,
[email protected]b9f22d12012-04-25 21:46:48121 const std::string& source_format,
[email protected]dcad8fc2012-04-30 23:31:33122 const std::string& mount_label,
[email protected]4ae73292011-11-15 05:20:18123 MountType type,
[email protected]4a404e52012-04-11 02:25:35124 const MountCallback& callback,
125 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18126 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
127 cros_disks::kMount);
128 dbus::MessageWriter writer(&method_call);
129 writer.AppendString(source_path);
[email protected]b9f22d12012-04-25 21:46:48130 writer.AppendString(source_format);
[email protected]4ae73292011-11-15 05:20:18131 std::vector<std::string> mount_options(kDefaultMountOptions,
132 kDefaultMountOptions +
133 arraysize(kDefaultMountOptions));
[email protected]dcad8fc2012-04-30 23:31:33134 if (!mount_label.empty()) {
135 std::string mount_label_option = base::StringPrintf("%s=%s",
136 kMountLabelOption,
137 mount_label.c_str());
138 mount_options.push_back(mount_label_option);
139 }
[email protected]4ae73292011-11-15 05:20:18140 writer.AppendArrayOfStrings(mount_options);
141 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
142 base::Bind(&CrosDisksClientImpl::OnMount,
143 weak_ptr_factory_.GetWeakPtr(),
144 callback,
145 error_callback));
146 }
147
148 // CrosDisksClient override.
149 virtual void Unmount(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35150 const UnmountCallback& callback,
151 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18152 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
153 cros_disks::kUnmount);
154 dbus::MessageWriter writer(&method_call);
155 writer.AppendString(device_path);
156 std::vector<std::string> unmount_options(kDefaultUnmountOptions,
157 kDefaultUnmountOptions +
158 arraysize(kDefaultUnmountOptions));
159 writer.AppendArrayOfStrings(unmount_options);
160 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
161 base::Bind(&CrosDisksClientImpl::OnUnmount,
162 weak_ptr_factory_.GetWeakPtr(),
163 device_path,
164 callback,
165 error_callback));
166 }
167
168 // CrosDisksClient override.
169 virtual void EnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35170 const EnumerateAutoMountableDevicesCallback& callback,
171 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18172 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
173 cros_disks::kEnumerateAutoMountableDevices);
174 proxy_->CallMethod(
175 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
176 base::Bind(&CrosDisksClientImpl::OnEnumerateAutoMountableDevices,
177 weak_ptr_factory_.GetWeakPtr(),
178 callback,
179 error_callback));
180 }
181
182 // CrosDisksClient override.
183 virtual void FormatDevice(const std::string& device_path,
184 const std::string& filesystem,
[email protected]4a404e52012-04-11 02:25:35185 const FormatDeviceCallback& callback,
186 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18187 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
188 cros_disks::kFormatDevice);
189 dbus::MessageWriter writer(&method_call);
190 writer.AppendString(device_path);
191 writer.AppendString(filesystem);
192 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
193 base::Bind(&CrosDisksClientImpl::OnFormatDevice,
194 weak_ptr_factory_.GetWeakPtr(),
195 device_path,
196 callback,
197 error_callback));
198 }
199
200 // CrosDisksClient override.
[email protected]4a404e52012-04-11 02:25:35201 virtual void GetDeviceProperties(
202 const std::string& device_path,
203 const GetDevicePropertiesCallback& callback,
204 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18205 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
206 cros_disks::kGetDeviceProperties);
207 dbus::MessageWriter writer(&method_call);
208 writer.AppendString(device_path);
209 proxy_->CallMethod(&method_call,
210 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
211 base::Bind(&CrosDisksClientImpl::OnGetDeviceProperties,
212 weak_ptr_factory_.GetWeakPtr(),
213 device_path,
214 callback,
215 error_callback));
216 }
217
218 // CrosDisksClient override.
219 virtual void SetUpConnections(
[email protected]4a404e52012-04-11 02:25:35220 const MountEventHandler& mount_event_handler,
221 const MountCompletedHandler& mount_completed_handler) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18222 static const SignalEventTuple kSignalEventTuples[] = {
[email protected]b3e3f492011-11-18 18:46:00223 { cros_disks::kDeviceAdded, DEVICE_ADDED },
224 { cros_disks::kDeviceScanned, DEVICE_SCANNED },
225 { cros_disks::kDeviceRemoved, DEVICE_REMOVED },
226 { cros_disks::kDiskAdded, DISK_ADDED },
227 { cros_disks::kDiskChanged, DISK_CHANGED },
228 { cros_disks::kDiskRemoved, DISK_REMOVED },
229 { cros_disks::kFormattingFinished, FORMATTING_FINISHED },
[email protected]4ae73292011-11-15 05:20:18230 };
231 const size_t kNumSignalEventTuples = arraysize(kSignalEventTuples);
232
233 for (size_t i = 0; i < kNumSignalEventTuples; ++i) {
234 proxy_->ConnectToSignal(
235 cros_disks::kCrosDisksInterface,
236 kSignalEventTuples[i].signal_name,
237 base::Bind(&CrosDisksClientImpl::OnMountEvent,
238 weak_ptr_factory_.GetWeakPtr(),
239 kSignalEventTuples[i].event_type,
240 mount_event_handler),
241 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
242 weak_ptr_factory_.GetWeakPtr()));
243 }
244 proxy_->ConnectToSignal(
245 cros_disks::kCrosDisksInterface,
[email protected]b3e3f492011-11-18 18:46:00246 cros_disks::kMountCompleted,
[email protected]4ae73292011-11-15 05:20:18247 base::Bind(&CrosDisksClientImpl::OnMountCompleted,
248 weak_ptr_factory_.GetWeakPtr(),
249 mount_completed_handler ),
250 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
251 weak_ptr_factory_.GetWeakPtr()));
252 }
253
254 private:
255 // A struct to contain a pair of signal name and mount event type.
256 // Used by SetUpConnections.
257 struct SignalEventTuple {
258 const char *signal_name;
259 MountEventType event_type;
260 };
261
262 // Handles the result of Mount and calls |callback| or |error_callback|.
[email protected]4a404e52012-04-11 02:25:35263 void OnMount(const MountCallback& callback,
264 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18265 dbus::Response* response) {
266 if (!response) {
267 error_callback.Run();
268 return;
269 }
270 callback.Run();
271 }
272
273 // Handles the result of Unount and calls |callback| or |error_callback|.
274 void OnUnmount(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35275 const UnmountCallback& callback,
276 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18277 dbus::Response* response) {
278 if (!response) {
279 error_callback.Run();
280 return;
281 }
282 callback.Run(device_path);
283 }
284
285 // Handles the result of EnumerateAutoMountableDevices and calls |callback| or
286 // |error_callback|.
287 void OnEnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35288 const EnumerateAutoMountableDevicesCallback& callback,
289 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18290 dbus::Response* response) {
291 if (!response) {
292 error_callback.Run();
293 return;
294 }
295 dbus::MessageReader reader(response);
296 std::vector<std::string> device_paths;
297 if (!reader.PopArrayOfStrings(&device_paths)) {
298 LOG(ERROR) << "Invalid response: " << response->ToString();
299 error_callback.Run();
300 return;
301 }
302 callback.Run(device_paths);
303 }
304
305 // Handles the result of FormatDevice and calls |callback| or
306 // |error_callback|.
307 void OnFormatDevice(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35308 const FormatDeviceCallback& callback,
309 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18310 dbus::Response* response) {
311 if (!response) {
312 error_callback.Run();
313 return;
314 }
315 dbus::MessageReader reader(response);
316 bool success = false;
317 if (!reader.PopBool(&success)) {
318 LOG(ERROR) << "Invalid response: " << response->ToString();
319 error_callback.Run();
320 return;
321 }
322 callback.Run(device_path, success);
323 }
324
325 // Handles the result of GetDeviceProperties and calls |callback| or
326 // |error_callback|.
327 void OnGetDeviceProperties(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35328 const GetDevicePropertiesCallback& callback,
329 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18330 dbus::Response* response) {
331 if (!response) {
332 error_callback.Run();
333 return;
334 }
335 DiskInfo disk(device_path, response);
336 callback.Run(disk);
337 }
338
339 // Handles mount event signals and calls |handler|.
340 void OnMountEvent(MountEventType event_type,
341 MountEventHandler handler,
342 dbus::Signal* signal) {
343 dbus::MessageReader reader(signal);
344 std::string device;
345 if (!reader.PopString(&device)) {
346 LOG(ERROR) << "Invalid signal: " << signal->ToString();
347 return;
348 }
349 handler.Run(event_type, device);
350 }
351
352 // Handles MountCompleted signal and calls |handler|.
353 void OnMountCompleted(MountCompletedHandler handler, dbus::Signal* signal) {
354 dbus::MessageReader reader(signal);
355 unsigned int error_code = 0;
356 std::string source_path;
357 unsigned int mount_type = 0;
358 std::string mount_path;
359 if (!reader.PopUint32(&error_code) ||
360 !reader.PopString(&source_path) ||
361 !reader.PopUint32(&mount_type) ||
362 !reader.PopString(&mount_path)) {
363 LOG(ERROR) << "Invalid signal: " << signal->ToString();
364 return;
365 }
366 handler.Run(static_cast<MountError>(error_code), source_path,
367 static_cast<MountType>(mount_type), mount_path);
368 }
369
370 // Handles the result of signal connection setup.
371 void OnSignalConnected(const std::string& interface,
372 const std::string& signal,
373 bool successed) {
374 LOG_IF(ERROR, !successed) << "Connect to " << interface << " " <<
375 signal << " failed.";
376 }
377
378 dbus::ObjectProxy* proxy_;
379 base::WeakPtrFactory<CrosDisksClientImpl> weak_ptr_factory_;
380
381 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl);
382};
383
384// A stub implementaion of CrosDisksClient.
385class CrosDisksClientStubImpl : public CrosDisksClient {
386 public:
387 CrosDisksClientStubImpl() {}
388 virtual ~CrosDisksClientStubImpl() {}
389
390 virtual void Mount(const std::string& source_path,
[email protected]b9f22d12012-04-25 21:46:48391 const std::string& source_format,
[email protected]dcad8fc2012-04-30 23:31:33392 const std::string& mount_label,
[email protected]4ae73292011-11-15 05:20:18393 MountType type,
[email protected]4a404e52012-04-11 02:25:35394 const MountCallback& callback,
395 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18396 virtual void Unmount(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35397 const UnmountCallback& callback,
398 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18399 virtual void EnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35400 const EnumerateAutoMountableDevicesCallback& callback,
401 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18402 virtual void FormatDevice(const std::string& device_path,
403 const std::string& filesystem,
[email protected]4a404e52012-04-11 02:25:35404 const FormatDeviceCallback& callback,
405 const ErrorCallback& error_callback) OVERRIDE {}
406 virtual void GetDeviceProperties(
407 const std::string& device_path,
408 const GetDevicePropertiesCallback& callback,
409 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18410 virtual void SetUpConnections(
[email protected]4a404e52012-04-11 02:25:35411 const MountEventHandler& mount_event_handler,
412 const MountCompletedHandler& mount_completed_handler) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18413
414 private:
415 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientStubImpl);
416};
417
418} // namespace
419
420////////////////////////////////////////////////////////////////////////////////
421// DiskInfo
422
423DiskInfo::DiskInfo(const std::string& device_path, dbus::Response* response)
424 : device_path_(device_path),
425 is_drive_(false),
426 has_media_(false),
427 on_boot_device_(false),
[email protected]2321d282012-01-31 23:06:59428 device_type_(DEVICE_TYPE_UNKNOWN),
[email protected]4ae73292011-11-15 05:20:18429 total_size_in_bytes_(0),
430 is_read_only_(false),
431 is_hidden_(true) {
432 InitializeFromResponse(response);
433}
434
435DiskInfo::~DiskInfo() {
436}
437
438// Initialize |this| from |response| given by the cros-disks service.
439// Below is an example of |response|'s raw message (long string is ellipsized).
440//
441//
442// message_type: MESSAGE_METHOD_RETURN
443// destination: :1.8
444// sender: :1.16
445// signature: a{sv}
446// serial: 96
447// reply_serial: 267
448//
449// array [
450// dict entry {
451// string "DeviceFile"
452// variant string "/dev/sdb"
453// }
454// dict entry {
455// string "DeviceIsDrive"
456// variant bool true
457// }
458// dict entry {
459// string "DeviceIsMediaAvailable"
460// variant bool true
461// }
462// dict entry {
463// string "DeviceIsMounted"
464// variant bool false
465// }
466// dict entry {
467// string "DeviceIsOnBootDevice"
468// variant bool false
469// }
470// dict entry {
[email protected]4ae73292011-11-15 05:20:18471// string "DeviceIsReadOnly"
472// variant bool false
473// }
474// dict entry {
475// string "DeviceIsVirtual"
476// variant bool false
477// }
478// dict entry {
479// string "DeviceMediaType"
480// variant uint32 1
481// }
482// dict entry {
483// string "DeviceMountPaths"
484// variant array [
485// ]
486// }
487// dict entry {
488// string "DevicePresentationHide"
489// variant bool true
490// }
491// dict entry {
492// string "DeviceSize"
493// variant uint64 7998537728
494// }
495// dict entry {
496// string "DriveIsRotational"
497// variant bool false
498// }
499// dict entry {
500// string "DriveModel"
501// variant string "TransMemory"
502// }
503// dict entry {
504// string "IdLabel"
505// variant string ""
506// }
507// dict entry {
508// string "IdUuid"
509// variant string ""
510// }
511// dict entry {
512// string "NativePath"
513// variant string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
514// }
515// ]
516void DiskInfo::InitializeFromResponse(dbus::Response* response) {
517 dbus::MessageReader response_reader(response);
518 dbus::MessageReader array_reader(response);
519 if (!response_reader.PopArray(&array_reader)) {
520 LOG(ERROR) << "Invalid response: " << response->ToString();
521 return;
522 }
523 // TODO(satorux): Rework this code using Protocol Buffers. crosbug.com/22626
[email protected]b307bceb2011-11-17 07:49:55524 typedef std::map<std::string, dbus::MessageReader*> PropertiesMap;
525 PropertiesMap properties;
526 STLValueDeleter<PropertiesMap> properties_value_deleter(&properties);
[email protected]4ae73292011-11-15 05:20:18527 while (array_reader.HasMoreData()) {
[email protected]4ae73292011-11-15 05:20:18528 dbus::MessageReader* value_reader = new dbus::MessageReader(response);
[email protected]4ae73292011-11-15 05:20:18529 dbus::MessageReader dict_entry_reader(response);
530 std::string key;
531 if (!array_reader.PopDictEntry(&dict_entry_reader) ||
532 !dict_entry_reader.PopString(&key) ||
533 !dict_entry_reader.PopVariant(value_reader)) {
534 LOG(ERROR) << "Invalid response: " << response->ToString();
535 return;
536 }
537 properties[key] = value_reader;
538 }
539 MaybePopBool(properties[cros_disks::kDeviceIsDrive], &is_drive_);
540 MaybePopBool(properties[cros_disks::kDeviceIsReadOnly], &is_read_only_);
541 MaybePopBool(properties[cros_disks::kDevicePresentationHide], &is_hidden_);
542 MaybePopBool(properties[cros_disks::kDeviceIsMediaAvailable], &has_media_);
543 MaybePopBool(properties[cros_disks::kDeviceIsOnBootDevice],
544 &on_boot_device_);
545 MaybePopString(properties[cros_disks::kNativePath], &system_path_);
546 MaybePopString(properties[cros_disks::kDeviceFile], &file_path_);
547 MaybePopString(properties[cros_disks::kDriveModel], &drive_model_);
548 MaybePopString(properties[cros_disks::kIdLabel], &label_);
[email protected]9c5620d32012-07-31 01:00:38549 MaybePopString(properties[cros_disks::kIdUuid], &uuid_);
[email protected]4ae73292011-11-15 05:20:18550 MaybePopUint64(properties[cros_disks::kDeviceSize], &total_size_in_bytes_);
551
[email protected]2321d282012-01-31 23:06:59552 uint32 media_type_uint32 = 0;
553 if (MaybePopUint32(properties[cros_disks::kDeviceMediaType],
554 &media_type_uint32)) {
555 device_type_ = DeviceMediaTypeToDeviceType(media_type_uint32);
556 }
557
[email protected]4ae73292011-11-15 05:20:18558 std::vector<std::string> mount_paths;
559 if (MaybePopArrayOfStrings(properties[cros_disks::kDeviceMountPaths],
560 &mount_paths) && !mount_paths.empty())
561 mount_path_ = mount_paths[0];
[email protected]4ae73292011-11-15 05:20:18562}
563
564////////////////////////////////////////////////////////////////////////////////
565// CrosDisksClient
566
567CrosDisksClient::CrosDisksClient() {}
568
569CrosDisksClient::~CrosDisksClient() {}
570
571// static
[email protected]e8db03d62012-03-31 04:08:38572CrosDisksClient* CrosDisksClient::Create(DBusClientImplementationType type,
573 dbus::Bus* bus) {
574 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
[email protected]4ae73292011-11-15 05:20:18575 return new CrosDisksClientImpl(bus);
[email protected]e8db03d62012-03-31 04:08:38576 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
577 return new CrosDisksClientStubImpl();
[email protected]4ae73292011-11-15 05:20:18578}
579
580} // namespace chromeos