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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 OnUnmountRemovableDevice(device_path, | 111 OnUnmountRemovableDevice(device_path, |
111 MOUNT_METHOD_ERROR_LOCAL, | 112 MOUNT_METHOD_ERROR_LOCAL, |
112 kLibraryNotLoaded); | 113 kLibraryNotLoaded); |
113 return; | 114 return; |
114 } | 115 } |
115 UnmountRemovableDevice(device_path, | 116 UnmountRemovableDevice(device_path, |
116 &MountLibraryImpl::UnmountRemovableDeviceCallback, | 117 &MountLibraryImpl::UnmountRemovableDeviceCallback, |
117 this); | 118 this); |
118 } | 119 } |
119 | 120 |
121 virtual void FormatUnmountedDevice(const char* device_path) OVERRIDE { | |
tbarzic
2011/07/25 20:43:04
Argument name should match name in MountLibrary.h
sidor
2011/07/25 21:40:07
Done.
| |
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
123 if (!CrosLibrary::Get()->EnsureLoaded()) { | |
124 OnFormatDevice(device_path, | |
125 false, | |
126 MOUNT_METHOD_ERROR_LOCAL, | |
127 kLibraryNotLoaded); | |
128 return; | |
129 } | |
tbarzic
2011/07/25 20:43:04
If you leave this exposed through MountLibrary, ch
sidor
2011/07/25 21:40:07
Done.
| |
130 FormatDevice(device_path, | |
131 "vfat", // currently format in vfat by default | |
132 &MountLibraryImpl::FormatDeviceCallback, | |
133 this); | |
134 } | |
135 | |
136 virtual void FormatMountedDevice(const char* device_mount_path) OVERRIDE { | |
137 DCHECK(device_mount_path); | |
tbarzic
2011/07/25 20:43:04
Would it be possible to pass device_path to this m
sidor
2011/07/25 21:40:07
Nope. UI, does not know the device path. At least
| |
138 std::string device_path, file_path; | |
139 for (MountLibrary::DiskMap::iterator it = disks_.begin(); | |
140 it != disks_.end(); ++it) { | |
141 if (it->second->mount_path().compare(device_mount_path) == 0) { | |
142 device_path = it->second->device_path(); | |
143 file_path = it->second->file_path(); | |
144 } | |
145 } | |
146 if (device_path.empty()) { | |
147 OnFormatDevice(device_path.c_str(), | |
148 false, | |
149 MOUNT_METHOD_ERROR_LOCAL, | |
150 "Device with this mount path not found."); | |
151 return; | |
152 } | |
153 if (to_be_formated_.find(device_path) != to_be_formated_.end()) { | |
tbarzic
2011/07/25 20:43:04
I agree with achuith that format_pending_ would be
sidor
2011/07/25 21:40:07
Done.
| |
154 OnFormatDevice(device_path.c_str(), | |
155 false, | |
156 MOUNT_METHOD_ERROR_LOCAL, | |
157 "Formatting is already pending."); | |
158 return; | |
159 } | |
160 // Formatting process continues, after unmounting. | |
161 to_be_formated_[device_path] = file_path; | |
162 UnmountPath(device_path.c_str()); | |
163 } | |
164 | |
120 virtual void UnmountDeviceRecursive(const char* device_path, | 165 virtual void UnmountDeviceRecursive(const char* device_path, |
121 UnmountDeviceRecursiveCallbackType callback, void* user_data) | 166 UnmountDeviceRecursiveCallbackType callback, void* user_data) |
122 OVERRIDE { | 167 OVERRIDE { |
123 bool success = true; | 168 bool success = true; |
124 const char* error_message = NULL; | 169 const char* error_message = NULL; |
125 std::vector<const char*> devices_to_unmount; | 170 std::vector<const char*> devices_to_unmount; |
126 | 171 |
127 if (!CrosLibrary::Get()->EnsureLoaded()) { | 172 if (!CrosLibrary::Get()->EnsureLoaded()) { |
128 success = false; | 173 success = false; |
129 error_message = kLibraryNotLoaded; | 174 error_message = kLibraryNotLoaded; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
200 const char* mount_path, | 245 const char* mount_path, |
201 MountMethodErrorType error, | 246 MountMethodErrorType error, |
202 const char* error_message) { | 247 const char* error_message) { |
203 DCHECK(object); | 248 DCHECK(object); |
204 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); | 249 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); |
205 self->OnUnmountRemovableDevice(device_path, | 250 self->OnUnmountRemovableDevice(device_path, |
206 error, | 251 error, |
207 error_message); | 252 error_message); |
208 } | 253 } |
209 | 254 |
255 // Callback for FormatRemovableDevice method. | |
256 static void FormatDeviceCallback(void* object, | |
257 const char* device_path, | |
258 bool success, | |
259 MountMethodErrorType error, | |
260 const char* error_message) { | |
261 DCHECK(object); | |
262 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); | |
263 self->OnFormatDevice(device_path, success, error, error_message); | |
264 } | |
265 | |
210 // Callback for UnmountDeviceRecursive. | 266 // Callback for UnmountDeviceRecursive. |
211 static void UnmountDeviceRecursiveCallback(void* object, | 267 static void UnmountDeviceRecursiveCallback(void* object, |
212 const char* device_path, | 268 const char* device_path, |
213 const char* mount_path, | 269 const char* mount_path, |
214 MountMethodErrorType error, | 270 MountMethodErrorType error, |
215 const char* error_message) { | 271 const char* error_message) { |
216 DCHECK(object); | 272 DCHECK(object); |
217 UnmountDeviceRecursiveCallbackData* cb_data = | 273 UnmountDeviceRecursiveCallbackData* cb_data = |
218 static_cast<UnmountDeviceRecursiveCallbackData*>(object); | 274 static_cast<UnmountDeviceRecursiveCallbackData*>(object); |
219 | 275 |
220 // Do standard processing for Unmount event. | 276 // Do standard processing for Unmount event. |
221 cb_data->object->OnUnmountRemovableDevice(device_path, | 277 cb_data->object->OnUnmountRemovableDevice(device_path, |
222 error, | 278 error, |
223 error_message); | 279 error_message); |
224 if (error == MOUNT_METHOD_ERROR_LOCAL) { | 280 if (error == MOUNT_METHOD_ERROR_LOCAL) { |
225 cb_data->success = false; | 281 cb_data->success = false; |
226 } else if (error == MOUNT_METHOD_ERROR_NONE) { | 282 } else if (error == MOUNT_METHOD_ERROR_NONE) { |
227 LOG(WARNING) << device_path << " unmounted."; | 283 LOG(WARNING) << device_path << " unmounted."; |
228 } | 284 } |
229 | 285 |
230 // This is safe as long as all callbacks are called on the same thread as | 286 // This is safe as long as all callbacks are called on the same thread as |
231 // UnmountDeviceRecursive. | 287 // UnmountDeviceRecursive. |
232 cb_data->pending_callbacks_count--; | 288 cb_data->pending_callbacks_count--; |
233 | 289 |
234 if (cb_data->pending_callbacks_count == 0) { | 290 if (cb_data->pending_callbacks_count == 0) { |
235 cb_data->callback(cb_data->user_data, cb_data->success); | 291 cb_data->callback(cb_data->user_data, cb_data->success); |
236 delete cb_data; | 292 delete cb_data; |
237 } | 293 } |
238 } | 294 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
307 std::string path(device_path); | 363 std::string path(device_path); |
308 DiskMap::iterator iter = disks_.find(path); | 364 DiskMap::iterator iter = disks_.find(path); |
309 if (iter == disks_.end()) { | 365 if (iter == disks_.end()) { |
310 // disk might have been removed by now? | 366 // disk might have been removed by now? |
311 return; | 367 return; |
312 } | 368 } |
313 Disk* disk = iter->second; | 369 Disk* disk = iter->second; |
314 DCHECK(disk); | 370 DCHECK(disk); |
315 disk->clear_mount_path(); | 371 disk->clear_mount_path(); |
316 FireDiskStatusUpdate(MOUNT_DISK_UNMOUNTED, disk); | 372 FireDiskStatusUpdate(MOUNT_DISK_UNMOUNTED, disk); |
373 // Check if there is a formatting scheduled | |
374 PathMap::iterator it = to_be_formated_.find(device_path); | |
375 if (it != to_be_formated_.end()) { | |
376 const std::string file_path = it->second; | |
377 to_be_formated_.erase(it); | |
378 FormatUnmountedDevice(file_path.c_str()); | |
379 } | |
317 } else { | 380 } else { |
318 LOG(WARNING) << "Unmount request failed for device " | 381 LOG(WARNING) << "Unmount request failed for device " |
319 << device_path << ", with error: " | 382 << device_path << ", with error: " |
320 << (error_message ? error_message : "Unknown"); | 383 << (error_message ? error_message : "Unknown"); |
321 } | 384 } |
322 } | 385 } |
323 | 386 |
387 void OnFormatDevice(const char* device_path, | |
388 bool success, | |
389 MountMethodErrorType error, | |
390 const char* error_message) { | |
391 DCHECK(device_path); | |
392 | |
393 if (error == MOUNT_METHOD_ERROR_NONE && device_path && success) { | |
394 FireDeviceStatusUpdate(MOUNT_FORMATTING_STARTED, device_path); | |
395 } else { | |
396 FireDeviceStatusUpdate(MOUNT_FORMATTING_STARTED, | |
tbarzic
2011/07/25 20:43:04
Have you considered adding MOUNT_FORMATTING_FAILED
sidor
2011/07/25 21:40:07
Yes, I already talk about this with BenChan. There
| |
397 std::string("!") + device_path); | |
398 LOG(WARNING) << "Format request failed for device " | |
399 << device_path << ", with error: " | |
400 << (error_message ? error_message : "Unknown"); | |
401 } | |
402 } | |
403 | |
404 | |
324 void OnGetDiskProperties(const char* device_path, | 405 void OnGetDiskProperties(const char* device_path, |
325 const DiskInfo* disk1, | 406 const DiskInfo* disk1, |
326 MountMethodErrorType error, | 407 MountMethodErrorType error, |
327 const char* error_message) { | 408 const char* error_message) { |
328 DCHECK(device_path); | 409 DCHECK(device_path); |
329 if (error == MOUNT_METHOD_ERROR_NONE && device_path) { | 410 if (error == MOUNT_METHOD_ERROR_NONE && device_path) { |
330 // TODO(zelidrag): Find a better way to filter these out before we | 411 // TODO(zelidrag): Find a better way to filter these out before we |
331 // fetch the properties: | 412 // fetch the properties: |
332 // Ignore disks coming from the device we booted the system from. | 413 // Ignore disks coming from the device we booted the system from. |
333 | 414 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
469 break; | 550 break; |
470 } | 551 } |
471 case DEVICE_REMOVED: { | 552 case DEVICE_REMOVED: { |
472 type = MOUNT_DEVICE_REMOVED; | 553 type = MOUNT_DEVICE_REMOVED; |
473 break; | 554 break; |
474 } | 555 } |
475 case DEVICE_SCANNED: { | 556 case DEVICE_SCANNED: { |
476 type = MOUNT_DEVICE_SCANNED; | 557 type = MOUNT_DEVICE_SCANNED; |
477 break; | 558 break; |
478 } | 559 } |
560 case FORMATTING_FINISHED: { | |
561 type = MOUNT_FORMATTING_FINISHED; | |
562 break; | |
563 } | |
479 } | 564 } |
480 FireDeviceStatusUpdate(type, std::string(device_path)); | 565 FireDeviceStatusUpdate(type, std::string(device_path)); |
481 } | 566 } |
482 | 567 |
483 void Init() { | 568 void Init() { |
484 // Getting the monitor status so that the daemon starts up. | 569 // Getting the monitor status so that the daemon starts up. |
485 mount_status_connection_ = MonitorMountEvents( | 570 mount_status_connection_ = MonitorMountEvents( |
486 &MonitorMountEventsHandler, this); | 571 &MonitorMountEventsHandler, this); |
487 } | 572 } |
488 | 573 |
(...skipping 16 matching lines...) Expand all Loading... | |
505 // Mount event change observers. | 590 // Mount event change observers. |
506 ObserverList<Observer> observers_; | 591 ObserverList<Observer> observers_; |
507 | 592 |
508 // A reference to the mount api, to allow callbacks when the mount | 593 // A reference to the mount api, to allow callbacks when the mount |
509 // status changes. | 594 // status changes. |
510 MountEventConnection mount_status_connection_; | 595 MountEventConnection mount_status_connection_; |
511 | 596 |
512 // The list of disks found. | 597 // The list of disks found. |
513 MountLibrary::DiskMap disks_; | 598 MountLibrary::DiskMap disks_; |
514 | 599 |
600 // Set of devices that are supposed to be formated, but are currently waiting | |
601 // to be unmounted. | |
602 PathMap to_be_formated_; //after unmounting | |
603 | |
515 DISALLOW_COPY_AND_ASSIGN(MountLibraryImpl); | 604 DISALLOW_COPY_AND_ASSIGN(MountLibraryImpl); |
516 }; | 605 }; |
517 | 606 |
518 class MountLibraryStubImpl : public MountLibrary { | 607 class MountLibraryStubImpl : public MountLibrary { |
519 public: | 608 public: |
520 MountLibraryStubImpl() {} | 609 MountLibraryStubImpl() {} |
521 virtual ~MountLibraryStubImpl() {} | 610 virtual ~MountLibraryStubImpl() {} |
522 | 611 |
523 // MountLibrary overrides. | 612 // MountLibrary overrides. |
524 virtual void AddObserver(Observer* observer) OVERRIDE {} | 613 virtual void AddObserver(Observer* observer) OVERRIDE {} |
525 virtual void RemoveObserver(Observer* observer) OVERRIDE {} | 614 virtual void RemoveObserver(Observer* observer) OVERRIDE {} |
526 virtual const DiskMap& disks() const OVERRIDE { return disks_; } | 615 virtual const DiskMap& disks() const OVERRIDE { return disks_; } |
527 virtual void RequestMountInfoRefresh() OVERRIDE {} | 616 virtual void RequestMountInfoRefresh() OVERRIDE {} |
528 virtual void MountPath(const char* device_path) OVERRIDE {} | 617 virtual void MountPath(const char* device_path) OVERRIDE {} |
529 virtual void UnmountPath(const char* device_path) OVERRIDE {} | 618 virtual void UnmountPath(const char* device_path) OVERRIDE {} |
619 virtual void FormatUnmountedDevice(const char* device_path) OVERRIDE {} | |
620 virtual void FormatMountedDevice(const char* device_mount_path) OVERRIDE {} | |
530 virtual void UnmountDeviceRecursive(const char* device_path, | 621 virtual void UnmountDeviceRecursive(const char* device_path, |
531 UnmountDeviceRecursiveCallbackType callback, void* user_data) | 622 UnmountDeviceRecursiveCallbackType callback, void* user_data) |
532 OVERRIDE {} | 623 OVERRIDE {} |
533 | 624 |
534 private: | 625 private: |
535 // The list of disks found. | 626 // The list of disks found. |
536 DiskMap disks_; | 627 DiskMap disks_; |
537 | 628 |
538 DISALLOW_COPY_AND_ASSIGN(MountLibraryStubImpl); | 629 DISALLOW_COPY_AND_ASSIGN(MountLibraryStubImpl); |
539 }; | 630 }; |
540 | 631 |
541 // static | 632 // static |
542 MountLibrary* MountLibrary::GetImpl(bool stub) { | 633 MountLibrary* MountLibrary::GetImpl(bool stub) { |
543 if (stub) | 634 if (stub) |
544 return new MountLibraryStubImpl(); | 635 return new MountLibraryStubImpl(); |
545 else | 636 else |
546 return new MountLibraryImpl(); | 637 return new MountLibraryImpl(); |
547 } | 638 } |
548 | 639 |
549 } // namespace chromeos | 640 } // namespace chromeos |
550 | 641 |
551 // Allows InvokeLater without adding refcounting. This class is a Singleton and | 642 // Allows InvokeLater without adding refcounting. This class is a Singleton and |
552 // won't be deleted until it's last InvokeLater is run. | 643 // won't be deleted until it's last InvokeLater is run. |
553 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::MountLibraryImpl); | 644 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::MountLibraryImpl); |
554 | 645 |
OLD | NEW |