PowerSwitch.cpp revision 525c260303268a83da4c3413b953d13c9084e834
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
32
33PowerSwitch PowerSwitch::sPowerSwitch;
34const PowerSwitch::PowerActivity PowerSwitch::DISCOVERY=0x01;
35const PowerSwitch::PowerActivity PowerSwitch::SE_ROUTING=0x02;
36const PowerSwitch::PowerActivity PowerSwitch::SE_CONNECTED=0x04;
37
38/*******************************************************************************
39**
40** Function:        PowerSwitch
41**
42** Description:     Initialize member variables.
43**
44** Returns:         None
45**
46*******************************************************************************/
47PowerSwitch::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*******************************************************************************/
65PowerSwitch::~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*******************************************************************************/
79PowerSwitch& 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*******************************************************************************/
94void 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*******************************************************************************/
133PowerSwitch::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*******************************************************************************/
153bool 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
190TheEnd:
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*******************************************************************************/
204bool 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*******************************************************************************/
226bool 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*******************************************************************************/
249bool 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;
318TheEnd:
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*******************************************************************************/
334const 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*******************************************************************************/
358const 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*******************************************************************************/
385void 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*******************************************************************************/
405void 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*******************************************************************************/
435bool PowerSwitch::isPowerOffSleepFeatureEnabled ()
436{
437    return mDesiredScreenOffPowerState == 0;
438}
439
440