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