PowerSwitch.cpp revision 9f8f6cf9c58405ecafe2d425801e6c14088db8c7
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;
37const PowerSwitch::PowerActivity PowerSwitch::HOST_ROUTING=0x08;
38
39/*******************************************************************************
40**
41** Function:        PowerSwitch
42**
43** Description:     Initialize member variables.
44**
45** Returns:         None
46**
47*******************************************************************************/
48PowerSwitch::PowerSwitch ()
49:   mCurrLevel (UNKNOWN_LEVEL),
50    mCurrDeviceMgtPowerState (NFA_DM_PWR_STATE_UNKNOWN),
51    mDesiredScreenOffPowerState (0),
52    mCurrActivity(0)
53{
54}
55
56
57/*******************************************************************************
58**
59** Function:        ~PowerSwitch
60**
61** Description:     Release all resources.
62**
63** Returns:         None
64**
65*******************************************************************************/
66PowerSwitch::~PowerSwitch ()
67{
68}
69
70
71/*******************************************************************************
72**
73** Function:        getInstance
74**
75** Description:     Get the singleton of this object.
76**
77** Returns:         Reference to this object.
78**
79*******************************************************************************/
80PowerSwitch& PowerSwitch::getInstance ()
81{
82    return sPowerSwitch;
83}
84
85
86/*******************************************************************************
87**
88** Function:        initialize
89**
90** Description:     Initialize member variables.
91**
92** Returns:         None
93**
94*******************************************************************************/
95void PowerSwitch::initialize (PowerLevel level)
96{
97    static const char fn [] = "PowerSwitch::initialize";
98
99    mMutex.lock ();
100
101    ALOGD ("%s: level=%s (%u)", fn, powerLevelToString(level), level);
102    GetNumValue (NAME_SCREEN_OFF_POWER_STATE, &mDesiredScreenOffPowerState, sizeof(mDesiredScreenOffPowerState));
103    ALOGD ("%s: desired screen-off state=%d", fn, mDesiredScreenOffPowerState);
104
105    switch (level)
106    {
107    case FULL_POWER:
108        mCurrDeviceMgtPowerState = NFA_DM_PWR_MODE_FULL;
109        mCurrLevel = level;
110        break;
111
112    case UNKNOWN_LEVEL:
113        mCurrDeviceMgtPowerState = NFA_DM_PWR_STATE_UNKNOWN;
114        mCurrLevel = level;
115        break;
116
117    default:
118        ALOGE ("%s: not handled", fn);
119        break;
120    }
121    mMutex.unlock ();
122}
123
124
125/*******************************************************************************
126**
127** Function:        getLevel
128**
129** Description:     Get the current power level of the controller.
130**
131** Returns:         Power level.
132**
133*******************************************************************************/
134PowerSwitch::PowerLevel PowerSwitch::getLevel ()
135{
136    PowerLevel level = UNKNOWN_LEVEL;
137    mMutex.lock ();
138    level = mCurrLevel;
139    mMutex.unlock ();
140    return level;
141}
142
143
144/*******************************************************************************
145**
146** Function:        setLevel
147**
148** Description:     Set the controller's power level.
149**                  level: power level.
150**
151** Returns:         True if ok.
152**
153*******************************************************************************/
154bool PowerSwitch::setLevel (PowerLevel newLevel)
155{
156    static const char fn [] = "PowerSwitch::setLevel";
157    bool retval = false;
158
159    mMutex.lock ();
160
161    ALOGD ("%s: level=%s (%u)", fn, powerLevelToString(newLevel), newLevel);
162    if (mCurrLevel == newLevel)
163    {
164        retval = true;
165        goto TheEnd;
166    }
167
168    switch (newLevel)
169    {
170    case FULL_POWER:
171        if (mCurrDeviceMgtPowerState == NFA_DM_PWR_MODE_OFF_SLEEP)
172            retval = setPowerOffSleepState (false);
173        break;
174
175    case LOW_POWER:
176    case POWER_OFF:
177        if (isPowerOffSleepFeatureEnabled())
178            retval = setPowerOffSleepState (true);
179        else if (mDesiredScreenOffPowerState == 1) //.conf file desires full-power
180        {
181            mCurrLevel = FULL_POWER;
182            retval = true;
183        }
184        break;
185
186    default:
187        ALOGE ("%s: not handled", fn);
188        break;
189    }
190
191TheEnd:
192    mMutex.unlock ();
193    return retval;
194}
195
196/*******************************************************************************
197**
198** Function:        setModeOff
199**
200** Description:     Set a mode to be deactive.
201**
202** Returns:         True if any mode is still active.
203**
204*******************************************************************************/
205bool PowerSwitch::setModeOff (PowerActivity deactivated)
206{
207    bool retVal = false;
208
209    mMutex.lock ();
210    mCurrActivity &= ~deactivated;
211    retVal = mCurrActivity != 0;
212    ALOGD ("PowerSwitch::setModeOff(deactivated=0x%x) : mCurrActivity=0x%x", deactivated, mCurrActivity);
213    mMutex.unlock ();
214    return retVal;
215}
216
217
218/*******************************************************************************
219**
220** Function:        setModeOn
221**
222** Description:     Set a mode to be active.
223**
224** Returns:         True if any mode is active.
225**
226*******************************************************************************/
227bool PowerSwitch::setModeOn (PowerActivity activated)
228{
229    bool retVal = false;
230
231    mMutex.lock ();
232    mCurrActivity |= activated;
233    retVal = mCurrActivity != 0;
234    ALOGD ("PowerSwitch::setModeOn(activated=0x%x) : mCurrActivity=0x%x", activated, mCurrActivity);
235    mMutex.unlock ();
236    return retVal;
237}
238
239
240/*******************************************************************************
241**
242** Function:        setPowerOffSleepState
243**
244** Description:     Adjust controller's power-off-sleep state.
245**                  sleep: whether to enter sleep state.
246**
247** Returns:         True if ok.
248**
249*******************************************************************************/
250bool PowerSwitch::setPowerOffSleepState (bool sleep)
251{
252    static const char fn [] = "PowerSwitch::setPowerOffSleepState";
253    ALOGD ("%s: enter; sleep=%u", fn, sleep);
254    tNFA_STATUS stat = NFA_STATUS_FAILED;
255    bool retval = false;
256
257    if (sleep) //enter power-off-sleep state
258    {
259        //make sure the current power state is ON
260        if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_OFF_SLEEP)
261        {
262            SyncEventGuard guard (mPowerStateEvent);
263            ALOGD ("%s: try power off", fn);
264            stat = NFA_PowerOffSleepMode (TRUE);
265            if (stat == NFA_STATUS_OK)
266            {
267                mPowerStateEvent.wait ();
268                mCurrLevel = LOW_POWER;
269            }
270            else
271            {
272                ALOGE ("%s: API fail; stat=0x%X", fn, stat);
273                goto TheEnd;
274            }
275        }
276        else
277        {
278            ALOGE ("%s: power is not ON; curr device mgt power state=%s (%u)", fn,
279                    deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState);
280            goto TheEnd;
281        }
282    }
283    else //exit power-off-sleep state
284    {
285        //make sure the current power state is OFF
286        if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_FULL)
287        {
288            mCurrDeviceMgtPowerState = NFA_DM_PWR_STATE_UNKNOWN;
289            SyncEventGuard guard (mPowerStateEvent);
290            ALOGD ("%s: try full power", fn);
291            stat = NFA_PowerOffSleepMode (FALSE);
292            if (stat == NFA_STATUS_OK)
293            {
294                mPowerStateEvent.wait ();
295                if (mCurrDeviceMgtPowerState != NFA_DM_PWR_MODE_FULL)
296                {
297                    ALOGE ("%s: unable to full power; curr device mgt power stat=%s (%u)", fn,
298                            deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState);
299                    goto TheEnd;
300                }
301                android::doStartupConfig ();
302                mCurrLevel = FULL_POWER;
303            }
304            else
305            {
306                ALOGE ("%s: API fail; stat=0x%X", fn, stat);
307                goto TheEnd;
308            }
309        }
310        else
311        {
312            ALOGE ("%s: not in power-off state; curr device mgt power state=%s (%u)", fn,
313                    deviceMgtPowerStateToString (mCurrDeviceMgtPowerState), mCurrDeviceMgtPowerState);
314            goto TheEnd;
315        }
316    }
317
318    retval = true;
319TheEnd:
320    ALOGD ("%s: exit; return %u", fn, retval);
321    return retval;
322}
323
324
325/*******************************************************************************
326**
327** Function:        deviceMgtPowerStateToString
328**
329** Description:     Decode power level to a string.
330**                  deviceMgtPowerState: power level.
331**
332** Returns:         Text representation of power level.
333**
334*******************************************************************************/
335const char* PowerSwitch::deviceMgtPowerStateToString (UINT8 deviceMgtPowerState)
336{
337    switch (deviceMgtPowerState)
338    {
339    case NFA_DM_PWR_MODE_FULL:
340        return "DM-FULL";
341    case NFA_DM_PWR_MODE_OFF_SLEEP:
342        return "DM-OFF";
343    default:
344        return "DM-unknown????";
345    }
346}
347
348
349/*******************************************************************************
350**
351** Function:        powerLevelToString
352**
353** Description:     Decode power level to a string.
354**                  level: power level.
355**
356** Returns:         Text representation of power level.
357**
358*******************************************************************************/
359const char* PowerSwitch::powerLevelToString (PowerLevel level)
360{
361    switch (level)
362    {
363    case UNKNOWN_LEVEL:
364        return "PS-UNKNOWN";
365    case FULL_POWER:
366        return "PS-FULL";
367    case LOW_POWER:
368        return "PS-LOW-POWER";
369    case POWER_OFF:
370        return "PS-POWER-OFF";
371    default:
372        return "PS-unknown????";
373    }
374}
375
376
377/*******************************************************************************
378**
379** Function:        abort
380**
381** Description:     Abort and unblock currrent operation.
382**
383** Returns:         None
384**
385*******************************************************************************/
386void PowerSwitch::abort ()
387{
388    static const char fn [] = "PowerSwitch::abort";
389    ALOGD ("%s", fn);
390    SyncEventGuard guard (mPowerStateEvent);
391    mPowerStateEvent.notifyOne ();
392}
393
394
395/*******************************************************************************
396**
397** Function:        deviceManagementCallback
398**
399** Description:     Callback function for the stack.
400**                  event: event ID.
401**                  eventData: event's data.
402**
403** Returns:         None
404**
405*******************************************************************************/
406void PowerSwitch::deviceManagementCallback (UINT8 event, tNFA_DM_CBACK_DATA* eventData)
407{
408    static const char fn [] = "PowerSwitch::deviceManagementCallback";
409
410    switch (event)
411    {
412    case NFA_DM_PWR_MODE_CHANGE_EVT:
413        {
414            tNFA_DM_PWR_MODE_CHANGE& power_mode = eventData->power_mode;
415            ALOGD ("%s: NFA_DM_PWR_MODE_CHANGE_EVT; status=%u; device mgt power mode=%s (%u)", fn,
416                    power_mode.status, sPowerSwitch.deviceMgtPowerStateToString (power_mode.power_mode), power_mode.power_mode);
417            SyncEventGuard guard (sPowerSwitch.mPowerStateEvent);
418            if (power_mode.status == NFA_STATUS_OK)
419                sPowerSwitch.mCurrDeviceMgtPowerState = power_mode.power_mode;
420            sPowerSwitch.mPowerStateEvent.notifyOne ();
421        }
422        break;
423    }
424}
425
426
427/*******************************************************************************
428**
429** Function:        isPowerOffSleepFeatureEnabled
430**
431** Description:     Whether power-off-sleep feature is enabled in .conf file.
432**
433** Returns:         True if feature is enabled.
434**
435*******************************************************************************/
436bool PowerSwitch::isPowerOffSleepFeatureEnabled ()
437{
438    return mDesiredScreenOffPowerState == 0;
439}
440
441