From c002dd9ecaa5f2dc29e1f488ed6d0b14adbdedb7 Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Wed, 12 Feb 2020 14:41:41 -0500 Subject: [PATCH] Create wrapper for 2.0/2.1 sensor HALs Creates a wrapper that makes a 2.0 sensor HAL appear to look like a 2.1 sensor HAL so that various pieces of code can be shared between the two implementations. Bug: 144139857 Test: Run VTS Change-Id: I4ee4fd2b900e5d4ca744f420f69e150ba38f7949 --- sensors/common/utils/Android.bp | 36 +++ .../common/utils/EventMessageQueueWrapper.h | 109 +++++++++ sensors/common/utils/ISensorsWrapper.h | 209 ++++++++++++++++++ sensors/common/utils/OWNERS | 3 + sensors/common/utils/convertV2_1.h | 122 ++++++++++ 5 files changed, 479 insertions(+) create mode 100644 sensors/common/utils/Android.bp create mode 100644 sensors/common/utils/EventMessageQueueWrapper.h create mode 100644 sensors/common/utils/ISensorsWrapper.h create mode 100644 sensors/common/utils/OWNERS create mode 100644 sensors/common/utils/convertV2_1.h diff --git a/sensors/common/utils/Android.bp b/sensors/common/utils/Android.bp new file mode 100644 index 0000000000..aec6c4b58b --- /dev/null +++ b/sensors/common/utils/Android.bp @@ -0,0 +1,36 @@ +// +// Copyright (C) 2020 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. + +cc_library_headers { + name: "android.hardware.sensors@2.X-shared-utils", + vendor_available: true, + defaults: ["hidl_defaults"], + export_include_dirs: ["."], + shared_libs: [ + "android.hardware.sensors@1.0", + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.1", + "libbinder", + "libcutils", + "libfmq", + "libhidlbase", + "liblog", + "libpower", + "libutils", + ], + static_libs: [ + "android.hardware.sensors@1.0-convert", + ], +} diff --git a/sensors/common/utils/EventMessageQueueWrapper.h b/sensors/common/utils/EventMessageQueueWrapper.h new file mode 100644 index 0000000000..bf3261ffbc --- /dev/null +++ b/sensors/common/utils/EventMessageQueueWrapper.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2020 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 ANDROID_HARDWARE_SENSORS_V2_1_EVENTMESSAGEQUEUEWRAPPER_H +#define ANDROID_HARDWARE_SENSORS_V2_1_EVENTMESSAGEQUEUEWRAPPER_H + +#include "convertV2_1.h" + +#include +#include +#include +#include +#include + +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_1 { +namespace implementation { + +class EventMessageQueueWrapperBase : public RefBase { + public: + virtual ~EventMessageQueueWrapperBase() {} + + virtual std::atomic* getEventFlagWord() = 0; + virtual size_t availableToRead() = 0; + virtual bool read(V2_1::Event* events, size_t numToRead) = 0; + virtual bool write(const std::vector& events) = 0; +}; + +class EventMessageQueueWrapperV1_0 : public EventMessageQueueWrapperBase { + public: + using EventMessageQueue = MessageQueue; + + EventMessageQueueWrapperV1_0(std::unique_ptr& queue) + : mQueue(std::move(queue)) {} + + const ::android::hardware::MQDescriptorSync* getDesc() { + return mQueue->getDesc(); + } + + virtual std::atomic* getEventFlagWord() override { + return mQueue->getEventFlagWord(); + } + + virtual size_t availableToRead() override { return mQueue->availableToRead(); } + + virtual bool read(V2_1::Event* events, size_t numToRead) override { + return mQueue->read(reinterpret_cast(events), numToRead); + } + + virtual bool write(const std::vector& events) override { + const std::vector& oldEvents = convertToOldEvents(events); + return mQueue->write(oldEvents.data(), oldEvents.size()); + } + + private: + std::unique_ptr mQueue; +}; + +class EventMessageQueueWrapperV2_1 : public EventMessageQueueWrapperBase { + public: + using EventMessageQueue = MessageQueue; + + EventMessageQueueWrapperV2_1(std::unique_ptr& queue) + : mQueue(std::move(queue)) {} + + const ::android::hardware::MQDescriptorSync* getDesc() { + return mQueue->getDesc(); + } + + std::atomic* getEventFlagWord() override { return mQueue->getEventFlagWord(); } + + virtual size_t availableToRead() override { return mQueue->availableToRead(); } + + virtual bool read(V2_1::Event* events, size_t numToRead) override { + return mQueue->read(events, numToRead); + } + + bool write(const std::vector& events) override { + return mQueue->write(events.data(), events.size()); + } + + private: + std::unique_ptr mQueue; +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace sensors +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_SENSORS_V2_1_EVENTMESSAGEQUEUEWRAPPER_H \ No newline at end of file diff --git a/sensors/common/utils/ISensorsWrapper.h b/sensors/common/utils/ISensorsWrapper.h new file mode 100644 index 0000000000..4c8b442396 --- /dev/null +++ b/sensors/common/utils/ISensorsWrapper.h @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2020 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 ANDROID_HARDWARE_SENSORS_V2_1_ISENSORSWRAPPER_H +#define ANDROID_HARDWARE_SENSORS_V2_1_ISENSORSWRAPPER_H + +#include "EventMessageQueueWrapper.h" +#include "convertV2_1.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * ISensorsWrapperBase wraps around the V2_1::ISensors APIs to make any HAL 2.0/2.1 interface + * appear as a HAL 2.1 implementation. This ensures the maximum amount of code can be shared + * between VTS, default implementations, and the sensors framework. + */ + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_1 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::sensors::V1_0::OperationMode; +using ::android::hardware::sensors::V1_0::RateLevel; +using ::android::hardware::sensors::V1_0::Result; +using ::android::hardware::sensors::V1_0::SharedMemInfo; + +// TODO: Look into providing this as a param if it needs to be a different value +// than the framework. +static constexpr size_t MAX_RECEIVE_BUFFER_EVENT_COUNT = 256; + +class ISensorsWrapperBase : public RefBase { + public: + virtual ~ISensorsWrapperBase() {} + + virtual EventMessageQueueWrapperBase& getEventQueue() = 0; + virtual Return getSensorsList(V2_1::ISensors::getSensorsList_2_1_cb _hidl_cb) = 0; + virtual Return injectSensorData(const V2_1::Event& event) = 0; + virtual Return initialize( + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) = 0; + + // V2_0::ISensors implementation + void linkToDeath(android::sp deathRecipient, + uint64_t cookie) { + getSensors()->linkToDeath(deathRecipient, cookie); + } + + Return activate(int32_t sensorHandle, bool enabled) { + return getSensors()->activate(sensorHandle, enabled); + } + + Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, + int64_t maxReportLatencyNs) { + return getSensors()->batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs); + } + + Return flush(int32_t sensorHandle) { return getSensors()->flush(sensorHandle); } + + Return registerDirectChannel(const SharedMemInfo& mem, + V2_0::ISensors::registerDirectChannel_cb _hidl_cb) { + return getSensors()->registerDirectChannel(mem, _hidl_cb); + } + + Return unregisterDirectChannel(int32_t channelHandle) { + return getSensors()->unregisterDirectChannel(channelHandle); + } + + Return configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, + V2_0::ISensors::configDirectReport_cb _hidl_cb) { + return getSensors()->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb); + } + + Return setOperationMode(OperationMode mode) { + return getSensors()->setOperationMode(mode); + } + + private: + virtual V2_0::ISensors* getSensors() = 0; +}; + +class ISensorsWrapperV2_0 : public ISensorsWrapperBase { + public: + typedef MessageQueue + EventMessageQueue; + + ISensorsWrapperV2_0(sp& sensors) : mSensors(sensors) { + auto eventQueue = std::make_unique(MAX_RECEIVE_BUFFER_EVENT_COUNT, + true /* configureEventFlagWord */); + mEventQueue = std::make_unique(eventQueue); + } + + EventMessageQueueWrapperBase& getEventQueue() override { return *mEventQueue; } + + Return initialize( + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) override { + return mSensors->initialize(*mEventQueue->getDesc(), wakeLockDescriptor, sensorsCallback); + } + + Return getSensorsList(V2_1::ISensors::getSensorsList_2_1_cb _hidl_cb) override { + return getSensors()->getSensorsList( + [&](const auto& list) { _hidl_cb(convertToNewSensorInfos(list)); }); + } + + Return injectSensorData(const V2_1::Event& event) override { + return mSensors->injectSensorData(convertToOldEvent(event)); + } + + private: + V2_0::ISensors* getSensors() override { return mSensors.get(); } + + sp mSensors; + std::unique_ptr mEventQueue; +}; + +class ISensorsWrapperV2_1 : public ISensorsWrapperBase { + public: + typedef MessageQueue + EventMessageQueue; + + ISensorsWrapperV2_1(sp& sensors) : mSensors(sensors) { + auto eventQueue = std::make_unique(MAX_RECEIVE_BUFFER_EVENT_COUNT, + true /* configureEventFlagWord */); + mEventQueue = std::make_unique(eventQueue); + } + + EventMessageQueueWrapperBase& getEventQueue() override { return *mEventQueue; } + + Return initialize( + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) override { + return mSensors->initialize_2_1(*mEventQueue->getDesc(), wakeLockDescriptor, + sensorsCallback); + } + + Return getSensorsList(V2_1::ISensors::getSensorsList_2_1_cb _hidl_cb) override { + return mSensors->getSensorsList_2_1(_hidl_cb); + } + + Return injectSensorData(const V2_1::Event& event) override { + return mSensors->injectSensorData_2_1(event); + } + + private: + V2_0::ISensors* getSensors() override { return mSensors.get(); } + + sp mSensors; + std::unique_ptr mEventQueue; +}; + +inline sp wrapISensors(sp sensors) { + return new ISensorsWrapperV2_0(sensors); +} + +inline sp wrapISensors(sp sensors) { + return new ISensorsWrapperV2_1(sensors); +} + +class NoOpSensorsCallback : public ISensorsCallback { + public: + Return onDynamicSensorsConnected( + const hidl_vec& /* sensorInfos */) override { + return Return(); + } + + Return onDynamicSensorsDisconnected( + const hidl_vec& /* sensorHandles */) override { + return Return(); + } + + Return onDynamicSensorsConnected_2_1( + const hidl_vec& /* sensorInfos */) override { + return Return(); + } +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace sensors +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_SENSORS_V2_1_ISENSORSWRAPPER_H diff --git a/sensors/common/utils/OWNERS b/sensors/common/utils/OWNERS new file mode 100644 index 0000000000..90c233030e --- /dev/null +++ b/sensors/common/utils/OWNERS @@ -0,0 +1,3 @@ +arthuri@google.com +bduddie@google.com +stange@google.com diff --git a/sensors/common/utils/convertV2_1.h b/sensors/common/utils/convertV2_1.h new file mode 100644 index 0000000000..9231011f3d --- /dev/null +++ b/sensors/common/utils/convertV2_1.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2020 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 ANDROID_HARDWARE_SENSORS_V2_1_CONVERT_H +#define ANDROID_HARDWARE_SENSORS_V2_1_CONVERT_H + +#include +#include +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_1 { +namespace implementation { + +static_assert(sizeof(V1_0::Event) == sizeof(V2_1::Event), + "New and old Event types must have the same size"); +static_assert(sizeof(V1_0::SensorInfo) == sizeof(V2_1::SensorInfo), + "New and old SensorInfo types must have the same size"); + +// The following conversion methods are safe as the only difference between +// V1_0 and V2_1 for these types is an added enum value to SensorType which doesn't +// change the memory layout of the types. +inline const V1_0::Event& convertToOldEvent(const V2_1::Event& event) { + return reinterpret_cast(event); +} + +inline const std::vector& convertToOldEvents(const std::vector& events) { + return reinterpret_cast&>(events); +} + +inline V1_0::Event* convertToOldEvent(V2_1::Event* event) { + return reinterpret_cast(event); +} + +inline const V2_1::SensorInfo& convertToNewSensorInfo(const V1_0::SensorInfo& info) { + return reinterpret_cast(info); +} + +inline const V1_0::SensorInfo& convertToOldSensorInfo(const V2_1::SensorInfo& info) { + return reinterpret_cast(info); +} + +inline const V2_1::Event& convertToNewEvent(const V1_0::Event& event) { + return reinterpret_cast(event); +} + +inline const std::vector& convertToNewEvents(const std::vector& events) { + return reinterpret_cast&>(events); +} + +inline const hidl_vec& convertToNewEvents(const hidl_vec& events) { + return reinterpret_cast&>(events); +} + +inline const hidl_vec& convertToNewSensorInfos( + const hidl_vec& infos) { + return reinterpret_cast&>(infos); +} + +inline const hidl_vec& convertToOldSensorInfos( + const hidl_vec& infos) { + return reinterpret_cast&>(infos); +} + +inline void convertFromSensorEvent(const sensors_event_t& src, V2_1::Event* dst) { + switch ((SensorType)src.type) { + case SensorType::HINGE_ANGLE: + // Only fill in values for hinge angle as other sensors + // will have it filled in by legacy code. + *dst = { + .timestamp = src.timestamp, + .sensorHandle = src.sensor, + .sensorType = (SensorType)src.type, + }; + dst->u.scalar = src.data[0]; + break; + default: + V1_0::implementation::convertFromSensorEvent(src, convertToOldEvent(dst)); + break; + } +} + +inline void convertToSensorEvent(const V2_1::Event& src, sensors_event_t* dst) { + switch (src.sensorType) { + case SensorType::HINGE_ANGLE: + // Only fill in values for hinge angle as other sensors + // will have it filled in by legacy code. + *dst = {.version = sizeof(sensors_event_t), + .sensor = src.sensorHandle, + .type = (int32_t)src.sensorType, + .reserved0 = 0, + .timestamp = src.timestamp}; + dst->data[0] = src.u.scalar; + break; + default: + V1_0::implementation::convertToSensorEvent(convertToOldEvent(src), dst); + break; + } +} + +} // namespace implementation +} // namespace V2_1 +} // namespace sensors +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_SENSORS_V2_1_CONVERT_H