| /* |
| * 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, 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(); |
| } |