Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Unified Diff: chrome/browser/chromeos/cros/mount_library.cc

Issue 6674043: Rewritten MountLibrary to work with non-blocking mount API calls in libcros.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/chromeos/cros/mount_library.h ('k') | chrome/browser/chromeos/usb_mount_observer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/chromeos/cros/mount_library.cc
===================================================================
--- chrome/browser/chromeos/cros/mount_library.cc (revision 78562)
+++ chrome/browser/chromeos/cros/mount_library.cc (working copy)
@@ -4,6 +4,8 @@
#include "chrome/browser/chromeos/cros/mount_library.h"
+#include <set>
+
#include "base/message_loop.h"
#include "base/string_util.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
@@ -14,106 +16,326 @@
class MountLibraryImpl : public MountLibrary {
public:
MountLibraryImpl() : mount_status_connection_(NULL) {
- if (CrosLibrary::Get()->EnsureLoaded()) {
+ if (CrosLibrary::Get()->EnsureLoaded())
Init();
- } else {
+ else
LOG(ERROR) << "Cros Library has not been loaded";
- }
}
- ~MountLibraryImpl() {
- if (mount_status_connection_) {
- DisconnectMountStatus(mount_status_connection_);
- }
+ virtual ~MountLibraryImpl() {
+ if (mount_status_connection_)
+ DisconnectMountEventMonitor(mount_status_connection_);
}
- void AddObserver(Observer* observer) {
+ // MountLibrary overrides.
+ virtual void AddObserver(Observer* observer) OVERRIDE {
observers_.AddObserver(observer);
}
- void RemoveObserver(Observer* observer) {
+ virtual void RemoveObserver(Observer* observer) OVERRIDE {
observers_.RemoveObserver(observer);
}
- bool MountPath(const char* device_path) {
- return MountDevicePath(device_path);
+ virtual void MountPath(const char* device_path) OVERRIDE {
+ MountRemovableDevice(device_path,
+ &MountLibraryImpl::MountRemovableDeviceCallback,
+ this);
}
- bool IsBootPath(const char* device_path) {
- return IsBootDevicePath(device_path);
+ virtual void UnmountPath(const char* device_path) OVERRIDE {
+ UnmountRemovableDevice(device_path,
+ &MountLibraryImpl::UnmountRemovableDeviceCallback,
+ this);
}
- const DiskVector& disks() const { return disks_; }
+ virtual void RequestMountInfoRefresh() OVERRIDE {
+ RequestMountInfo(&MountLibraryImpl::RequestMountInfoCallback,
+ this);
+ }
+ virtual void RefreshDiskProperties(const Disk* disk) OVERRIDE {
+ DCHECK(disk);
+ GetDiskProperties(disk->device_path().c_str(),
+ &MountLibraryImpl::GetDiskPropertiesCallback,
+ this);
+ }
+
+ const DiskMap& disks() const OVERRIDE { return disks_; }
+
private:
- void ParseDisks(const MountStatus& status) {
- disks_.clear();
- for (int i = 0; i < status.size; i++) {
+
+ // Callback for MountRemovableDevice method.
+ static void MountRemovableDeviceCallback(void* object,
+ const char* device_path,
+ const char* mount_path,
+ MountMethodErrorType error,
+ const char* error_message) {
+ DCHECK(object);
+ MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
+ self->OnMountRemovableDevice(device_path,
+ mount_path,
+ error,
+ error_message);
+ }
+
+ // Callback for UnmountRemovableDevice method.
+ static void UnmountRemovableDeviceCallback(void* object,
+ const char* device_path,
+ const char* mount_path,
+ MountMethodErrorType error,
+ const char* error_message) {
+ DCHECK(object);
+ MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
+ self->OnUnmountRemovableDevice(device_path,
+ error,
+ error_message);
+ }
+
+ // Callback for disk information retrieval calls.
+ static void GetDiskPropertiesCallback(void* object,
+ const char* device_path,
+ const DiskInfo* disk,
+ MountMethodErrorType error,
+ const char* error_message) {
+ DCHECK(object);
+ MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
+ self->OnGetDiskProperties(device_path,
+ disk,
+ error,
+ error_message);
+ }
+
+ // Callback for RequestMountInfo call.
+ static void RequestMountInfoCallback(void* object,
+ const char** devices,
+ size_t device_len,
+ MountMethodErrorType error,
+ const char* error_message) {
+ DCHECK(object);
+ MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
+ self->OnRequestMountInfo(devices,
+ device_len,
+ error,
+ error_message);
+ }
+
+ // This method will receive events that are caused by drive status changes.
+ static void MonitorMountEventsHandler(void* object,
+ MountEventType evt,
+ const char* device_path) {
+ DCHECK(object);
+ MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
+ self->OnMountEvent(evt, device_path);
+ }
+
+
+ void OnMountRemovableDevice(const char* device_path,
+ const char* mount_path,
+ MountMethodErrorType error,
+ const char* error_message) {
+ DCHECK(device_path);
+ DCHECK(mount_path);
+ if (error == MOUNT_METHOD_ERROR_NONE && device_path && mount_path) {
+ std::string path(device_path);
+ DiskMap::iterator iter = disks_.find(path);
+ if (iter == disks_.end()) {
+ // disk might have been removed by now?
+ return;
+ }
+ Disk* disk = iter->second;
+ DCHECK(disk);
+ disk->set_mount_path(mount_path);
+ FireDiskStatusUpdate(MOUNT_DISK_MOUNTED, disk);
+ } else {
+ LOG(WARNING) << "Mount request failed for device "
+ << device_path << ", with error: "
+ << (error_message ? error_message : "Unknown");
+ }
+ }
+
+ void OnUnmountRemovableDevice(const char* device_path,
+ MountMethodErrorType error,
+ const char* error_message) {
+ DCHECK(device_path);
+ if (error == MOUNT_METHOD_ERROR_NONE && device_path) {
+ std::string path(device_path);
+ DiskMap::iterator iter = disks_.find(path);
+ if (iter == disks_.end()) {
+ // disk might have been removed by now?
+ return;
+ }
+ Disk* disk = iter->second;
+ DCHECK(disk);
+ disk->clear_mount_path();
+ FireDiskStatusUpdate(MOUNT_DISK_UNMOUNTED, disk);
+ } else {
+ LOG(WARNING) << "Unmount request failed for device "
+ << device_path << ", with error: "
+ << (error_message ? error_message : "Unknown");
+ }
+ }
+
+ void OnGetDiskProperties(const char* device_path,
+ const DiskInfo* disk,
+ MountMethodErrorType error,
+ const char* error_message) {
+ DCHECK(device_path);
+ if (error == MOUNT_METHOD_ERROR_NONE && device_path) {
+ // TODO(zelidrag): Find a better way to filter these out before we
+ // fetch the properties:
+ // Ignore disks coming from the device we booted the system from.
+ if (disk->on_boot_device())
+ return;
+
+ LOG(WARNING) << "Found disk " << device_path;
+ // Delete previous disk info for this path:
+ bool is_new = true;
+ std::string device_path_string(device_path);
+ DiskMap::iterator iter = disks_.find(device_path_string);
+ if (iter != disks_.end()) {
+ delete iter->second;
+ disks_.erase(iter);
+ is_new = false;
+ }
std::string path;
std::string mountpath;
std::string systempath;
- bool parent;
- bool hasmedia;
- if (status.disks[i].path != NULL) {
- path = status.disks[i].path;
+ if (disk->path() != NULL)
+ path = disk->path();
+
+ if (disk->mount_path() != NULL)
+ mountpath = disk->mount_path();
+
+ if (disk->system_path() != NULL)
+ systempath = disk->system_path();
+
+ Disk* new_disk = new Disk(path,
+ mountpath,
+ systempath,
+ disk->is_drive(),
+ disk->has_media(),
+ disk->on_boot_device());
+ disks_.insert(
+ std::pair<std::string, Disk*>(device_path_string, new_disk));
+ FireDiskStatusUpdate(is_new ? MOUNT_DISK_ADDED : MOUNT_DISK_CHANGED,
+ new_disk);
+ } else {
+ LOG(WARNING) << "Property retrieval request failed for device "
+ << device_path << ", with error: "
+ << (error_message ? error_message : "Unknown");
+ }
+ }
+
+ void OnRequestMountInfo(const char** devices,
+ size_t devices_len,
+ MountMethodErrorType error,
+ const char* error_message) {
+ std::set<std::string> current_device_set;
+ if (error == MOUNT_METHOD_ERROR_NONE && devices && devices_len) {
+ // Initiate properties fetch for all removable disks,
+ bool found_disk = false;
+ for (size_t i = 0; i < devices_len; i++) {
+ if (!devices[i]) {
+ NOTREACHED();
+ continue;
+ }
+ current_device_set.insert(std::string(devices[i]));
+ found_disk = true;
+ // Initiate disk property retrieval for each relevant device path.
+ GetDiskProperties(devices[i],
+ &MountLibraryImpl::GetDiskPropertiesCallback,
+ this);
}
- if (status.disks[i].mountpath != NULL) {
- mountpath = status.disks[i].mountpath;
+ } else if (error != MOUNT_METHOD_ERROR_NONE) {
+ LOG(WARNING) << "Request mount info retrieval request failed with error: "
+ << (error_message ? error_message : "Unknown");
+ }
+ // Search and remove disks that are no longer present.
+ for (MountLibrary::DiskMap::iterator iter = disks_.begin();
+ iter != disks_.end(); ) {
+ if (current_device_set.find(iter->first) == current_device_set.end()) {
+ Disk* disk = iter->second;
+ FireDiskStatusUpdate(MOUNT_DISK_REMOVED, disk);
+ delete iter->second;
+ disks_.erase(iter++);
+ } else {
+ ++iter;
}
- if (status.disks[i].systempath != NULL) {
- systempath = status.disks[i].systempath;
- }
- parent = status.disks[i].isparent;
- hasmedia = status.disks[i].hasmedia;
- disks_.push_back(Disk(path,
- mountpath,
- systempath,
- parent,
- hasmedia));
}
}
- static void MountStatusChangedHandler(void* object,
- const MountStatus& status,
- MountEventType evt,
- const char* path) {
- MountLibraryImpl* mount = static_cast<MountLibraryImpl*>(object);
- std::string devicepath = path;
- mount->ParseDisks(status);
- mount->UpdateMountStatus(status, evt, devicepath);
+ void OnMountEvent(MountEventType evt,
+ const char* device_path) {
+ if (!device_path)
+ return;
+ MountLibraryEventType type;
+ switch (evt) {
+ case DISK_ADDED:
+ case DISK_CHANGED: {
+ GetDiskProperties(device_path,
+ &MountLibraryImpl::GetDiskPropertiesCallback,
+ this);
+ return;
+ }
+ case DISK_REMOVED: {
+ // Search and remove disks that are no longer present.
+ MountLibrary::DiskMap::iterator iter =
+ disks_.find(std::string(device_path));
+ if (iter != disks_.end()) {
+ Disk* disk = iter->second;
+ FireDiskStatusUpdate(MOUNT_DISK_REMOVED, disk);
+ delete iter->second;
+ disks_.erase(iter);
+ }
+ return;
+ }
+ case DEVICE_ADDED: {
+ type = MOUNT_DEVICE_ADDED;
+ break;
+ }
+ case DEVICE_REMOVED: {
+ type = MOUNT_DEVICE_REMOVED;
+ break;
+ }
+ case DEVICE_SCANNED: {
+ type = MOUNT_DEVICE_SCANNED;
+ break;
+ }
+ }
+ FireDeviceStatusUpdate(type, std::string(device_path));
}
void Init() {
// Getting the monitor status so that the daemon starts up.
- MountStatus* mount = RetrieveMountInformation();
- if (!mount) {
- LOG(ERROR) << "Failed to retrieve mount information";
- return;
- }
- ParseDisks(*mount);
- FreeMountStatus(mount);
+ mount_status_connection_ = MonitorMountEvents(
+ &MonitorMountEventsHandler, this);
+ }
- mount_status_connection_ = MonitorMountStatus(
- &MountStatusChangedHandler, this);
+ void FireDiskStatusUpdate(MountLibraryEventType evt,
+ const Disk* disk) {
+ // Make sure we run on UI thread.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ FOR_EACH_OBSERVER(
+ Observer, observers_, DiskChanged(evt, disk));
}
- void UpdateMountStatus(const MountStatus& status,
- MountEventType evt,
- const std::string& path) {
+ void FireDeviceStatusUpdate(MountLibraryEventType evt,
+ const std::string& device_path) {
// Make sure we run on UI thread.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
FOR_EACH_OBSERVER(
- Observer, observers_, MountChanged(this, evt, path));
+ Observer, observers_, DeviceChanged(evt, device_path));
}
+
+ // Mount event change observers.
ObserverList<Observer> observers_;
// A reference to the mount api, to allow callbacks when the mount
// status changes.
- MountStatusConnection mount_status_connection_;
+ MountEventConnection mount_status_connection_;
// The list of disks found.
- DiskVector disks_;
+ MountLibrary::DiskMap disks_;
DISALLOW_COPY_AND_ASSIGN(MountLibraryImpl);
};
@@ -124,15 +346,17 @@
virtual ~MountLibraryStubImpl() {}
// MountLibrary overrides.
- virtual void AddObserver(Observer* observer) {}
- virtual void RemoveObserver(Observer* observer) {}
- virtual const DiskVector& disks() const { return disks_; }
- virtual bool MountPath(const char* device_path) { return false; }
- virtual bool IsBootPath(const char* device_path) { return true; }
+ virtual void AddObserver(Observer* observer) OVERRIDE {}
+ virtual void RemoveObserver(Observer* observer) OVERRIDE {}
+ virtual const DiskMap& disks() const OVERRIDE { return disks_; }
+ virtual void RequestMountInfoRefresh() OVERRIDE {}
+ virtual void MountPath(const char* device_path) OVERRIDE {}
+ virtual void UnmountPath(const char* device_path) OVERRIDE {}
+ virtual bool IsBootPath(const char* device_path) OVERRIDE { return true; }
private:
// The list of disks found.
- DiskVector disks_;
+ DiskMap disks_;
DISALLOW_COPY_AND_ASSIGN(MountLibraryStubImpl);
};
« no previous file with comments | « chrome/browser/chromeos/cros/mount_library.h ('k') | chrome/browser/chromeos/usb_mount_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698