/* * 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" #include "ASensorManager.h" #define LOG_TAG "libsensorndkbridge" #include <android-base/logging.h> #include <android/looper.h> #include <hidl/HidlTransportSupport.h> #include <sensors/convert.h> using android::hardware::sensors::V1_0::SensorInfo; using android::frameworks::sensorservice::V1_0::IEventQueue; using android::frameworks::sensorservice::V1_0::ISensorManager; using android::frameworks::sensorservice::V1_0::Result; using android::hardware::sensors::V1_0::SensorType; using android::sp; using android::wp; using android::Mutex; using android::status_t; using android::OK; using android::NO_INIT; using android::BAD_VALUE; using android::hardware::hidl_vec; using android::hardware::Return; static Mutex gLock; // static ASensorManager *ASensorManager::sInstance = NULL; // static ASensorManager *ASensorManager::getInstance() { Mutex::Autolock autoLock(gLock); if (sInstance == NULL) { sInstance = new ASensorManager; if (sInstance->initCheck() != OK) { delete sInstance; sInstance = NULL; } } return sInstance; } void ASensorManager::SensorDeathRecipient::serviceDied( uint64_t, const wp<::android::hidl::base::V1_0::IBase>&) { LOG(ERROR) << "Sensor service died. Cleanup sensor manager instance!"; Mutex::Autolock autoLock(gLock); delete sInstance; sInstance = NULL; } ASensorManager::ASensorManager() : mInitCheck(NO_INIT) { mManager = ISensorManager::getService(); if (mManager != NULL) { mDeathRecipient = new SensorDeathRecipient(); Return<bool> linked = mManager->linkToDeath(mDeathRecipient, /*cookie*/ 0); if (!linked.isOk()) { LOG(ERROR) << "Transaction error in linking to sensor service death: " << linked.description().c_str(); } else if (!linked) { LOG(WARNING) << "Unable to link to sensor service death notifications"; } else { LOG(DEBUG) << "Link to sensor service death notification successful"; mInitCheck = OK; } } } status_t ASensorManager::initCheck() const { return mInitCheck; } int ASensorManager::getSensorList(ASensorList *out) { LOG(VERBOSE) << "ASensorManager::getSensorList"; Mutex::Autolock autoLock(mLock); if (mSensorList == NULL) { Return<void> ret = mManager->getSensorList([&](const auto &list, auto result) { if (result != Result::OK) { return; } mSensors = list; }); (void)ret.isOk(); mSensorList.reset(new ASensorRef[mSensors.size()]); for (size_t i = 0; i < mSensors.size(); ++i) { mSensorList.get()[i] = reinterpret_cast<ASensorRef>(&mSensors[i]); } } if (out) { *out = reinterpret_cast<ASensorList>(mSensorList.get()); } return mSensors.size(); } ASensorRef ASensorManager::getDefaultSensor(int type) { (void)getSensorList(NULL /* list */); ASensorRef defaultSensor = NULL; Return<void> ret = mManager->getDefaultSensor( static_cast<SensorType>(type), [&](const auto &sensor, auto result) { if (result != Result::OK) { return; } for (size_t i = 0; i < mSensors.size(); ++i) { if (sensor == mSensors[i]) { defaultSensor = reinterpret_cast<ASensorRef>(&mSensors[i]); break; } } }); (void)ret.isOk(); return defaultSensor; } ASensorRef ASensorManager::getDefaultSensorEx( int /* type */, bool /* wakeup */) { // XXX ISensorManager's getDefaultSensorEx() lacks a "wakeup" parameter. return NULL; } ASensorEventQueue *ASensorManager::createEventQueue( ALooper *looper, int ident, ALooper_callbackFunc callback, void *data) { LOG(VERBOSE) << "ASensorManager::createEventQueue"; sp<ASensorEventQueue> queue = new ASensorEventQueue(looper, ident, callback, data); ::android::hardware::setMinSchedulerPolicy(queue, SCHED_FIFO, 98); Result result; Return<void> ret = mManager->createEventQueue( queue, [&](const sp<IEventQueue> &queueImpl, auto tmpResult) { result = tmpResult; if (result != Result::OK) { return; } queue->setImpl(queueImpl); }); if (!ret.isOk() || result != Result::OK) { LOG(ERROR) << "FAILED to create event queue"; return NULL; } queue->incStrong(NULL /* id */); LOG(VERBOSE) << "Returning event queue " << queue.get(); return queue.get(); } void ASensorManager::destroyEventQueue(ASensorEventQueue *queue) { LOG(VERBOSE) << "ASensorManager::destroyEventQueue(" << queue << ")"; queue->invalidate(); queue->decStrong(NULL /* id */); queue = NULL; } //////////////////////////////////////////////////////////////////////////////// ASensorManager *ASensorManager_getInstance() { return ASensorManager::getInstance(); } ASensorManager *ASensorManager_getInstanceForPackage( const char* /* packageName */) { return ASensorManager::getInstance(); } #define RETURN_IF_MANAGER_IS_NULL(x) \ do { \ if (manager == NULL) { \ return x; \ } \ } while (0) #define RETURN_IF_QUEUE_IS_NULL(x) \ do { \ if (queue == NULL) { \ return x; \ } \ } while (0) #define RETURN_IF_SENSOR_IS_NULL(x) \ do { \ if (sensor == NULL) { \ return x; \ } \ } while (0) int ASensorManager_getSensorList(ASensorManager* manager, ASensorList* list) { RETURN_IF_MANAGER_IS_NULL(BAD_VALUE); return manager->getSensorList(list); } ASensor const* ASensorManager_getDefaultSensor( ASensorManager* manager, int type) { RETURN_IF_MANAGER_IS_NULL(NULL); return manager->getDefaultSensor(type); } #if 0 ASensor const* ASensorManager_getDefaultSensorEx( ASensorManager* manager, int type, bool wakeUp) { RETURN_IF_MANAGER_IS_NULL(NULL); return manager->getDefaultSensorEx(type, wakeUp); } #endif ASensorEventQueue* ASensorManager_createEventQueue( ASensorManager* manager, ALooper* looper, int ident, ALooper_callbackFunc callback, void* data) { RETURN_IF_MANAGER_IS_NULL(NULL); if (looper == NULL) { return NULL; } return manager->createEventQueue(looper, ident, callback, data); } int ASensorManager_destroyEventQueue( ASensorManager* manager, ASensorEventQueue* queue) { RETURN_IF_MANAGER_IS_NULL(BAD_VALUE); RETURN_IF_QUEUE_IS_NULL(BAD_VALUE); manager->destroyEventQueue(queue); queue = NULL; return OK; } #if 0 int ASensorManager_createSharedMemoryDirectChannel( ASensorManager* manager, int fd, size_t size) { RETURN_IF_MANAGER_IS_NULL(BAD_VALUE); return OK; } int ASensorManager_createHardwareBufferDirectChannel( ASensorManager* manager, AHardwareBuffer const * buffer, size_t size) { RETURN_IF_MANAGER_IS_NULL(BAD_VALUE); return OK; } void ASensorManager_destroyDirectChannel( ASensorManager* manager, int channelId) { } int ASensorManager_configureDirectReport( ASensorManager* manager, ASensor const* sensor, int channelId,int rate) { RETURN_IF_MANAGER_IS_NULL(BAD_VALUE); return OK; } #endif int ASensorEventQueue_registerSensor( ASensorEventQueue* queue, ASensor const* sensor, int32_t samplingPeriodUs, int64_t maxBatchReportLatencyUs) { LOG(VERBOSE) << "ASensorEventQueue_registerSensor"; RETURN_IF_QUEUE_IS_NULL(BAD_VALUE); return queue->registerSensor( sensor, samplingPeriodUs, maxBatchReportLatencyUs); } int ASensorEventQueue_enableSensor( ASensorEventQueue* queue, ASensor const* sensor) { LOG(VERBOSE) << "ASensorEventQueue_enableSensor(queue " << queue << ")"; RETURN_IF_QUEUE_IS_NULL(BAD_VALUE); return queue->enableSensor(sensor); } int ASensorEventQueue_disableSensor( ASensorEventQueue* queue, ASensor const* sensor) { LOG(VERBOSE) << "ASensorEventQueue_disableSensor"; RETURN_IF_QUEUE_IS_NULL(BAD_VALUE); return queue->disableSensor(sensor); } int ASensorEventQueue_setEventRate( ASensorEventQueue* queue, ASensor const* sensor, int32_t usec) { RETURN_IF_QUEUE_IS_NULL(BAD_VALUE); return queue->setEventRate(sensor, usec); } int ASensorEventQueue_hasEvents(ASensorEventQueue* queue) { RETURN_IF_QUEUE_IS_NULL(BAD_VALUE); return queue->hasEvents(); } ssize_t ASensorEventQueue_getEvents( ASensorEventQueue* queue, ASensorEvent* events, size_t count) { LOG(VERBOSE) << "ASensorEventQueue_getEvents"; RETURN_IF_QUEUE_IS_NULL(BAD_VALUE); return queue->getEvents(events, count); } const char *ASensor_getName(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(NULL); return reinterpret_cast<const SensorInfo *>(sensor)->name.c_str(); } const char *ASensor_getVendor(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(NULL); return reinterpret_cast<const SensorInfo *>(sensor)->vendor.c_str(); } int ASensor_getType(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(ASENSOR_TYPE_INVALID); return static_cast<int>( reinterpret_cast<const SensorInfo *>(sensor)->type); } float ASensor_getResolution(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(ASENSOR_RESOLUTION_INVALID); return reinterpret_cast<const SensorInfo *>(sensor)->resolution; } int ASensor_getMinDelay(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(ASENSOR_DELAY_INVALID); return reinterpret_cast<const SensorInfo *>(sensor)->minDelay; } int ASensor_getFifoMaxEventCount(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(ASENSOR_FIFO_COUNT_INVALID); return reinterpret_cast<const SensorInfo *>(sensor)->fifoMaxEventCount; } int ASensor_getFifoReservedEventCount(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(ASENSOR_FIFO_COUNT_INVALID); return reinterpret_cast<const SensorInfo *>(sensor)->fifoReservedEventCount; } const char* ASensor_getStringType(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(NULL); return reinterpret_cast<const SensorInfo *>(sensor)->typeAsString.c_str(); } extern "C" float ASensor_getMaxRange(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(nanf("")); return reinterpret_cast<const SensorInfo *>(sensor)->maxRange; } #if 0 int ASensor_getReportingMode(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(AREPORTING_MODE_INVALID); return 0; } bool ASensor_isWakeUpSensor(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(false); return false; } bool ASensor_isDirectChannelTypeSupported( ASensor const* sensor, int channelType) { RETURN_IF_SENSOR_IS_NULL(false); return false; } int ASensor_getHighestDirectReportRateLevel(ASensor const* sensor) { RETURN_IF_SENSOR_IS_NULL(ASENSOR_DIRECT_RATE_STOP); return 0; } #endif static ALooper *getTheLooper() { static ALooper *sLooper = NULL; Mutex::Autolock autoLock(gLock); if (sLooper == NULL) { sLooper = new ALooper; } return sLooper; } ALooper *ALooper_forThread() { LOG(VERBOSE) << "ALooper_forThread"; return getTheLooper(); } ALooper *ALooper_prepare(int /* opts */) { LOG(VERBOSE) << "ALooper_prepare"; return getTheLooper(); } int ALooper_pollOnce( int timeoutMillis, int* outFd, int* outEvents, void** outData) { int res = getTheLooper()->pollOnce(timeoutMillis, outFd, outEvents, outData); LOG(VERBOSE) << "ALooper_pollOnce => " << res; return res; } void ALooper_wake(ALooper* looper) { LOG(VERBOSE) << "ALooper_wake"; looper->wake(); }