summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriele M <moto.falcon.git@gmail.com>2017-08-30 22:36:47 +0200
committerHemant Sharma <hemantbeast@gmail.com>2018-01-10 18:58:13 +0530
commit715c96cb885d67d6b46ff39a7956ac9869681b14 (patch)
tree081d4fb0d0df360e94bd136a831224172d08a50b
parent06930fe861080ca8ef49baf8307dc42cd43aca01 (diff)
armani: sensors: Initial implementation of a wrapper for old sensors HAL
This is a wrapper based on multihal that tries to make old sensors HALs compliant with API 1.3. See the followings pages for more details: - https://source.android.com/devices/sensors/versioning - https://source.android.com/devices/sensors/hal-interface Change-Id: I9513164864d8220fae1309f15306cff7e53b6935
-rw-r--r--sensors/multihal.cpp96
1 files changed, 74 insertions, 22 deletions
diff --git a/sensors/multihal.cpp b/sensors/multihal.cpp
index 887a4ba..059ff3e 100644
--- a/sensors/multihal.cpp
+++ b/sensors/multihal.cpp
@@ -26,6 +26,7 @@
#include <string>
#include <fstream>
#include <map>
+#include <unordered_map>
#include <dirent.h>
#include <dlfcn.h>
@@ -55,6 +56,11 @@ bool waiting_for_data = false;
static std::vector<hw_module_t *> *sub_hw_modules = NULL;
/*
+ * Map to retrieve the API version of each sub_hw_module.
+ */
+static std::unordered_map<hw_module_t *, int> *sub_hw_versions = NULL;
+
+/*
* Comparable class that globally identifies a sensor, by module index and local handle.
* A module index is the module's index in sub_hw_modules.
* A local handle is the handle the sub-module assigns to a sensor.
@@ -255,16 +261,6 @@ int sensors_poll_context_t::get_device_version_by_handle(int handle) {
}
}
-// Android N and hire require sensor HALs to be at least 1_3 compliant
-#define HAL_VERSION_IS_COMPLIANT(version) \
- (version >= SENSORS_DEVICE_API_VERSION_1_3)
-
-// Returns true if HAL is compliant, false if HAL is not compliant or if handle is invalid
-static bool halIsCompliant(sensors_poll_context_t *ctx, int handle) {
- int version = ctx->get_device_version_by_handle(handle);
- return version != -1 && HAL_VERSION_IS_COMPLIANT(version);
-}
-
static bool halIsAPILevelCompliant(sensors_poll_context_t *ctx, int handle, int level) {
int version = ctx->get_device_version_by_handle(handle);
return version != -1 && (version >= level);
@@ -292,7 +288,7 @@ int sensors_poll_context_t::activate(int handle, int enabled) {
ALOGV("activate");
int local_handle = get_local_handle(handle);
sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
- if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
+ if (local_handle >= 0 && v0) {
retval = v0->activate(v0, local_handle, enabled);
} else {
ALOGE("IGNORING activate(enable %d) call to non-API-compliant sensor handle=%d !",
@@ -307,7 +303,7 @@ int sensors_poll_context_t::setDelay(int handle, int64_t ns) {
ALOGV("setDelay");
int local_handle = get_local_handle(handle);
sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
- if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
+ if (local_handle >= 0 && v0) {
retval = v0->setDelay(v0, local_handle, ns);
} else {
ALOGE("IGNORING setDelay() call for non-API-compliant sensor handle=%d !", handle);
@@ -385,8 +381,37 @@ int sensors_poll_context_t::batch(int handle, int flags, int64_t period_ns, int6
int retval = -EINVAL;
int local_handle = get_local_handle(handle);
sensors_poll_device_1_t* v1 = this->get_v1_device_by_handle(handle);
- if (halIsCompliant(this, handle) && local_handle >= 0 && v1) {
- retval = v1->batch(v1, local_handle, flags, period_ns, timeout);
+ if (local_handle >= 0 && v1) {
+ if (halIsAPILevelCompliant(this, handle, SENSORS_DEVICE_API_VERSION_1_1)) {
+ retval = v1->batch(v1, local_handle, flags, period_ns, timeout);
+ } else {
+ // NOTE: unlike setDelay(), batch() can be called when the
+ // sensor is disabled.
+
+ // Negative values are not allowed
+ if (period_ns < 0 || timeout < 0) {
+ ALOGE("%s: Invalid parameters", __func__);
+ return -EINVAL;
+ }
+
+ // The HAL should silently clamp period_ns. Here it is assumed
+ // that maxDelay and minDelay are set properly
+ int sub_index = get_module_index(handle);
+ int maxDelay = global_sensors_list[sub_index].maxDelay;
+ int minDelay = global_sensors_list[sub_index].minDelay;
+ if (period_ns < minDelay) {
+ period_ns = minDelay;
+ } else if (period_ns > maxDelay) {
+ period_ns = maxDelay;
+ }
+
+ retval = v1->setDelay((sensors_poll_device_t*)v1, handle, period_ns);
+
+ // Batch should only fail for internal errors
+ if (retval < 0) {
+ ALOGE("setDelay() returned %d", retval);
+ }
+ }
} else {
ALOGE("IGNORING batch() call to non-API-compliant sensor handle=%d !", handle);
}
@@ -399,8 +424,15 @@ int sensors_poll_context_t::flush(int handle) {
int retval = -EINVAL;
int local_handle = get_local_handle(handle);
sensors_poll_device_1_t* v1 = this->get_v1_device_by_handle(handle);
- if (halIsCompliant(this, handle) && local_handle >= 0 && v1) {
- retval = v1->flush(v1, local_handle);
+ if (local_handle >= 0 && v1) {
+ if (halIsAPILevelCompliant(this, handle, SENSORS_DEVICE_API_VERSION_1_1)) {
+ retval = v1->flush(v1, local_handle);
+ } else {
+ // FIXME: for now sensorservice allows -EINVAL as return value
+ // for non-oneshot sensors. This may change in future and flush()
+ // will need to generate META_DATA_FLUSH_COMPLETE events.
+ retval = -EINVAL;
+ }
} else {
ALOGE("IGNORING flush() call to non-API-compliant sensor handle=%d !", handle);
}
@@ -574,6 +606,22 @@ static void lazy_init_modules() {
}
/*
+ * Fix the flags of the sensor to be compliant with the API version
+ * reported by the wrapper.
+ */
+static void fix_sensor_flags(int version, sensor_t& sensor) {
+ if (version < SENSORS_DEVICE_API_VERSION_1_3) {
+ if (sensor.type == SENSOR_TYPE_PROXIMITY ||
+ sensor.type == SENSOR_TYPE_TILT_DETECTOR) {
+ int new_flags = SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_ON_CHANGE_MODE;
+ ALOGV("Changing flags of handle=%d from %x to %x",
+ sensor.handle, sensor.flags, new_flags);
+ sensor.flags = new_flags;
+ }
+ }
+}
+
+/*
* Lazy-initializes global_sensors_count, global_sensors_list, and module_sensor_handles.
*/
static void lazy_init_sensors_list() {
@@ -632,6 +680,9 @@ static void lazy_init_sensors_list() {
ALOGV("module_index %d, local_handle %d, global_handle %d",
module_index, local_handle, global_handle);
+ int version = sub_hw_versions->at(*it);
+ fix_sensor_flags(version, mutable_sensor_list[mutable_sensor_index]);
+
mutable_sensor_index++;
}
module_index++;
@@ -639,6 +690,9 @@ static void lazy_init_sensors_list() {
// Set the const static global_sensors_list to the mutable one allocated by this function.
global_sensors_list = mutable_sensor_list;
+ delete sub_hw_versions;
+ sub_hw_versions = NULL;
+
pthread_mutex_unlock(&init_sensors_mutex);
ALOGV("end lazy_init_sensors_list");
}
@@ -700,6 +754,7 @@ static int open_sensors(const struct hw_module_t* hw_module, const char* name,
dev->nextReadIndex = 0;
+ sub_hw_versions = new std::unordered_map<hw_module_t *, int>();
// Open() the subhal modules. Remember their devices in a vector parallel to sub_hw_modules.
for (std::vector<hw_module_t*>::iterator it = sub_hw_modules->begin();
it != sub_hw_modules->end(); it++) {
@@ -707,13 +762,10 @@ static int open_sensors(const struct hw_module_t* hw_module, const char* name,
struct hw_device_t* sub_hw_device;
int sub_open_result = sensors_module->common.methods->open(*it, name, &sub_hw_device);
if (!sub_open_result) {
- if (!HAL_VERSION_IS_COMPLIANT(sub_hw_device->version)) {
- ALOGE("SENSORS_DEVICE_API_VERSION_1_3 or newer is required for all sensor HALs");
- ALOGE("This HAL reports non-compliant API level : %s",
- apiNumToStr(sub_hw_device->version));
- ALOGE("Sensors belonging to this HAL will get ignored !");
- }
+ ALOGV("This HAL reports API level : %s",
+ apiNumToStr(sub_hw_device->version));
dev->addSubHwDevice(sub_hw_device);
+ sub_hw_versions->insert(std::make_pair(*it, sub_hw_device->version));
}
}