From 7ae480b63e5ef4c2db201af5cedd2092dad2f2cd Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Thu, 13 Apr 2023 16:28:25 +0200 Subject: [PATCH] hidl: sensors: Import 1.0 sensors impl Change-Id: I18b77c5fa0a14c466a2d672b47713201057087f7 --- hidl/sensors/1.0/Android.bp | 51 +++ hidl/sensors/1.0/Sensors.cpp | 360 +++++++++++++++++++ hidl/sensors/1.0/Sensors.h | 88 +++++ hidl/sensors/1.0/convert.cpp | 390 +++++++++++++++++++++ hidl/sensors/1.0/include/sensors/convert.h | 45 +++ 5 files changed, 934 insertions(+) create mode 100644 hidl/sensors/1.0/Android.bp create mode 100644 hidl/sensors/1.0/Sensors.cpp create mode 100644 hidl/sensors/1.0/Sensors.h create mode 100644 hidl/sensors/1.0/convert.cpp create mode 100644 hidl/sensors/1.0/include/sensors/convert.h diff --git a/hidl/sensors/1.0/Android.bp b/hidl/sensors/1.0/Android.bp new file mode 100644 index 0000000..707b123 --- /dev/null +++ b/hidl/sensors/1.0/Android.bp @@ -0,0 +1,51 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_library_shared { + name: "android.hardware.sensors@1.0-impl", + defaults: ["hidl_defaults"], + proprietary: true, + relative_install_path: "hw", + srcs: ["Sensors.cpp"], + shared_libs: [ + "liblog", + "libcutils", + "libhardware", + "libbase", + "libutils", + "libhidlbase", + "android.hardware.sensors@1.0", + ], + static_libs: [ + "android.hardware.sensors@1.0-convert", + "multihal", + ], + local_include_dirs: ["include/sensors"], +} + +cc_library_static { + name: "android.hardware.sensors@1.0-convert", + vendor_available: true, + defaults: ["hidl_defaults"], + srcs: ["convert.cpp"], + export_include_dirs: ["include"], + shared_libs: [ + "liblog", + "libcutils", + "libhardware", + "libbase", + "libutils", + "libhidlbase", + "android.hardware.sensors@1.0", + ], + local_include_dirs: ["include/sensors"], + export_shared_lib_headers: [ + "libhardware", + ], +} diff --git a/hidl/sensors/1.0/Sensors.cpp b/hidl/sensors/1.0/Sensors.cpp new file mode 100644 index 0000000..1100dd6 --- /dev/null +++ b/hidl/sensors/1.0/Sensors.cpp @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2016 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 "Sensors.h" +#include "convert.h" +#include "multihal.h" + +#include + +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V1_0 { +namespace implementation { + +/* + * If a multi-hal configuration file exists in the proper location, + * return true indicating we need to use multi-hal functionality. + */ +static bool UseMultiHal() { + const std::string& name = MULTI_HAL_CONFIG_FILE_PATH; + struct stat buffer; + return (stat (name.c_str(), &buffer) == 0); +} + +static Result ResultFromStatus(status_t err) { + switch (err) { + case OK: + return Result::OK; + case PERMISSION_DENIED: + return Result::PERMISSION_DENIED; + case NO_MEMORY: + return Result::NO_MEMORY; + case BAD_VALUE: + return Result::BAD_VALUE; + default: + return Result::INVALID_OPERATION; + } +} + +Sensors::Sensors() + : mInitCheck(NO_INIT), + mSensorModule(nullptr), + mSensorDevice(nullptr) { + status_t err = OK; + if (UseMultiHal()) { + mSensorModule = ::get_multi_hal_module_info(); + } else { + err = hw_get_module( + SENSORS_HARDWARE_MODULE_ID, + (hw_module_t const **)&mSensorModule); + } + if (mSensorModule == NULL) { + err = UNKNOWN_ERROR; + } + + if (err != OK) { + LOG(ERROR) << "Couldn't load " + << SENSORS_HARDWARE_MODULE_ID + << " module (" + << strerror(-err) + << ")"; + + mInitCheck = err; + return; + } + + err = sensors_open_1(&mSensorModule->common, &mSensorDevice); + + if (err != OK) { + LOG(ERROR) << "Couldn't open device for module " + << SENSORS_HARDWARE_MODULE_ID + << " (" + << strerror(-err) + << ")"; + + mInitCheck = err; + return; + } + + // Require all the old HAL APIs to be present except for injection, which + // is considered optional. + CHECK_GE(getHalDeviceVersion(), SENSORS_DEVICE_API_VERSION_1_3); + + if (getHalDeviceVersion() == SENSORS_DEVICE_API_VERSION_1_4) { + if (mSensorDevice->inject_sensor_data == nullptr) { + LOG(ERROR) << "HAL specifies version 1.4, but does not implement inject_sensor_data()"; + } + if (mSensorModule->set_operation_mode == nullptr) { + LOG(ERROR) << "HAL specifies version 1.4, but does not implement set_operation_mode()"; + } + } + + mInitCheck = OK; +} + +status_t Sensors::initCheck() const { + return mInitCheck; +} + +Return Sensors::getSensorsList(getSensorsList_cb _hidl_cb) { + sensor_t const *list; + size_t count = mSensorModule->get_sensors_list(mSensorModule, &list); + + hidl_vec out; + out.resize(count); + + for (size_t i = 0; i < count; ++i) { + const sensor_t *src = &list[i]; + SensorInfo *dst = &out[i]; + + convertFromSensor(*src, dst); + } + + _hidl_cb(out); + + return Void(); +} + +int Sensors::getHalDeviceVersion() const { + if (!mSensorDevice) { + return -1; + } + + return mSensorDevice->common.version; +} + +Return Sensors::setOperationMode(OperationMode mode) { + if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4 + || mSensorModule->set_operation_mode == nullptr) { + return Result::INVALID_OPERATION; + } + return ResultFromStatus(mSensorModule->set_operation_mode((uint32_t)mode)); +} + +Return Sensors::activate( + int32_t sensor_handle, bool enabled) { + return ResultFromStatus( + mSensorDevice->activate( + reinterpret_cast(mSensorDevice), + sensor_handle, + enabled)); +} + +Return Sensors::poll(int32_t maxCount, poll_cb _hidl_cb) { + + hidl_vec out; + hidl_vec dynamicSensorsAdded; + + std::unique_ptr data; + int err = android::NO_ERROR; + + { // scope of reentry lock + + // This enforces a single client, meaning that a maximum of one client can call poll(). + // If this function is re-entred, it means that we are stuck in a state that may prevent + // the system from proceeding normally. + // + // Exit and let the system restart the sensor-hal-implementation hidl service. + // + // This function must not call _hidl_cb(...) or return until there is no risk of blocking. + std::unique_lock lock(mPollLock, std::try_to_lock); + if(!lock.owns_lock()){ + // cannot get the lock, hidl service will go into deadlock if it is not restarted. + // This is guaranteed to not trigger in passthrough mode. + LOG(ERROR) << + "ISensors::poll() re-entry. I do not know what to do except killing myself."; + ::exit(-1); + } + + if (maxCount <= 0) { + err = android::BAD_VALUE; + } else { + int bufferSize = maxCount <= kPollMaxBufferSize ? maxCount : kPollMaxBufferSize; + data.reset(new sensors_event_t[bufferSize]); + err = mSensorDevice->poll( + reinterpret_cast(mSensorDevice), + data.get(), bufferSize); + } + } + + if (err < 0) { + _hidl_cb(ResultFromStatus(err), out, dynamicSensorsAdded); + return Void(); + } + + const size_t count = (size_t)err; + + for (size_t i = 0; i < count; ++i) { + if (data[i].type != SENSOR_TYPE_DYNAMIC_SENSOR_META) { + continue; + } + + const dynamic_sensor_meta_event_t *dyn = &data[i].dynamic_sensor_meta; + + if (!dyn->connected) { + continue; + } + + CHECK(dyn->sensor != nullptr); + CHECK_EQ(dyn->sensor->handle, dyn->handle); + + SensorInfo info; + convertFromSensor(*dyn->sensor, &info); + + size_t numDynamicSensors = dynamicSensorsAdded.size(); + dynamicSensorsAdded.resize(numDynamicSensors + 1); + dynamicSensorsAdded[numDynamicSensors] = info; + } + + out.resize(count); + convertFromSensorEvents(err, data.get(), &out); + + _hidl_cb(Result::OK, out, dynamicSensorsAdded); + + return Void(); +} + +Return Sensors::batch( + int32_t sensor_handle, + int64_t sampling_period_ns, + int64_t max_report_latency_ns) { + return ResultFromStatus( + mSensorDevice->batch( + mSensorDevice, + sensor_handle, + 0, /*flags*/ + sampling_period_ns, + max_report_latency_ns)); +} + +Return Sensors::flush(int32_t sensor_handle) { + return ResultFromStatus(mSensorDevice->flush(mSensorDevice, sensor_handle)); +} + +Return Sensors::injectSensorData(const Event& event) { + if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4 + || mSensorDevice->inject_sensor_data == nullptr) { + return Result::INVALID_OPERATION; + } + + sensors_event_t out; + convertToSensorEvent(event, &out); + + return ResultFromStatus( + mSensorDevice->inject_sensor_data(mSensorDevice, &out)); +} + +Return Sensors::registerDirectChannel( + const SharedMemInfo& mem, registerDirectChannel_cb _hidl_cb) { + if (mSensorDevice->register_direct_channel == nullptr + || mSensorDevice->config_direct_report == nullptr) { + // HAL does not support + _hidl_cb(Result::INVALID_OPERATION, -1); + return Void(); + } + + sensors_direct_mem_t m; + if (!convertFromSharedMemInfo(mem, &m)) { + _hidl_cb(Result::BAD_VALUE, -1); + return Void(); + } + + int err = mSensorDevice->register_direct_channel(mSensorDevice, &m, -1); + + if (err < 0) { + _hidl_cb(ResultFromStatus(err), -1); + } else { + int32_t channelHandle = static_cast(err); + _hidl_cb(Result::OK, channelHandle); + } + return Void(); +} + +Return Sensors::unregisterDirectChannel(int32_t channelHandle) { + if (mSensorDevice->register_direct_channel == nullptr + || mSensorDevice->config_direct_report == nullptr) { + // HAL does not support + return Result::INVALID_OPERATION; + } + + mSensorDevice->register_direct_channel(mSensorDevice, nullptr, channelHandle); + + return Result::OK; +} + +Return Sensors::configDirectReport( + int32_t sensorHandle, int32_t channelHandle, RateLevel rate, + configDirectReport_cb _hidl_cb) { + if (mSensorDevice->register_direct_channel == nullptr + || mSensorDevice->config_direct_report == nullptr) { + // HAL does not support + _hidl_cb(Result::INVALID_OPERATION, -1); + return Void(); + } + + sensors_direct_cfg_t cfg = { + .rate_level = convertFromRateLevel(rate) + }; + if (cfg.rate_level < 0) { + _hidl_cb(Result::BAD_VALUE, -1); + return Void(); + } + + int err = mSensorDevice->config_direct_report(mSensorDevice, + sensorHandle, channelHandle, &cfg); + + if (rate == RateLevel::STOP) { + _hidl_cb(ResultFromStatus(err), -1); + } else { + _hidl_cb(err > 0 ? Result::OK : ResultFromStatus(err), err); + } + return Void(); +} + +// static +void Sensors::convertFromSensorEvents( + size_t count, + const sensors_event_t *srcArray, + hidl_vec *dstVec) { + for (size_t i = 0; i < count; ++i) { + const sensors_event_t &src = srcArray[i]; + Event *dst = &(*dstVec)[i]; + + convertFromSensorEvent(src, dst); + } +} + +ISensors *HIDL_FETCH_ISensors(const char * /* hal */) { + Sensors *sensors = new Sensors; + if (sensors->initCheck() != OK) { + delete sensors; + sensors = nullptr; + + return nullptr; + } + + return sensors; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace sensors +} // namespace hardware +} // namespace android diff --git a/hidl/sensors/1.0/Sensors.h b/hidl/sensors/1.0/Sensors.h new file mode 100644 index 0000000..be00a96 --- /dev/null +++ b/hidl/sensors/1.0/Sensors.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016 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. + */ + +#ifndef HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_SENSORS_H_ + +#define HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_SENSORS_H_ + +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V1_0 { +namespace implementation { + + +struct Sensors : public ::android::hardware::sensors::V1_0::ISensors { + Sensors(); + + status_t initCheck() const; + + Return getSensorsList(getSensorsList_cb _hidl_cb) override; + + Return setOperationMode(OperationMode mode) override; + + Return activate( + int32_t sensor_handle, bool enabled) override; + + Return poll(int32_t maxCount, poll_cb _hidl_cb) override; + + Return batch( + int32_t sensor_handle, + int64_t sampling_period_ns, + int64_t max_report_latency_ns) override; + + Return flush(int32_t sensor_handle) override; + + Return injectSensorData(const Event& event) override; + + Return registerDirectChannel( + const SharedMemInfo& mem, registerDirectChannel_cb _hidl_cb) override; + + Return unregisterDirectChannel(int32_t channelHandle) override; + + Return configDirectReport( + int32_t sensorHandle, int32_t channelHandle, RateLevel rate, + configDirectReport_cb _hidl_cb) override; + +private: + static constexpr int32_t kPollMaxBufferSize = 128; + status_t mInitCheck; + sensors_module_t *mSensorModule; + sensors_poll_device_1_t *mSensorDevice; + std::mutex mPollLock; + + int getHalDeviceVersion() const; + + static void convertFromSensorEvents( + size_t count, const sensors_event_t *src, hidl_vec *dst); + + DISALLOW_COPY_AND_ASSIGN(Sensors); +}; + +extern "C" ISensors *HIDL_FETCH_ISensors(const char *name); + +} // namespace implementation +} // namespace V1_0 +} // namespace sensors +} // namespace hardware +} // namespace android + +#endif // HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_SENSORS_H_ diff --git a/hidl/sensors/1.0/convert.cpp b/hidl/sensors/1.0/convert.cpp new file mode 100644 index 0000000..43ee327 --- /dev/null +++ b/hidl/sensors/1.0/convert.cpp @@ -0,0 +1,390 @@ +/* + * Copyright (C) 2016 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 "convert.h" + +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V1_0 { +namespace implementation { + +void convertFromSensor(const sensor_t &src, SensorInfo *dst) { + dst->name = src.name; + dst->vendor = src.vendor; + dst->version = src.version; + dst->sensorHandle = src.handle; + dst->type = (SensorType)src.type; + dst->maxRange = src.maxRange; + dst->resolution = src.resolution; + dst->power = src.power; + dst->minDelay = src.minDelay; + dst->fifoReservedEventCount = src.fifoReservedEventCount; + dst->fifoMaxEventCount = src.fifoMaxEventCount; + dst->typeAsString = src.stringType; + dst->requiredPermission = src.requiredPermission; + dst->maxDelay = src.maxDelay; + dst->flags = src.flags; +} + +void convertToSensor( + const ::android::hardware::sensors::V1_0::SensorInfo &src, + sensor_t *dst) { + dst->name = strdup(src.name.c_str()); + dst->vendor = strdup(src.vendor.c_str()); + dst->version = src.version; + dst->handle = src.sensorHandle; + dst->type = (int)src.type; + dst->maxRange = src.maxRange; + dst->resolution = src.resolution; + dst->power = src.power; + dst->minDelay = src.minDelay; + dst->fifoReservedEventCount = src.fifoReservedEventCount; + dst->fifoMaxEventCount = src.fifoMaxEventCount; + dst->stringType = strdup(src.typeAsString.c_str()); + dst->requiredPermission = strdup(src.requiredPermission.c_str()); + dst->maxDelay = src.maxDelay; + dst->flags = src.flags; + dst->reserved[0] = dst->reserved[1] = 0; +} + +void convertFromSensorEvent(const sensors_event_t &src, Event *dst) { + typedef ::android::hardware::sensors::V1_0::SensorType SensorType; + typedef ::android::hardware::sensors::V1_0::MetaDataEventType MetaDataEventType; + + *dst = { + .timestamp = src.timestamp, + .sensorHandle = src.sensor, + .sensorType = (SensorType)src.type, + }; + + switch (dst->sensorType) { + case SensorType::META_DATA: { + dst->u.meta.what = (MetaDataEventType)src.meta_data.what; + // Legacy HALs contain the handle reference in the meta data field. + // Copy that over to the handle of the event. In legacy HALs this + // field was expected to be 0. + dst->sensorHandle = src.meta_data.sensor; + break; + } + + case SensorType::ACCELEROMETER: + case SensorType::MAGNETIC_FIELD: + case SensorType::ORIENTATION: + case SensorType::GYROSCOPE: + case SensorType::GRAVITY: + case SensorType::LINEAR_ACCELERATION: { + dst->u.vec3.x = src.acceleration.x; + dst->u.vec3.y = src.acceleration.y; + dst->u.vec3.z = src.acceleration.z; + dst->u.vec3.status = (SensorStatus)src.acceleration.status; + break; + } + + case SensorType::GAME_ROTATION_VECTOR: { + dst->u.vec4.x = src.data[0]; + dst->u.vec4.y = src.data[1]; + dst->u.vec4.z = src.data[2]; + dst->u.vec4.w = src.data[3]; + break; + } + + case SensorType::ROTATION_VECTOR: + case SensorType::GEOMAGNETIC_ROTATION_VECTOR: { + dst->u.data[0] = src.data[0]; + dst->u.data[1] = src.data[1]; + dst->u.data[2] = src.data[2]; + dst->u.data[3] = src.data[3]; + dst->u.data[4] = src.data[4]; + break; + } + + case SensorType::MAGNETIC_FIELD_UNCALIBRATED: + case SensorType::GYROSCOPE_UNCALIBRATED: + case SensorType::ACCELEROMETER_UNCALIBRATED: { + dst->u.uncal.x = src.uncalibrated_gyro.x_uncalib; + dst->u.uncal.y = src.uncalibrated_gyro.y_uncalib; + dst->u.uncal.z = src.uncalibrated_gyro.z_uncalib; + dst->u.uncal.x_bias = src.uncalibrated_gyro.x_bias; + dst->u.uncal.y_bias = src.uncalibrated_gyro.y_bias; + dst->u.uncal.z_bias = src.uncalibrated_gyro.z_bias; + break; + } + + case SensorType::DEVICE_ORIENTATION: + case SensorType::LIGHT: + case SensorType::PRESSURE: + case SensorType::TEMPERATURE: + case SensorType::PROXIMITY: + case SensorType::RELATIVE_HUMIDITY: + case SensorType::AMBIENT_TEMPERATURE: + case SensorType::SIGNIFICANT_MOTION: + case SensorType::STEP_DETECTOR: + case SensorType::TILT_DETECTOR: + case SensorType::WAKE_GESTURE: + case SensorType::GLANCE_GESTURE: + case SensorType::PICK_UP_GESTURE: + case SensorType::WRIST_TILT_GESTURE: + case SensorType::STATIONARY_DETECT: + case SensorType::MOTION_DETECT: + case SensorType::HEART_BEAT: + case SensorType::LOW_LATENCY_OFFBODY_DETECT: { + dst->u.scalar = src.data[0]; + break; + } + + case SensorType::STEP_COUNTER: { + dst->u.stepCount = src.u64.step_counter; + break; + } + + case SensorType::HEART_RATE: { + dst->u.heartRate.bpm = src.heart_rate.bpm; + dst->u.heartRate.status = (SensorStatus)src.heart_rate.status; + break; + } + + case SensorType::POSE_6DOF: { // 15 floats + for (size_t i = 0; i < 15; ++i) { + dst->u.pose6DOF[i] = src.data[i]; + } + break; + } + + case SensorType::DYNAMIC_SENSOR_META: { + dst->u.dynamic.connected = src.dynamic_sensor_meta.connected; + dst->u.dynamic.sensorHandle = src.dynamic_sensor_meta.handle; + + memcpy(dst->u.dynamic.uuid.data(), src.dynamic_sensor_meta.uuid, 16); + + break; + } + + case SensorType::ADDITIONAL_INFO: { + ::android::hardware::sensors::V1_0::AdditionalInfo* dstInfo = &dst->u.additional; + + const additional_info_event_t& srcInfo = src.additional_info; + + dstInfo->type = (::android::hardware::sensors::V1_0::AdditionalInfoType)srcInfo.type; + + dstInfo->serial = srcInfo.serial; + + CHECK_EQ(sizeof(dstInfo->u), sizeof(srcInfo.data_int32)); + memcpy(&dstInfo->u, srcInfo.data_int32, sizeof(srcInfo.data_int32)); + break; + } + + default: { + memcpy(dst->u.data.data(), src.data, 16 * sizeof(float)); + break; + } + } +} + +void convertToSensorEvent(const Event &src, sensors_event_t *dst) { + *dst = {.version = sizeof(sensors_event_t), + .sensor = src.sensorHandle, + .type = (int32_t)src.sensorType, + .reserved0 = 0, + .timestamp = src.timestamp}; + + switch (src.sensorType) { + case SensorType::META_DATA: { + // Legacy HALs expect the handle reference in the meta data field. + // Copy it over from the handle of the event. + dst->meta_data.what = (int32_t)src.u.meta.what; + dst->meta_data.sensor = src.sensorHandle; + // Set the sensor handle to 0 to maintain compatibility. + dst->sensor = 0; + break; + } + + case SensorType::ACCELEROMETER: + case SensorType::MAGNETIC_FIELD: + case SensorType::ORIENTATION: + case SensorType::GYROSCOPE: + case SensorType::GRAVITY: + case SensorType::LINEAR_ACCELERATION: { + dst->acceleration.x = src.u.vec3.x; + dst->acceleration.y = src.u.vec3.y; + dst->acceleration.z = src.u.vec3.z; + dst->acceleration.status = (int8_t)src.u.vec3.status; + break; + } + + case SensorType::GAME_ROTATION_VECTOR: { + dst->data[0] = src.u.vec4.x; + dst->data[1] = src.u.vec4.y; + dst->data[2] = src.u.vec4.z; + dst->data[3] = src.u.vec4.w; + break; + } + + case SensorType::ROTATION_VECTOR: + case SensorType::GEOMAGNETIC_ROTATION_VECTOR: { + dst->data[0] = src.u.data[0]; + dst->data[1] = src.u.data[1]; + dst->data[2] = src.u.data[2]; + dst->data[3] = src.u.data[3]; + dst->data[4] = src.u.data[4]; + break; + } + + case SensorType::MAGNETIC_FIELD_UNCALIBRATED: + case SensorType::GYROSCOPE_UNCALIBRATED: + case SensorType::ACCELEROMETER_UNCALIBRATED: + { + dst->uncalibrated_gyro.x_uncalib = src.u.uncal.x; + dst->uncalibrated_gyro.y_uncalib = src.u.uncal.y; + dst->uncalibrated_gyro.z_uncalib = src.u.uncal.z; + dst->uncalibrated_gyro.x_bias = src.u.uncal.x_bias; + dst->uncalibrated_gyro.y_bias = src.u.uncal.y_bias; + dst->uncalibrated_gyro.z_bias = src.u.uncal.z_bias; + break; + } + + case SensorType::DEVICE_ORIENTATION: + case SensorType::LIGHT: + case SensorType::PRESSURE: + case SensorType::TEMPERATURE: + case SensorType::PROXIMITY: + case SensorType::RELATIVE_HUMIDITY: + case SensorType::AMBIENT_TEMPERATURE: + case SensorType::SIGNIFICANT_MOTION: + case SensorType::STEP_DETECTOR: + case SensorType::TILT_DETECTOR: + case SensorType::WAKE_GESTURE: + case SensorType::GLANCE_GESTURE: + case SensorType::PICK_UP_GESTURE: + case SensorType::WRIST_TILT_GESTURE: + case SensorType::STATIONARY_DETECT: + case SensorType::MOTION_DETECT: + case SensorType::HEART_BEAT: + case SensorType::LOW_LATENCY_OFFBODY_DETECT: { + dst->data[0] = src.u.scalar; + break; + } + + case SensorType::STEP_COUNTER: { + dst->u64.step_counter = src.u.stepCount; + break; + } + + case SensorType::HEART_RATE: { + dst->heart_rate.bpm = src.u.heartRate.bpm; + dst->heart_rate.status = (int8_t)src.u.heartRate.status; + break; + } + + case SensorType::POSE_6DOF: { // 15 floats + for (size_t i = 0; i < 15; ++i) { + dst->data[i] = src.u.pose6DOF[i]; + } + break; + } + + case SensorType::DYNAMIC_SENSOR_META: { + dst->dynamic_sensor_meta.connected = src.u.dynamic.connected; + dst->dynamic_sensor_meta.handle = src.u.dynamic.sensorHandle; + dst->dynamic_sensor_meta.sensor = NULL; // to be filled in later + + memcpy(dst->dynamic_sensor_meta.uuid, + src.u.dynamic.uuid.data(), + 16); + + break; + } + + case SensorType::ADDITIONAL_INFO: { + const ::android::hardware::sensors::V1_0::AdditionalInfo &srcInfo = + src.u.additional; + + additional_info_event_t *dstInfo = &dst->additional_info; + dstInfo->type = (int32_t)srcInfo.type; + dstInfo->serial = srcInfo.serial; + + CHECK_EQ(sizeof(srcInfo.u), sizeof(dstInfo->data_int32)); + + memcpy(dstInfo->data_int32, + &srcInfo.u, + sizeof(dstInfo->data_int32)); + + break; + } + + default: { + memcpy(dst->data, src.u.data.data(), 16 * sizeof(float)); + break; + } + } +} + +bool convertFromSharedMemInfo(const SharedMemInfo& memIn, sensors_direct_mem_t *memOut) { + if (memOut == nullptr) { + return false; + } + + switch(memIn.type) { + case SharedMemType::ASHMEM: + memOut->type = SENSOR_DIRECT_MEM_TYPE_ASHMEM; + break; + case SharedMemType::GRALLOC: + memOut->type = SENSOR_DIRECT_MEM_TYPE_GRALLOC; + break; + default: + return false; + } + + switch(memIn.format) { + case SharedMemFormat::SENSORS_EVENT: + memOut->format = SENSOR_DIRECT_FMT_SENSORS_EVENT; + break; + default: + return false; + } + + if (memIn.memoryHandle == nullptr) { + return false; + } + + memOut->size = memIn.size; + memOut->handle = memIn.memoryHandle; + return true; +} + +int convertFromRateLevel(RateLevel rate) { + switch(rate) { + case RateLevel::STOP: + return SENSOR_DIRECT_RATE_STOP; + case RateLevel::NORMAL: + return SENSOR_DIRECT_RATE_NORMAL; + case RateLevel::FAST: + return SENSOR_DIRECT_RATE_FAST; + case RateLevel::VERY_FAST: + return SENSOR_DIRECT_RATE_VERY_FAST; + default: + return -1; + } +} + +} // namespace implementation +} // namespace V1_0 +} // namespace sensors +} // namespace hardware +} // namespace android + diff --git a/hidl/sensors/1.0/include/sensors/convert.h b/hidl/sensors/1.0/include/sensors/convert.h new file mode 100644 index 0000000..c3a0125 --- /dev/null +++ b/hidl/sensors/1.0/include/sensors/convert.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016 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. + */ + +#ifndef HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_INCLUDE_CONVERT_H_ + +#define HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_INCLUDE_CONVERT_H_ + +#include +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V1_0 { +namespace implementation { + +void convertFromSensor(const sensor_t &src, SensorInfo *dst); +void convertToSensor(const SensorInfo &src, sensor_t *dst); + +void convertFromSensorEvent(const sensors_event_t &src, Event *dst); +void convertToSensorEvent(const Event &src, sensors_event_t *dst); + +bool convertFromSharedMemInfo(const SharedMemInfo& memIn, sensors_direct_mem_t *memOut); +int convertFromRateLevel(RateLevel rate); + +} // namespace implementation +} // namespace V1_0 +} // namespace sensors +} // namespace hardware +} // namespace android + +#endif // HARDWARE_INTERFACES_SENSORS_V1_0_DEFAULT_INCLUDE_CONVERT_H_