From 3b170173460def252c834fa46706775ed4e1d9a7 Mon Sep 17 00:00:00 2001 From: Peng Xu Date: Wed, 15 Feb 2017 23:25:21 -0800 Subject: [PATCH] Add direct sensor report NDK API Added libandroid mapping and implementation of the following API: * ASensorManager_configureDirectReport * ASensorManager_createSharedMemoryDirectChannel * ASensorManager_createHardwareBufferDirectChannel * ASensorManager_destroyDirectChannel * ASensor_getHighestDirectReportRateLevel * ASensor_isDirectChannelTypeSupported Test: cts-tradefed run cts --module CtsSensorTestCases \ --test android.hardware.cts.SensorNativeTest Bug: 30985702 Change-Id: Ic808cc50d1ecbc789944ef77a4b247dc0c83c28a --- native/android/libandroid.map.txt | 7 ++ native/android/sensor.cpp | 109 ++++++++++++++++++++++++++++-- 2 files changed, 111 insertions(+), 5 deletions(-) diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index e2623d4fd9eea..1b1f28c374696 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -170,14 +170,20 @@ LIBANDROID { ASensorEventQueue_getEvents; ASensorEventQueue_hasEvents; ASensorEventQueue_setEventRate; + ASensorManager_configureDirectReport; # introduced=26 ASensorManager_createEventQueue; + ASensorManager_createHardwareBufferDirectChannel; # introduced=26 + ASensorManager_createSharedMemoryDirectChannel; # introduced=26 + ASensorManager_destroyDirectChannel; # introduced=26 ASensorManager_destroyEventQueue; ASensorManager_getDefaultSensor; ASensorManager_getDefaultSensorEx; # introduced=21 ASensorManager_getInstance; + ASensorManager_getInstanceForPackage; # introduced=26 ASensorManager_getSensorList; ASensor_getFifoMaxEventCount; # introduced=21 ASensor_getFifoReservedEventCount; # introduced=21 + ASensor_getHighestDirectReportRateLevel; # introduced=26 ASensor_getMinDelay; ASensor_getName; ASensor_getReportingMode; # introduced=21 @@ -185,6 +191,7 @@ LIBANDROID { ASensor_getStringType; # introduced=21 ASensor_getType; ASensor_getVendor; + ASensor_isDirectChannelTypeSupported; # introduced=26 ASensor_isWakeUpSensor; # introduced=21 ASharedMemory_create; # introduced=26 ASharedMemory_getSize; # introduced=26 diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp index 5cfe3004514c9..c7bc885ea4b07 100644 --- a/native/android/sensor.cpp +++ b/native/android/sensor.cpp @@ -17,16 +17,17 @@ #define LOG_TAG "sensor" #include +#include #include #include - -#include -#include -#include - +#include +#include #include #include #include +#include +#include +#include #include @@ -38,6 +39,22 @@ using android::String8; using android::String16; /*****************************************************************************/ +#define ERROR_INVALID_PARAMETER(message) ALOGE("%s: " message, __func__) + +// frequently used check +#define RETURN_IF_MANAGER_IS_NULL(retval) do {\ + if (manager == nullptr) { \ + ERROR_INVALID_PARAMETER("manager cannot be NULL"); \ + return retval; \ + } \ + } while (false) +#define RETURN_IF_SENSOR_IS_NULL(retval) do {\ + if (sensor == nullptr) { \ + ERROR_INVALID_PARAMETER("sensor cannot be NULL"); \ + return retval; \ + } \ + } while (false) + ASensorManager* ASensorManager_getInstance() { return ASensorManager_getInstanceForPackage(NULL); @@ -103,6 +120,78 @@ int ASensorManager_destroyEventQueue(ASensorManager* manager, return 0; } +int ASensorManager_createSharedMemoryDirectChannel( + ASensorManager *manager, int fd, size_t size) { + RETURN_IF_MANAGER_IS_NULL(android::BAD_VALUE); + + if (fd < 0) { + ERROR_INVALID_PARAMETER("fd is invalid."); + return android::BAD_VALUE; + } + + if (size < sizeof(ASensorEvent)) { + ERROR_INVALID_PARAMETER("size has to be greater or equal to sizeof(ASensorEvent)."); + } + + native_handle_t *resourceHandle = native_handle_create(1 /* nFd */, 0 /* nInt */); + if (!resourceHandle) { + return android::NO_MEMORY; + } + + resourceHandle->data[0] = fd; + int ret = static_cast(manager)->createDirectChannel( + size, ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY, resourceHandle); + native_handle_delete(resourceHandle); + return ret; +} + +int ASensorManager_createHardwareBufferDirectChannel( + ASensorManager *manager, AHardwareBuffer const *buffer, size_t size) { + RETURN_IF_MANAGER_IS_NULL(android::BAD_VALUE); + + if (buffer == nullptr) { + ERROR_INVALID_PARAMETER("buffer cannot be NULL"); + return android::BAD_VALUE; + } + + if (size < sizeof(ASensorEvent)) { + ERROR_INVALID_PARAMETER("size has to be greater or equal to sizeof(ASensorEvent)."); + } + + const native_handle_t *resourceHandle = AHardwareBuffer_getNativeHandle(buffer); + if (!resourceHandle) { + return android::NO_MEMORY; + } + + return static_cast(manager)->createDirectChannel( + size, ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER, resourceHandle); +} + +void ASensorManager_destroyDirectChannel(ASensorManager *manager, int channelId) { + RETURN_IF_MANAGER_IS_NULL(void()); + + static_cast(manager)->destroyDirectChannel(channelId); +} + +int ASensorManager_configureDirectReport( + ASensorManager *manager, ASensor const *sensor, int channelId, int rate) { + RETURN_IF_MANAGER_IS_NULL(android::BAD_VALUE); + + int sensorHandle; + if (sensor == nullptr) { + if (rate != ASENSOR_DIRECT_RATE_STOP) { + ERROR_INVALID_PARAMETER( + "sensor cannot be null when rate is not ASENSOR_DIRECT_RATE_STOP"); + return android::BAD_VALUE; + } + sensorHandle = -1; + } else { + sensorHandle = static_cast(sensor)->getHandle(); + } + return static_cast(manager)->configureDirectChannel( + channelId, sensorHandle, rate); +} + /*****************************************************************************/ int ASensorEventQueue_registerSensor(ASensorEventQueue* queue, ASensor const* sensor, @@ -211,3 +300,13 @@ bool ASensor_isWakeUpSensor(ASensor const* sensor) { return static_cast(sensor)->isWakeUpSensor(); } + +bool ASensor_isDirectChannelTypeSupported(ASensor const *sensor, int channelType) { + RETURN_IF_SENSOR_IS_NULL(false); + return static_cast(sensor)->isDirectChannelTypeSupported(channelType); +} + +int ASensor_getHighestDirectReportRateLevel(ASensor const *sensor) { + RETURN_IF_SENSOR_IS_NULL(ASENSOR_DIRECT_RATE_STOP); + return static_cast(sensor)->getHighestDirectReportRateLevel(); +}