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 
     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