blob: 9850fb380c5164f5f872d5087a5056fc5dc353fe [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]4cbead42012-08-26 12:02:395#include "chromeos/disks/disk_mount_manager.h"
[email protected]a66a23cb2012-06-19 23:15:336
[email protected]4ae73292011-11-15 05:20:187#include <map>
8#include <set>
9
[email protected]4ae73292011-11-15 05:20:1810#include "base/bind.h"
[email protected]c6944272012-01-06 22:12:2811#include "base/memory/weak_ptr.h"
[email protected]3fc40c142011-12-01 13:09:0412#include "base/observer_list.h"
[email protected]4ae73292011-11-15 05:20:1813#include "base/string_util.h"
[email protected]64e199252012-04-06 01:54:3614#include "chromeos/dbus/dbus_thread_manager.h"
[email protected]4ae73292011-11-15 05:20:1815
16namespace chromeos {
17namespace disks {
18
19namespace {
20
21const char kDeviceNotFound[] = "Device could not be found";
22
23DiskMountManager* g_disk_mount_manager = NULL;
24
25// The DiskMountManager implementation.
26class DiskMountManagerImpl : public DiskMountManager {
27 public:
28 DiskMountManagerImpl() : weak_ptr_factory_(this) {
29 DBusThreadManager* dbus_thread_manager = DBusThreadManager::Get();
30 DCHECK(dbus_thread_manager);
31 cros_disks_client_ = dbus_thread_manager->GetCrosDisksClient();
32 DCHECK(cros_disks_client_);
33
34 cros_disks_client_->SetUpConnections(
35 base::Bind(&DiskMountManagerImpl::OnMountEvent,
36 weak_ptr_factory_.GetWeakPtr()),
37 base::Bind(&DiskMountManagerImpl::OnMountCompleted,
38 weak_ptr_factory_.GetWeakPtr()));
39 }
40
41 virtual ~DiskMountManagerImpl() {
42 }
43
44 // DiskMountManager override.
45 virtual void AddObserver(Observer* observer) OVERRIDE {
46 observers_.AddObserver(observer);
47 }
48
49 // DiskMountManager override.
50 virtual void RemoveObserver(Observer* observer) OVERRIDE {
51 observers_.RemoveObserver(observer);
52 }
53
54 // DiskMountManager override.
55 virtual void MountPath(const std::string& source_path,
[email protected]b9f22d12012-04-25 21:46:4856 const std::string& source_format,
[email protected]dcad8fc2012-04-30 23:31:3357 const std::string& mount_label,
[email protected]4ae73292011-11-15 05:20:1858 MountType type) OVERRIDE {
59 // Hidden and non-existent devices should not be mounted.
60 if (type == MOUNT_TYPE_DEVICE) {
61 DiskMap::const_iterator it = disks_.find(source_path);
62 if (it == disks_.end() || it->second->is_hidden()) {
63 OnMountCompleted(MOUNT_ERROR_INTERNAL, source_path, type, "");
64 return;
65 }
66 }
[email protected]4ae73292011-11-15 05:20:1867 cros_disks_client_->Mount(
68 source_path,
[email protected]b9f22d12012-04-25 21:46:4869 source_format,
[email protected]dcad8fc2012-04-30 23:31:3370 mount_label,
[email protected]4ae73292011-11-15 05:20:1871 type,
72 // When succeeds, OnMountCompleted will be called by
73 // "MountCompleted" signal instead.
[email protected]c6944272012-01-06 22:12:2874 base::Bind(&base::DoNothing),
[email protected]4ae73292011-11-15 05:20:1875 base::Bind(&DiskMountManagerImpl::OnMountCompleted,
76 weak_ptr_factory_.GetWeakPtr(),
77 MOUNT_ERROR_INTERNAL,
78 source_path,
79 type,
80 ""));
81 }
82
83 // DiskMountManager override.
84 virtual void UnmountPath(const std::string& mount_path) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:1885 cros_disks_client_->Unmount(mount_path,
86 base::Bind(&DiskMountManagerImpl::OnUnmountPath,
87 weak_ptr_factory_.GetWeakPtr()),
[email protected]c6944272012-01-06 22:12:2888 base::Bind(&base::DoNothing));
[email protected]4ae73292011-11-15 05:20:1889 }
90
91 // DiskMountManager override.
[email protected]4ae73292011-11-15 05:20:1892 virtual void FormatUnmountedDevice(const std::string& file_path) OVERRIDE {
[email protected]4ae73292011-11-15 05:20:1893 for (DiskMountManager::DiskMap::iterator it = disks_.begin();
94 it != disks_.end(); ++it) {
95 if (it->second->file_path() == file_path &&
96 !it->second->mount_path().empty()) {
97 LOG(ERROR) << "Device is still mounted: " << file_path;
98 OnFormatDevice(file_path, false);
99 return;
100 }
101 }
102 const char kFormatVFAT[] = "vfat";
103 cros_disks_client_->FormatDevice(
104 file_path,
105 kFormatVFAT,
106 base::Bind(&DiskMountManagerImpl::OnFormatDevice,
107 weak_ptr_factory_.GetWeakPtr()),
108 base::Bind(&DiskMountManagerImpl::OnFormatDevice,
109 weak_ptr_factory_.GetWeakPtr(),
110 file_path,
111 false));
112 }
113
114 // DiskMountManager override.
115 virtual void FormatMountedDevice(const std::string& mount_path) OVERRIDE {
116 Disk* disk = NULL;
117 for (DiskMountManager::DiskMap::iterator it = disks_.begin();
118 it != disks_.end(); ++it) {
119 if (it->second->mount_path() == mount_path) {
120 disk = it->second;
121 break;
122 }
123 }
124 if (!disk) {
125 LOG(ERROR) << "Device with this mount path not found: " << mount_path;
126 OnFormatDevice(mount_path, false);
127 return;
128 }
129 if (formatting_pending_.find(disk->device_path()) !=
130 formatting_pending_.end()) {
131 LOG(ERROR) << "Formatting is already pending: " << mount_path;
132 OnFormatDevice(mount_path, false);
133 return;
134 }
135 // Formatting process continues, after unmounting.
136 formatting_pending_[disk->device_path()] = disk->file_path();
137 UnmountPath(disk->mount_path());
138 }
139
140 // DiskMountManager override.
141 virtual void UnmountDeviceRecursive(
142 const std::string& device_path,
143 UnmountDeviceRecursiveCallbackType callback,
144 void* user_data) OVERRIDE {
145 bool success = true;
146 std::string error_message;
147 std::vector<std::string> devices_to_unmount;
148
149 // Get list of all devices to unmount.
150 int device_path_len = device_path.length();
151 for (DiskMap::iterator it = disks_.begin(); it != disks_.end(); ++it) {
152 if (!it->second->mount_path().empty() &&
153 strncmp(device_path.c_str(), it->second->device_path().c_str(),
154 device_path_len) == 0) {
155 devices_to_unmount.push_back(it->second->mount_path());
156 }
157 }
158 // We should detect at least original device.
159 if (devices_to_unmount.empty()) {
160 if (disks_.find(device_path) == disks_.end()) {
161 success = false;
162 error_message = kDeviceNotFound;
163 } else {
164 // Nothing to unmount.
165 callback(user_data, true);
166 return;
167 }
168 }
169 if (success) {
170 // We will send the same callback data object to all Unmount calls and use
171 // it to syncronize callbacks.
172 UnmountDeviceRecursiveCallbackData* cb_data =
173 new UnmountDeviceRecursiveCallbackData(user_data, callback,
174 devices_to_unmount.size());
175 for (size_t i = 0; i < devices_to_unmount.size(); ++i) {
176 cros_disks_client_->Unmount(
177 devices_to_unmount[i],
178 base::Bind(&DiskMountManagerImpl::OnUnmountDeviceRecursive,
179 weak_ptr_factory_.GetWeakPtr(), cb_data, true),
180 base::Bind(&DiskMountManagerImpl::OnUnmountDeviceRecursive,
181 weak_ptr_factory_.GetWeakPtr(),
182 cb_data,
183 false,
184 devices_to_unmount[i]));
185 }
186 } else {
187 LOG(WARNING) << "Unmount recursive request failed for device "
188 << device_path << ", with error: " << error_message;
189 callback(user_data, false);
190 }
191 }
192
193 // DiskMountManager override.
194 virtual void RequestMountInfoRefresh() OVERRIDE {
[email protected]4ae73292011-11-15 05:20:18195 cros_disks_client_->EnumerateAutoMountableDevices(
196 base::Bind(&DiskMountManagerImpl::OnRequestMountInfo,
197 weak_ptr_factory_.GetWeakPtr()),
[email protected]c6944272012-01-06 22:12:28198 base::Bind(&base::DoNothing));
[email protected]4ae73292011-11-15 05:20:18199 }
200
201 // DiskMountManager override.
[email protected]28a520f2012-08-30 19:48:25202 virtual const DiskMap& disks() const OVERRIDE { return disks_; }
[email protected]4ae73292011-11-15 05:20:18203
[email protected]bcfa0072012-08-07 01:08:57204 // DiskMountManager override.
205 virtual const Disk* FindDiskBySourcePath(const std::string& source_path)
206 const OVERRIDE {
207 DiskMap::const_iterator disk_it = disks_.find(source_path);
208 return disk_it == disks_.end() ? NULL : disk_it->second;
209 }
[email protected]4ae73292011-11-15 05:20:18210
211 // DiskMountManager override.
[email protected]28a520f2012-08-30 19:48:25212 virtual const MountPointMap& mount_points() const OVERRIDE {
213 return mount_points_;
214 }
[email protected]4ae73292011-11-15 05:20:18215
216 private:
217 struct UnmountDeviceRecursiveCallbackData {
218 void* user_data;
219 UnmountDeviceRecursiveCallbackType callback;
220 size_t pending_callbacks_count;
221
222 UnmountDeviceRecursiveCallbackData(void* ud,
223 UnmountDeviceRecursiveCallbackType cb,
224 int count)
225 : user_data(ud),
226 callback(cb),
227 pending_callbacks_count(count) {
228 }
229 };
230
231 // Callback for UnmountDeviceRecursive.
232 void OnUnmountDeviceRecursive(UnmountDeviceRecursiveCallbackData* cb_data,
233 bool success,
234 const std::string& mount_path) {
235 if (success) {
236 // Do standard processing for Unmount event.
237 OnUnmountPath(mount_path);
238 LOG(INFO) << mount_path << " unmounted.";
239 }
240 // This is safe as long as all callbacks are called on the same thread as
241 // UnmountDeviceRecursive.
242 cb_data->pending_callbacks_count--;
243
244 if (cb_data->pending_callbacks_count == 0) {
245 cb_data->callback(cb_data->user_data, success);
246 delete cb_data;
247 }
248 }
249
250 // Callback to handle MountCompleted signal and Mount method call failure.
251 void OnMountCompleted(MountError error_code,
252 const std::string& source_path,
253 MountType mount_type,
254 const std::string& mount_path) {
255 MountCondition mount_condition = MOUNT_CONDITION_NONE;
256 if (mount_type == MOUNT_TYPE_DEVICE) {
[email protected]a66a23cb2012-06-19 23:15:33257 if (error_code == MOUNT_ERROR_UNKNOWN_FILESYSTEM) {
[email protected]4ae73292011-11-15 05:20:18258 mount_condition = MOUNT_CONDITION_UNKNOWN_FILESYSTEM;
[email protected]a66a23cb2012-06-19 23:15:33259 }
260 if (error_code == MOUNT_ERROR_UNSUPPORTED_FILESYSTEM) {
[email protected]4ae73292011-11-15 05:20:18261 mount_condition = MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM;
[email protected]a66a23cb2012-06-19 23:15:33262 }
[email protected]4ae73292011-11-15 05:20:18263 }
264 const MountPointInfo mount_info(source_path, mount_path, mount_type,
265 mount_condition);
266
267 NotifyMountCompleted(MOUNTING, error_code, mount_info);
268
269 // If the device is corrupted but it's still possible to format it, it will
270 // be fake mounted.
271 if ((error_code == MOUNT_ERROR_NONE || mount_info.mount_condition) &&
272 mount_points_.find(mount_info.mount_path) == mount_points_.end()) {
273 mount_points_.insert(MountPointMap::value_type(mount_info.mount_path,
274 mount_info));
275 }
276 if ((error_code == MOUNT_ERROR_NONE || mount_info.mount_condition) &&
277 mount_info.mount_type == MOUNT_TYPE_DEVICE &&
278 !mount_info.source_path.empty() &&
279 !mount_info.mount_path.empty()) {
280 DiskMap::iterator iter = disks_.find(mount_info.source_path);
281 if (iter == disks_.end()) {
282 // disk might have been removed by now?
283 return;
284 }
285 Disk* disk = iter->second;
286 DCHECK(disk);
287 disk->set_mount_path(mount_info.mount_path);
288 NotifyDiskStatusUpdate(MOUNT_DISK_MOUNTED, disk);
289 }
290 }
291
292 // Callback for UnmountPath.
293 void OnUnmountPath(const std::string& mount_path) {
294 MountPointMap::iterator mount_points_it = mount_points_.find(mount_path);
295 if (mount_points_it == mount_points_.end())
296 return;
297 // TODO(tbarzic): Add separate, PathUnmounted event to Observer.
[email protected]a66a23cb2012-06-19 23:15:33298 NotifyMountCompleted(
299 UNMOUNTING, MOUNT_ERROR_NONE,
300 MountPointInfo(mount_points_it->second.source_path,
301 mount_points_it->second.mount_path,
302 mount_points_it->second.mount_type,
303 mount_points_it->second.mount_condition));
[email protected]4ae73292011-11-15 05:20:18304 std::string path(mount_points_it->second.source_path);
305 mount_points_.erase(mount_points_it);
306 DiskMap::iterator iter = disks_.find(path);
307 if (iter == disks_.end()) {
308 // disk might have been removed by now.
309 return;
310 }
311 Disk* disk = iter->second;
312 DCHECK(disk);
313 disk->clear_mount_path();
314 // Check if there is a formatting scheduled.
315 PathMap::iterator it = formatting_pending_.find(disk->device_path());
316 if (it != formatting_pending_.end()) {
[email protected]b307bceb2011-11-17 07:49:55317 // Copy the string before it gets erased.
318 const std::string file_path = it->second;
[email protected]4ae73292011-11-15 05:20:18319 formatting_pending_.erase(it);
320 FormatUnmountedDevice(file_path);
321 }
322 }
323
324 // Callback for FormatDevice.
325 void OnFormatDevice(const std::string& device_path, bool success) {
326 if (success) {
327 NotifyDeviceStatusUpdate(MOUNT_FORMATTING_STARTED, device_path);
328 } else {
329 NotifyDeviceStatusUpdate(MOUNT_FORMATTING_STARTED,
330 std::string("!") + device_path);
331 LOG(WARNING) << "Format request failed for device " << device_path;
332 }
333 }
334
335 // Callbcak for GetDeviceProperties.
336 void OnGetDeviceProperties(const DiskInfo& disk_info) {
337 // TODO(zelidrag): Find a better way to filter these out before we
338 // fetch the properties:
339 // Ignore disks coming from the device we booted the system from.
340 if (disk_info.on_boot_device())
341 return;
342
343 LOG(WARNING) << "Found disk " << disk_info.device_path();
344 // Delete previous disk info for this path:
345 bool is_new = true;
346 DiskMap::iterator iter = disks_.find(disk_info.device_path());
347 if (iter != disks_.end()) {
348 delete iter->second;
349 disks_.erase(iter);
350 is_new = false;
351 }
352 Disk* disk = new Disk(disk_info.device_path(),
353 disk_info.mount_path(),
354 disk_info.system_path(),
355 disk_info.file_path(),
356 disk_info.label(),
357 disk_info.drive_label(),
[email protected]202e9fee2012-09-13 20:21:29358 disk_info.vendor_id(),
359 disk_info.vendor_name(),
360 disk_info.product_id(),
361 disk_info.product_name(),
[email protected]9c5620d32012-07-31 01:00:38362 disk_info.uuid(),
[email protected]4ae73292011-11-15 05:20:18363 FindSystemPathPrefix(disk_info.system_path()),
364 disk_info.device_type(),
365 disk_info.total_size_in_bytes(),
366 disk_info.is_drive(),
367 disk_info.is_read_only(),
368 disk_info.has_media(),
369 disk_info.on_boot_device(),
370 disk_info.is_hidden());
371 disks_.insert(std::make_pair(disk_info.device_path(), disk));
372 NotifyDiskStatusUpdate(is_new ? MOUNT_DISK_ADDED : MOUNT_DISK_CHANGED,
373 disk);
374 }
375
376 // Callbcak for RequestMountInfo.
377 void OnRequestMountInfo(const std::vector<std::string>& devices) {
378 std::set<std::string> current_device_set;
379 if (!devices.empty()) {
380 // Initiate properties fetch for all removable disks,
381 for (size_t i = 0; i < devices.size(); i++) {
382 current_device_set.insert(devices[i]);
383 // Initiate disk property retrieval for each relevant device path.
384 cros_disks_client_->GetDeviceProperties(
385 devices[i],
386 base::Bind(&DiskMountManagerImpl::OnGetDeviceProperties,
387 weak_ptr_factory_.GetWeakPtr()),
[email protected]c6944272012-01-06 22:12:28388 base::Bind(&base::DoNothing));
[email protected]4ae73292011-11-15 05:20:18389 }
390 }
391 // Search and remove disks that are no longer present.
392 for (DiskMap::iterator iter = disks_.begin(); iter != disks_.end(); ) {
393 if (current_device_set.find(iter->first) == current_device_set.end()) {
394 Disk* disk = iter->second;
395 NotifyDiskStatusUpdate(MOUNT_DISK_REMOVED, disk);
396 delete iter->second;
397 disks_.erase(iter++);
398 } else {
399 ++iter;
400 }
401 }
402 }
403
404 // Callback to handle mount event signals.
[email protected]e24f8762011-12-20 00:10:04405 void OnMountEvent(MountEventType event, const std::string& device_path_arg) {
406 // Take a copy of the argument so we can modify it below.
407 std::string device_path = device_path_arg;
[email protected]4ae73292011-11-15 05:20:18408 DiskMountManagerEventType type = MOUNT_DEVICE_ADDED;
409 switch (event) {
410 case DISK_ADDED: {
411 cros_disks_client_->GetDeviceProperties(
412 device_path,
413 base::Bind(&DiskMountManagerImpl::OnGetDeviceProperties,
414 weak_ptr_factory_.GetWeakPtr()),
[email protected]c6944272012-01-06 22:12:28415 base::Bind(&base::DoNothing));
[email protected]4ae73292011-11-15 05:20:18416 return;
417 }
418 case DISK_REMOVED: {
419 // Search and remove disks that are no longer present.
420 DiskMountManager::DiskMap::iterator iter = disks_.find(device_path);
421 if (iter != disks_.end()) {
422 Disk* disk = iter->second;
423 NotifyDiskStatusUpdate(MOUNT_DISK_REMOVED, disk);
424 delete iter->second;
425 disks_.erase(iter);
426 }
427 return;
428 }
429 case DEVICE_ADDED: {
430 type = MOUNT_DEVICE_ADDED;
431 system_path_prefixes_.insert(device_path);
432 break;
433 }
434 case DEVICE_REMOVED: {
435 type = MOUNT_DEVICE_REMOVED;
436 system_path_prefixes_.erase(device_path);
437 break;
438 }
439 case DEVICE_SCANNED: {
440 type = MOUNT_DEVICE_SCANNED;
441 break;
442 }
443 case FORMATTING_FINISHED: {
444 // FORMATTING_FINISHED actually returns file path instead of device
445 // path.
446 device_path = FilePathToDevicePath(device_path);
447 if (device_path.empty()) {
448 LOG(ERROR) << "Error while handling disks metadata. Cannot find "
449 << "device that is being formatted.";
450 return;
451 }
452 type = MOUNT_FORMATTING_FINISHED;
453 break;
454 }
455 default: {
456 LOG(ERROR) << "Unknown event: " << event;
457 return;
458 }
459 }
460 NotifyDeviceStatusUpdate(type, device_path);
461 }
462
463 // Notifies all observers about disk status update.
464 void NotifyDiskStatusUpdate(DiskMountManagerEventType event,
465 const Disk* disk) {
[email protected]4ae73292011-11-15 05:20:18466 FOR_EACH_OBSERVER(Observer, observers_, DiskChanged(event, disk));
467 }
468
469 // Notifies all observers about device status update.
470 void NotifyDeviceStatusUpdate(DiskMountManagerEventType event,
471 const std::string& device_path) {
[email protected]4ae73292011-11-15 05:20:18472 FOR_EACH_OBSERVER(Observer, observers_, DeviceChanged(event, device_path));
473 }
474
475 // Notifies all observers about mount completion.
476 void NotifyMountCompleted(MountEvent event_type,
477 MountError error_code,
478 const MountPointInfo& mount_info) {
[email protected]4ae73292011-11-15 05:20:18479 FOR_EACH_OBSERVER(Observer, observers_,
480 MountCompleted(event_type, error_code, mount_info));
481 }
482
483 // Converts file path to device path.
484 std::string FilePathToDevicePath(const std::string& file_path) {
485 // TODO(hashimoto): Refactor error handling code like here.
486 // Appending "!" is not the best way to indicate error. This kind of trick
487 // also makes it difficult to simplify the code paths. crosbug.com/22972
488 const int failed = StartsWithASCII(file_path, "!", true);
489 for (DiskMountManager::DiskMap::iterator it = disks_.begin();
490 it != disks_.end(); ++it) {
491 // Skip the leading '!' on the failure case.
492 if (it->second->file_path() == file_path.substr(failed)) {
493 if (failed)
494 return std::string("!") + it->second->device_path();
495 else
496 return it->second->device_path();
497 }
498 }
499 return "";
500 }
501
502 // Finds system path prefix from |system_path|.
503 const std::string& FindSystemPathPrefix(const std::string& system_path) {
504 if (system_path.empty())
505 return EmptyString();
506 for (SystemPathPrefixSet::const_iterator it = system_path_prefixes_.begin();
507 it != system_path_prefixes_.end();
508 ++it) {
509 const std::string& prefix = *it;
510 if (StartsWithASCII(system_path, prefix, true))
511 return prefix;
512 }
513 return EmptyString();
514 }
515
[email protected]4ae73292011-11-15 05:20:18516 // Mount event change observers.
517 ObserverList<Observer> observers_;
518
519 CrosDisksClient* cros_disks_client_;
520
521 // The list of disks found.
522 DiskMountManager::DiskMap disks_;
523
524 DiskMountManager::MountPointMap mount_points_;
525
526 typedef std::set<std::string> SystemPathPrefixSet;
527 SystemPathPrefixSet system_path_prefixes_;
528
529 // A map from device path (e.g. /sys/devices/pci0000:00/.../sdb/sdb1)) to file
530 // path (e.g. /dev/sdb).
531 // Devices in this map are supposed to be formatted, but are currently waiting
532 // to be unmounted. When device is in this map, the formatting process HAVEN'T
533 // started yet.
534 typedef std::map<std::string, std::string> PathMap;
535 PathMap formatting_pending_;
536
537 base::WeakPtrFactory<DiskMountManagerImpl> weak_ptr_factory_;
538
539 DISALLOW_COPY_AND_ASSIGN(DiskMountManagerImpl);
540};
541
[email protected]a66a23cb2012-06-19 23:15:33542} // namespace
[email protected]4ae73292011-11-15 05:20:18543
544DiskMountManager::Disk::Disk(const std::string& device_path,
545 const std::string& mount_path,
546 const std::string& system_path,
547 const std::string& file_path,
548 const std::string& device_label,
549 const std::string& drive_label,
[email protected]202e9fee2012-09-13 20:21:29550 const std::string& vendor_id,
551 const std::string& vendor_name,
552 const std::string& product_id,
553 const std::string& product_name,
[email protected]9c5620d32012-07-31 01:00:38554 const std::string& fs_uuid,
[email protected]4ae73292011-11-15 05:20:18555 const std::string& system_path_prefix,
556 DeviceType device_type,
557 uint64 total_size_in_bytes,
558 bool is_parent,
559 bool is_read_only,
560 bool has_media,
561 bool on_boot_device,
562 bool is_hidden)
563 : device_path_(device_path),
564 mount_path_(mount_path),
565 system_path_(system_path),
566 file_path_(file_path),
567 device_label_(device_label),
568 drive_label_(drive_label),
[email protected]202e9fee2012-09-13 20:21:29569 vendor_id_(vendor_id),
570 vendor_name_(vendor_name),
571 product_id_(product_id),
572 product_name_(product_name),
[email protected]9c5620d32012-07-31 01:00:38573 fs_uuid_(fs_uuid),
[email protected]4ae73292011-11-15 05:20:18574 system_path_prefix_(system_path_prefix),
575 device_type_(device_type),
576 total_size_in_bytes_(total_size_in_bytes),
577 is_parent_(is_parent),
578 is_read_only_(is_read_only),
579 has_media_(has_media),
580 on_boot_device_(on_boot_device),
581 is_hidden_(is_hidden) {
582}
583
584DiskMountManager::Disk::~Disk() {}
585
586// static
587std::string DiskMountManager::MountTypeToString(MountType type) {
588 switch (type) {
589 case MOUNT_TYPE_DEVICE:
590 return "device";
591 case MOUNT_TYPE_ARCHIVE:
592 return "file";
593 case MOUNT_TYPE_NETWORK_STORAGE:
594 return "network";
[email protected]9bb24222012-02-09 02:00:43595 case MOUNT_TYPE_GDATA:
596 return "gdata";
[email protected]4ae73292011-11-15 05:20:18597 case MOUNT_TYPE_INVALID:
598 return "invalid";
599 default:
600 NOTREACHED();
601 }
602 return "";
603}
604
605// static
606std::string DiskMountManager::MountConditionToString(MountCondition condition) {
607 switch (condition) {
608 case MOUNT_CONDITION_NONE:
609 return "";
610 case MOUNT_CONDITION_UNKNOWN_FILESYSTEM:
611 return "unknown_filesystem";
612 case MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM:
613 return "unsupported_filesystem";
614 default:
615 NOTREACHED();
616 }
617 return "";
618}
619
620// static
621MountType DiskMountManager::MountTypeFromString(const std::string& type_str) {
622 if (type_str == "device")
623 return MOUNT_TYPE_DEVICE;
624 else if (type_str == "network")
625 return MOUNT_TYPE_NETWORK_STORAGE;
626 else if (type_str == "file")
627 return MOUNT_TYPE_ARCHIVE;
[email protected]9bb24222012-02-09 02:00:43628 else if (type_str == "gdata")
629 return MOUNT_TYPE_GDATA;
[email protected]4ae73292011-11-15 05:20:18630 else
631 return MOUNT_TYPE_INVALID;
632}
633
634// static
[email protected]2321d282012-01-31 23:06:59635std::string DiskMountManager::DeviceTypeToString(DeviceType type) {
636 switch (type) {
637 case DEVICE_TYPE_USB:
638 return "usb";
639 case DEVICE_TYPE_SD:
640 return "sd";
641 case DEVICE_TYPE_OPTICAL_DISC:
642 return "optical";
643 case DEVICE_TYPE_MOBILE:
644 return "mobile";
645 default:
646 return "unknown";
647 }
648}
649
650// static
[email protected]4ae73292011-11-15 05:20:18651void DiskMountManager::Initialize() {
[email protected]b307bceb2011-11-17 07:49:55652 if (g_disk_mount_manager) {
653 LOG(WARNING) << "DiskMountManager was already initialized";
654 return;
655 }
[email protected]4ae73292011-11-15 05:20:18656 g_disk_mount_manager = new DiskMountManagerImpl();
[email protected]b307bceb2011-11-17 07:49:55657 VLOG(1) << "DiskMountManager initialized";
658}
659
660// static
661void DiskMountManager::InitializeForTesting(
662 DiskMountManager* disk_mount_manager) {
663 if (g_disk_mount_manager) {
664 LOG(WARNING) << "DiskMountManager was already initialized";
665 return;
666 }
667 g_disk_mount_manager = disk_mount_manager;
668 VLOG(1) << "DiskMountManager initialized";
[email protected]4ae73292011-11-15 05:20:18669}
670
671// static
672void DiskMountManager::Shutdown() {
[email protected]b307bceb2011-11-17 07:49:55673 if (!g_disk_mount_manager) {
674 LOG(WARNING) << "DiskMountManager::Shutdown() called with NULL manager";
675 return;
[email protected]4ae73292011-11-15 05:20:18676 }
[email protected]b307bceb2011-11-17 07:49:55677 delete g_disk_mount_manager;
678 g_disk_mount_manager = NULL;
679 VLOG(1) << "DiskMountManager Shutdown completed";
[email protected]4ae73292011-11-15 05:20:18680}
681
682// static
683DiskMountManager* DiskMountManager::GetInstance() {
684 return g_disk_mount_manager;
685}
686
687} // namespace disks
688} // namespace chromeos