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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 435 bool PowerSwitch::isPowerOffSleepFeatureEnabled () 436 { 437 return mDesiredScreenOffPowerState == 0; 438 } 439 440