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

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

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

Powered by Google App Engine
This is Rietveld 408576698