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 #ifndef ANDROID_BUBBLE_LEVEL_IMPL_
18 #define ANDROID_BUBBLE_LEVEL_IMPL_
19 
20 #include "BubbleLevel.h"
21 #include <utils/Looper.h>
22 #include <gui/Sensor.h>
23 #include <gui/SensorManager.h>
24 #include <gui/SensorEventQueue.h>
25 
26 
27 namespace android {
28 
29 class BubbleLevelImpl : public Thread
30 {
31 public:
32 
33     BubbleLevelImpl();
34     virtual ~BubbleLevelImpl();
35 
initStatus()36     int initStatus() const { return mInitStatus; }
37 
38     // BubbleLevel interface
39     int setCallback(BubbleLevel_CallBack_t callback, void *userData);
40     int setPollInterval(unsigned int seconds);
41     int startPolling();
42     int stopPolling();
43     int pollOnce();
44 
45     // RefBase
46     virtual     void        onFirstRef();
47     // Thread virtuals
48     virtual     bool        threadLoop();
49 
50     enum state {
51         BL_STATE_IDLE,
52         BL_STATE_POLLING,
53         BL_STATE_POLLING_ONCE,
54         BL_STATE_SLEEPING,
55     };
56 
state()57     uint32_t state() const { return mState; }
lockState()58     void lockState() { mStateLock.lock(); }
unlockState()59     void unlockState() { mStateLock.unlock(); }
pollCount()60     uint32_t pollCount() { return mPollCount; }
incPollCount()61     void incPollCount() { mPollCount++; }
incLevelCount()62     void incLevelCount() { mLevelCount++; }
sensorEventQueue()63     sp<SensorEventQueue> sensorEventQueue() const { return mSensorEventQueue; }
numSensors()64     size_t numSensors() const { return mNumSensors; }
65 
66 private:
67     enum command {
68         BL_CMD_NONE,
69         BL_CMD_START_POLL,
70         BL_CMD_STOP_POLL,
71         BL_CMD_POLL_ONCE,
72         BL_CMD_EXIT,
73     };
74 
75     int init();
76 
77     Mutex  mStateLock;
78     Mutex  mCallbackLock;
79     Condition mCond;
80     uint32_t mState;
81     uint32_t mCmd;
82     uint32_t mPollIntervalSec;
83     uint32_t mPollCount;
84     uint32_t mLevelCount;
85 
86     BubbleLevel_CallBack_t mCallBack;
87     void *mUserData;
88 
89     size_t mNumSensors;
90     Sensor const* mAccelerometer;
91     sp<SensorEventQueue> mSensorEventQueue;
92     sp<Looper> mLooper;
93     int mInitStatus;
94 };
95 
96 };
97 
98 class BubbleLevelBase: public BubbleLevel
99 {
100 public:
BubbleLevelBase()101     BubbleLevelBase() { mBubbleLevel = new android::BubbleLevelImpl(); }
~BubbleLevelBase()102     virtual ~BubbleLevelBase() {}
103 
initStatus()104     int initStatus() {
105         return mBubbleLevel->initStatus();
106     }
107 
108     // BubbleLevel interface
setCallback(BubbleLevel_CallBack_t callback,void * userData)109     virtual int setCallback(BubbleLevel_CallBack_t callback, void *userData) {
110         return mBubbleLevel->setCallback(callback, userData);
111     }
setPollInterval(unsigned int seconds)112     virtual int setPollInterval(unsigned int seconds) {
113         return mBubbleLevel->setPollInterval(seconds);
114     }
startPolling()115     virtual int startPolling() {
116         return mBubbleLevel->startPolling();
117     }
stopPolling()118     virtual int stopPolling() {
119         return mBubbleLevel->stopPolling();
120     }
pollOnce()121     virtual int pollOnce() {
122         return mBubbleLevel->pollOnce();
123     }
124 
125 private:
126     android::sp<android::BubbleLevelImpl> mBubbleLevel;
127 };
128 
create()129 BubbleLevel *BubbleLevel::create() {
130     BubbleLevelBase *bl = new BubbleLevelBase();
131 
132     if (bl->initStatus() != 0) {
133         delete bl;
134         bl = NULL;
135     }
136     return static_cast<BubbleLevel *>(bl);
137 }
138 
139 struct bubble_level_C_impl
140 {
141     struct bubble_level interface;
142     android::sp<android::BubbleLevelImpl> bubble_level;
143 };
144 
145 #endif /*ANDROID_BUBBLE_LEVEL_IMPL_*/
146