PowerSwitch.cpp revision a8aa07142ea0078d3ae4ae486e094e2f2f4ff732
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 215TheEnd: 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*******************************************************************************/ 229bool 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*******************************************************************************/ 251bool 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*******************************************************************************/ 274bool 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; 345TheEnd: 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*******************************************************************************/ 361const 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*******************************************************************************/ 385const 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*******************************************************************************/ 412void 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*******************************************************************************/ 432void 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*******************************************************************************/ 467bool PowerSwitch::isPowerOffSleepFeatureEnabled () 468{ 469 return mDesiredScreenOffPowerState == 0; 470} 471 472