diff options
| author | Gabriele M <moto.falcon.git@gmail.com> | 2017-08-30 22:36:47 +0200 |
|---|---|---|
| committer | Hemant Sharma <hemantbeast@gmail.com> | 2018-01-10 18:58:13 +0530 |
| commit | 715c96cb885d67d6b46ff39a7956ac9869681b14 (patch) | |
| tree | 081d4fb0d0df360e94bd136a831224172d08a50b | |
| parent | 06930fe861080ca8ef49baf8307dc42cd43aca01 (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.cpp | 96 |
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)); } } |
