OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/cros/mount_library.h" | 5 #include "chrome/browser/chromeos/cros/mount_library.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <vector> | |
8 | 9 |
9 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
11 #include "chrome/browser/chromeos/cros/cros_library.h" | 12 #include "chrome/browser/chromeos/cros/cros_library.h" |
12 #include "content/browser/browser_thread.h" | 13 #include "content/browser/browser_thread.h" |
13 | 14 |
14 const char* kLibraryNotLoaded = "Cros Library not loaded"; | 15 const char* kLibraryNotLoaded = "Cros Library not loaded"; |
15 const char* kDeviceNotFound = "Device could not be found"; | 16 const char* kDeviceNotFound = "Device could not be found"; |
16 | 17 |
17 namespace chromeos { | 18 namespace chromeos { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 OnUnmountPath(mount_path, | 137 OnUnmountPath(mount_path, |
137 MOUNT_METHOD_ERROR_LOCAL, | 138 MOUNT_METHOD_ERROR_LOCAL, |
138 kLibraryNotLoaded); | 139 kLibraryNotLoaded); |
139 return; | 140 return; |
140 } | 141 } |
141 | 142 |
142 UnmountMountPoint(mount_path, &MountLibraryImpl::UnmountMountPointCallback, | 143 UnmountMountPoint(mount_path, &MountLibraryImpl::UnmountMountPointCallback, |
143 this); | 144 this); |
144 } | 145 } |
145 | 146 |
147 virtual void FormatUnmountedDevice(const char* file_path) OVERRIDE { | |
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
149 if (!CrosLibrary::Get()->EnsureLoaded()) { | |
150 OnFormatDevice(file_path, | |
151 false, | |
152 MOUNT_METHOD_ERROR_LOCAL, | |
153 kLibraryNotLoaded); | |
154 return; | |
155 } | |
156 for (MountLibrary::DiskMap::iterator it = disks_.begin(); | |
157 it != disks_.end(); ++it) { | |
158 if (it->second->file_path().compare(file_path) == 0 && | |
159 !it->second->mount_path().empty()) { | |
160 OnFormatDevice(file_path, | |
161 false, | |
162 MOUNT_METHOD_ERROR_LOCAL, | |
163 "Device is still mounted."); | |
164 return; | |
165 } | |
166 } | |
167 FormatDevice(file_path, | |
168 "vfat", // currently format in vfat by default | |
169 &MountLibraryImpl::FormatDeviceCallback, | |
170 this); | |
171 } | |
172 | |
173 virtual void FormatMountedDevice(const char* mount_path) OVERRIDE { | |
174 DCHECK(mount_path); | |
175 Disk* disk = NULL; | |
176 for (MountLibrary::DiskMap::iterator it = disks_.begin(); | |
177 it != disks_.end(); ++it) { | |
178 if (it->second->mount_path().compare(mount_path) == 0) { | |
179 disk = it->second; | |
180 break; | |
181 } | |
182 } | |
183 | |
184 if (!disk) { | |
185 OnFormatDevice(disk->device_path().c_str(), | |
186 false, | |
187 MOUNT_METHOD_ERROR_LOCAL, | |
188 "Device with this mount path not found."); | |
sidor.dev
2011/08/11 22:46:53
One more space here?
| |
189 return; | |
190 } | |
191 if (formatting_pending_.find(disk->device_path()) != | |
192 formatting_pending_.end()) { | |
193 OnFormatDevice(disk->device_path, | |
194 false, | |
195 MOUNT_METHOD_ERROR_LOCAL, | |
196 "Formatting is already pending."); | |
197 return; | |
198 } | |
199 // Formatting process continues, after unmounting. | |
200 formatting_pending_[disk->device_path()] = disk->file_path(); | |
201 UnmountPath(disk->mount_path().c_str()); | |
202 } | |
203 | |
146 virtual void UnmountDeviceRecursive(const char* device_path, | 204 virtual void UnmountDeviceRecursive(const char* device_path, |
147 UnmountDeviceRecursiveCallbackType callback, void* user_data) | 205 UnmountDeviceRecursiveCallbackType callback, void* user_data) |
148 OVERRIDE { | 206 OVERRIDE { |
149 bool success = true; | 207 bool success = true; |
150 const char* error_message = NULL; | 208 const char* error_message = NULL; |
151 std::vector<const char*> devices_to_unmount; | 209 std::vector<const char*> devices_to_unmount; |
152 | 210 |
153 if (!CrosLibrary::Get()->EnsureLoaded()) { | 211 if (!CrosLibrary::Get()->EnsureLoaded()) { |
154 success = false; | 212 success = false; |
155 error_message = kLibraryNotLoaded; | 213 error_message = kLibraryNotLoaded; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 // Callback for UnmountRemovableDevice method. | 288 // Callback for UnmountRemovableDevice method. |
231 static void UnmountMountPointCallback(void* object, | 289 static void UnmountMountPointCallback(void* object, |
232 const char* mount_path, | 290 const char* mount_path, |
233 MountMethodErrorType error, | 291 MountMethodErrorType error, |
234 const char* error_message) { | 292 const char* error_message) { |
235 DCHECK(object); | 293 DCHECK(object); |
236 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); | 294 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); |
237 self->OnUnmountPath(mount_path, error, error_message); | 295 self->OnUnmountPath(mount_path, error, error_message); |
238 } | 296 } |
239 | 297 |
298 // Callback for FormatRemovableDevice method. | |
299 static void FormatDeviceCallback(void* object, | |
300 const char* device_path, | |
301 bool success, | |
302 MountMethodErrorType error, | |
303 const char* error_message) { | |
304 DCHECK(object); | |
305 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); | |
306 self->OnFormatDevice(device_path, success, error, error_message); | |
307 } | |
308 | |
240 // Callback for UnmountDeviceRecursive. | 309 // Callback for UnmountDeviceRecursive. |
241 static void UnmountDeviceRecursiveCallback(void* object, | 310 static void UnmountDeviceRecursiveCallback(void* object, |
242 const char* mount_path, | 311 const char* mount_path, |
243 MountMethodErrorType error, | 312 MountMethodErrorType error, |
244 const char* error_message) { | 313 const char* error_message) { |
245 DCHECK(object); | 314 DCHECK(object); |
246 UnmountDeviceRecursiveCallbackData* cb_data = | 315 UnmountDeviceRecursiveCallbackData* cb_data = |
247 static_cast<UnmountDeviceRecursiveCallbackData*>(object); | 316 static_cast<UnmountDeviceRecursiveCallbackData*>(object); |
248 | 317 |
249 // Do standard processing for Unmount event. | 318 // Do standard processing for Unmount event. |
250 cb_data->object->OnUnmountPath(mount_path, | 319 cb_data->object->OnUnmountPath(mount_path, |
251 error, | 320 error, |
252 error_message); | 321 error_message); |
253 if (error == MOUNT_METHOD_ERROR_LOCAL) { | 322 if (error == MOUNT_METHOD_ERROR_LOCAL) { |
254 cb_data->success = false; | 323 cb_data->success = false; |
255 } else if (error == MOUNT_METHOD_ERROR_NONE) { | 324 } else if (error == MOUNT_METHOD_ERROR_NONE) { |
256 LOG(INFO) << mount_path << " unmounted."; | 325 LOG(INFO) << mount_path << " unmounted."; |
257 } | 326 } |
258 | 327 |
259 // This is safe as long as all callbacks are called on the same thread as | 328 // This is safe as long as all callbacks are called on the same thread as |
260 // UnmountDeviceRecursive. | 329 // UnmountDeviceRecursive. |
261 cb_data->pending_callbacks_count--; | 330 cb_data->pending_callbacks_count--; |
262 | 331 |
263 if (cb_data->pending_callbacks_count == 0) { | 332 if (cb_data->pending_callbacks_count == 0) { |
264 cb_data->callback(cb_data->user_data, cb_data->success); | 333 cb_data->callback(cb_data->user_data, cb_data->success); |
265 delete cb_data; | 334 delete cb_data; |
266 } | 335 } |
267 } | 336 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 return; | 413 return; |
345 // TODO(tbarzic): Add separate, PathUnmounted event to Observer. | 414 // TODO(tbarzic): Add separate, PathUnmounted event to Observer. |
346 FireMountCompleted( | 415 FireMountCompleted( |
347 UNMOUNTING, | 416 UNMOUNTING, |
348 MOUNT_ERROR_NONE, | 417 MOUNT_ERROR_NONE, |
349 MountPointInfo(mount_points_it->second.source_path.c_str(), | 418 MountPointInfo(mount_points_it->second.source_path.c_str(), |
350 mount_points_it->second.mount_path.c_str(), | 419 mount_points_it->second.mount_path.c_str(), |
351 mount_points_it->second.mount_type)); | 420 mount_points_it->second.mount_type)); |
352 std::string path(mount_points_it->second.source_path); | 421 std::string path(mount_points_it->second.source_path); |
353 mount_points_.erase(mount_points_it); | 422 mount_points_.erase(mount_points_it); |
354 | |
355 DiskMap::iterator iter = disks_.find(path); | 423 DiskMap::iterator iter = disks_.find(path); |
356 if (iter == disks_.end()) { | 424 if (iter == disks_.end()) { |
357 // disk might have been removed by now? | 425 // disk might have been removed by now. |
358 return; | 426 return; |
359 } | 427 } |
360 Disk* disk = iter->second; | 428 Disk* disk = iter->second; |
361 DCHECK(disk); | 429 DCHECK(disk); |
362 disk->clear_mount_path(); | 430 disk->clear_mount_path(); |
363 FireDiskStatusUpdate(MOUNT_DISK_UNMOUNTED, disk); | 431 // Check if there is a formatting scheduled |
432 PathMap::iterator it = formatting_pending_.find(disk->device_path()); | |
433 if (it != formatting_pending_.end()) { | |
434 const std::string file_path = it->second; | |
435 formatting_pending_.erase(it); | |
436 FormatUnmountedDevice(file_path.c_str()); | |
364 } else { | 437 } else { |
365 LOG(WARNING) << "Unmount request failed for device " | 438 LOG(WARNING) << "Unmount request failed for device " |
366 << mount_path << ", with error: " | 439 << mount_path << ", with error: " |
367 << (error_message ? error_message : "Unknown"); | 440 << (error_message ? error_message : "Unknown"); |
368 } | 441 } |
369 } | 442 } |
370 | 443 |
444 void OnFormatDevice(const char* device_path, | |
445 bool success, | |
446 MountMethodErrorType error, | |
447 const char* error_message) { | |
448 DCHECK(device_path); | |
449 if (error == MOUNT_METHOD_ERROR_NONE && device_path && success) { | |
450 FireDeviceStatusUpdate(MOUNT_FORMATTING_STARTED, device_path); | |
451 } else { | |
452 FireDeviceStatusUpdate(MOUNT_FORMATTING_STARTED, | |
453 std::string("!") + device_path); | |
454 LOG(WARNING) << "Format request failed for device " | |
455 << device_path << ", with error: " | |
456 << (error_message ? error_message : "Unknown"); | |
457 } | |
458 } | |
459 | |
460 | |
371 void OnGetDiskProperties(const char* device_path, | 461 void OnGetDiskProperties(const char* device_path, |
372 const DiskInfo* disk1, | 462 const DiskInfo* disk1, |
373 MountMethodErrorType error, | 463 MountMethodErrorType error, |
374 const char* error_message) { | 464 const char* error_message) { |
375 DCHECK(device_path); | 465 DCHECK(device_path); |
376 if (error == MOUNT_METHOD_ERROR_NONE && device_path) { | 466 if (error == MOUNT_METHOD_ERROR_NONE && device_path) { |
377 // TODO(zelidrag): Find a better way to filter these out before we | 467 // TODO(zelidrag): Find a better way to filter these out before we |
378 // fetch the properties: | 468 // fetch the properties: |
379 // Ignore disks coming from the device we booted the system from. | 469 // Ignore disks coming from the device we booted the system from. |
380 | 470 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
516 break; | 606 break; |
517 } | 607 } |
518 case DEVICE_REMOVED: { | 608 case DEVICE_REMOVED: { |
519 type = MOUNT_DEVICE_REMOVED; | 609 type = MOUNT_DEVICE_REMOVED; |
520 break; | 610 break; |
521 } | 611 } |
522 case DEVICE_SCANNED: { | 612 case DEVICE_SCANNED: { |
523 type = MOUNT_DEVICE_SCANNED; | 613 type = MOUNT_DEVICE_SCANNED; |
524 break; | 614 break; |
525 } | 615 } |
616 case FORMATTING_FINISHED: { | |
617 type = MOUNT_FORMATTING_FINISHED; | |
618 break; | |
619 } | |
526 default: { | 620 default: { |
527 return; | 621 return; |
528 } | 622 } |
529 } | 623 } |
530 FireDeviceStatusUpdate(type, std::string(device_path)); | 624 FireDeviceStatusUpdate(type, std::string(device_path)); |
531 } | 625 } |
532 | 626 |
533 void Init() { | 627 void Init() { |
534 // Getting the monitor status so that the daemon starts up. | 628 // Getting the monitor status so that the daemon starts up. |
535 mount_status_connection_ = MonitorAllMountEvents( | 629 mount_status_connection_ = MonitorAllMountEvents( |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 ObserverList<Observer> observers_; | 661 ObserverList<Observer> observers_; |
568 | 662 |
569 // A reference to the mount api, to allow callbacks when the mount | 663 // A reference to the mount api, to allow callbacks when the mount |
570 // status changes. | 664 // status changes. |
571 MountEventConnection mount_status_connection_; | 665 MountEventConnection mount_status_connection_; |
572 | 666 |
573 // The list of disks found. | 667 // The list of disks found. |
574 MountLibrary::DiskMap disks_; | 668 MountLibrary::DiskMap disks_; |
575 | 669 |
576 MountLibrary::MountPointMap mount_points_; | 670 MountLibrary::MountPointMap mount_points_; |
671 // Set of devices that are supposed to be formated, but are currently waiting | |
672 // to be unmounted. When device is in this map, the formatting process HAVEN'T | |
673 // started yet. | |
674 PathMap formatting_pending_; | |
577 | 675 |
578 DISALLOW_COPY_AND_ASSIGN(MountLibraryImpl); | 676 DISALLOW_COPY_AND_ASSIGN(MountLibraryImpl); |
579 }; | 677 }; |
580 | 678 |
581 class MountLibraryStubImpl : public MountLibrary { | 679 class MountLibraryStubImpl : public MountLibrary { |
582 public: | 680 public: |
583 MountLibraryStubImpl() {} | 681 MountLibraryStubImpl() {} |
584 virtual ~MountLibraryStubImpl() {} | 682 virtual ~MountLibraryStubImpl() {} |
585 | 683 |
586 // MountLibrary overrides. | 684 // MountLibrary overrides. |
587 virtual void AddObserver(Observer* observer) OVERRIDE {} | 685 virtual void AddObserver(Observer* observer) OVERRIDE {} |
588 virtual void RemoveObserver(Observer* observer) OVERRIDE {} | 686 virtual void RemoveObserver(Observer* observer) OVERRIDE {} |
589 virtual const DiskMap& disks() const OVERRIDE { return disks_; } | 687 virtual const DiskMap& disks() const OVERRIDE { return disks_; } |
590 virtual const MountPointMap& mount_points() const OVERRIDE { | 688 virtual const MountPointMap& mount_points() const OVERRIDE { |
591 return mount_points_; | 689 return mount_points_; |
592 } | 690 } |
593 virtual void RequestMountInfoRefresh() OVERRIDE {} | 691 virtual void RequestMountInfoRefresh() OVERRIDE {} |
594 virtual void MountPath(const char* source_path, MountType type, | 692 virtual void MountPath(const char* source_path, MountType type, |
595 const MountPathOptions& options) OVERRIDE {} | 693 const MountPathOptions& options) OVERRIDE {} |
596 virtual void UnmountPath(const char* mount_path) OVERRIDE {} | 694 virtual void UnmountPath(const char* mount_path) OVERRIDE {} |
695 virtual void FormatUnmountedDevice(const char* device_path) OVERRIDE {} | |
696 virtual void FormatMountedDevice(const char* mount_path) OVERRIDE {} | |
597 virtual void UnmountDeviceRecursive(const char* device_path, | 697 virtual void UnmountDeviceRecursive(const char* device_path, |
598 UnmountDeviceRecursiveCallbackType callback, void* user_data) | 698 UnmountDeviceRecursiveCallbackType callback, void* user_data) |
599 OVERRIDE {} | 699 OVERRIDE {} |
600 | 700 |
601 private: | 701 private: |
602 // The list of disks found. | 702 // The list of disks found. |
603 DiskMap disks_; | 703 DiskMap disks_; |
604 MountPointMap mount_points_; | 704 MountPointMap mount_points_; |
605 | 705 |
606 DISALLOW_COPY_AND_ASSIGN(MountLibraryStubImpl); | 706 DISALLOW_COPY_AND_ASSIGN(MountLibraryStubImpl); |
607 }; | 707 }; |
608 | 708 |
609 // static | 709 // static |
610 MountLibrary* MountLibrary::GetImpl(bool stub) { | 710 MountLibrary* MountLibrary::GetImpl(bool stub) { |
611 if (stub) | 711 if (stub) |
612 return new MountLibraryStubImpl(); | 712 return new MountLibraryStubImpl(); |
613 else | 713 else |
614 return new MountLibraryImpl(); | 714 return new MountLibraryImpl(); |
615 } | 715 } |
616 | 716 |
617 } // namespace chromeos | 717 } // namespace chromeos |
618 | 718 |
619 // Allows InvokeLater without adding refcounting. This class is a Singleton and | 719 // Allows InvokeLater without adding refcounting. This class is a Singleton and |
620 // won't be deleted until it's last InvokeLater is run. | 720 // won't be deleted until it's last InvokeLater is run. |
621 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::MountLibraryImpl); | 721 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::MountLibraryImpl); |
622 | 722 |
OLD | NEW |