• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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