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