Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(435)

Side by Side Diff: chrome/browser/chromeos/dbus/cros_disks_client.cc

Issue 9838085: Move files inside chrome/browser/chromeos/dbus to chromeos/dbus (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: _ Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/chromeos/dbus/cros_disks_client.h"
6
7 #include "base/bind.h"
8 #include "base/chromeos/chromeos_version.h"
9 #include "base/stl_util.h"
10 #include "dbus/bus.h"
11 #include "dbus/message.h"
12 #include "dbus/object_path.h"
13 #include "dbus/object_proxy.h"
14 #include "third_party/cros_system_api/dbus/service_constants.h"
15
16 namespace chromeos {
17
18 namespace {
19
20 const char* kDefaultMountOptions[] = {
21 "rw",
22 "nodev",
23 "noexec",
24 "nosuid",
25 };
26
27 const char* kDefaultUnmountOptions[] = {
28 "force",
29 };
30
31 // Checks if retrieved media type is in boundaries of DeviceMediaType.
32 bool IsValidMediaType(uint32 type) {
33 return type < static_cast<uint32>(cros_disks::DEVICE_MEDIA_NUM_VALUES);
34 }
35
36
37 // Translates enum used in cros-disks to enum used in Chrome.
38 // Note that we could just do static_cast, but this is less sensitive to
39 // changes in cros-disks.
40 DeviceType DeviceMediaTypeToDeviceType(uint32 media_type_uint32) {
41 if (!IsValidMediaType(media_type_uint32))
42 return DEVICE_TYPE_UNKNOWN;
43
44 cros_disks::DeviceMediaType media_type =
45 cros_disks::DeviceMediaType(media_type_uint32);
46
47 switch (media_type) {
48 case(cros_disks::DEVICE_MEDIA_UNKNOWN):
49 return DEVICE_TYPE_UNKNOWN;
50 case(cros_disks::DEVICE_MEDIA_USB):
51 return DEVICE_TYPE_USB;
52 case(cros_disks::DEVICE_MEDIA_SD):
53 return DEVICE_TYPE_SD;
54 case(cros_disks::DEVICE_MEDIA_OPTICAL_DISC):
55 return DEVICE_TYPE_OPTICAL_DISC;
56 case(cros_disks::DEVICE_MEDIA_MOBILE):
57 return DEVICE_TYPE_MOBILE;
58 default:
59 return DEVICE_TYPE_UNKNOWN;
60 }
61 }
62
63 // Pops a bool value when |reader| is not NULL.
64 // Returns true when a value is popped, false otherwise.
65 bool MaybePopBool(dbus::MessageReader* reader, bool* value) {
66 if (!reader)
67 return false;
68 return reader->PopBool(value);
69 }
70
71 // Pops a string value when |reader| is not NULL.
72 // Returns true when a value is popped, false otherwise.
73 bool MaybePopString(dbus::MessageReader* reader, std::string* value) {
74 if (!reader)
75 return false;
76 return reader->PopString(value);
77 }
78
79 // Pops a uint32 value when |reader| is not NULL.
80 // Returns true when a value is popped, false otherwise.
81 bool MaybePopUint32(dbus::MessageReader* reader, uint32* value) {
82 if (!reader)
83 return false;
84
85 return reader->PopUint32(value);
86 }
87
88 // Pops a uint64 value when |reader| is not NULL.
89 // Returns true when a value is popped, false otherwise.
90 bool MaybePopUint64(dbus::MessageReader* reader, uint64* value) {
91 if (!reader)
92 return false;
93 return reader->PopUint64(value);
94 }
95
96 // Pops an array of strings when |reader| is not NULL.
97 // Returns true when an array is popped, false otherwise.
98 bool MaybePopArrayOfStrings(dbus::MessageReader* reader,
99 std::vector<std::string>* value) {
100 if (!reader)
101 return false;
102 return reader->PopArrayOfStrings(value);
103 }
104
105 // The CrosDisksClient implementation.
106 class CrosDisksClientImpl : public CrosDisksClient {
107 public:
108 explicit CrosDisksClientImpl(dbus::Bus* bus)
109 : proxy_(bus->GetObjectProxy(
110 cros_disks::kCrosDisksServiceName,
111 dbus::ObjectPath(cros_disks::kCrosDisksServicePath))),
112 weak_ptr_factory_(this) {
113 }
114
115 // CrosDisksClient override.
116 virtual void Mount(const std::string& source_path,
117 MountType type,
118 MountCallback callback,
119 ErrorCallback error_callback) OVERRIDE {
120 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
121 cros_disks::kMount);
122 dbus::MessageWriter writer(&method_call);
123 writer.AppendString(source_path);
124 writer.AppendString(""); // auto detect filesystem.
125 std::vector<std::string> mount_options(kDefaultMountOptions,
126 kDefaultMountOptions +
127 arraysize(kDefaultMountOptions));
128 writer.AppendArrayOfStrings(mount_options);
129 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
130 base::Bind(&CrosDisksClientImpl::OnMount,
131 weak_ptr_factory_.GetWeakPtr(),
132 callback,
133 error_callback));
134 }
135
136 // CrosDisksClient override.
137 virtual void Unmount(const std::string& device_path,
138 UnmountCallback callback,
139 ErrorCallback error_callback) OVERRIDE {
140 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
141 cros_disks::kUnmount);
142 dbus::MessageWriter writer(&method_call);
143 writer.AppendString(device_path);
144 std::vector<std::string> unmount_options(kDefaultUnmountOptions,
145 kDefaultUnmountOptions +
146 arraysize(kDefaultUnmountOptions));
147 writer.AppendArrayOfStrings(unmount_options);
148 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
149 base::Bind(&CrosDisksClientImpl::OnUnmount,
150 weak_ptr_factory_.GetWeakPtr(),
151 device_path,
152 callback,
153 error_callback));
154 }
155
156 // CrosDisksClient override.
157 virtual void EnumerateAutoMountableDevices(
158 EnumerateAutoMountableDevicesCallback callback,
159 ErrorCallback error_callback) OVERRIDE {
160 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
161 cros_disks::kEnumerateAutoMountableDevices);
162 proxy_->CallMethod(
163 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
164 base::Bind(&CrosDisksClientImpl::OnEnumerateAutoMountableDevices,
165 weak_ptr_factory_.GetWeakPtr(),
166 callback,
167 error_callback));
168 }
169
170 // CrosDisksClient override.
171 virtual void FormatDevice(const std::string& device_path,
172 const std::string& filesystem,
173 FormatDeviceCallback callback,
174 ErrorCallback error_callback) OVERRIDE {
175 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
176 cros_disks::kFormatDevice);
177 dbus::MessageWriter writer(&method_call);
178 writer.AppendString(device_path);
179 writer.AppendString(filesystem);
180 proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
181 base::Bind(&CrosDisksClientImpl::OnFormatDevice,
182 weak_ptr_factory_.GetWeakPtr(),
183 device_path,
184 callback,
185 error_callback));
186 }
187
188 // CrosDisksClient override.
189 virtual void GetDeviceProperties(const std::string& device_path,
190 GetDevicePropertiesCallback callback,
191 ErrorCallback error_callback) OVERRIDE {
192 dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
193 cros_disks::kGetDeviceProperties);
194 dbus::MessageWriter writer(&method_call);
195 writer.AppendString(device_path);
196 proxy_->CallMethod(&method_call,
197 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
198 base::Bind(&CrosDisksClientImpl::OnGetDeviceProperties,
199 weak_ptr_factory_.GetWeakPtr(),
200 device_path,
201 callback,
202 error_callback));
203 }
204
205 // CrosDisksClient override.
206 virtual void SetUpConnections(
207 MountEventHandler mount_event_handler,
208 MountCompletedHandler mount_completed_handler) OVERRIDE {
209 static const SignalEventTuple kSignalEventTuples[] = {
210 { cros_disks::kDeviceAdded, DEVICE_ADDED },
211 { cros_disks::kDeviceScanned, DEVICE_SCANNED },
212 { cros_disks::kDeviceRemoved, DEVICE_REMOVED },
213 { cros_disks::kDiskAdded, DISK_ADDED },
214 { cros_disks::kDiskChanged, DISK_CHANGED },
215 { cros_disks::kDiskRemoved, DISK_REMOVED },
216 { cros_disks::kFormattingFinished, FORMATTING_FINISHED },
217 };
218 const size_t kNumSignalEventTuples = arraysize(kSignalEventTuples);
219
220 for (size_t i = 0; i < kNumSignalEventTuples; ++i) {
221 proxy_->ConnectToSignal(
222 cros_disks::kCrosDisksInterface,
223 kSignalEventTuples[i].signal_name,
224 base::Bind(&CrosDisksClientImpl::OnMountEvent,
225 weak_ptr_factory_.GetWeakPtr(),
226 kSignalEventTuples[i].event_type,
227 mount_event_handler),
228 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
229 weak_ptr_factory_.GetWeakPtr()));
230 }
231 proxy_->ConnectToSignal(
232 cros_disks::kCrosDisksInterface,
233 cros_disks::kMountCompleted,
234 base::Bind(&CrosDisksClientImpl::OnMountCompleted,
235 weak_ptr_factory_.GetWeakPtr(),
236 mount_completed_handler ),
237 base::Bind(&CrosDisksClientImpl::OnSignalConnected,
238 weak_ptr_factory_.GetWeakPtr()));
239 }
240
241 private:
242 // A struct to contain a pair of signal name and mount event type.
243 // Used by SetUpConnections.
244 struct SignalEventTuple {
245 const char *signal_name;
246 MountEventType event_type;
247 };
248
249 // Handles the result of Mount and calls |callback| or |error_callback|.
250 void OnMount(MountCallback callback,
251 ErrorCallback error_callback,
252 dbus::Response* response) {
253 if (!response) {
254 error_callback.Run();
255 return;
256 }
257 callback.Run();
258 }
259
260 // Handles the result of Unount and calls |callback| or |error_callback|.
261 void OnUnmount(const std::string& device_path,
262 UnmountCallback callback,
263 ErrorCallback error_callback,
264 dbus::Response* response) {
265 if (!response) {
266 error_callback.Run();
267 return;
268 }
269 callback.Run(device_path);
270 }
271
272 // Handles the result of EnumerateAutoMountableDevices and calls |callback| or
273 // |error_callback|.
274 void OnEnumerateAutoMountableDevices(
275 EnumerateAutoMountableDevicesCallback callback,
276 ErrorCallback error_callback,
277 dbus::Response* response) {
278 if (!response) {
279 error_callback.Run();
280 return;
281 }
282 dbus::MessageReader reader(response);
283 std::vector<std::string> device_paths;
284 if (!reader.PopArrayOfStrings(&device_paths)) {
285 LOG(ERROR) << "Invalid response: " << response->ToString();
286 error_callback.Run();
287 return;
288 }
289 callback.Run(device_paths);
290 }
291
292 // Handles the result of FormatDevice and calls |callback| or
293 // |error_callback|.
294 void OnFormatDevice(const std::string& device_path,
295 FormatDeviceCallback callback,
296 ErrorCallback error_callback,
297 dbus::Response* response) {
298 if (!response) {
299 error_callback.Run();
300 return;
301 }
302 dbus::MessageReader reader(response);
303 bool success = false;
304 if (!reader.PopBool(&success)) {
305 LOG(ERROR) << "Invalid response: " << response->ToString();
306 error_callback.Run();
307 return;
308 }
309 callback.Run(device_path, success);
310 }
311
312 // Handles the result of GetDeviceProperties and calls |callback| or
313 // |error_callback|.
314 void OnGetDeviceProperties(const std::string& device_path,
315 GetDevicePropertiesCallback callback,
316 ErrorCallback error_callback,
317 dbus::Response* response) {
318 if (!response) {
319 error_callback.Run();
320 return;
321 }
322 DiskInfo disk(device_path, response);
323 callback.Run(disk);
324 }
325
326 // Handles mount event signals and calls |handler|.
327 void OnMountEvent(MountEventType event_type,
328 MountEventHandler handler,
329 dbus::Signal* signal) {
330 dbus::MessageReader reader(signal);
331 std::string device;
332 if (!reader.PopString(&device)) {
333 LOG(ERROR) << "Invalid signal: " << signal->ToString();
334 return;
335 }
336 handler.Run(event_type, device);
337 }
338
339 // Handles MountCompleted signal and calls |handler|.
340 void OnMountCompleted(MountCompletedHandler handler, dbus::Signal* signal) {
341 dbus::MessageReader reader(signal);
342 unsigned int error_code = 0;
343 std::string source_path;
344 unsigned int mount_type = 0;
345 std::string mount_path;
346 if (!reader.PopUint32(&error_code) ||
347 !reader.PopString(&source_path) ||
348 !reader.PopUint32(&mount_type) ||
349 !reader.PopString(&mount_path)) {
350 LOG(ERROR) << "Invalid signal: " << signal->ToString();
351 return;
352 }
353 handler.Run(static_cast<MountError>(error_code), source_path,
354 static_cast<MountType>(mount_type), mount_path);
355 }
356
357 // Handles the result of signal connection setup.
358 void OnSignalConnected(const std::string& interface,
359 const std::string& signal,
360 bool successed) {
361 LOG_IF(ERROR, !successed) << "Connect to " << interface << " " <<
362 signal << " failed.";
363 }
364
365 dbus::ObjectProxy* proxy_;
366 base::WeakPtrFactory<CrosDisksClientImpl> weak_ptr_factory_;
367
368 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl);
369 };
370
371 // A stub implementaion of CrosDisksClient.
372 class CrosDisksClientStubImpl : public CrosDisksClient {
373 public:
374 CrosDisksClientStubImpl() {}
375 virtual ~CrosDisksClientStubImpl() {}
376
377 virtual void Mount(const std::string& source_path,
378 MountType type,
379 MountCallback callback,
380 ErrorCallback error_callback) OVERRIDE {}
381 virtual void Unmount(const std::string& device_path,
382 UnmountCallback callback,
383 ErrorCallback error_callback) OVERRIDE {}
384 virtual void EnumerateAutoMountableDevices(
385 EnumerateAutoMountableDevicesCallback callback,
386 ErrorCallback error_callback) OVERRIDE {}
387 virtual void FormatDevice(const std::string& device_path,
388 const std::string& filesystem,
389 FormatDeviceCallback callback,
390 ErrorCallback error_callback) OVERRIDE {}
391 virtual void GetDeviceProperties(const std::string& device_path,
392 GetDevicePropertiesCallback callback,
393 ErrorCallback error_callback) OVERRIDE {}
394 virtual void SetUpConnections(
395 MountEventHandler mount_event_handler,
396 MountCompletedHandler mount_completed_handler) OVERRIDE {}
397
398 private:
399 DISALLOW_COPY_AND_ASSIGN(CrosDisksClientStubImpl);
400 };
401
402 } // namespace
403
404 ////////////////////////////////////////////////////////////////////////////////
405 // DiskInfo
406
407 DiskInfo::DiskInfo(const std::string& device_path, dbus::Response* response)
408 : device_path_(device_path),
409 is_drive_(false),
410 has_media_(false),
411 on_boot_device_(false),
412 device_type_(DEVICE_TYPE_UNKNOWN),
413 total_size_in_bytes_(0),
414 is_read_only_(false),
415 is_hidden_(true) {
416 InitializeFromResponse(response);
417 }
418
419 DiskInfo::~DiskInfo() {
420 }
421
422 // Initialize |this| from |response| given by the cros-disks service.
423 // Below is an example of |response|'s raw message (long string is ellipsized).
424 //
425 //
426 // message_type: MESSAGE_METHOD_RETURN
427 // destination: :1.8
428 // sender: :1.16
429 // signature: a{sv}
430 // serial: 96
431 // reply_serial: 267
432 //
433 // array [
434 // dict entry {
435 // string "DeviceFile"
436 // variant string "/dev/sdb"
437 // }
438 // dict entry {
439 // string "DeviceIsDrive"
440 // variant bool true
441 // }
442 // dict entry {
443 // string "DeviceIsMediaAvailable"
444 // variant bool true
445 // }
446 // dict entry {
447 // string "DeviceIsMounted"
448 // variant bool false
449 // }
450 // dict entry {
451 // string "DeviceIsOnBootDevice"
452 // variant bool false
453 // }
454 // dict entry {
455 // string "DeviceIsOpticalDisc"
456 // variant bool false
457 // }
458 // dict entry {
459 // string "DeviceIsReadOnly"
460 // variant bool false
461 // }
462 // dict entry {
463 // string "DeviceIsVirtual"
464 // variant bool false
465 // }
466 // dict entry {
467 // string "DeviceMediaType"
468 // variant uint32 1
469 // }
470 // dict entry {
471 // string "DeviceMountPaths"
472 // variant array [
473 // ]
474 // }
475 // dict entry {
476 // string "DevicePresentationHide"
477 // variant bool true
478 // }
479 // dict entry {
480 // string "DeviceSize"
481 // variant uint64 7998537728
482 // }
483 // dict entry {
484 // string "DriveIsRotational"
485 // variant bool false
486 // }
487 // dict entry {
488 // string "DriveModel"
489 // variant string "TransMemory"
490 // }
491 // dict entry {
492 // string "IdLabel"
493 // variant string ""
494 // }
495 // dict entry {
496 // string "IdUuid"
497 // variant string ""
498 // }
499 // dict entry {
500 // string "NativePath"
501 // variant string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
502 // }
503 // ]
504 void DiskInfo::InitializeFromResponse(dbus::Response* response) {
505 dbus::MessageReader response_reader(response);
506 dbus::MessageReader array_reader(response);
507 if (!response_reader.PopArray(&array_reader)) {
508 LOG(ERROR) << "Invalid response: " << response->ToString();
509 return;
510 }
511 // TODO(satorux): Rework this code using Protocol Buffers. crosbug.com/22626
512 typedef std::map<std::string, dbus::MessageReader*> PropertiesMap;
513 PropertiesMap properties;
514 STLValueDeleter<PropertiesMap> properties_value_deleter(&properties);
515 while (array_reader.HasMoreData()) {
516 dbus::MessageReader* value_reader = new dbus::MessageReader(response);
517 dbus::MessageReader dict_entry_reader(response);
518 std::string key;
519 if (!array_reader.PopDictEntry(&dict_entry_reader) ||
520 !dict_entry_reader.PopString(&key) ||
521 !dict_entry_reader.PopVariant(value_reader)) {
522 LOG(ERROR) << "Invalid response: " << response->ToString();
523 return;
524 }
525 properties[key] = value_reader;
526 }
527 MaybePopBool(properties[cros_disks::kDeviceIsDrive], &is_drive_);
528 MaybePopBool(properties[cros_disks::kDeviceIsReadOnly], &is_read_only_);
529 MaybePopBool(properties[cros_disks::kDevicePresentationHide], &is_hidden_);
530 MaybePopBool(properties[cros_disks::kDeviceIsMediaAvailable], &has_media_);
531 MaybePopBool(properties[cros_disks::kDeviceIsOnBootDevice],
532 &on_boot_device_);
533 MaybePopString(properties[cros_disks::kNativePath], &system_path_);
534 MaybePopString(properties[cros_disks::kDeviceFile], &file_path_);
535 MaybePopString(properties[cros_disks::kDriveModel], &drive_model_);
536 MaybePopString(properties[cros_disks::kIdLabel], &label_);
537 MaybePopUint64(properties[cros_disks::kDeviceSize], &total_size_in_bytes_);
538
539 uint32 media_type_uint32 = 0;
540 if (MaybePopUint32(properties[cros_disks::kDeviceMediaType],
541 &media_type_uint32)) {
542 device_type_ = DeviceMediaTypeToDeviceType(media_type_uint32);
543 }
544
545 std::vector<std::string> mount_paths;
546 if (MaybePopArrayOfStrings(properties[cros_disks::kDeviceMountPaths],
547 &mount_paths) && !mount_paths.empty())
548 mount_path_ = mount_paths[0];
549 }
550
551 ////////////////////////////////////////////////////////////////////////////////
552 // CrosDisksClient
553
554 CrosDisksClient::CrosDisksClient() {}
555
556 CrosDisksClient::~CrosDisksClient() {}
557
558 // static
559 CrosDisksClient* CrosDisksClient::Create(dbus::Bus* bus) {
560 if (base::chromeos::IsRunningOnChromeOS())
561 return new CrosDisksClientImpl(bus);
562 else
563 return new CrosDisksClientStubImpl();
564 }
565
566 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698