| 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 | 8 |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 | 83 |
| 84 // MountLibrary overrides. | 84 // MountLibrary overrides. |
| 85 virtual void AddObserver(Observer* observer) OVERRIDE { | 85 virtual void AddObserver(Observer* observer) OVERRIDE { |
| 86 observers_.AddObserver(observer); | 86 observers_.AddObserver(observer); |
| 87 } | 87 } |
| 88 | 88 |
| 89 virtual void RemoveObserver(Observer* observer) OVERRIDE { | 89 virtual void RemoveObserver(Observer* observer) OVERRIDE { |
| 90 observers_.RemoveObserver(observer); | 90 observers_.RemoveObserver(observer); |
| 91 } | 91 } |
| 92 | 92 |
| 93 virtual void MountPath(const char* device_path) OVERRIDE { | 93 virtual void MountPath(const char* source_path, |
| 94 MountType type, |
| 95 const MountPathOptions& options) OVERRIDE { |
| 94 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 96 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 95 if (!CrosLibrary::Get()->EnsureLoaded()) { | 97 if (!CrosLibrary::Get()->EnsureLoaded()) { |
| 96 OnMountRemovableDevice(device_path, | 98 OnMountCompleted(LIBRARY_NOT_LOADED, |
| 97 NULL, | 99 source_path, |
| 98 MOUNT_METHOD_ERROR_LOCAL, | 100 type, |
| 99 kLibraryNotLoaded); | 101 NULL); |
| 100 return; | 102 return; |
| 101 } | 103 } |
| 102 MountRemovableDevice(device_path, | 104 MountSourcePath(source_path, type, options, &MountCompletedHandler, this); |
| 103 &MountLibraryImpl::MountRemovableDeviceCallback, | |
| 104 this); | |
| 105 } | 105 } |
| 106 | 106 |
| 107 virtual void UnmountPath(const char* device_path) OVERRIDE { | 107 virtual void UnmountPath(const char* path) OVERRIDE { |
| 108 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 108 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 109 if (!CrosLibrary::Get()->EnsureLoaded()) { | 109 if (!CrosLibrary::Get()->EnsureLoaded()) { |
| 110 OnUnmountRemovableDevice(device_path, | 110 OnUnmountRemovableDevice(path, |
| 111 MOUNT_METHOD_ERROR_LOCAL, | 111 MOUNT_METHOD_ERROR_LOCAL, |
| 112 kLibraryNotLoaded); | 112 kLibraryNotLoaded); |
| 113 return; | 113 return; |
| 114 } | 114 } |
| 115 UnmountRemovableDevice(device_path, | 115 UnmountMountPoint(path, &MountLibraryImpl::UnmountMountPointCallback, this); |
| 116 &MountLibraryImpl::UnmountRemovableDeviceCallback, | |
| 117 this); | |
| 118 } | 116 } |
| 119 | 117 |
| 120 virtual void UnmountDeviceRecursive(const char* device_path, | 118 virtual void UnmountDeviceRecursive(const char* device_path, |
| 121 UnmountDeviceRecursiveCallbackType callback, void* user_data) | 119 UnmountDeviceRecursiveCallbackType callback, void* user_data) |
| 122 OVERRIDE { | 120 OVERRIDE { |
| 123 bool success = true; | 121 bool success = true; |
| 124 const char* error_message = NULL; | 122 const char* error_message = NULL; |
| 125 std::vector<const char*> devices_to_unmount; | 123 std::vector<const char*> devices_to_unmount; |
| 126 | 124 |
| 127 if (!CrosLibrary::Get()->EnsureLoaded()) { | 125 if (!CrosLibrary::Get()->EnsureLoaded()) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 144 } | 142 } |
| 145 } | 143 } |
| 146 | 144 |
| 147 if (success) { | 145 if (success) { |
| 148 // We will send the same callback data object to all Unmount calls and use | 146 // We will send the same callback data object to all Unmount calls and use |
| 149 // it to syncronize callbacks. | 147 // it to syncronize callbacks. |
| 150 UnmountDeviceRecursiveCallbackData* | 148 UnmountDeviceRecursiveCallbackData* |
| 151 cb_data = new UnmountDeviceRecursiveCallbackData(this, user_data, | 149 cb_data = new UnmountDeviceRecursiveCallbackData(this, user_data, |
| 152 callback, devices_to_unmount.size()); | 150 callback, devices_to_unmount.size()); |
| 153 for (std::vector<const char*>::iterator it = devices_to_unmount.begin(); | 151 for (std::vector<const char*>::iterator it = devices_to_unmount.begin(); |
| 154 it != devices_to_unmount.end(); | 152 it != devices_to_unmount.end(); |
| 155 ++it) { | 153 ++it) { |
| 156 UnmountRemovableDevice(*it, | 154 UnmountRemovableDevice( |
| 155 *it, |
| 157 &MountLibraryImpl::UnmountDeviceRecursiveCallback, | 156 &MountLibraryImpl::UnmountDeviceRecursiveCallback, |
| 158 cb_data); | 157 cb_data); |
| 159 } | 158 } |
| 160 } else { | 159 } else { |
| 161 LOG(WARNING) << "Unmount recursive request failed for device " | 160 LOG(WARNING) << "Unmount recursive request failed for device " |
| 162 << device_path << ", with error: " << error_message; | 161 << device_path << ", with error: " << error_message; |
| 163 callback(user_data, false); | 162 callback(user_data, false); |
| 164 } | 163 } |
| 165 } | 164 } |
| 166 | 165 |
| 167 virtual void RequestMountInfoRefresh() OVERRIDE { | 166 virtual void RequestMountInfoRefresh() OVERRIDE { |
| 168 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 167 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 169 if (!CrosLibrary::Get()->EnsureLoaded()) { | 168 if (!CrosLibrary::Get()->EnsureLoaded()) { |
| 170 OnRequestMountInfo(NULL, | 169 OnRequestMountInfo(NULL, |
| 171 0, | 170 0, |
| 172 MOUNT_METHOD_ERROR_LOCAL, | 171 MOUNT_METHOD_ERROR_LOCAL, |
| 173 kLibraryNotLoaded); | 172 kLibraryNotLoaded); |
| 174 return; | 173 return; |
| 175 } | 174 } |
| 176 RequestMountInfo(&MountLibraryImpl::RequestMountInfoCallback, | 175 RequestMountInfo(&MountLibraryImpl::RequestMountInfoCallback, |
| 177 this); | 176 this); |
| 178 } | 177 } |
| 179 | 178 |
| 180 const DiskMap& disks() const OVERRIDE { return disks_; } | 179 const DiskMap& disks() const OVERRIDE { return disks_; } |
| 181 | 180 |
| 182 private: | 181 private: |
| 183 // Callback for MountRemovableDevice method. | 182 // Callback for MountComplete signal and MountSourcePath method. |
| 184 static void MountRemovableDeviceCallback(void* object, | 183 static void MountCompletedHandler(void* object, |
| 185 const char* device_path, | 184 MountError error_code, |
| 186 const char* mount_path, | 185 const char* source_path, |
| 187 MountMethodErrorType error, | 186 MountType type, |
| 188 const char* error_message) { | 187 const char* mount_path) { |
| 188 LOG(WARNING) <<"MountCompleted" <<error_code<<source_path<<mount_path; |
| 189 DCHECK(object); | 189 DCHECK(object); |
| 190 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); | 190 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); |
| 191 self->OnMountRemovableDevice(device_path, | 191 self->OnMountCompleted(static_cast<MountError>(error_code), |
| 192 mount_path, | 192 source_path, |
| 193 error, | 193 static_cast<MountType>(type), |
| 194 error_message); | 194 mount_path); |
| 195 } | 195 } |
| 196 | 196 |
| 197 // Callback for UnmountRemovableDevice method. | 197 // Callback for UnmountRemovableDevice method. |
| 198 static void UnmountRemovableDeviceCallback(void* object, | 198 static void UnmountMountPointCallback(void* object, |
| 199 const char* device_path, | 199 const char* device_path, |
| 200 const char* mount_path, | 200 MountMethodErrorType error, |
| 201 MountMethodErrorType error, | 201 const char* error_message) { |
| 202 const char* error_message) { | |
| 203 DCHECK(object); | 202 DCHECK(object); |
| 204 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); | 203 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); |
| 205 self->OnUnmountRemovableDevice(device_path, | 204 self->OnUnmountRemovableDevice(device_path, |
| 206 error, | 205 error, |
| 207 error_message); | 206 error_message); |
| 208 } | 207 } |
| 209 | 208 |
| 210 // Callback for UnmountDeviceRecursive. | 209 // Callback for UnmountDeviceRecursive. |
| 211 static void UnmountDeviceRecursiveCallback(void* object, | 210 static void UnmountDeviceRecursiveCallback(void* object, |
| 212 const char* device_path, | 211 const char* device_path, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 // This method will receive events that are caused by drive status changes. | 267 // This method will receive events that are caused by drive status changes. |
| 269 static void MonitorMountEventsHandler(void* object, | 268 static void MonitorMountEventsHandler(void* object, |
| 270 MountEventType evt, | 269 MountEventType evt, |
| 271 const char* device_path) { | 270 const char* device_path) { |
| 272 DCHECK(object); | 271 DCHECK(object); |
| 273 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); | 272 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object); |
| 274 self->OnMountEvent(evt, device_path); | 273 self->OnMountEvent(evt, device_path); |
| 275 } | 274 } |
| 276 | 275 |
| 277 | 276 |
| 278 void OnMountRemovableDevice(const char* device_path, | 277 void OnMountCompleted(MountError error_code, |
| 279 const char* mount_path, | 278 const char* source_path, |
| 280 MountMethodErrorType error, | 279 MountType type, |
| 281 const char* error_message) { | 280 const char* mount_path) { |
| 282 DCHECK(device_path); | 281 DCHECK(source_path); |
| 283 | 282 |
| 284 if (error == MOUNT_METHOD_ERROR_NONE && device_path && mount_path) { | 283 LOG(WARNING) <<"MountCompleted fired" <<error_code<<source_path<<mount_path; |
| 285 std::string path(device_path); | 284 FireMountCompleted(error_code, source_path, type, mount_path); |
| 285 |
| 286 if (error_code == NO_ERROR) |
| 287 mount_points_.insert(mount_path); |
| 288 |
| 289 if (error_code == NO_ERROR && type == DEVICE && source_path && |
| 290 mount_path) { |
| 291 std::string path(source_path); |
| 286 DiskMap::iterator iter = disks_.find(path); | 292 DiskMap::iterator iter = disks_.find(path); |
| 287 if (iter == disks_.end()) { | 293 if (iter == disks_.end()) { |
| 288 // disk might have been removed by now? | 294 // disk might have been removed by now? |
| 289 return; | 295 return; |
| 290 } | 296 } |
| 291 Disk* disk = iter->second; | 297 Disk* disk = iter->second; |
| 292 DCHECK(disk); | 298 DCHECK(disk); |
| 293 disk->set_mount_path(mount_path); | 299 disk->set_mount_path(mount_path); |
| 294 FireDiskStatusUpdate(MOUNT_DISK_MOUNTED, disk); | 300 FireDiskStatusUpdate(MOUNT_DISK_MOUNTED, disk); |
| 295 } else { | |
| 296 LOG(WARNING) << "Mount request failed for device " | |
| 297 << device_path << ", with error: " | |
| 298 << (error_message ? error_message : "Unknown"); | |
| 299 } | 301 } |
| 300 } | 302 } |
| 301 | 303 |
| 302 void OnUnmountRemovableDevice(const char* device_path, | 304 void OnUnmountRemovableDevice(const char* device_path, |
| 303 MountMethodErrorType error, | 305 MountMethodErrorType error, |
| 304 const char* error_message) { | 306 const char* error_message) { |
| 305 DCHECK(device_path); | 307 DCHECK(device_path); |
| 306 if (error == MOUNT_METHOD_ERROR_NONE && device_path) { | 308 if (error == MOUNT_METHOD_ERROR_NONE && device_path) { |
| 307 std::string path(device_path); | 309 std::string path(device_path); |
| 308 DiskMap::iterator iter = disks_.find(path); | 310 DiskMap::iterator iter = disks_.find(path); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 case DEVICE_SCANNED: { | 477 case DEVICE_SCANNED: { |
| 476 type = MOUNT_DEVICE_SCANNED; | 478 type = MOUNT_DEVICE_SCANNED; |
| 477 break; | 479 break; |
| 478 } | 480 } |
| 479 } | 481 } |
| 480 FireDeviceStatusUpdate(type, std::string(device_path)); | 482 FireDeviceStatusUpdate(type, std::string(device_path)); |
| 481 } | 483 } |
| 482 | 484 |
| 483 void Init() { | 485 void Init() { |
| 484 // Getting the monitor status so that the daemon starts up. | 486 // Getting the monitor status so that the daemon starts up. |
| 485 mount_status_connection_ = MonitorMountEvents( | 487 mount_status_connection_ = MonitorAllMountEvents( |
| 486 &MonitorMountEventsHandler, this); | 488 &MonitorMountEventsHandler, &MountCompletedHandler, this); |
| 487 } | 489 } |
| 488 | 490 |
| 489 void FireDiskStatusUpdate(MountLibraryEventType evt, | 491 void FireDiskStatusUpdate(MountLibraryEventType evt, |
| 490 const Disk* disk) { | 492 const Disk* disk) { |
| 491 // Make sure we run on UI thread. | 493 // Make sure we run on UI thread. |
| 492 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 494 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 493 FOR_EACH_OBSERVER( | 495 FOR_EACH_OBSERVER( |
| 494 Observer, observers_, DiskChanged(evt, disk)); | 496 Observer, observers_, DiskChanged(evt, disk)); |
| 495 } | 497 } |
| 496 | 498 |
| 497 void FireDeviceStatusUpdate(MountLibraryEventType evt, | 499 void FireDeviceStatusUpdate(MountLibraryEventType evt, |
| 498 const std::string& device_path) { | 500 const std::string& device_path) { |
| 499 // Make sure we run on UI thread. | 501 // Make sure we run on UI thread. |
| 500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 502 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 501 FOR_EACH_OBSERVER( | 503 FOR_EACH_OBSERVER( |
| 502 Observer, observers_, DeviceChanged(evt, device_path)); | 504 Observer, observers_, DeviceChanged(evt, device_path)); |
| 503 } | 505 } |
| 504 | 506 |
| 507 void FireMountCompleted(MountError error_code, |
| 508 const char* source_path, |
| 509 MountType mount_type, |
| 510 const char* mount_path) { |
| 511 // Make sure we run on UI thread. |
| 512 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 513 FOR_EACH_OBSERVER( |
| 514 Observer, observers_, MountCompleted(error_code, |
| 515 source_path, |
| 516 mount_type, |
| 517 mount_path)); |
| 518 } |
| 519 |
| 505 // Mount event change observers. | 520 // Mount event change observers. |
| 506 ObserverList<Observer> observers_; | 521 ObserverList<Observer> observers_; |
| 507 | 522 |
| 508 // A reference to the mount api, to allow callbacks when the mount | 523 // A reference to the mount api, to allow callbacks when the mount |
| 509 // status changes. | 524 // status changes. |
| 510 MountEventConnection mount_status_connection_; | 525 MountEventConnection mount_status_connection_; |
| 511 | 526 |
| 512 // The list of disks found. | 527 // The list of disks found. |
| 513 MountLibrary::DiskMap disks_; | 528 MountLibrary::DiskMap disks_; |
| 514 | 529 |
| 530 MountLibrary::MountPointSet mount_points_; |
| 531 |
| 515 DISALLOW_COPY_AND_ASSIGN(MountLibraryImpl); | 532 DISALLOW_COPY_AND_ASSIGN(MountLibraryImpl); |
| 516 }; | 533 }; |
| 517 | 534 |
| 518 class MountLibraryStubImpl : public MountLibrary { | 535 class MountLibraryStubImpl : public MountLibrary { |
| 519 public: | 536 public: |
| 520 MountLibraryStubImpl() {} | 537 MountLibraryStubImpl() {} |
| 521 virtual ~MountLibraryStubImpl() {} | 538 virtual ~MountLibraryStubImpl() {} |
| 522 | 539 |
| 523 // MountLibrary overrides. | 540 // MountLibrary overrides. |
| 524 virtual void AddObserver(Observer* observer) OVERRIDE {} | 541 virtual void AddObserver(Observer* observer) OVERRIDE {} |
| 525 virtual void RemoveObserver(Observer* observer) OVERRIDE {} | 542 virtual void RemoveObserver(Observer* observer) OVERRIDE {} |
| 526 virtual const DiskMap& disks() const OVERRIDE { return disks_; } | 543 virtual const DiskMap& disks() const OVERRIDE { return disks_; } |
| 527 virtual void RequestMountInfoRefresh() OVERRIDE {} | 544 virtual void RequestMountInfoRefresh() OVERRIDE {} |
| 528 virtual void MountPath(const char* device_path) OVERRIDE {} | 545 virtual void MountPath(const char* source_path, MountType type, |
| 529 virtual void UnmountPath(const char* device_path) OVERRIDE {} | 546 const MountPathOptions& options) OVERRIDE {} |
| 547 virtual void UnmountPath(const char* path) OVERRIDE {} |
| 530 virtual void UnmountDeviceRecursive(const char* device_path, | 548 virtual void UnmountDeviceRecursive(const char* device_path, |
| 531 UnmountDeviceRecursiveCallbackType callback, void* user_data) | 549 UnmountDeviceRecursiveCallbackType callback, void* user_data) |
| 532 OVERRIDE {} | 550 OVERRIDE {} |
| 533 | 551 |
| 534 private: | 552 private: |
| 535 // The list of disks found. | 553 // The list of disks found. |
| 536 DiskMap disks_; | 554 DiskMap disks_; |
| 537 | 555 |
| 538 DISALLOW_COPY_AND_ASSIGN(MountLibraryStubImpl); | 556 DISALLOW_COPY_AND_ASSIGN(MountLibraryStubImpl); |
| 539 }; | 557 }; |
| 540 | 558 |
| 541 // static | 559 // static |
| 542 MountLibrary* MountLibrary::GetImpl(bool stub) { | 560 MountLibrary* MountLibrary::GetImpl(bool stub) { |
| 543 if (stub) | 561 if (stub) |
| 544 return new MountLibraryStubImpl(); | 562 return new MountLibraryStubImpl(); |
| 545 else | 563 else |
| 546 return new MountLibraryImpl(); | 564 return new MountLibraryImpl(); |
| 547 } | 565 } |
| 548 | 566 |
| 549 } // namespace chromeos | 567 } // namespace chromeos |
| 550 | 568 |
| 551 // Allows InvokeLater without adding refcounting. This class is a Singleton and | 569 // Allows InvokeLater without adding refcounting. This class is a Singleton and |
| 552 // won't be deleted until it's last InvokeLater is run. | 570 // won't be deleted until it's last InvokeLater is run. |
| 553 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::MountLibraryImpl); | 571 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::MountLibraryImpl); |
| 554 | 572 |
| OLD | NEW |