1 /*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*
18 * Adjust the controller's power states.
19 */
20 #include "OverrideLog.h"
21 #include "PowerSwitch.h"
22 #include "NfcJniUtil.h"
23 #include "config.h"
24 #include "SecureElement.h"
25
26
27 namespace android
28 {
29 void doStartupConfig ();
30 }
31
32
33 PowerSwitch PowerSwitch::sPowerSwitch;
34 const PowerSwitch::PowerActivity PowerSwitch::DISCOVERY=0x01;
35 const PowerSwitch::PowerActivity PowerSwitch::SE_ROUTING=0x02;
36 const PowerSwitch::PowerActivity PowerSwitch::SE_CONNECTED=0x04;
37
38 /*******************************************************************************
39 **
40 ** Function: PowerSwitch
41 **
42 ** Description: Initialize member variables.
43 **
44 ** Returns: None
45 **
46 *******************************************************************************/
PowerSwitch()47 PowerSwitch::PowerSwitch ()
48 : mCurrLevel (UNKNOWN_LEVEL),
49 mCurrDeviceMgtPowerState (NFA_DM_PWR_STATE_UNKNOWN),
50 mDesiredScreenOffPowerState (0),
51 mCurrActivity(0)
52 {
53 }
54
55
56 /*******************************************************************************
57 **
58 ** Function: ~PowerSwitch
59 **
60 ** Description: Release all resources.
61 **
62 ** Returns: None
63 **
64 *******************************************************************************/
~PowerSwitch()65 PowerSwitch::~PowerSwitch ()
66 {
67 }
68
69
70 /*******************************************************************************
71 **
72 ** Function: getInstance
73 **
74 ** Description: Get the singleton of this object.
75 **
76 ** Returns: Reference to this object.
77 **
78 *******************************************************************************/
getInstance()79 PowerSwitch& PowerSwitch::getInstance ()
80 {
81 return sPowerSwitch;
82 }
83
84
85 /*******************************************************************************
86 **
87 ** Function: initialize
88 **
89 ** Description: Initialize member variables.
90 **
91 ** Returns: None
92 **
93 *******************************************************************************/
initialize(PowerLevel level)94 void PowerSwitch::initialize (PowerLevel level)
95 {
96 static const char fn [] = "PowerSwitch::initialize";
97
98 mMutex.lock ();
99
100 ALOGD ("%s: level=%s (%u)", fn, powerLevelToString(level), level);
101 GetNumValue (NAME_SCREEN_OFF_POWER_STATE, &mDesiredScreenOffPowerState, sizeof(mDesiredScreenOffPowerState));
102 ALOGD ("%s: desired screen-off state=%d", fn, mDesiredScreenOffPowerState);
103
104 switch (level)
105 {
106 case FULL_POWER:
107 mCurrDeviceMgtPowerState = NFA_DM_PWR_MODE_FULL;
108 mCurrLevel = level;
109 break;
110
111 case UNKNOWN_LEVEL:
112 mCurrDeviceMgtPowerState = NFA_DM_PWR_STATE_UNKNOWN;
113 mCurrLevel = level;
114 break;
115
116 default:
117 ALOGE ("%s: not handled", fn);
118 break;
119 }
120 mMutex.unlock ();
121 }
122
123
124 /*******************************************************************************
125 **
126 ** Function: getLevel
127 **
128 ** Description: Get the current power level of the controller.
129 **
130 ** Returns: Power level.
131 **
132 *******************************************************************************/
getLevel()133 PowerSwitch::PowerLevel PowerSwitch::getLevel ()
134 {
135 PowerLevel level = UNKNOWN_LEVEL;
136 mMutex.lock ();
137 level = mCurrLevel;
138 mMutex.unlock ();
139 return level;
140 }
141
142
143 /*******************************************************************************
144 **
145 ** Function: setLevel
146 **
147 ** Description: Set the controller's power level.
148 ** level: power level.
149 **
150 ** Returns: True if ok.
151 **
152 *******************************************************************************/
setLevel(PowerLevel newLevel)153 bool PowerSwitch::setLevel (PowerLevel newLevel)
154 {
155 static const char fn [] = "PowerSwitch::setLevel";
156 bool retval = false;
157
158 mMutex.lock ();
159
160 ALOGD ("%s: level=%s (%u)", fn, powerLevelToString(newLevel), newLevel);
161 if (mCurrLevel == newLevel)
162 {
163 retval = true;
164 goto TheEnd;
165 }
166
167 switch (newLevel)
168 {
169 case FULL_POWER:
170 if (mCurrDeviceMgtPowerState == NFA_DM_PWR_MODE_OFF_SLEEP)
171 retval = setPowerOffSleepState (false);
172 break;
173
174 case LOW_POWER:
175 case POWER_OFF:
176 if (isPowerOffSleepFeatureEnabled())
177 retval = setPowerOffSleepState (true);
178 else if (mDesiredScreenOffPowerState == 1) //.conf file desires full-power
179 {
180 mCurrLevel = FULL_POWER;
181 retval = true;
182 }
183 break;
184
185 default:
186 ALOGE ("%s: not handled", fn);
187 break;
188 }
189
190 TheEnd:
191 mMutex.unlock ();
192 return retval;
193 }
194
195 /*******************************************************************************
196 **
197 ** Function: setModeOff
198 **
199 ** Description: Set a mode to be deactive.
200 **
201 ** Returns: True if any mode is still active.
202 **
203 *******************************************************************************/
setModeOff(PowerActivity deactivated)204 bool PowerSwitch::setModeOff (PowerActivity deactivated)
205 {
206 bool retVal = false;
207
208 mMutex.lock ();
209 mCurrActivity &= ~deactivated;
210 retVal = mCurrActivity != 0;
211 ALOGD ("PowerSwitch::setModeOff(deactivated=0x%x) : mCurrActivity=0x%x", deactivated, mCurrActivity);
212 mMutex.unlock ();
213 return retVal;
214 }
215
216
217 /*******************************************************************************
218 **
219 ** Function: setModeOn
220 **
221 ** Description: Set a mode to be active.
222 **
223 ** Returns: True if any mode is active.
224 **
225 *******************************************************************************/
setModeOn(PowerActivity activated)226 bool PowerSwitch::setModeOn (PowerActivity activated)
227 {
228 bool retVal = false;
229
230 mMutex.lock ();
231 mCurrActivity |= activated;
232 retVal = mCurrActivity != 0;
233 ALOGD ("PowerSwitch::setModeOn(activated=0x%x) : mCurrActivity=0x%x", activated, mCurrActivity);
234 mMutex.unlock ();
235 return retVal;
236 }
237
238
239 /*******************************************************************************
240 **
241 ** Function: setPowerOffSleepState
242 **
243 ** Description: Adjust controller's power-off-sleep state.
244 ** sleep: whether to enter sleep state.
245 **
246 ** Returns: True if ok.
247 **
248 *******************************************************************************/
setPowerOffSleepState(bool sleep)249 bool PowerSwitch::setPowerOffSleepState (bool sleep)
250 {
251 static const char fn [] = "PowerSwitch::setPowerOffSleepState";
252 ALOGD ("%s: enter; sleep=%u", fn, sleep);
253 tNFA_STATUS stat = NFA_STATUS_FAILED;
254 bool retval = false;
255
256 if (sleep) //enter power-off-sleep state
257 {
258 //make sure the current power state is ON
259 if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_OFF_SLEEP)
260 {
261 SyncEventGuard guard (mPowerStateEvent);
262 ALOGD ("%s: try power off", fn);
263 stat = NFA_PowerOffSleepMode (TRUE);
264 if (stat == NFA_STATUS_OK)
265 {
266 mPowerStateEvent.wait ();
267 mCurrLevel = LOW_POWER;
268 }
269 else
270 {
271 ALOGE ("%s: API fail; stat=0x%X", fn, stat);
272 goto TheEnd;
273 }
274 }
275 else
276 {
277 ALOGE ("%s: power is not ON; curr device mgt power state=%s (%u)", fn,
278 deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState);
279 goto TheEnd;
280 }
281 }
282 else //exit power-off-sleep state
283 {
284 //make sure the current power state is OFF
285 if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_FULL)
286 {
287 mCurrDeviceMgtPowerState = NFA_DM_PWR_STATE_UNKNOWN;
288 SyncEventGuard guard (mPowerStateEvent);
289 ALOGD ("%s: try full power", fn);
290 stat = NFA_PowerOffSleepMode (FALSE);
291 if (stat == NFA_STATUS_OK)
292 {
293 mPowerStateEvent.wait ();
294 if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_FULL)
295 {
296 ALOGE ("%s: unable to full power; curr device mgt power stat=%s (%u)", fn,
297 deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState);
298 goto TheEnd;
299 }
300 android::doStartupConfig ();
301 mCurrLevel = FULL_POWER;
302 }
303 else
304 {
305 ALOGE ("%s: API fail; stat=0x%X", fn, stat);
306 goto TheEnd;
307 }
308 }
309 else
310 {
311 ALOGE ("%s: not in power-off state; curr device mgt power state=%s (%u)", fn,
312 deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState);
313 goto TheEnd;
314 }
315 }
316
317 retval = true;
318 TheEnd:
319 ALOGD ("%s: exit; return %u", fn, retval);
320 return retval;
321 }
322
323
324 /*******************************************************************************
325 **
326 ** Function: deviceMgtPowerStateToString
327 **
328 ** Description: Decode power level to a string.
329 ** deviceMgtPowerState: power level.
330 **
331 ** Returns: Text representation of power level.
332 **
333 *******************************************************************************/
deviceMgtPowerStateToString(UINT8 deviceMgtPowerState)334 const char* PowerSwitch::deviceMgtPowerStateToString (UINT8 deviceMgtPowerState)
335 {
336 switch (deviceMgtPowerState)
337 {
338 case NFA_DM_PWR_MODE_FULL:
339 return "DM-FULL";
340 case NFA_DM_PWR_MODE_OFF_SLEEP:
341 return "DM-OFF";
342 default:
343 return "DM-unknown????";
344 }
345 }
346
347
348 /*******************************************************************************
349 **
350 ** Function: powerLevelToString
351 **
352 ** Description: Decode power level to a string.
353 ** level: power level.
354 **
355 ** Returns: Text representation of power level.
356 **
357 *******************************************************************************/
powerLevelToString(PowerLevel level)358 const char* PowerSwitch::powerLevelToString (PowerLevel level)
359 {
360 switch (level)
361 {
362 case UNKNOWN_LEVEL:
363 return "PS-UNKNOWN";
364 case FULL_POWER:
365 return "PS-FULL";
366 case LOW_POWER:
367 return "PS-LOW-POWER";
368 case POWER_OFF:
369 return "PS-POWER-OFF";
370 default:
371 return "PS-unknown????";
372 }
373 }
374
375
376 /*******************************************************************************
377 **
378 ** Function: abort
379 **
380 ** Description: Abort and unblock currrent operation.
381 **
382 ** Returns: None
383 **
384 *******************************************************************************/
abort()385 void PowerSwitch::abort ()
386 {
387 static const char fn [] = "PowerSwitch::abort";
388 ALOGD ("%s", fn);
389 SyncEventGuard guard (mPowerStateEvent);
390 mPowerStateEvent.notifyOne ();
391 }
392
393
394 /*******************************************************************************
395 **
396 ** Function: deviceManagementCallback
397 **
398 ** Description: Callback function for the stack.
399 ** event: event ID.
400 ** eventData: event's data.
401 **
402 ** Returns: None
403 **
404 *******************************************************************************/
deviceManagementCallback(UINT8 event,tNFA_DM_CBACK_DATA * eventData)405 void PowerSwitch::deviceManagementCallback (UINT8 event, tNFA_DM_CBACK_DATA* eventData)
406 {
407 static const char fn [] = "PowerSwitch::deviceManagementCallback";
408
409 switch (event)
410 {
411 case NFA_DM_PWR_MODE_CHANGE_EVT:
412 {
413 tNFA_DM_PWR_MODE_CHANGE& power_mode = eventData->power_mode;
414 ALOGD ("%s: NFA_DM_PWR_MODE_CHANGE_EVT; status=%u; device mgt power mode=%s (%u)", fn,
415 power_mode.status, sPowerSwitch.deviceMgtPowerStateToString (power_mode.power_mode), power_mode.power_mode);
416 SyncEventGuard guard (sPowerSwitch.mPowerStateEvent);
417 if (power_mode.status == NFA_STATUS_OK)
418 sPowerSwitch.mCurrDeviceMgtPowerState = power_mode.power_mode;
419 sPowerSwitch.mPowerStateEvent.notifyOne ();
420 }
421 break;
422 }
423 }
424
425
426 /*******************************************************************************
427 **
428 ** Function: isPowerOffSleepFeatureEnabled
429 **
430 ** Description: Whether power-off-sleep feature is enabled in .conf file.
431 **
432 ** Returns: True if feature is enabled.
433 **
434 *******************************************************************************/
isPowerOffSleepFeatureEnabled()435 bool PowerSwitch::isPowerOffSleepFeatureEnabled ()
436 {
437 return mDesiredScreenOffPowerState == 0;
438 }
439
440