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