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
25
26 namespace android
27 {
28 void doStartupConfig ();
29 }
30
31 extern bool gActivated;
32 extern SyncEvent gDeactivatedEvent;
33
34 PowerSwitch PowerSwitch::sPowerSwitch;
35 const PowerSwitch::PowerActivity PowerSwitch::DISCOVERY=0x01;
36 const PowerSwitch::PowerActivity PowerSwitch::SE_ROUTING=0x02;
37 const PowerSwitch::PowerActivity PowerSwitch::SE_CONNECTED=0x04;
38 const PowerSwitch::PowerActivity PowerSwitch::HOST_ROUTING=0x08;
39
40 /*******************************************************************************
41 **
42 ** Function: PowerSwitch
43 **
44 ** Description: Initialize member variables.
45 **
46 ** Returns: None
47 **
48 *******************************************************************************/
PowerSwitch()49 PowerSwitch::PowerSwitch ()
50 : mCurrLevel (UNKNOWN_LEVEL),
51 mCurrDeviceMgtPowerState (NFA_DM_PWR_STATE_UNKNOWN),
52 mExpectedDeviceMgtPowerState (NFA_DM_PWR_STATE_UNKNOWN),
53 mDesiredScreenOffPowerState (0),
54 mCurrActivity(0)
55 {
56 }
57
58
59 /*******************************************************************************
60 **
61 ** Function: ~PowerSwitch
62 **
63 ** Description: Release all resources.
64 **
65 ** Returns: None
66 **
67 *******************************************************************************/
~PowerSwitch()68 PowerSwitch::~PowerSwitch ()
69 {
70 }
71
72
73 /*******************************************************************************
74 **
75 ** Function: getInstance
76 **
77 ** Description: Get the singleton of this object.
78 **
79 ** Returns: Reference to this object.
80 **
81 *******************************************************************************/
getInstance()82 PowerSwitch& PowerSwitch::getInstance ()
83 {
84 return sPowerSwitch;
85 }
86
87
88 /*******************************************************************************
89 **
90 ** Function: initialize
91 **
92 ** Description: Initialize member variables.
93 **
94 ** Returns: None
95 **
96 *******************************************************************************/
initialize(PowerLevel level)97 void PowerSwitch::initialize (PowerLevel level)
98 {
99 static const char fn [] = "PowerSwitch::initialize";
100 unsigned long num = 0;
101
102 mMutex.lock ();
103
104 ALOGD ("%s: level=%s (%u)", fn, powerLevelToString(level), level);
105 if (GetNumValue (NAME_SCREEN_OFF_POWER_STATE, &num, sizeof(num)))
106 mDesiredScreenOffPowerState = (int) num;
107 ALOGD ("%s: desired screen-off state=%d", fn, mDesiredScreenOffPowerState);
108
109 switch (level)
110 {
111 case FULL_POWER:
112 mCurrDeviceMgtPowerState = NFA_DM_PWR_MODE_FULL;
113 mCurrLevel = level;
114 break;
115
116 case UNKNOWN_LEVEL:
117 mCurrDeviceMgtPowerState = NFA_DM_PWR_STATE_UNKNOWN;
118 mCurrLevel = level;
119 break;
120
121 default:
122 ALOGE ("%s: not handled", fn);
123 break;
124 }
125 mMutex.unlock ();
126 }
127
128
129 /*******************************************************************************
130 **
131 ** Function: getLevel
132 **
133 ** Description: Get the current power level of the controller.
134 **
135 ** Returns: Power level.
136 **
137 *******************************************************************************/
getLevel()138 PowerSwitch::PowerLevel PowerSwitch::getLevel ()
139 {
140 PowerLevel level = UNKNOWN_LEVEL;
141 mMutex.lock ();
142 level = mCurrLevel;
143 mMutex.unlock ();
144 return level;
145 }
146
147
148 /*******************************************************************************
149 **
150 ** Function: setLevel
151 **
152 ** Description: Set the controller's power level.
153 ** level: power level.
154 **
155 ** Returns: True if ok.
156 **
157 *******************************************************************************/
setLevel(PowerLevel newLevel)158 bool PowerSwitch::setLevel (PowerLevel newLevel)
159 {
160 static const char fn [] = "PowerSwitch::setLevel";
161 bool retval = false;
162
163 mMutex.lock ();
164
165 ALOGD ("%s: level=%s (%u)", fn, powerLevelToString(newLevel), newLevel);
166 if (mCurrLevel == newLevel)
167 {
168 retval = true;
169 goto TheEnd;
170 }
171
172 if (mCurrLevel == UNKNOWN_LEVEL)
173 {
174 ALOGE ("%s: unknown power level", fn);
175 goto TheEnd;
176 }
177
178 if ( (mCurrLevel == LOW_POWER && newLevel == FULL_POWER) ||
179 (mCurrLevel == FULL_POWER && newLevel == LOW_POWER) )
180 {
181 mMutex.unlock ();
182 SyncEventGuard g (gDeactivatedEvent);
183 if (gActivated)
184 {
185 ALOGD("%s: wait for deactivation", fn);
186 gDeactivatedEvent.wait ();
187 }
188 mMutex.lock ();
189 }
190
191 switch (newLevel)
192 {
193 case FULL_POWER:
194 if (mCurrDeviceMgtPowerState == NFA_DM_PWR_MODE_OFF_SLEEP)
195 retval = setPowerOffSleepState (false);
196 break;
197
198 case LOW_POWER:
199 case POWER_OFF:
200 if (isPowerOffSleepFeatureEnabled())
201 retval = setPowerOffSleepState (true);
202 else if (mDesiredScreenOffPowerState == 1) //.conf file desires full-power
203 {
204 mCurrLevel = FULL_POWER;
205 retval = true;
206 }
207 break;
208
209 default:
210 ALOGE ("%s: not handled", fn);
211 break;
212 }
213
214 ALOGD("%s: actual power level=%s", fn, powerLevelToString(mCurrLevel));
215
216 TheEnd:
217 mMutex.unlock ();
218 return retval;
219 }
220
221
setScreenOffPowerState(ScreenOffPowerState newState)222 bool PowerSwitch::setScreenOffPowerState (ScreenOffPowerState newState)
223 {
224 ALOGD ("PowerSwitch::setScreenOffPowerState: level=%s (%u)",
225 screenOffPowerStateToString(newState), newState);
226
227 mMutex.lock ();
228 mDesiredScreenOffPowerState = (int) newState;
229 mMutex.unlock ();
230
231 return true;
232 }
233
234
235 /*******************************************************************************
236 **
237 ** Function: setModeOff
238 **
239 ** Description: Set a mode to be deactive.
240 **
241 ** Returns: True if any mode is still active.
242 **
243 *******************************************************************************/
setModeOff(PowerActivity deactivated)244 bool PowerSwitch::setModeOff (PowerActivity deactivated)
245 {
246 bool retVal = false;
247
248 mMutex.lock ();
249 mCurrActivity &= ~deactivated;
250 retVal = mCurrActivity != 0;
251 ALOGD ("PowerSwitch::setModeOff(deactivated=0x%x) : mCurrActivity=0x%x", deactivated, mCurrActivity);
252 mMutex.unlock ();
253 return retVal;
254 }
255
256
257 /*******************************************************************************
258 **
259 ** Function: setModeOn
260 **
261 ** Description: Set a mode to be active.
262 **
263 ** Returns: True if any mode is active.
264 **
265 *******************************************************************************/
setModeOn(PowerActivity activated)266 bool PowerSwitch::setModeOn (PowerActivity activated)
267 {
268 bool retVal = false;
269
270 mMutex.lock ();
271 mCurrActivity |= activated;
272 retVal = mCurrActivity != 0;
273 ALOGD ("PowerSwitch::setModeOn(activated=0x%x) : mCurrActivity=0x%x", activated, mCurrActivity);
274 mMutex.unlock ();
275 return retVal;
276 }
277
278
279 /*******************************************************************************
280 **
281 ** Function: setPowerOffSleepState
282 **
283 ** Description: Adjust controller's power-off-sleep state.
284 ** sleep: whether to enter sleep state.
285 **
286 ** Returns: True if ok.
287 **
288 *******************************************************************************/
setPowerOffSleepState(bool sleep)289 bool PowerSwitch::setPowerOffSleepState (bool sleep)
290 {
291 static const char fn [] = "PowerSwitch::setPowerOffSleepState";
292 ALOGD ("%s: enter; sleep=%u", fn, sleep);
293 tNFA_STATUS stat = NFA_STATUS_FAILED;
294 bool retval = false;
295
296 if (sleep) //enter power-off-sleep state
297 {
298 //make sure the current power state is ON
299 if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_OFF_SLEEP)
300 {
301 SyncEventGuard guard (mPowerStateEvent);
302 mExpectedDeviceMgtPowerState = NFA_DM_PWR_MODE_OFF_SLEEP; //if power adjustment is ok, then this is the expected state
303 ALOGD ("%s: try power off", fn);
304 stat = NFA_PowerOffSleepMode (TRUE);
305 if (stat == NFA_STATUS_OK)
306 {
307 mPowerStateEvent.wait ();
308 mCurrLevel = LOW_POWER;
309 }
310 else
311 {
312 ALOGE ("%s: API fail; stat=0x%X", fn, stat);
313 goto TheEnd;
314 }
315 }
316 else
317 {
318 ALOGE ("%s: power is not ON; curr device mgt power state=%s (%u)", fn,
319 deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState);
320 goto TheEnd;
321 }
322 }
323 else //exit power-off-sleep state
324 {
325 //make sure the current power state is OFF
326 if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_FULL)
327 {
328 SyncEventGuard guard (mPowerStateEvent);
329 mCurrDeviceMgtPowerState = NFA_DM_PWR_STATE_UNKNOWN;
330 mExpectedDeviceMgtPowerState = NFA_DM_PWR_MODE_FULL; //if power adjustment is ok, then this is the expected state
331 ALOGD ("%s: try full power", fn);
332 stat = NFA_PowerOffSleepMode (FALSE);
333 if (stat == NFA_STATUS_OK)
334 {
335 mPowerStateEvent.wait ();
336 if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_FULL)
337 {
338 ALOGE ("%s: unable to full power; curr device mgt power stat=%s (%u)", fn,
339 deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState);
340 goto TheEnd;
341 }
342 android::doStartupConfig ();
343 mCurrLevel = FULL_POWER;
344 }
345 else
346 {
347 ALOGE ("%s: API fail; stat=0x%X", fn, stat);
348 goto TheEnd;
349 }
350 }
351 else
352 {
353 ALOGE ("%s: not in power-off state; curr device mgt power state=%s (%u)", fn,
354 deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState);
355 goto TheEnd;
356 }
357 }
358
359 retval = true;
360 TheEnd:
361 ALOGD ("%s: exit; return %u", fn, retval);
362 return retval;
363 }
364
365
366 /*******************************************************************************
367 **
368 ** Function: deviceMgtPowerStateToString
369 **
370 ** Description: Decode power level to a string.
371 ** deviceMgtPowerState: power level.
372 **
373 ** Returns: Text representation of power level.
374 **
375 *******************************************************************************/
deviceMgtPowerStateToString(UINT8 deviceMgtPowerState)376 const char* PowerSwitch::deviceMgtPowerStateToString (UINT8 deviceMgtPowerState)
377 {
378 switch (deviceMgtPowerState)
379 {
380 case NFA_DM_PWR_MODE_FULL:
381 return "DM-FULL";
382 case NFA_DM_PWR_MODE_OFF_SLEEP:
383 return "DM-OFF";
384 default:
385 return "DM-unknown????";
386 }
387 }
388
389
390 /*******************************************************************************
391 **
392 ** Function: powerLevelToString
393 **
394 ** Description: Decode power level to a string.
395 ** level: power level.
396 **
397 ** Returns: Text representation of power level.
398 **
399 *******************************************************************************/
powerLevelToString(PowerLevel level)400 const char* PowerSwitch::powerLevelToString (PowerLevel level)
401 {
402 switch (level)
403 {
404 case UNKNOWN_LEVEL:
405 return "PS-UNKNOWN";
406 case FULL_POWER:
407 return "PS-FULL";
408 case LOW_POWER:
409 return "PS-LOW-POWER";
410 case POWER_OFF:
411 return "PS-POWER-OFF";
412 default:
413 return "PS-unknown????";
414 }
415 }
416
417 /*******************************************************************************
418 **
419 ** Function: screenOffPowerStateToString
420 **
421 ** Description: Decode power level to a string.
422 ** level: power level.
423 **
424 ** Returns: Text representation of power level.
425 **
426 *******************************************************************************/
screenOffPowerStateToString(ScreenOffPowerState state)427 const char* PowerSwitch::screenOffPowerStateToString (ScreenOffPowerState state)
428 {
429 switch (state)
430 {
431 case POWER_STATE_OFF:
432 return "SOPS-POWER_OFF";
433 case POWER_STATE_FULL:
434 return "SOPS-FULL";
435 case POWER_STATE_CARD_EMULATION:
436 return "SOPS-CARD_EMULATION";
437 default:
438 return "SOPS-unknown????";
439 }
440 }
441
442 /*******************************************************************************
443 **
444 ** Function: abort
445 **
446 ** Description: Abort and unblock currrent operation.
447 **
448 ** Returns: None
449 **
450 *******************************************************************************/
abort()451 void PowerSwitch::abort ()
452 {
453 static const char fn [] = "PowerSwitch::abort";
454 ALOGD ("%s", fn);
455 SyncEventGuard guard (mPowerStateEvent);
456 mPowerStateEvent.notifyOne ();
457 }
458
459
460 /*******************************************************************************
461 **
462 ** Function: deviceManagementCallback
463 **
464 ** Description: Callback function for the stack.
465 ** event: event ID.
466 ** eventData: event's data.
467 **
468 ** Returns: None
469 **
470 *******************************************************************************/
deviceManagementCallback(UINT8 event,tNFA_DM_CBACK_DATA * eventData)471 void PowerSwitch::deviceManagementCallback (UINT8 event, tNFA_DM_CBACK_DATA* eventData)
472 {
473 static const char fn [] = "PowerSwitch::deviceManagementCallback";
474
475 switch (event)
476 {
477 case NFA_DM_PWR_MODE_CHANGE_EVT:
478 {
479 tNFA_DM_PWR_MODE_CHANGE& power_mode = eventData->power_mode;
480 ALOGD ("%s: NFA_DM_PWR_MODE_CHANGE_EVT; status=0x%X; device mgt power state=%s (0x%X)", fn,
481 power_mode.status, sPowerSwitch.deviceMgtPowerStateToString (power_mode.power_mode),
482 power_mode.power_mode);
483 SyncEventGuard guard (sPowerSwitch.mPowerStateEvent);
484 if (power_mode.status == NFA_STATUS_OK)
485 {
486 //the event data does not contain the newly configured power mode,
487 //so this code assigns the expected value
488 sPowerSwitch.mCurrDeviceMgtPowerState = sPowerSwitch.mExpectedDeviceMgtPowerState;
489 }
490 sPowerSwitch.mPowerStateEvent.notifyOne ();
491 }
492 break;
493 }
494 }
495
496
497 /*******************************************************************************
498 **
499 ** Function: isPowerOffSleepFeatureEnabled
500 **
501 ** Description: Whether power-off-sleep feature is enabled in .conf file.
502 **
503 ** Returns: True if feature is enabled.
504 **
505 *******************************************************************************/
isPowerOffSleepFeatureEnabled()506 bool PowerSwitch::isPowerOffSleepFeatureEnabled ()
507 {
508 return mDesiredScreenOffPowerState == 0;
509 }
510
511