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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 506 bool PowerSwitch::isPowerOffSleepFeatureEnabled () 507 { 508 return mDesiredScreenOffPowerState == 0; 509 } 510 511