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

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

Powered by Google App Engine
This is Rietveld 408576698