Index: chromeos/disks/disk_mount_manager.cc |
diff --git a/chromeos/disks/disk_mount_manager.cc b/chromeos/disks/disk_mount_manager.cc |
index c25cf1527a9b1ab8cb032d4b6fea7ef60c80e4cf..a1f6db8c65579e51c924664ab625d74c55f8ca0a 100644 |
--- a/chromeos/disks/disk_mount_manager.cc |
+++ b/chromeos/disks/disk_mount_manager.cc |
@@ -26,7 +26,9 @@ DiskMountManager* g_disk_mount_manager = NULL; |
// The DiskMountManager implementation. |
class DiskMountManagerImpl : public DiskMountManager { |
public: |
- DiskMountManagerImpl() : weak_ptr_factory_(this) { |
+ DiskMountManagerImpl() : |
+ already_refreshed_(false), |
+ weak_ptr_factory_(this) { |
DBusThreadManager* dbus_thread_manager = DBusThreadManager::Get(); |
DCHECK(dbus_thread_manager); |
cros_disks_client_ = dbus_thread_manager->GetCrosDisksClient(); |
@@ -155,7 +157,7 @@ class DiskMountManagerImpl : public DiskMountManager { |
} |
// We will send the same callback data object to all Unmount calls and use |
- // it to syncronize callbacks. |
+ // it to synchronize callbacks. |
// Note: this implementation has a potential memory leak issue. For |
// example if this instance is destructed before all the callbacks for |
// Unmount are invoked, the memory pointed by |cb_data| will be leaked. |
@@ -189,11 +191,22 @@ class DiskMountManagerImpl : public DiskMountManager { |
} |
// DiskMountManager override. |
- virtual void RequestMountInfoRefresh() OVERRIDE { |
- cros_disks_client_->EnumerateAutoMountableDevices( |
- base::Bind(&DiskMountManagerImpl::OnRequestMountInfo, |
- weak_ptr_factory_.GetWeakPtr()), |
- base::Bind(&base::DoNothing)); |
+ virtual void EnsureMountInfoRefreshed( |
+ const EnsureMountInfoRefreshedCallback& callback) OVERRIDE { |
+ if (already_refreshed_) { |
+ callback.Run(true); |
+ return; |
+ } |
+ |
+ refresh_callbacks_.push_back(callback); |
+ if (refresh_callbacks_.size() == 1) { |
+ // If there's no in-flight refreshing task, start it. |
+ cros_disks_client_->EnumerateAutoMountableDevices( |
+ base::Bind(&DiskMountManagerImpl::RefreshAfterEnumerateDevices, |
+ weak_ptr_factory_.GetWeakPtr()), |
+ base::Bind(&DiskMountManagerImpl::RefreshCompleted, |
+ weak_ptr_factory_.GetWeakPtr(), false)); |
+ } |
} |
// DiskMountManager override. |
@@ -414,7 +427,7 @@ class DiskMountManagerImpl : public DiskMountManager { |
NotifyFormatStatusUpdate(FORMAT_COMPLETED, error_code, device_path); |
} |
- // Callbcak for GetDeviceProperties. |
+ // Callback for GetDeviceProperties. |
void OnGetDeviceProperties(const DiskInfo& disk_info) { |
// TODO(zelidrag): Find a better way to filter these out before we |
// fetch the properties: |
@@ -454,32 +467,64 @@ class DiskMountManagerImpl : public DiskMountManager { |
NotifyDiskStatusUpdate(is_new ? DISK_ADDED : DISK_CHANGED, disk); |
} |
- // Callbcak for RequestMountInfo. |
- void OnRequestMountInfo(const std::vector<std::string>& devices) { |
- std::set<std::string> current_device_set; |
- if (!devices.empty()) { |
- // Initiate properties fetch for all removable disks, |
- for (size_t i = 0; i < devices.size(); i++) { |
- current_device_set.insert(devices[i]); |
- // Initiate disk property retrieval for each relevant device path. |
- cros_disks_client_->GetDeviceProperties( |
- devices[i], |
- base::Bind(&DiskMountManagerImpl::OnGetDeviceProperties, |
- weak_ptr_factory_.GetWeakPtr()), |
- base::Bind(&base::DoNothing)); |
- } |
- } |
- // Search and remove disks that are no longer present. |
+ // Part of EnsureMountInfoRefreshed(). Called after the list of devices are |
+ // enumerated. |
+ void RefreshAfterEnumerateDevices(const std::vector<std::string>& devices) { |
+ std::set<std::string> current_device_set(devices.begin(), devices.end()); |
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(DISK_REMOVED, disk); |
delete iter->second; |
disks_.erase(iter++); |
} else { |
++iter; |
} |
} |
+ RefreshDeviceAtIndex(devices, 0); |
+ } |
+ |
+ // Part of EnsureMountInfoRefreshed(). Called for each device to refresh info. |
+ void RefreshDeviceAtIndex(const std::vector<std::string>& devices, |
+ size_t index) { |
+ if (index == devices.size()) { |
+ // All devices info retrieved. Proceed to enumerate mount point info. |
+ cros_disks_client_->EnumerateMountEntries( |
+ base::Bind(&DiskMountManagerImpl::RefreshAfterEnumerateMountEntries, |
+ weak_ptr_factory_.GetWeakPtr()), |
+ base::Bind(&DiskMountManagerImpl::RefreshCompleted, |
+ weak_ptr_factory_.GetWeakPtr(), false)); |
+ return; |
+ } |
+ |
+ cros_disks_client_->GetDeviceProperties( |
+ devices[index], |
+ base::Bind(&DiskMountManagerImpl::RefreshAfterGetDeviceProperties, |
+ weak_ptr_factory_.GetWeakPtr(), devices, index + 1), |
+ base::Bind(&DiskMountManagerImpl::RefreshCompleted, |
+ weak_ptr_factory_.GetWeakPtr(), false)); |
+ } |
+ |
+ // Part of EnsureMountInfoRefreshed(). |
+ void RefreshAfterGetDeviceProperties(const std::vector<std::string>& devices, |
+ size_t next_index, |
+ const DiskInfo& disk_info) { |
+ OnGetDeviceProperties(disk_info); |
+ RefreshDeviceAtIndex(devices, next_index); |
+ } |
+ |
+ // Part of EnsureMountInfoRefreshed(). Called after mount entries are listed. |
+ void RefreshAfterEnumerateMountEntries( |
+ const std::vector<MountEntry>& entries) { |
+ for (size_t i = 0; i < entries.size(); ++i) |
+ OnMountCompleted(entries[i]); |
+ RefreshCompleted(true); |
+ } |
+ |
+ // Part of EnsureMountInfoRefreshed(). Called when the refreshing is done. |
+ void RefreshCompleted(bool success) { |
+ already_refreshed_ = true; |
+ for (size_t i = 0; i < refresh_callbacks_.size(); ++i) |
+ refresh_callbacks_[i].Run(success); |
+ refresh_callbacks_.clear(); |
} |
// Callback to handle mount event signals. |
@@ -580,6 +625,9 @@ class DiskMountManagerImpl : public DiskMountManager { |
typedef std::set<std::string> SystemPathPrefixSet; |
SystemPathPrefixSet system_path_prefixes_; |
+ bool already_refreshed_; |
+ std::vector<EnsureMountInfoRefreshedCallback> refresh_callbacks_; |
+ |
base::WeakPtrFactory<DiskMountManagerImpl> weak_ptr_factory_; |
DISALLOW_COPY_AND_ASSIGN(DiskMountManagerImpl); |