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:
PowerLibraryImpl()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
~PowerLibraryImpl()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
AddObserver(Observer * observer)37 void AddObserver(Observer* observer) {
38 observers_.AddObserver(observer);
39 }
40
RemoveObserver(Observer * observer)41 void RemoveObserver(Observer* observer) {
42 observers_.RemoveObserver(observer);
43 }
44
line_power_on() const45 bool line_power_on() const {
46 return status_.line_power_on;
47 }
48
battery_is_present() const49 bool battery_is_present() const {
50 return status_.battery_is_present;
51 }
52
battery_fully_charged() const53 bool battery_fully_charged() const {
54 return status_.battery_state == chromeos::BATTERY_STATE_FULLY_CHARGED;
55 }
56
battery_percentage() const57 double battery_percentage() const {
58 return status_.battery_percentage;
59 }
60
battery_time_to_empty() const61 base::TimeDelta battery_time_to_empty() const {
62 return base::TimeDelta::FromSeconds(status_.battery_time_to_empty);
63 }
64
battery_time_to_full() const65 base::TimeDelta battery_time_to_full() const {
66 return base::TimeDelta::FromSeconds(status_.battery_time_to_full);
67 }
68
EnableScreenLock(bool enable)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
RequestRestart()85 virtual void RequestRestart() {
86 if (!CrosLibrary::Get()->EnsureLoaded())
87 return;
88 chromeos::RequestRestart();
89 }
90
RequestShutdown()91 virtual void RequestShutdown() {
92 if (!CrosLibrary::Get()->EnsureLoaded())
93 return;
94 chromeos::RequestShutdown();
95 }
96
97 private:
PowerStatusChangedHandler(void * object,const chromeos::PowerStatus & status)98 static void PowerStatusChangedHandler(void* object,
99 const chromeos::PowerStatus& status) {
100 PowerLibraryImpl* power = static_cast<PowerLibraryImpl*>(object);
101 power->UpdatePowerStatus(status);
102 }
103
SystemResumedHandler(void * object)104 static void SystemResumedHandler(void* object) {
105 PowerLibraryImpl* power = static_cast<PowerLibraryImpl*>(object);
106 power->SystemResumed();
107 }
108
Init()109 void Init() {
110 power_status_connection_ = chromeos::MonitorPowerStatus(
111 &PowerStatusChangedHandler, this);
112 resume_status_connection_ =
113 chromeos::MonitorResume(&SystemResumedHandler, this);
114 }
115
UpdatePowerStatus(const chromeos::PowerStatus & status)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
SystemResumed()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:
PowerLibraryStubImpl()164 PowerLibraryStubImpl() {}
~PowerLibraryStubImpl()165 ~PowerLibraryStubImpl() {}
AddObserver(Observer * observer)166 void AddObserver(Observer* observer) {}
RemoveObserver(Observer * observer)167 void RemoveObserver(Observer* observer) {}
line_power_on() const168 bool line_power_on() const { return false; }
battery_is_present() const169 bool battery_is_present() const { return true; }
battery_fully_charged() const170 bool battery_fully_charged() const { return false; }
battery_percentage() const171 double battery_percentage() const { return 50.0; }
battery_time_to_empty() const172 base::TimeDelta battery_time_to_empty() const {
173 return base::TimeDelta::FromSeconds(10 * 60);
174 }
battery_time_to_full() const175 base::TimeDelta battery_time_to_full() const {
176 return base::TimeDelta::FromSeconds(0);
177 }
EnableScreenLock(bool enable)178 virtual void EnableScreenLock(bool enable) {}
RequestRestart()179 virtual void RequestRestart() {}
RequestShutdown()180 virtual void RequestShutdown() {}
181 };
182
183 // static
GetImpl(bool stub)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