PowerSwitch.cpp revision d2604c0544f7bc26e5b2407f0215cccfffedae2c
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 27namespace android 28{ 29 void doStartupConfig (); 30} 31 32extern bool gActivated; 33extern SyncEvent gDeactivatedEvent; 34 35PowerSwitch PowerSwitch::sPowerSwitch; 36const PowerSwitch::PowerActivity PowerSwitch::DISCOVERY=0x01; 37const PowerSwitch::PowerActivity PowerSwitch::SE_ROUTING=0x02; 38const PowerSwitch::PowerActivity PowerSwitch::SE_CONNECTED=0x04; 39const PowerSwitch::PowerActivity PowerSwitch::HOST_ROUTING=0x08; 40 41/******************************************************************************* 42** 43** Function: PowerSwitch 44** 45** Description: Initialize member variables. 46** 47** Returns: None 48** 49*******************************************************************************/ 50PowerSwitch::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*******************************************************************************/ 69PowerSwitch::~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*******************************************************************************/ 83PowerSwitch& 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*******************************************************************************/ 98void 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*******************************************************************************/ 139PowerSwitch::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*******************************************************************************/ 159bool 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 ALOGD("%s: actual power level=%s", fn, powerLevelToString(mCurrLevel)); 216 217TheEnd: 218 mMutex.unlock (); 219 return retval; 220} 221 222 223bool PowerSwitch::setScreenOffPowerState (ScreenOffPowerState newState) 224{ 225 ALOGD ("PowerSwitch::setScreenOffPowerState: level=%s (%u)", 226 screenOffPowerStateToString(newState), newState); 227 228 mMutex.lock (); 229 mDesiredScreenOffPowerState = (int) newState; 230 mMutex.unlock (); 231 232 return true; 233} 234 235 236/******************************************************************************* 237** 238** Function: setModeOff 239** 240** Description: Set a mode to be deactive. 241** 242** Returns: True if any mode is still active. 243** 244*******************************************************************************/ 245bool PowerSwitch::setModeOff (PowerActivity deactivated) 246{ 247 bool retVal = false; 248 249 mMutex.lock (); 250 mCurrActivity &= ~deactivated; 251 retVal = mCurrActivity != 0; 252 ALOGD ("PowerSwitch::setModeOff(deactivated=0x%x) : mCurrActivity=0x%x", deactivated, mCurrActivity); 253 mMutex.unlock (); 254 return retVal; 255} 256 257 258/******************************************************************************* 259** 260** Function: setModeOn 261** 262** Description: Set a mode to be active. 263** 264** Returns: True if any mode is active. 265** 266*******************************************************************************/ 267bool PowerSwitch::setModeOn (PowerActivity activated) 268{ 269 bool retVal = false; 270 271 mMutex.lock (); 272 mCurrActivity |= activated; 273 retVal = mCurrActivity != 0; 274 ALOGD ("PowerSwitch::setModeOn(activated=0x%x) : mCurrActivity=0x%x", activated, mCurrActivity); 275 mMutex.unlock (); 276 return retVal; 277} 278 279 280/******************************************************************************* 281** 282** Function: setPowerOffSleepState 283** 284** Description: Adjust controller's power-off-sleep state. 285** sleep: whether to enter sleep state. 286** 287** Returns: True if ok. 288** 289*******************************************************************************/ 290bool PowerSwitch::setPowerOffSleepState (bool sleep) 291{ 292 static const char fn [] = "PowerSwitch::setPowerOffSleepState"; 293 ALOGD ("%s: enter; sleep=%u", fn, sleep); 294 tNFA_STATUS stat = NFA_STATUS_FAILED; 295 bool retval = false; 296 297 if (sleep) //enter power-off-sleep state 298 { 299 //make sure the current power state is ON 300 if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_OFF_SLEEP) 301 { 302 SyncEventGuard guard (mPowerStateEvent); 303 mExpectedDeviceMgtPowerState = NFA_DM_PWR_MODE_OFF_SLEEP; //if power adjustment is ok, then this is the expected state 304 ALOGD ("%s: try power off", fn); 305 stat = NFA_PowerOffSleepMode (TRUE); 306 if (stat == NFA_STATUS_OK) 307 { 308 mPowerStateEvent.wait (); 309 mCurrLevel = LOW_POWER; 310 } 311 else 312 { 313 ALOGE ("%s: API fail; stat=0x%X", fn, stat); 314 goto TheEnd; 315 } 316 } 317 else 318 { 319 ALOGE ("%s: power is not ON; curr device mgt power state=%s (%u)", fn, 320 deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState); 321 goto TheEnd; 322 } 323 } 324 else //exit power-off-sleep state 325 { 326 //make sure the current power state is OFF 327 if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_FULL) 328 { 329 SyncEventGuard guard (mPowerStateEvent); 330 mCurrDeviceMgtPowerState = NFA_DM_PWR_STATE_UNKNOWN; 331 mExpectedDeviceMgtPowerState = NFA_DM_PWR_MODE_FULL; //if power adjustment is ok, then this is the expected state 332 ALOGD ("%s: try full power", fn); 333 stat = NFA_PowerOffSleepMode (FALSE); 334 if (stat == NFA_STATUS_OK) 335 { 336 mPowerStateEvent.wait (); 337 if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_FULL) 338 { 339 ALOGE ("%s: unable to full power; curr device mgt power stat=%s (%u)", fn, 340 deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState); 341 goto TheEnd; 342 } 343 android::doStartupConfig (); 344 mCurrLevel = FULL_POWER; 345 } 346 else 347 { 348 ALOGE ("%s: API fail; stat=0x%X", fn, stat); 349 goto TheEnd; 350 } 351 } 352 else 353 { 354 ALOGE ("%s: not in power-off state; curr device mgt power state=%s (%u)", fn, 355 deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState); 356 goto TheEnd; 357 } 358 } 359 360 retval = true; 361TheEnd: 362 ALOGD ("%s: exit; return %u", fn, retval); 363 return retval; 364} 365 366 367/******************************************************************************* 368** 369** Function: deviceMgtPowerStateToString 370** 371** Description: Decode power level to a string. 372** deviceMgtPowerState: power level. 373** 374** Returns: Text representation of power level. 375** 376*******************************************************************************/ 377const char* PowerSwitch::deviceMgtPowerStateToString (UINT8 deviceMgtPowerState) 378{ 379 switch (deviceMgtPowerState) 380 { 381 case NFA_DM_PWR_MODE_FULL: 382 return "DM-FULL"; 383 case NFA_DM_PWR_MODE_OFF_SLEEP: 384 return "DM-OFF"; 385 default: 386 return "DM-unknown????"; 387 } 388} 389 390 391/******************************************************************************* 392** 393** Function: powerLevelToString 394** 395** Description: Decode power level to a string. 396** level: power level. 397** 398** Returns: Text representation of power level. 399** 400*******************************************************************************/ 401const char* PowerSwitch::powerLevelToString (PowerLevel level) 402{ 403 switch (level) 404 { 405 case UNKNOWN_LEVEL: 406 return "PS-UNKNOWN"; 407 case FULL_POWER: 408 return "PS-FULL"; 409 case LOW_POWER: 410 return "PS-LOW-POWER"; 411 case POWER_OFF: 412 return "PS-POWER-OFF"; 413 default: 414 return "PS-unknown????"; 415 } 416} 417 418/******************************************************************************* 419** 420** Function: screenOffPowerStateToString 421** 422** Description: Decode power level to a string. 423** level: power level. 424** 425** Returns: Text representation of power level. 426** 427*******************************************************************************/ 428const char* PowerSwitch::screenOffPowerStateToString (ScreenOffPowerState state) 429{ 430 switch (state) 431 { 432 case POWER_STATE_OFF: 433 return "SOPS-POWER_OFF"; 434 case POWER_STATE_FULL: 435 return "SOPS-FULL"; 436 case POWER_STATE_CARD_EMULATION: 437 return "SOPS-CARD_EMULATION"; 438 default: 439 return "SOPS-unknown????"; 440 } 441} 442 443/******************************************************************************* 444** 445** Function: abort 446** 447** Description: Abort and unblock currrent operation. 448** 449** Returns: None 450** 451*******************************************************************************/ 452void PowerSwitch::abort () 453{ 454 static const char fn [] = "PowerSwitch::abort"; 455 ALOGD ("%s", fn); 456 SyncEventGuard guard (mPowerStateEvent); 457 mPowerStateEvent.notifyOne (); 458} 459 460 461/******************************************************************************* 462** 463** Function: deviceManagementCallback 464** 465** Description: Callback function for the stack. 466** event: event ID. 467** eventData: event's data. 468** 469** Returns: None 470** 471*******************************************************************************/ 472void PowerSwitch::deviceManagementCallback (UINT8 event, tNFA_DM_CBACK_DATA* eventData) 473{ 474 static const char fn [] = "PowerSwitch::deviceManagementCallback"; 475 476 switch (event) 477 { 478 case NFA_DM_PWR_MODE_CHANGE_EVT: 479 { 480 tNFA_DM_PWR_MODE_CHANGE& power_mode = eventData->power_mode; 481 ALOGD ("%s: NFA_DM_PWR_MODE_CHANGE_EVT; status=0x%X; device mgt power state=%s (0x%X)", fn, 482 power_mode.status, sPowerSwitch.deviceMgtPowerStateToString (power_mode.power_mode), 483 power_mode.power_mode); 484 SyncEventGuard guard (sPowerSwitch.mPowerStateEvent); 485 if (power_mode.status == NFA_STATUS_OK) 486 { 487 //the event data does not contain the newly configured power mode, 488 //so this code assigns the expected value 489 sPowerSwitch.mCurrDeviceMgtPowerState = sPowerSwitch.mExpectedDeviceMgtPowerState; 490 } 491 sPowerSwitch.mPowerStateEvent.notifyOne (); 492 } 493 break; 494 } 495} 496 497 498/******************************************************************************* 499** 500** Function: isPowerOffSleepFeatureEnabled 501** 502** Description: Whether power-off-sleep feature is enabled in .conf file. 503** 504** Returns: True if feature is enabled. 505** 506*******************************************************************************/ 507bool PowerSwitch::isPowerOffSleepFeatureEnabled () 508{ 509 return mDesiredScreenOffPowerState == 0; 510} 511 512