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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/cros/power_library.h" 6 7 #include "base/message_loop.h" 8 #include "base/string_util.h" 9 #include "chrome/browser/chromeos/cros/cros_library.h" 10 #include "content/browser/browser_thread.h" 11 #include "third_party/cros/chromeos_resume.h" 12 13 namespace chromeos { 14 15 class PowerLibraryImpl : public PowerLibrary { 16 public: 17 PowerLibraryImpl() 18 : power_status_connection_(NULL), 19 resume_status_connection_(NULL), 20 status_(chromeos::PowerStatus()) { 21 if (CrosLibrary::Get()->EnsureLoaded()) { 22 Init(); 23 } 24 } 25 26 ~PowerLibraryImpl() { 27 if (power_status_connection_) { 28 chromeos::DisconnectPowerStatus(power_status_connection_); 29 power_status_connection_ = NULL; 30 } 31 if (resume_status_connection_) { 32 chromeos::DisconnectResume(resume_status_connection_); 33 resume_status_connection_ = NULL; 34 } 35 } 36 37 void AddObserver(Observer* observer) { 38 observers_.AddObserver(observer); 39 } 40 41 void RemoveObserver(Observer* observer) { 42 observers_.RemoveObserver(observer); 43 } 44 45 bool line_power_on() const { 46 return status_.line_power_on; 47 } 48 49 bool battery_is_present() const { 50 return status_.battery_is_present; 51 } 52 53 bool battery_fully_charged() const { 54 return status_.battery_state == chromeos::BATTERY_STATE_FULLY_CHARGED; 55 } 56 57 double battery_percentage() const { 58 return status_.battery_percentage; 59 } 60 61 base::TimeDelta battery_time_to_empty() const { 62 return base::TimeDelta::FromSeconds(status_.battery_time_to_empty); 63 } 64 65 base::TimeDelta battery_time_to_full() const { 66 return base::TimeDelta::FromSeconds(status_.battery_time_to_full); 67 } 68 69 virtual void EnableScreenLock(bool enable) { 70 if (!CrosLibrary::Get()->EnsureLoaded()) 71 return; 72 73 // Make sure we run on FILE thread becuase chromeos::EnableScreenLock 74 // would write power manager config file to disk. 75 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { 76 BrowserThread::PostTask( 77 BrowserThread::FILE, FROM_HERE, 78 NewRunnableMethod(this, &PowerLibraryImpl::EnableScreenLock, enable)); 79 return; 80 } 81 82 chromeos::EnableScreenLock(enable); 83 } 84 85 virtual void RequestRestart() { 86 if (!CrosLibrary::Get()->EnsureLoaded()) 87 return; 88 chromeos::RequestRestart(); 89 } 90 91 virtual void RequestShutdown() { 92 if (!CrosLibrary::Get()->EnsureLoaded()) 93 return; 94 chromeos::RequestShutdown(); 95 } 96 97 private: 98 static void PowerStatusChangedHandler(void* object, 99 const chromeos::PowerStatus& status) { 100 PowerLibraryImpl* power = static_cast<PowerLibraryImpl*>(object); 101 power->UpdatePowerStatus(status); 102 } 103 104 static void SystemResumedHandler(void* object) { 105 PowerLibraryImpl* power = static_cast<PowerLibraryImpl*>(object); 106 power->SystemResumed(); 107 } 108 109 void Init() { 110 power_status_connection_ = chromeos::MonitorPowerStatus( 111 &PowerStatusChangedHandler, this); 112 resume_status_connection_ = 113 chromeos::MonitorResume(&SystemResumedHandler, this); 114 } 115 116 void UpdatePowerStatus(const chromeos::PowerStatus& status) { 117 // Make sure we run on UI thread. 118 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 119 BrowserThread::PostTask( 120 BrowserThread::UI, FROM_HERE, 121 NewRunnableMethod( 122 this, &PowerLibraryImpl::UpdatePowerStatus, status)); 123 return; 124 } 125 126 DVLOG(1) << "Power lpo=" << status.line_power_on 127 << " sta=" << status.battery_state 128 << " per=" << status.battery_percentage 129 << " tte=" << status.battery_time_to_empty 130 << " ttf=" << status.battery_time_to_full; 131 status_ = status; 132 FOR_EACH_OBSERVER(Observer, observers_, PowerChanged(this)); 133 } 134 135 void SystemResumed() { 136 // Make sure we run on the UI thread. 137 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 138 BrowserThread::PostTask( 139 BrowserThread::UI, FROM_HERE, 140 NewRunnableMethod(this, &PowerLibraryImpl::SystemResumed)); 141 return; 142 } 143 144 FOR_EACH_OBSERVER(Observer, observers_, SystemResumed()); 145 } 146 147 ObserverList<Observer> observers_; 148 149 // A reference to the battery power api, to allow callbacks when the battery 150 // status changes. 151 chromeos::PowerStatusConnection power_status_connection_; 152 153 // A reference to the resume alerts. 154 chromeos::ResumeConnection resume_status_connection_; 155 156 // The latest power status. 157 chromeos::PowerStatus status_; 158 159 DISALLOW_COPY_AND_ASSIGN(PowerLibraryImpl); 160 }; 161 162 class PowerLibraryStubImpl : public PowerLibrary { 163 public: 164 PowerLibraryStubImpl() {} 165 ~PowerLibraryStubImpl() {} 166 void AddObserver(Observer* observer) {} 167 void RemoveObserver(Observer* observer) {} 168 bool line_power_on() const { return false; } 169 bool battery_is_present() const { return true; } 170 bool battery_fully_charged() const { return false; } 171 double battery_percentage() const { return 50.0; } 172 base::TimeDelta battery_time_to_empty() const { 173 return base::TimeDelta::FromSeconds(10 * 60); 174 } 175 base::TimeDelta battery_time_to_full() const { 176 return base::TimeDelta::FromSeconds(0); 177 } 178 virtual void EnableScreenLock(bool enable) {} 179 virtual void RequestRestart() {} 180 virtual void RequestShutdown() {} 181 }; 182 183 // static 184 PowerLibrary* PowerLibrary::GetImpl(bool stub) { 185 if (stub) 186 return new PowerLibraryStubImpl(); 187 else 188 return new PowerLibraryImpl(); 189 } 190 191 } // namespace chromeos 192 193 // Allows InvokeLater without adding refcounting. This class is a Singleton and 194 // won't be deleted until it's last InvokeLater is run. 195 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::PowerLibraryImpl); 196