Home | History | Annotate | Download | only in jni
      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