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

Unified Diff: base/system_monitor/system_monitor_win.cc

Issue 10893006: Extend system monitor capacity for watching the free space changes (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 4 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
Index: base/system_monitor/system_monitor_win.cc
diff --git a/base/system_monitor/system_monitor_win.cc b/base/system_monitor/system_monitor_win.cc
index a8cd54a6db1b8e27716e9b489650c30e8ce849ec..a512fa38bdbae427d392cc5de6606cda1a115c7c 100644
--- a/base/system_monitor/system_monitor_win.cc
+++ b/base/system_monitor/system_monitor_win.cc
@@ -4,8 +4,121 @@
#include "base/system_monitor/system_monitor.h"
+#include "base/file_util.h"
+#include "base/message_loop_proxy.h"
+#include "base/win/object_watcher.h"
+
namespace base {
+namespace {
+class StorageDeviceWatcher
+ : public FilePathWatcher::PlatformDelegate,
+ public base::win::ObjectWatcher::Delegate,
+ public MessageLoop::DestructionObserver
+ {
+ public:
+ StorageDeviceWatcher() {}
+ virtual StorageDeviceWatcher() {}
+
+ // Overriden from FilePathWatcher::PlatformDelegate.
+ virtual bool Watch(const FilePath& path,
+ FilePathWatcher::Delegate* delegate) OVERRIDE;
+ virtual void Cancel() OVERRIDE;
+ virtual void CancelOnMessageLoopThread() OVERRIDE;
+
+ private:
+ // Overriden from ObjectWatcher::Delegate.
+ virtual void OnObjectSignaled(HANDLE object) OVERRIDE;
+
+ void DestroyWatch();
+
+ base::win::ObjectWatcher watcher_;
+ HANDLE handle_;
+ FilePath path_;
+};
+
+// StorageDeviceWatcher
+bool StorageDeviceWatcher::Watch(const FilePath& path,
+ FilePathWatcher::Delegate* delegate) {
+ if (handle_ != INVALID_HANDLE_VALUE)
+ DestroyWatch()
+
+ set_message_loop(base::MessageLoopProxy::current());
+ MessageLoop::current()->AddDestructionObserver(this);
+
+ if (!file_util::DirectoryExists(path))
+ return false;
+
+ handle_ = FindFirstChangeNotification(path.value().c_str(),
+ TRUE, // Watch sub directories
+ FILE_NOTIFY_CHANGE_SIZE);
+ if (handle_ == INVALID_HANDLE_VALUE) {
+ DPLOG(ERROR) << "FindFirstChangeNotification failed: " << GetLastError();
+ return false;
+ }
+
+ path_ = path;
+ watcher_.StartWatching(handle_, this);
+ return true;
+}
+
+void StorageDeviceWatcher::Cancel() {
+ if (!message_loop()->BelongsToCurrentThread()) {
+ message_loop()->PostTask(FROM_HERE,
+ base::Bind(&StorageDeviceWatcher::CancelOnMessageLoopThread, this));
+ } else {
+ CancelOnMessageLoopThread();
+ }
+}
+
+void StorageDeviceWatcher::CancelOnMessageLoopThread() {
+ set_cancelled();
+ if (handle_ != INVALID_HANDLE_VALUE)
+ DestroyWatch();
+
+ MessageLoop::current()->RemoveDestructionObserver(this);
+}
+
+void StorageDeviceWatcher::OnObjectSignaled(HANDLE object) {
+ DCHECK(object == handle_);
+
+ // TODO (hongbo): need to control the frequency of the storage
+ // free space change event.
+ SystemMonitor::Get()->NotifyStorageFreeSpaceChanged(path_.value());
+
+ watcher_.StartWatching(handle_, this);
+}
+
+void StorageDeviceWatcher::DestroyWatch() {
+ watcher_.StopWatching();
+ FindCloseChangeNotification(handle_);
+ handle_ = INVALID_HANDLE_VALUE;
+}
+
+}
+
+bool SystemMonitor::StartWatchStorageDevice(const FilePath::StringType& path) {
+ scoped_refptr<FilePathWatcher::PlatformDelegate> watcher(
+ new StorageDeviceWatcher());
+ if (watcher->Watch(FilePath(path), NULL)) {
+ storage_watcher_map_.insert(
+ std::pair<FilePath::StringType,
+ scoped_refptr<FilePathWatcher::PlatformDelegate>(path, watcher));
+ return true;
+ }
+ return false;
+}
+
+bool SystemMonitor::StopWatchStorageDevice(const FilePath::StringType& path) {
+ StorageDeviceWatcherMap::iterator iter = storage_watcher_map_.find(path);
+ if (iter == storage_watcher_map_.end())
+ return false;
+
+ iter->second->Cancel();
+ storage_watcher_map_.erase(iter);
+ return true;
+}
+
void SystemMonitor::ProcessWmPowerBroadcastMessage(int event_id) {
PowerEvent power_event;
switch (event_id) {
« base/system_monitor/system_monitor.h ('K') | « base/system_monitor/system_monitor.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698