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 #define LOG_TAG "BubbleLevelImpl"
18 //#define LOG_NDEBUG 0
19
20 #include <utils/Log.h>
21 #include <binder/IServiceManager.h>
22 #include "BubbleLevelImpl.h"
23
24 namespace android {
25
26 static int sensor_callback(int fd, int events, void* data);
27
28 #define BL_SENSOR_POLL_INTERVAL_MS 20
29 #define BL_SENSOR_POLL_TIMEOUT_MS (BL_SENSOR_POLL_INTERVAL_MS * 5)
30 #define BL_SENSOR_POLL_COUNT 10
31 #define BL_SENSOR_LEVEL_THRESHOLD (2.0)
32
BubbleLevelImpl()33 BubbleLevelImpl::BubbleLevelImpl()
34 : Thread(false),
35 mState(BL_STATE_IDLE), mCmd(BL_CMD_NONE),
36 mPollIntervalSec(BL_POLL_INTERVAL_DEFAULT_SEC), mPollCount(0), mLevelCount(0),
37 mCallBack(NULL), mUserData(NULL),
38 mNumSensors(0), mAccelerometer(NULL),
39 mInitStatus(-ENODEV)
40 {
41 init();
42 }
43
init()44 int BubbleLevelImpl::init()
45 {
46 if (mInitStatus == 0) {
47 return 0;
48 }
49
50 if (defaultServiceManager()->checkService(String16("sensorservice")) == 0) {
51 ALOGW("CSTOR sensorservice not ready yet");
52 return mInitStatus;
53 }
54
55 SensorManager& mgr(SensorManager::getInstance());
56 Sensor const* const* sensorList;
57
58 mNumSensors = mgr.getSensorList(&sensorList);
59
60 if (mNumSensors <= 0) {
61 ALOGE("CSTOR mNumSensors error %d", mNumSensors);
62 goto exit;
63 }
64 mAccelerometer = mgr.getDefaultSensor(Sensor::TYPE_ACCELEROMETER);
65 if (mAccelerometer == NULL) {
66 ALOGE("CSTOR mAccelerometer error NULL");
67 goto exit;
68 }
69
70 mSensorEventQueue = mgr.createEventQueue();
71 if (mSensorEventQueue == 0) {
72 ALOGE("createEventQueue returned 0");
73 goto exit;
74 }
75
76 mLooper = new Looper(false);
77 mLooper->addFd(mSensorEventQueue->getFd(), 0, ALOOPER_EVENT_INPUT, sensor_callback, this);
78
79 mInitStatus = 0;
80
81 exit:
82 return mInitStatus;
83 }
84
~BubbleLevelImpl()85 BubbleLevelImpl::~BubbleLevelImpl()
86 {
87 {
88 Mutex::Autolock _l(mStateLock);
89 mCmd = BL_CMD_EXIT;
90 mLooper->wake();
91 mCond.broadcast();
92 }
93 requestExitAndWait();
94 }
95
onFirstRef()96 void BubbleLevelImpl::onFirstRef()
97 {
98 if (mInitStatus == 0) {
99 run("Acc Loop", ANDROID_PRIORITY_URGENT_AUDIO);
100 }
101 }
102
threadLoop()103 bool BubbleLevelImpl::threadLoop() {
104 bool isLevel;
105
106 while(!exitPending()) {
107 {
108 Mutex::Autolock _l(mStateLock);
109
110 isLevel = false;
111
112 switch (mCmd) {
113 case BL_CMD_POLL_ONCE:
114 case BL_CMD_START_POLL:
115 if (mState == BL_STATE_IDLE) {
116 mSensorEventQueue->enableSensor(mAccelerometer);
117 mSensorEventQueue->setEventRate(mAccelerometer,
118 ms2ns(BL_SENSOR_POLL_INTERVAL_MS));
119 mPollCount = 0;
120 mLevelCount = 0;
121 if (mCmd == BL_CMD_START_POLL) {
122 mState = BL_STATE_POLLING;
123 } else {
124 mState = BL_STATE_POLLING_ONCE;
125 }
126 }
127 if ((mCmd == BL_CMD_START_POLL) && (mState == BL_STATE_POLLING_ONCE)) {
128 mState = BL_STATE_POLLING;
129 }
130 break;
131 case BL_CMD_STOP_POLL:
132 if (mState == BL_STATE_POLLING ||
133 mState == BL_STATE_POLLING_ONCE ||
134 mState == BL_STATE_SLEEPING) {
135 mSensorEventQueue->disableSensor(mAccelerometer);
136 mState = BL_STATE_IDLE;
137 }
138 break;
139 case BL_CMD_EXIT:
140 continue;
141 case BL_CMD_NONE:
142 break;
143 default:
144 ALOGE("unknown command: %d", mCmd);
145 }
146 mCmd = BL_CMD_NONE;
147
148 switch (mState) {
149 case BL_STATE_IDLE:
150 mCond.wait(mStateLock);
151 continue;
152
153 case BL_STATE_POLLING:
154 case BL_STATE_POLLING_ONCE:
155 if (mPollCount >= BL_SENSOR_POLL_COUNT) {
156 // majority vote
157 isLevel = (mLevelCount > (BL_SENSOR_POLL_COUNT / 2));
158 if (mState == BL_STATE_POLLING_ONCE) {
159 mCmd = BL_CMD_STOP_POLL;
160 }
161 mState = BL_STATE_SLEEPING;
162 }
163 break;
164 case BL_STATE_SLEEPING:
165 mCond.waitRelative(mStateLock, seconds(mPollIntervalSec));
166 mPollCount = 0;
167 mLevelCount = 0;
168 mState = BL_STATE_POLLING;
169 break;
170
171 default:
172 ALOGE("unknown state: %d", mState);
173 mState = BL_STATE_IDLE;
174 continue;
175 }
176 }
177
178 if (mState == BL_STATE_SLEEPING) {
179 Mutex::Autolock _l(mCallbackLock);
180 if (mCallBack != NULL) {
181 mCallBack(isLevel, mUserData);
182 }
183 continue;
184 }
185 mLooper->pollOnce(BL_SENSOR_POLL_TIMEOUT_MS);
186 }
187 ALOGV("threadLoop EXIT");
188 return false;
189 }
190
setCallback(BubbleLevel_CallBack_t callback,void * userData)191 int BubbleLevelImpl::setCallback(BubbleLevel_CallBack_t callback, void *userData)
192 {
193 Mutex::Autolock _l(mCallbackLock);
194 if (mInitStatus != 0) {
195 return mInitStatus;
196 }
197 mCallBack = callback;
198 mUserData = userData;
199 return 0;
200 }
201
setPollInterval(unsigned int seconds)202 int BubbleLevelImpl::setPollInterval(unsigned int seconds)
203 {
204 if (seconds < BL_POLL_INTERVAL_MIN_SEC) {
205 return -EINVAL;
206 }
207
208 Mutex::Autolock _l(mStateLock);
209 if (mInitStatus != 0) {
210 return mInitStatus;
211 }
212 mPollIntervalSec = seconds;
213 return 0;
214 }
startPolling()215 int BubbleLevelImpl::startPolling()
216 {
217 Mutex::Autolock _l(mStateLock);
218 if (mInitStatus != 0) {
219 return mInitStatus;
220 }
221 if (mCmd != BL_CMD_EXIT) {
222 mCmd = BL_CMD_START_POLL;
223 mCond.signal();
224 }
225 return 0;
226 }
227
stopPolling()228 int BubbleLevelImpl::stopPolling()
229 {
230 Mutex::Autolock _l(mStateLock);
231 if (mInitStatus != 0) {
232 return mInitStatus;
233 }
234 if (mCmd != BL_CMD_EXIT) {
235 mCmd = BL_CMD_STOP_POLL;
236 mCond.signal();
237 }
238 return 0;
239 }
240
pollOnce()241 int BubbleLevelImpl::pollOnce()
242 {
243 Mutex::Autolock _l(mStateLock);
244 if (mInitStatus != 0) {
245 return mInitStatus;
246 }
247 if (mCmd != BL_CMD_EXIT) {
248 mCmd = BL_CMD_POLL_ONCE;
249 mCond.signal();
250 }
251 return 0;
252 }
253
sensor_callback(int fd,int events,void * data)254 static int sensor_callback(int fd, int events, void* data)
255 {
256 sp<BubbleLevelImpl> bl = sp<BubbleLevelImpl>((BubbleLevelImpl *)data);
257
258 bl->lockState();
259 if (((bl->state() != BubbleLevelImpl::BL_STATE_POLLING) &&
260 (bl->state() != BubbleLevelImpl::BL_STATE_POLLING_ONCE)) ||
261 (bl->pollCount() >= BL_SENSOR_POLL_COUNT)) {
262 bl->unlockState();
263 return 1;
264 }
265 bl->unlockState();
266
267 sp<SensorEventQueue> sensorEventQueue = bl->sensorEventQueue();
268 size_t numSensors = bl->numSensors();
269 bool isLevel = false;
270 ASensorEvent sensorEvents[numSensors];
271 ssize_t ret = sensorEventQueue->read(sensorEvents, numSensors);
272 if (ret > 0) {
273 for (int i = 0; i < ret; i++) {
274 if (sensorEvents[i].type == Sensor::TYPE_ACCELEROMETER) {
275 ALOGV("sensor_callback() azimuth = %f pitch = %f roll = %f",
276 sensorEvents[i].vector.azimuth,
277 sensorEvents[i].vector.pitch,
278 sensorEvents[i].vector.roll);
279
280 if ((sensorEvents[i].vector.roll > 0.0) &&
281 (sensorEvents[i].vector.azimuth < BL_SENSOR_LEVEL_THRESHOLD) &&
282 (sensorEvents[i].vector.azimuth > -BL_SENSOR_LEVEL_THRESHOLD) &&
283 (sensorEvents[i].vector.pitch < BL_SENSOR_LEVEL_THRESHOLD) &&
284 (sensorEvents[i].vector.pitch > -BL_SENSOR_LEVEL_THRESHOLD)) {
285 isLevel = true;
286 }
287 break;
288 }
289 }
290 }
291
292 bl->lockState();
293 bl->incPollCount();
294 if (isLevel) {
295 bl->incLevelCount();
296 }
297 bl->unlockState();
298
299 return 1;
300 }
301
302 }; // namespace android
303
304 extern "C" {
305
bl_set_callback(const struct bubble_level * bubble_level,BubbleLevel_CallBack_t callback,void * userData)306 static int bl_set_callback(const struct bubble_level *bubble_level,
307 BubbleLevel_CallBack_t callback, void *userData)
308 {
309 bubble_level_C_impl *bl = (bubble_level_C_impl *)bubble_level;
310 return bl->bubble_level->setCallback(callback, userData);
311 }
312
bl_set_poll_interval(const struct bubble_level * bubble_level,unsigned int seconds)313 static int bl_set_poll_interval(const struct bubble_level *bubble_level, unsigned int seconds)
314 {
315 bubble_level_C_impl *bl = (bubble_level_C_impl *)bubble_level;
316 return bl->bubble_level->setPollInterval(seconds);
317 }
318
bl_start_polling(const struct bubble_level * bubble_level)319 static int bl_start_polling(const struct bubble_level *bubble_level)
320 {
321 bubble_level_C_impl *bl = (bubble_level_C_impl *)bubble_level;
322 return bl->bubble_level->startPolling();
323 }
324
bl_stop_polling(const struct bubble_level * bubble_level)325 static int bl_stop_polling(const struct bubble_level *bubble_level)
326 {
327 bubble_level_C_impl *bl = (bubble_level_C_impl *)bubble_level;
328 return bl->bubble_level->stopPolling();
329 }
330
bl_poll_once(const struct bubble_level * bubble_level)331 static int bl_poll_once(const struct bubble_level *bubble_level)
332 {
333 bubble_level_C_impl *bl = (bubble_level_C_impl *)bubble_level;
334 return bl->bubble_level->pollOnce();
335 }
336
337
bubble_level_create()338 struct bubble_level *bubble_level_create()
339 {
340 bubble_level_C_impl *bl = new bubble_level_C_impl();
341 bl->bubble_level = new android::BubbleLevelImpl();
342 if (bl->bubble_level->initStatus() != 0) {
343 bubble_level_release((struct bubble_level *)bl);
344 return NULL;
345 }
346 bl->interface.set_callback = bl_set_callback;
347 bl->interface.set_poll_interval = bl_set_poll_interval;
348 bl->interface.start_polling = bl_start_polling;
349 bl->interface.stop_polling = bl_stop_polling;
350 bl->interface.poll_once = bl_poll_once;
351
352 return (struct bubble_level *)bl;
353 }
354
bubble_level_release(const struct bubble_level * bubble_level)355 void bubble_level_release(const struct bubble_level *bubble_level)
356 {
357 bubble_level_C_impl *bl = (bubble_level_C_impl *)bubble_level;
358
359 if (bl == NULL)
360 return;
361
362 bl->bubble_level.clear();
363 delete bubble_level;
364 }
365
366 };
367