1 /*
2 * Copyright (C) 2017 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 #include "ALooper.h"
18
19 #include "ASensorEventQueue.h"
20
21 #define LOG_TAG "libsensorndkbridge"
22 #include <android/looper.h>
23 #include <android-base/logging.h>
24
25 using android::Mutex;
26 using android::sp;
27 using android::wp;
28
ALooper()29 ALooper::ALooper()
30 : mAwoken(false) {
31 }
32
signalSensorEvents(wp<ASensorEventQueue> queue)33 void ALooper::signalSensorEvents(wp<ASensorEventQueue> queue) {
34 Mutex::Autolock autoLock(mLock);
35 mReadyQueues.insert(queue);
36 mCondition.signal();
37 }
38
wake()39 void ALooper::wake() {
40 Mutex::Autolock autoLock(mLock);
41 mAwoken = true;
42 mCondition.signal();
43 }
44
pollOnce(int timeoutMillis,int * outFd,int * outEvents,void ** outData)45 int ALooper::pollOnce(
46 int timeoutMillis, int *outFd, int *outEvents, void **outData) {
47 if (outFd) { *outFd = 0; }
48 if (outEvents) { *outEvents = 0; }
49 if (outData) { *outData = NULL; }
50
51 int64_t waitUntilNs;
52 if (timeoutMillis < 0) {
53 waitUntilNs = -1;
54 } else {
55 waitUntilNs = systemTime(SYSTEM_TIME_MONOTONIC) + timeoutMillis * 1000000LL;
56 }
57
58 Mutex::Autolock autoLock(mLock);
59 int64_t nowNs;
60 while ((timeoutMillis < 0
61 || (nowNs = systemTime(SYSTEM_TIME_MONOTONIC)) < waitUntilNs)
62 && mReadyQueues.empty()
63 && !mAwoken) {
64 if (timeoutMillis < 0) {
65 mCondition.wait(mLock);
66 } else {
67 mCondition.waitRelative(mLock, waitUntilNs - nowNs);
68 }
69 }
70
71 int result = ALOOPER_POLL_TIMEOUT;
72
73 if (!mReadyQueues.empty()) {
74 result = ALOOPER_POLL_CALLBACK;
75
76 for (auto& queue : mReadyQueues) {
77 sp<ASensorEventQueue> promotedQueue = queue.promote();
78 if (promotedQueue != nullptr) {
79 promotedQueue->dispatchCallback();
80 }
81 }
82
83 mReadyQueues.clear();
84 } else if (mAwoken) {
85 result = ALOOPER_POLL_WAKE;
86 mAwoken = false;
87 }
88
89 LOG(VERBOSE) << "pollOnce returning " << result;
90
91 return result;
92 }
93
invalidateSensorQueue(wp<ASensorEventQueue> queue)94 void ALooper::invalidateSensorQueue(wp<ASensorEventQueue> queue) {
95 Mutex::Autolock autoLock(mLock);
96 mReadyQueues.erase(queue);
97 }
98