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 26namespace android 27{ 28 void doStartupConfig (); 29} 30 31extern bool gActivated; 32extern SyncEvent gDeactivatedEvent; 33 34PowerSwitch PowerSwitch::sPowerSwitch; 35const PowerSwitch::PowerActivity PowerSwitch::DISCOVERY=0x01; 36const PowerSwitch::PowerActivity PowerSwitch::SE_ROUTING=0x02; 37const PowerSwitch::PowerActivity PowerSwitch::SE_CONNECTED=0x04; 38const PowerSwitch::PowerActivity PowerSwitch::HOST_ROUTING=0x08; 39 40/******************************************************************************* 41** 42** Function: PowerSwitch 43** 44** Description: Initialize member variables. 45** 46** Returns: None 47** 48*******************************************************************************/ 49PowerSwitch::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*******************************************************************************/ 68PowerSwitch::~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*******************************************************************************/ 82PowerSwitch& 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*******************************************************************************/ 97void 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*******************************************************************************/ 138PowerSwitch::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*******************************************************************************/ 158bool 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 216TheEnd: 217 mMutex.unlock (); 218 return retval; 219} 220 221 222bool 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*******************************************************************************/ 244bool 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*******************************************************************************/ 266bool 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*******************************************************************************/ 289bool 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; 360TheEnd: 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*******************************************************************************/ 376const 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*******************************************************************************/ 400const 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*******************************************************************************/ 427const 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*******************************************************************************/ 451void 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*******************************************************************************/ 471void 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*******************************************************************************/ 506bool PowerSwitch::isPowerOffSleepFeatureEnabled () 507{ 508 return mDesiredScreenOffPowerState == 0; 509} 510 511