blob: 693372ddb18e34f4ef43e3a1061903d25b5dcbd3 [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;
60 default:
61 return DEVICE_TYPE_UNKNOWN;
62 }
[email protected]4ae73292011-11-15 05:20:1863}
64
65// Pops a bool value when |reader| is not NULL.
66// Returns true when a value is popped, false otherwise.
67bool MaybePopBool(dbus::MessageReader* reader, bool* value) {
68 if (!reader)
69 return false;
70 return reader->PopBool(value);
71}
72
73// Pops a string value when |reader| is not NULL.
74// Returns true when a value is popped, false otherwise.
75bool MaybePopString(dbus::MessageReader* reader, std::string* value) {
76 if (!reader)
77 return false;
78 return reader->PopString(value);
79}
80
[email protected]2321d282012-01-31 23:06:5981// Pops a uint32 value when |reader| is not NULL.
82// Returns true when a value is popped, false otherwise.
83bool MaybePopUint32(dbus::MessageReader* reader, uint32* value) {
84 if (!reader)
85 return false;
86
87 return reader->PopUint32(value);
88}
89
[email protected]4ae73292011-11-15 05:20:1890// Pops a uint64 value when |reader| is not NULL.
91// Returns true when a value is popped, false otherwise.
92bool MaybePopUint64(dbus::MessageReader* reader, uint64* value) {
93 if (!reader)
94 return false;
95 return reader->PopUint64(value);
96}
97
98// Pops an array of strings when |reader| is not NULL.
99// Returns true when an array is popped, false otherwise.
100bool MaybePopArrayOfStrings(dbus::MessageReader* reader,
101 std::vector<std::string>* value) {
102 if (!reader)
103 return false;
104 return reader->PopArrayOfStrings(value);
105}
106
107// The CrosDisksClient implementation.
108class CrosDisksClientImpl : public CrosDisksClient {
109 public:
110 explicit CrosDisksClientImpl(dbus::Bus* bus)
[email protected]216ed0b2012-02-14 21:29:06111 : proxy_(bus->GetObjectProxy(
112 cros_disks::kCrosDisksServiceName,
113 dbus::ObjectPath(cros_disks::kCrosDisksServicePath))),
[email protected]4ae73292011-11-15 05:20:18114 weak_ptr_factory_(this) {
115 }
116
117 // CrosDisksClient override.
118 virtual void Mount(const std::string& source_path,
[email protected]b9f22d12012-04-25 21:46:48119 const std::string& source_format,
[email protected]dcad8fc2012-04-30 23:31:33120 const std::string& mount_label,
[email protected]4ae73292011-11-15 05:20:18121 MountType type,
[email protected]4a404e52012-04-11 02:25:35122 const MountCallback& callback,
123 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18124 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
125 cros_disks::kMount);
126 dbus::MessageWriter writer(&method_call);
127 writer.AppendString(source_path);
[email protected]b9f22d12012-04-25 21:46:48128 writer.AppendString(source_format);
[email protected]4ae73292011-11-15 05:20:18129 std::vector<std::string> mount_options(kDefaultMountOptions,
130 kDefaultMountOptions +
131 arraysize(kDefaultMountOptions));
[email protected]dcad8fc2012-04-30 23:31:33132 if (!mount_label.empty()) {
133 std::string mount_label_option = base::StringPrintf("%s=%s",
134 kMountLabelOption,
135 mount_label.c_str());
136 mount_options.push_back(mount_label_option);
137 }
[email protected]4ae73292011-11-15 05:20:18138 writer.AppendArrayOfStrings(mount_options);
139 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
140 base::Bind(&CrosDisksClientImpl::OnMount,
141 weak_ptr_factory_.GetWeakPtr(),
142 callback,
143 error_callback));
144 }
145
146 // CrosDisksClient override.
147 virtual void Unmount(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35148 const UnmountCallback& callback,
149 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18150 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
151 cros_disks::kUnmount);
152 dbus::MessageWriter writer(&method_call);
153 writer.AppendString(device_path);
154 std::vector<std::string> unmount_options(kDefaultUnmountOptions,
155 kDefaultUnmountOptions +
156 arraysize(kDefaultUnmountOptions));
157 writer.AppendArrayOfStrings(unmount_options);
158 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
159 base::Bind(&CrosDisksClientImpl::OnUnmount,
160 weak_ptr_factory_.GetWeakPtr(),
161 device_path,
162 callback,
163 error_callback));
164 }
165
166 // CrosDisksClient override.
167 virtual void EnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35168 const EnumerateAutoMountableDevicesCallback& callback,
169 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18170 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
171 cros_disks::kEnumerateAutoMountableDevices);
172 proxy_->CallMethod(
173 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
174 base::Bind(&CrosDisksClientImpl::OnEnumerateAutoMountableDevices,
175 weak_ptr_factory_.GetWeakPtr(),
176 callback,
177 error_callback));
178 }
179
180 // CrosDisksClient override.
181 virtual void FormatDevice(const std::string& device_path,
182 const std::string& filesystem,
[email protected]4a404e52012-04-11 02:25:35183 const FormatDeviceCallback& callback,
184 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18185 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
186 cros_disks::kFormatDevice);
187 dbus::MessageWriter writer(&method_call);
188 writer.AppendString(device_path);
189 writer.AppendString(filesystem);
190 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
191 base::Bind(&CrosDisksClientImpl::OnFormatDevice,
192 weak_ptr_factory_.GetWeakPtr(),
193 device_path,
194 callback,
195 error_callback));
196 }
197
198 // CrosDisksClient override.
[email protected]4a404e52012-04-11 02:25:35199 virtual void GetDeviceProperties(
200 const std::string& device_path,
201 const GetDevicePropertiesCallback& callback,
202 const ErrorCallback& error_callback) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18203 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
204 cros_disks::kGetDeviceProperties);
205 dbus::MessageWriter writer(&method_call);
206 writer.AppendString(device_path);
207 proxy_->CallMethod(&method_call,
208 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
209 base::Bind(&CrosDisksClientImpl::OnGetDeviceProperties,
210 weak_ptr_factory_.GetWeakPtr(),
211 device_path,
212 callback,
213 error_callback));
214 }
215
216 // CrosDisksClient override.
217 virtual void SetUpConnections(
[email protected]4a404e52012-04-11 02:25:35218 const MountEventHandler& mount_event_handler,
219 const MountCompletedHandler& mount_completed_handler) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18220 static const SignalEventTuple kSignalEventTuples[] = {
[email protected]b3e3f492011-11-18 18:46:00221 { cros_disks::kDeviceAdded, DEVICE_ADDED },
222 { cros_disks::kDeviceScanned, DEVICE_SCANNED },
223 { cros_disks::kDeviceRemoved, DEVICE_REMOVED },
224 { cros_disks::kDiskAdded, DISK_ADDED },
225 { cros_disks::kDiskChanged, DISK_CHANGED },
226 { cros_disks::kDiskRemoved, DISK_REMOVED },
227 { cros_disks::kFormattingFinished, FORMATTING_FINISHED },
[email protected]4ae73292011-11-15 05:20:18228 };
229 const size_t kNumSignalEventTuples = arraysize(kSignalEventTuples);
230
231 for (size_t i = 0; i < kNumSignalEventTuples; ++i) {
232 proxy_->ConnectToSignal(
233 cros_disks::kCrosDisksInterface,
234 kSignalEventTuples[i].signal_name,
235 base::Bind(&CrosDisksClientImpl::OnMountEvent,
236 weak_ptr_factory_.GetWeakPtr(),
237 kSignalEventTuples[i].event_type,
238 mount_event_handler),
239 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
240 weak_ptr_factory_.GetWeakPtr()));
241 }
242 proxy_->ConnectToSignal(
243 cros_disks::kCrosDisksInterface,
[email protected]b3e3f492011-11-18 18:46:00244 cros_disks::kMountCompleted,
[email protected]4ae73292011-11-15 05:20:18245 base::Bind(&CrosDisksClientImpl::OnMountCompleted,
246 weak_ptr_factory_.GetWeakPtr(),
247 mount_completed_handler ),
248 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
249 weak_ptr_factory_.GetWeakPtr()));
250 }
251
252 private:
253 // A struct to contain a pair of signal name and mount event type.
254 // Used by SetUpConnections.
255 struct SignalEventTuple {
256 const char *signal_name;
257 MountEventType event_type;
258 };
259
260 // Handles the result of Mount and calls |callback| or |error_callback|.
[email protected]4a404e52012-04-11 02:25:35261 void OnMount(const MountCallback& callback,
262 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18263 dbus::Response* response) {
264 if (!response) {
265 error_callback.Run();
266 return;
267 }
268 callback.Run();
269 }
270
271 // Handles the result of Unount and calls |callback| or |error_callback|.
272 void OnUnmount(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35273 const UnmountCallback& callback,
274 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18275 dbus::Response* response) {
276 if (!response) {
277 error_callback.Run();
278 return;
279 }
280 callback.Run(device_path);
281 }
282
283 // Handles the result of EnumerateAutoMountableDevices and calls |callback| or
284 // |error_callback|.
285 void OnEnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35286 const EnumerateAutoMountableDevicesCallback& callback,
287 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18288 dbus::Response* response) {
289 if (!response) {
290 error_callback.Run();
291 return;
292 }
293 dbus::MessageReader reader(response);
294 std::vector<std::string> device_paths;
295 if (!reader.PopArrayOfStrings(&device_paths)) {
296 LOG(ERROR) << "Invalid response: " << response->ToString();
297 error_callback.Run();
298 return;
299 }
300 callback.Run(device_paths);
301 }
302
303 // Handles the result of FormatDevice and calls |callback| or
304 // |error_callback|.
305 void OnFormatDevice(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35306 const FormatDeviceCallback& callback,
307 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18308 dbus::Response* response) {
309 if (!response) {
310 error_callback.Run();
311 return;
312 }
313 dbus::MessageReader reader(response);
314 bool success = false;
315 if (!reader.PopBool(&success)) {
316 LOG(ERROR) << "Invalid response: " << response->ToString();
317 error_callback.Run();
318 return;
319 }
320 callback.Run(device_path, success);
321 }
322
323 // Handles the result of GetDeviceProperties and calls |callback| or
324 // |error_callback|.
325 void OnGetDeviceProperties(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35326 const GetDevicePropertiesCallback& callback,
327 const ErrorCallback& error_callback,
[email protected]4ae73292011-11-15 05:20:18328 dbus::Response* response) {
329 if (!response) {
330 error_callback.Run();
331 return;
332 }
333 DiskInfo disk(device_path, response);
334 callback.Run(disk);
335 }
336
337 // Handles mount event signals and calls |handler|.
338 void OnMountEvent(MountEventType event_type,
339 MountEventHandler handler,
340 dbus::Signal* signal) {
341 dbus::MessageReader reader(signal);
342 std::string device;
343 if (!reader.PopString(&device)) {
344 LOG(ERROR) << "Invalid signal: " << signal->ToString();
345 return;
346 }
347 handler.Run(event_type, device);
348 }
349
350 // Handles MountCompleted signal and calls |handler|.
351 void OnMountCompleted(MountCompletedHandler handler, dbus::Signal* signal) {
352 dbus::MessageReader reader(signal);
353 unsigned int error_code = 0;
354 std::string source_path;
355 unsigned int mount_type = 0;
356 std::string mount_path;
357 if (!reader.PopUint32(&error_code) ||
358 !reader.PopString(&source_path) ||
359 !reader.PopUint32(&mount_type) ||
360 !reader.PopString(&mount_path)) {
361 LOG(ERROR) << "Invalid signal: " << signal->ToString();
362 return;
363 }
364 handler.Run(static_cast<MountError>(error_code), source_path,
365 static_cast<MountType>(mount_type), mount_path);
366 }
367
368 // Handles the result of signal connection setup.
369 void OnSignalConnected(const std::string& interface,
370 const std::string& signal,
371 bool successed) {
372 LOG_IF(ERROR, !successed) << "Connect to " << interface << " " <<
373 signal << " failed.";
374 }
375
376 dbus::ObjectProxy* proxy_;
377 base::WeakPtrFactory<CrosDisksClientImpl> weak_ptr_factory_;
378
379 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl);
380};
381
382// A stub implementaion of CrosDisksClient.
383class CrosDisksClientStubImpl : public CrosDisksClient {
384 public:
385 CrosDisksClientStubImpl() {}
386 virtual ~CrosDisksClientStubImpl() {}
387
388 virtual void Mount(const std::string& source_path,
[email protected]b9f22d12012-04-25 21:46:48389 const std::string& source_format,
[email protected]dcad8fc2012-04-30 23:31:33390 const std::string& mount_label,
[email protected]4ae73292011-11-15 05:20:18391 MountType type,
[email protected]4a404e52012-04-11 02:25:35392 const MountCallback& callback,
393 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18394 virtual void Unmount(const std::string& device_path,
[email protected]4a404e52012-04-11 02:25:35395 const UnmountCallback& callback,
396 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18397 virtual void EnumerateAutoMountableDevices(
[email protected]4a404e52012-04-11 02:25:35398 const EnumerateAutoMountableDevicesCallback& callback,
399 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18400 virtual void FormatDevice(const std::string& device_path,
401 const std::string& filesystem,
[email protected]4a404e52012-04-11 02:25:35402 const FormatDeviceCallback& callback,
403 const ErrorCallback& error_callback) OVERRIDE {}
404 virtual void GetDeviceProperties(
405 const std::string& device_path,
406 const GetDevicePropertiesCallback& callback,
407 const ErrorCallback& error_callback) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18408 virtual void SetUpConnections(
[email protected]4a404e52012-04-11 02:25:35409 const MountEventHandler& mount_event_handler,
410 const MountCompletedHandler& mount_completed_handler) OVERRIDE {}
[email protected]4ae73292011-11-15 05:20:18411
412 private:
413 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientStubImpl);
414};
415
416} // namespace
417
418////////////////////////////////////////////////////////////////////////////////
419// DiskInfo
420
421DiskInfo::DiskInfo(const std::string& device_path, dbus::Response* response)
422 : device_path_(device_path),
423 is_drive_(false),
424 has_media_(false),
425 on_boot_device_(false),
[email protected]2321d282012-01-31 23:06:59426 device_type_(DEVICE_TYPE_UNKNOWN),
[email protected]4ae73292011-11-15 05:20:18427 total_size_in_bytes_(0),
428 is_read_only_(false),
429 is_hidden_(true) {
430 InitializeFromResponse(response);
431}
432
433DiskInfo::~DiskInfo() {
434}
435
436// Initialize |this| from |response| given by the cros-disks service.
437// Below is an example of |response|'s raw message (long string is ellipsized).
438//
439//
440// message_type: MESSAGE_METHOD_RETURN
441// destination: :1.8
442// sender: :1.16
443// signature: a{sv}
444// serial: 96
445// reply_serial: 267
446//
447// array [
448// dict entry {
449// string "DeviceFile"
450// variant string "/dev/sdb"
451// }
452// dict entry {
453// string "DeviceIsDrive"
454// variant bool true
455// }
456// dict entry {
457// string "DeviceIsMediaAvailable"
458// variant bool true
459// }
460// dict entry {
461// string "DeviceIsMounted"
462// variant bool false
463// }
464// dict entry {
465// string "DeviceIsOnBootDevice"
466// variant bool false
467// }
468// dict entry {
469// string "DeviceIsOpticalDisc"
470// variant bool false
471// }
472// dict entry {
473// string "DeviceIsReadOnly"
474// variant bool false
475// }
476// dict entry {
477// string "DeviceIsVirtual"
478// variant bool false
479// }
480// dict entry {
481// string "DeviceMediaType"
482// variant uint32 1
483// }
484// dict entry {
485// string "DeviceMountPaths"
486// variant array [
487// ]
488// }
489// dict entry {
490// string "DevicePresentationHide"
491// variant bool true
492// }
493// dict entry {
494// string "DeviceSize"
495// variant uint64 7998537728
496// }
497// dict entry {
498// string "DriveIsRotational"
499// variant bool false
500// }
501// dict entry {
502// string "DriveModel"
503// variant string "TransMemory"
504// }
505// dict entry {
506// string "IdLabel"
507// variant string ""
508// }
509// dict entry {
510// string "IdUuid"
511// variant string ""
512// }
513// dict entry {
514// string "NativePath"
515// variant string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
516// }
517// ]
518void DiskInfo::InitializeFromResponse(dbus::Response* response) {
519 dbus::MessageReader response_reader(response);
520 dbus::MessageReader array_reader(response);
521 if (!response_reader.PopArray(&array_reader)) {
522 LOG(ERROR) << "Invalid response: " << response->ToString();
523 return;
524 }
525 // TODO(satorux): Rework this code using Protocol Buffers. crosbug.com/22626
[email protected]b307bceb2011-11-17 07:49:55526 typedef std::map<std::string, dbus::MessageReader*> PropertiesMap;
527 PropertiesMap properties;
528 STLValueDeleter<PropertiesMap> properties_value_deleter(&properties);
[email protected]4ae73292011-11-15 05:20:18529 while (array_reader.HasMoreData()) {
[email protected]4ae73292011-11-15 05:20:18530 dbus::MessageReader* value_reader = new dbus::MessageReader(response);
[email protected]4ae73292011-11-15 05:20:18531 dbus::MessageReader dict_entry_reader(response);
532 std::string key;
533 if (!array_reader.PopDictEntry(&dict_entry_reader) ||
534 !dict_entry_reader.PopString(&key) ||
535 !dict_entry_reader.PopVariant(value_reader)) {
536 LOG(ERROR) << "Invalid response: " << response->ToString();
537 return;
538 }
539 properties[key] = value_reader;
540 }
541 MaybePopBool(properties[cros_disks::kDeviceIsDrive], &is_drive_);
542 MaybePopBool(properties[cros_disks::kDeviceIsReadOnly], &is_read_only_);
543 MaybePopBool(properties[cros_disks::kDevicePresentationHide], &is_hidden_);
544 MaybePopBool(properties[cros_disks::kDeviceIsMediaAvailable], &has_media_);
545 MaybePopBool(properties[cros_disks::kDeviceIsOnBootDevice],
546 &on_boot_device_);
547 MaybePopString(properties[cros_disks::kNativePath], &system_path_);
548 MaybePopString(properties[cros_disks::kDeviceFile], &file_path_);
549 MaybePopString(properties[cros_disks::kDriveModel], &drive_model_);
550 MaybePopString(properties[cros_disks::kIdLabel], &label_);
551 MaybePopUint64(properties[cros_disks::kDeviceSize], &total_size_in_bytes_);
552
[email protected]2321d282012-01-31 23:06:59553 uint32 media_type_uint32 = 0;
554 if (MaybePopUint32(properties[cros_disks::kDeviceMediaType],
555 &media_type_uint32)) {
556 device_type_ = DeviceMediaTypeToDeviceType(media_type_uint32);
557 }
558
[email protected]4ae73292011-11-15 05:20:18559 std::vector<std::string> mount_paths;
560 if (MaybePopArrayOfStrings(properties[cros_disks::kDeviceMountPaths],
561 &mount_paths) && !mount_paths.empty())
562 mount_path_ = mount_paths[0];
[email protected]4ae73292011-11-15 05:20:18563}
564
565////////////////////////////////////////////////////////////////////////////////
566// CrosDisksClient
567
568CrosDisksClient::CrosDisksClient() {}
569
570CrosDisksClient::~CrosDisksClient() {}
571
572// static
[email protected]e8db03d62012-03-31 04:08:38573CrosDisksClient* CrosDisksClient::Create(DBusClientImplementationType type,
574 dbus::Bus* bus) {
575 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
[email protected]4ae73292011-11-15 05:20:18576 return new CrosDisksClientImpl(bus);
[email protected]e8db03d62012-03-31 04:08:38577 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
578 return new CrosDisksClientStubImpl();
[email protected]4ae73292011-11-15 05:20:18579}
580
581} // namespace chromeos