/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ALooper.h" #include "ASensorEventQueue.h" #define LOG_TAG "libsensorndkbridge" #include <android/looper.h> #include <android-base/logging.h> using android::Mutex; ALooper::ALooper() : mAwoken(false) { } void ALooper::signalSensorEvents(ASensorEventQueue *queue) { Mutex::Autolock autoLock(mLock); mReadyQueues.insert(queue); mCondition.signal(); } void ALooper::wake() { Mutex::Autolock autoLock(mLock); mAwoken = true; mCondition.signal(); } int ALooper::pollOnce( int timeoutMillis, int *outFd, int *outEvents, void **outData) { if (outFd) { *outFd = 0; } if (outEvents) { *outEvents = 0; } if (outData) { *outData = NULL; } int64_t waitUntilNs; if (timeoutMillis < 0) { waitUntilNs = -1; } else { waitUntilNs = systemTime(SYSTEM_TIME_MONOTONIC) + timeoutMillis * 1000000ll; } Mutex::Autolock autoLock(mLock); int64_t nowNs; while ((timeoutMillis < 0 || (nowNs = systemTime(SYSTEM_TIME_MONOTONIC)) < waitUntilNs) && mReadyQueues.empty() && !mAwoken) { if (timeoutMillis < 0) { mCondition.wait(mLock); } else { mCondition.waitRelative(mLock, waitUntilNs - nowNs); } } int result = ALOOPER_POLL_TIMEOUT; if (!mReadyQueues.empty()) { result = ALOOPER_POLL_CALLBACK; for (auto queue : mReadyQueues) { queue->dispatchCallback(); } mReadyQueues.clear(); } else if (mAwoken) { result = ALOOPER_POLL_WAKE; mAwoken = false; } LOG(VERBOSE) << "pollOnce returning " << result; return result; } void ALooper::invalidateSensorQueue(ASensorEventQueue *queue) { Mutex::Autolock autoLock(mLock); mReadyQueues.erase(queue); }