Index: chromeos/disks/disk_mount_manager.cc |
diff --git a/chromeos/disks/disk_mount_manager.cc b/chromeos/disks/disk_mount_manager.cc |
index 6f450d2f9987eaa8bb1ab6d802afc29b3cad059a..66c2a0bf784f577efdaf1adab9700cbbea0c0904 100644 |
--- a/chromeos/disks/disk_mount_manager.cc |
+++ b/chromeos/disks/disk_mount_manager.cc |
@@ -30,7 +30,6 @@ class DiskMountManagerImpl : public DiskMountManager { |
DCHECK(dbus_thread_manager); |
cros_disks_client_ = dbus_thread_manager->GetCrosDisksClient(); |
DCHECK(cros_disks_client_); |
- |
cros_disks_client_->SetUpConnections( |
base::Bind(&DiskMountManagerImpl::OnMountEvent, |
weak_ptr_factory_.GetWeakPtr()), |
@@ -94,52 +93,31 @@ class DiskMountManagerImpl : public DiskMountManager { |
} |
// DiskMountManager override. |
- virtual void FormatUnmountedDevice(const std::string& file_path) OVERRIDE { |
- for (DiskMountManager::DiskMap::iterator it = disks_.begin(); |
- it != disks_.end(); ++it) { |
- if (it->second->file_path() == file_path && |
- !it->second->mount_path().empty()) { |
- LOG(ERROR) << "Device is still mounted: " << file_path; |
- OnFormatDevice(file_path, false); |
- return; |
- } |
- } |
- const char kFormatVFAT[] = "vfat"; |
- cros_disks_client_->FormatDevice( |
- file_path, |
- kFormatVFAT, |
- base::Bind(&DiskMountManagerImpl::OnFormatDevice, |
- weak_ptr_factory_.GetWeakPtr()), |
- base::Bind(&DiskMountManagerImpl::OnFormatDevice, |
- weak_ptr_factory_.GetWeakPtr(), |
- file_path, |
- false)); |
- } |
- |
- // DiskMountManager override. |
virtual void FormatMountedDevice(const std::string& mount_path) OVERRIDE { |
- Disk* disk = NULL; |
- for (DiskMountManager::DiskMap::iterator it = disks_.begin(); |
- it != disks_.end(); ++it) { |
- if (it->second->mount_path() == mount_path) { |
- disk = it->second; |
- break; |
- } |
- } |
- if (!disk) { |
- LOG(ERROR) << "Device with this mount path not found: " << mount_path; |
+ MountPointMap::const_iterator mount_point = mount_points_.find(mount_path); |
+ if (mount_point == mount_points_.end()) { |
+ LOG(ERROR) << "Mount point with path \"" << mount_path << "\" not found."; |
OnFormatDevice(mount_path, false); |
return; |
} |
- if (formatting_pending_.find(disk->device_path()) != |
- formatting_pending_.end()) { |
+ |
+ std::string device_path = mount_point->second.source_path; |
+ DiskMap::const_iterator disk = disks_.find(device_path); |
+ if (disk == disks_.end()) { |
+ LOG(ERROR) << "Device with path \"" << device_path << "\" not found."; |
+ OnFormatDevice(device_path, false); |
+ return; |
+ } |
+ |
+ if (formatting_pending_.find(device_path) != formatting_pending_.end()) { |
LOG(ERROR) << "Formatting is already pending: " << mount_path; |
- OnFormatDevice(mount_path, false); |
+ OnFormatDevice(device_path, false); |
return; |
} |
+ |
// Formatting process continues, after unmounting. |
- formatting_pending_[disk->device_path()] = disk->file_path(); |
- UnmountPath(disk->mount_path(), UNMOUNT_OPTIONS_NONE); |
+ formatting_pending_.insert(device_path); |
+ UnmountPath(disk->second->mount_path(), UNMOUNT_OPTIONS_NONE); |
} |
// DiskMountManager override. |
@@ -216,6 +194,35 @@ class DiskMountManagerImpl : public DiskMountManager { |
return mount_points_; |
} |
+ // DiskMountManager override. |
+ virtual bool AddDiskForTest(Disk* disk) OVERRIDE { |
+ if (disks_.find(disk->device_path()) != disks_.end()) { |
+ LOG(ERROR) << "Attempt to add a duplicate disk"; |
+ return false; |
+ } |
+ |
+ disks_.insert(std::make_pair(disk->device_path(), disk)); |
+ return true; |
+ } |
+ |
+ // DiskMountManager override. |
+ // Corresponding disk should be added to the manager before this is called. |
+ virtual bool AddMountPointForTest( |
+ const MountPointInfo& mount_point) OVERRIDE { |
+ if (mount_points_.find(mount_point.mount_path) != mount_points_.end()) { |
+ LOG(ERROR) << "Attempt to add a duplicate mount point"; |
+ return false; |
+ } |
+ if (mount_point.mount_type == chromeos::MOUNT_TYPE_DEVICE && |
+ disks_.find(mount_point.source_path) == disks_.end()) { |
+ LOG(ERROR) << "Device mount points must have a disk entry."; |
+ return false; |
+ } |
+ |
+ mount_points_.insert(std::make_pair(mount_point.mount_path, mount_point)); |
+ return true; |
+ } |
+ |
private: |
struct UnmountDeviceRecursiveCallbackData { |
void* user_data; |
@@ -285,7 +292,7 @@ class DiskMountManagerImpl : public DiskMountManager { |
const MountPointInfo mount_info(source_path, mount_path, mount_type, |
mount_condition); |
- NotifyMountCompleted(MOUNTING, error_code, mount_info); |
+ NotifyMountStatusUpdate(MOUNTING, error_code, mount_info); |
// If the device is corrupted but it's still possible to format it, it will |
// be fake mounted. |
@@ -306,7 +313,6 @@ class DiskMountManagerImpl : public DiskMountManager { |
Disk* disk = iter->second; |
DCHECK(disk); |
disk->set_mount_path(mount_info.mount_path); |
- NotifyDiskStatusUpdate(MOUNT_DISK_MOUNTED, disk); |
} |
} |
@@ -315,7 +321,8 @@ class DiskMountManagerImpl : public DiskMountManager { |
MountPointMap::iterator mount_points_it = mount_points_.find(mount_path); |
if (mount_points_it == mount_points_.end()) |
return; |
- NotifyMountCompleted( |
+ |
+ NotifyMountStatusUpdate( |
UNMOUNTING, |
success ? MOUNT_ERROR_NONE : MOUNT_ERROR_INTERNAL, |
MountPointInfo(mount_points_it->second.source_path, |
@@ -327,40 +334,48 @@ class DiskMountManagerImpl : public DiskMountManager { |
if (success) |
mount_points_.erase(mount_points_it); |
- DiskMap::iterator iter = disks_.find(path); |
- if (iter == disks_.end()) { |
- // disk might have been removed by now. |
- return; |
+ DiskMap::iterator disk_iter = disks_.find(path); |
+ if (disk_iter != disks_.end()) { |
+ DCHECK(disk_iter->second); |
+ if (success) |
+ disk_iter->second->clear_mount_path(); |
} |
- Disk* disk = iter->second; |
- DCHECK(disk); |
- if (success) |
- disk->clear_mount_path(); |
- |
+ FormatTaskSet::iterator format_iter = formatting_pending_.find(path); |
// Check if there is a formatting scheduled. |
- PathMap::iterator it = formatting_pending_.find(disk->device_path()); |
- if (it != formatting_pending_.end()) { |
- // Copy the string before it gets erased. |
- const std::string file_path = it->second; |
- formatting_pending_.erase(it); |
- if (success) { |
- FormatUnmountedDevice(file_path); |
+ if (format_iter != formatting_pending_.end()) { |
+ formatting_pending_.erase(format_iter); |
+ if (success && disk_iter != disks_.end()) { |
+ FormatUnmountedDevice(path); |
} else { |
- OnFormatDevice(file_path, false); |
+ OnFormatDevice(path, false); |
} |
} |
} |
+ // Starts device formatting. |
+ void FormatUnmountedDevice(const std::string& device_path) { |
+ DiskMap::const_iterator disk = disks_.find(device_path); |
+ DCHECK(disk != disks_.end() && disk->second->mount_path().empty()); |
+ |
+ const char kFormatVFAT[] = "vfat"; |
+ cros_disks_client_->FormatDevice( |
+ device_path, |
+ kFormatVFAT, |
+ base::Bind(&DiskMountManagerImpl::OnFormatDevice, |
+ weak_ptr_factory_.GetWeakPtr()), |
+ base::Bind(&DiskMountManagerImpl::OnFormatDevice, |
+ weak_ptr_factory_.GetWeakPtr(), |
+ device_path, |
+ false)); |
+ } |
+ |
// Callback for FormatDevice. |
+ // TODO(tbarzic): Pass FormatError instead of bool. |
void OnFormatDevice(const std::string& device_path, bool success) { |
- if (success) { |
- NotifyDeviceStatusUpdate(MOUNT_FORMATTING_STARTED, device_path); |
- } else { |
- NotifyDeviceStatusUpdate(MOUNT_FORMATTING_STARTED, |
- std::string("!") + device_path); |
- LOG(WARNING) << "Format request failed for device " << device_path; |
- } |
+ FormatError error_code = |
+ success ? FORMAT_ERROR_NONE : FORMAT_ERROR_UNKNOWN; |
+ NotifyFormatStatusUpdate(FORMAT_STARTED, error_code, device_path); |
} |
// Callbcak for GetDeviceProperties. |
@@ -400,8 +415,7 @@ class DiskMountManagerImpl : public DiskMountManager { |
disk_info.on_boot_device(), |
disk_info.is_hidden()); |
disks_.insert(std::make_pair(disk_info.device_path(), disk)); |
- NotifyDiskStatusUpdate(is_new ? MOUNT_DISK_ADDED : MOUNT_DISK_CHANGED, |
- disk); |
+ NotifyDiskStatusUpdate(is_new ? DISK_ADDED : DISK_CHANGED, disk); |
} |
// Callbcak for RequestMountInfo. |
@@ -423,7 +437,7 @@ class DiskMountManagerImpl : public DiskMountManager { |
for (DiskMap::iterator iter = disks_.begin(); iter != disks_.end(); ) { |
if (current_device_set.find(iter->first) == current_device_set.end()) { |
Disk* disk = iter->second; |
- NotifyDiskStatusUpdate(MOUNT_DISK_REMOVED, disk); |
+ NotifyDiskStatusUpdate(DISK_REMOVED, disk); |
delete iter->second; |
disks_.erase(iter++); |
} else { |
@@ -436,98 +450,110 @@ class DiskMountManagerImpl : public DiskMountManager { |
void OnMountEvent(MountEventType event, const std::string& device_path_arg) { |
// Take a copy of the argument so we can modify it below. |
std::string device_path = device_path_arg; |
- DiskMountManagerEventType type = MOUNT_DEVICE_ADDED; |
switch (event) { |
- case DISK_ADDED: { |
+ case CROS_DISKS_DISK_ADDED: { |
cros_disks_client_->GetDeviceProperties( |
device_path, |
base::Bind(&DiskMountManagerImpl::OnGetDeviceProperties, |
weak_ptr_factory_.GetWeakPtr()), |
base::Bind(&base::DoNothing)); |
- return; |
+ break; |
} |
- case DISK_REMOVED: { |
+ case CROS_DISKS_DISK_REMOVED: { |
// Search and remove disks that are no longer present. |
DiskMountManager::DiskMap::iterator iter = disks_.find(device_path); |
if (iter != disks_.end()) { |
Disk* disk = iter->second; |
- NotifyDiskStatusUpdate(MOUNT_DISK_REMOVED, disk); |
+ NotifyDiskStatusUpdate(DISK_REMOVED, disk); |
delete iter->second; |
disks_.erase(iter); |
} |
- return; |
+ break; |
} |
- case DEVICE_ADDED: { |
- type = MOUNT_DEVICE_ADDED; |
+ case CROS_DISKS_DEVICE_ADDED: { |
system_path_prefixes_.insert(device_path); |
+ NotifyDeviceStatusUpdate(DEVICE_ADDED, device_path); |
break; |
} |
- case DEVICE_REMOVED: { |
- type = MOUNT_DEVICE_REMOVED; |
+ case CROS_DISKS_DEVICE_REMOVED: { |
system_path_prefixes_.erase(device_path); |
+ NotifyDeviceStatusUpdate(DEVICE_REMOVED, device_path); |
break; |
} |
- case DEVICE_SCANNED: { |
- type = MOUNT_DEVICE_SCANNED; |
+ case CROS_DISKS_DEVICE_SCANNED: { |
+ NotifyDeviceStatusUpdate(DEVICE_SCANNED, device_path); |
break; |
} |
- case FORMATTING_FINISHED: { |
- // FORMATTING_FINISHED actually returns file path instead of device |
- // path. |
- device_path = FilePathToDevicePath(device_path); |
- if (device_path.empty()) { |
- LOG(ERROR) << "Error while handling disks metadata. Cannot find " |
- << "device that is being formatted."; |
- return; |
+ case CROS_DISKS_FORMATTING_FINISHED: { |
+ std::string path; |
+ FormatError error_code; |
+ ParseFormatFinishedPath(device_path, &path, &error_code); |
+ |
+ if (!path.empty()) { |
+ NotifyFormatStatusUpdate(FORMAT_COMPLETED, error_code, path); |
+ break; |
} |
- type = MOUNT_FORMATTING_FINISHED; |
+ |
+ LOG(ERROR) << "Error while handling disks metadata. Cannot find " |
+ << "device that is being formatted."; |
break; |
} |
default: { |
LOG(ERROR) << "Unknown event: " << event; |
- return; |
} |
} |
- NotifyDeviceStatusUpdate(type, device_path); |
} |
// Notifies all observers about disk status update. |
- void NotifyDiskStatusUpdate(DiskMountManagerEventType event, |
+ void NotifyDiskStatusUpdate(DiskEvent event, |
const Disk* disk) { |
- FOR_EACH_OBSERVER(Observer, observers_, DiskChanged(event, disk)); |
+ FOR_EACH_OBSERVER(Observer, observers_, OnDiskEvent(event, disk)); |
} |
// Notifies all observers about device status update. |
- void NotifyDeviceStatusUpdate(DiskMountManagerEventType event, |
+ void NotifyDeviceStatusUpdate(DeviceEvent event, |
const std::string& device_path) { |
- FOR_EACH_OBSERVER(Observer, observers_, DeviceChanged(event, device_path)); |
+ FOR_EACH_OBSERVER(Observer, observers_, OnDeviceEvent(event, device_path)); |
} |
// Notifies all observers about mount completion. |
- void NotifyMountCompleted(MountEvent event_type, |
- MountError error_code, |
- const MountPointInfo& mount_info) { |
+ void NotifyMountStatusUpdate(MountEvent event, |
+ MountError error_code, |
+ const MountPointInfo& mount_info) { |
+ FOR_EACH_OBSERVER(Observer, observers_, |
+ OnMountEvent(event, error_code, mount_info)); |
+ } |
+ |
+ void NotifyFormatStatusUpdate(FormatEvent event, |
+ FormatError error_code, |
+ const std::string& device_path) { |
FOR_EACH_OBSERVER(Observer, observers_, |
- MountCompleted(event_type, error_code, mount_info)); |
+ OnFormatEvent(event, error_code, device_path)); |
} |
// Converts file path to device path. |
- std::string FilePathToDevicePath(const std::string& file_path) { |
- // TODO(hashimoto): Refactor error handling code like here. |
+ void ParseFormatFinishedPath(const std::string& received_path, |
+ std::string* device_path, |
+ FormatError* error_code) { |
+ // TODO(tbarzic): Refactor error handling code like here. |
// Appending "!" is not the best way to indicate error. This kind of trick |
- // also makes it difficult to simplify the code paths. crosbug.com/22972 |
- const int failed = StartsWithASCII(file_path, "!", true); |
+ // also makes it difficult to simplify the code paths. |
+ bool success = !StartsWithASCII(received_path, "!", true); |
+ *error_code = success ? FORMAT_ERROR_NONE : FORMAT_ERROR_UNKNOWN; |
+ |
+ std::string path = received_path.substr(success ? 0 : 1); |
+ |
+ // Depending on cros disks implementation the event may return either file |
+ // path or device path. We want to use device path. |
for (DiskMountManager::DiskMap::iterator it = disks_.begin(); |
it != disks_.end(); ++it) { |
// Skip the leading '!' on the failure case. |
- if (it->second->file_path() == file_path.substr(failed)) { |
- if (failed) |
- return std::string("!") + it->second->device_path(); |
- else |
- return it->second->device_path(); |
+ if (it->second->file_path() == path || |
+ it->second->device_path() == path) { |
+ *device_path = it->second->device_path(); |
+ return; |
} |
} |
- return ""; |
} |
// Finds system path prefix from |system_path|. |
@@ -562,8 +588,8 @@ class DiskMountManagerImpl : public DiskMountManager { |
// Devices in this map are supposed to be formatted, but are currently waiting |
// to be unmounted. When device is in this map, the formatting process HAVEN'T |
// started yet. |
- typedef std::map<std::string, std::string> PathMap; |
- PathMap formatting_pending_; |
+ typedef std::set<std::string> FormatTaskSet; |
+ FormatTaskSet formatting_pending_; |
base::WeakPtrFactory<DiskMountManagerImpl> weak_ptr_factory_; |
@@ -614,6 +640,14 @@ DiskMountManager::Disk::Disk(const std::string& device_path, |
DiskMountManager::Disk::~Disk() {} |
+bool DiskMountManager::AddDiskForTest(Disk* disk) { |
+ return false; |
+} |
+ |
+bool DiskMountManager::AddMountPointForTest(const MountPointInfo& mount_point) { |
+ return false; |
+} |
+ |
// static |
std::string DiskMountManager::MountTypeToString(MountType type) { |
switch (type) { |