| 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 "base/system_monitor/system_monitor.h" | 5 #include "base/system_monitor/system_monitor.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" |
| 8 #include "base/message_loop_proxy.h" |
| 9 #include "base/win/object_watcher.h" |
| 10 |
| 7 namespace base { | 11 namespace base { |
| 8 | 12 |
| 13 namespace { |
| 14 class StorageDeviceWatcher |
| 15 : public FilePathWatcher::PlatformDelegate, |
| 16 public base::win::ObjectWatcher::Delegate, |
| 17 public MessageLoop::DestructionObserver |
| 18 { |
| 19 public: |
| 20 StorageDeviceWatcher() {} |
| 21 virtual StorageDeviceWatcher() {} |
| 22 |
| 23 // Overriden from FilePathWatcher::PlatformDelegate. |
| 24 virtual bool Watch(const FilePath& path, |
| 25 FilePathWatcher::Delegate* delegate) OVERRIDE; |
| 26 virtual void Cancel() OVERRIDE; |
| 27 virtual void CancelOnMessageLoopThread() OVERRIDE; |
| 28 |
| 29 private: |
| 30 // Overriden from ObjectWatcher::Delegate. |
| 31 virtual void OnObjectSignaled(HANDLE object) OVERRIDE; |
| 32 |
| 33 void DestroyWatch(); |
| 34 |
| 35 base::win::ObjectWatcher watcher_; |
| 36 HANDLE handle_; |
| 37 FilePath path_; |
| 38 }; |
| 39 |
| 40 // StorageDeviceWatcher |
| 41 bool StorageDeviceWatcher::Watch(const FilePath& path, |
| 42 FilePathWatcher::Delegate* delegate) { |
| 43 if (handle_ != INVALID_HANDLE_VALUE) |
| 44 DestroyWatch() |
| 45 |
| 46 set_message_loop(base::MessageLoopProxy::current()); |
| 47 MessageLoop::current()->AddDestructionObserver(this); |
| 48 |
| 49 if (!file_util::DirectoryExists(path)) |
| 50 return false; |
| 51 |
| 52 handle_ = FindFirstChangeNotification(path.value().c_str(), |
| 53 TRUE, // Watch sub directories |
| 54 FILE_NOTIFY_CHANGE_SIZE); |
| 55 if (handle_ == INVALID_HANDLE_VALUE) { |
| 56 DPLOG(ERROR) << "FindFirstChangeNotification failed: " << GetLastError(); |
| 57 return false; |
| 58 } |
| 59 |
| 60 path_ = path; |
| 61 watcher_.StartWatching(handle_, this); |
| 62 return true; |
| 63 } |
| 64 |
| 65 void StorageDeviceWatcher::Cancel() { |
| 66 if (!message_loop()->BelongsToCurrentThread()) { |
| 67 message_loop()->PostTask(FROM_HERE, |
| 68 base::Bind(&StorageDeviceWatcher::CancelOnMessageLoopThread, this)); |
| 69 } else { |
| 70 CancelOnMessageLoopThread(); |
| 71 } |
| 72 } |
| 73 |
| 74 void StorageDeviceWatcher::CancelOnMessageLoopThread() { |
| 75 set_cancelled(); |
| 76 if (handle_ != INVALID_HANDLE_VALUE) |
| 77 DestroyWatch(); |
| 78 |
| 79 MessageLoop::current()->RemoveDestructionObserver(this); |
| 80 } |
| 81 |
| 82 void StorageDeviceWatcher::OnObjectSignaled(HANDLE object) { |
| 83 DCHECK(object == handle_); |
| 84 |
| 85 // TODO (hongbo): need to control the frequency of the storage |
| 86 // free space change event. |
| 87 SystemMonitor::Get()->NotifyStorageFreeSpaceChanged(path_.value()); |
| 88 |
| 89 watcher_.StartWatching(handle_, this); |
| 90 } |
| 91 |
| 92 void StorageDeviceWatcher::DestroyWatch() { |
| 93 watcher_.StopWatching(); |
| 94 FindCloseChangeNotification(handle_); |
| 95 handle_ = INVALID_HANDLE_VALUE; |
| 96 } |
| 97 |
| 98 } |
| 99 |
| 100 bool SystemMonitor::StartWatchStorageDevice(const FilePath::StringType& path) { |
| 101 scoped_refptr<FilePathWatcher::PlatformDelegate> watcher( |
| 102 new StorageDeviceWatcher()); |
| 103 if (watcher->Watch(FilePath(path), NULL)) { |
| 104 storage_watcher_map_.insert( |
| 105 std::pair<FilePath::StringType, |
| 106 scoped_refptr<FilePathWatcher::PlatformDelegate>(path, watcher)); |
| 107 return true; |
| 108 } |
| 109 return false; |
| 110 } |
| 111 |
| 112 bool SystemMonitor::StopWatchStorageDevice(const FilePath::StringType& path) { |
| 113 StorageDeviceWatcherMap::iterator iter = storage_watcher_map_.find(path); |
| 114 if (iter == storage_watcher_map_.end()) |
| 115 return false; |
| 116 |
| 117 iter->second->Cancel(); |
| 118 storage_watcher_map_.erase(iter); |
| 119 return true; |
| 120 } |
| 121 |
| 9 void SystemMonitor::ProcessWmPowerBroadcastMessage(int event_id) { | 122 void SystemMonitor::ProcessWmPowerBroadcastMessage(int event_id) { |
| 10 PowerEvent power_event; | 123 PowerEvent power_event; |
| 11 switch (event_id) { | 124 switch (event_id) { |
| 12 case PBT_APMPOWERSTATUSCHANGE: // The power status changed. | 125 case PBT_APMPOWERSTATUSCHANGE: // The power status changed. |
| 13 power_event = POWER_STATE_EVENT; | 126 power_event = POWER_STATE_EVENT; |
| 14 break; | 127 break; |
| 15 case PBT_APMRESUMEAUTOMATIC: // Resume from suspend. | 128 case PBT_APMRESUMEAUTOMATIC: // Resume from suspend. |
| 16 //case PBT_APMRESUMESUSPEND: // User-initiated resume from suspend. | 129 //case PBT_APMRESUMESUSPEND: // User-initiated resume from suspend. |
| 17 // We don't notify for this latter event | 130 // We don't notify for this latter event |
| 18 // because if it occurs it is always sent as a | 131 // because if it occurs it is always sent as a |
| (...skipping 22 matching lines...) Expand all Loading... |
| 41 bool SystemMonitor::IsBatteryPower() { | 154 bool SystemMonitor::IsBatteryPower() { |
| 42 SYSTEM_POWER_STATUS status; | 155 SYSTEM_POWER_STATUS status; |
| 43 if (!GetSystemPowerStatus(&status)) { | 156 if (!GetSystemPowerStatus(&status)) { |
| 44 DLOG(ERROR) << "GetSystemPowerStatus failed: " << GetLastError(); | 157 DLOG(ERROR) << "GetSystemPowerStatus failed: " << GetLastError(); |
| 45 return false; | 158 return false; |
| 46 } | 159 } |
| 47 return (status.ACLineStatus == 0); | 160 return (status.ACLineStatus == 0); |
| 48 } | 161 } |
| 49 | 162 |
| 50 } // namespace base | 163 } // namespace base |
| OLD | NEW |