From bc20e5c2a32e3693242259dc7f9eca6a3a368dcb Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Tue, 3 Mar 2020 15:32:39 -0500 Subject: [PATCH 1/3] Set up Multi-HAL for Sensors HAL 2.1 Bug: 149758467 Test: Load onto device and verify VTS passes Test: Verify new fake subhals load properly and that unit tests pass that have been updated in this topic Change-Id: Icefae8c1261b29d704beedd51de5b3f53b374cc4 --- sensors/2.0/multihal/Android.bp | 8 +- sensors/2.0/multihal/service.cpp | 4 +- .../common/default/2.X/multihal/Android.bp | 5 + .../common/default/2.X/multihal/HalProxy.cpp | 207 +++++++++------- .../default/2.X/multihal/HalProxyCallback.cpp | 82 +++++++ .../default/2.X/multihal/include/HalProxy.h | 228 +++++++++++------- .../2.X/multihal/include/HalProxyCallback.h | 171 +++++++++++++ .../2.X/multihal/include/SubHalWrapper.h | 188 +++++++++++++++ .../multihal/include/V2_0/ScopedWakelock.h | 2 +- .../default/2.X/multihal/tests/Android.bp | 6 + .../2.X/multihal/tests/HalProxy_test.cpp | 5 +- .../common/utils/EventMessageQueueWrapper.h | 36 +++ .../common/utils/ISensorsCallbackWrapper.h | 96 ++++++++ 13 files changed, 855 insertions(+), 183 deletions(-) create mode 100644 sensors/common/default/2.X/multihal/HalProxyCallback.cpp create mode 100644 sensors/common/default/2.X/multihal/include/HalProxyCallback.h create mode 100644 sensors/common/default/2.X/multihal/include/SubHalWrapper.h create mode 100644 sensors/common/utils/ISensorsCallbackWrapper.h diff --git a/sensors/2.0/multihal/Android.bp b/sensors/2.0/multihal/Android.bp index 3ce33906cc..bf51fcdbbc 100644 --- a/sensors/2.0/multihal/Android.bp +++ b/sensors/2.0/multihal/Android.bp @@ -25,6 +25,9 @@ cc_binary { ], init_rc: ["android.hardware.sensors@2.0-service-multihal.rc"], vintf_fragments: ["android.hardware.sensors@2.0-multihal.xml"], + header_libs: [ + "android.hardware.sensors@2.X-shared-utils", + ], shared_libs: [ "android.hardware.sensors@2.0", "android.hardware.sensors@2.0-ScopedWakelock", @@ -37,5 +40,8 @@ cc_binary { "libpower", "libutils", ], - static_libs: ["android.hardware.sensors@2.X-multihal"], + static_libs: [ + "android.hardware.sensors@1.0-convert", + "android.hardware.sensors@2.X-multihal", + ], } diff --git a/sensors/2.0/multihal/service.cpp b/sensors/2.0/multihal/service.cpp index ef77048020..f50ad7e16a 100644 --- a/sensors/2.0/multihal/service.cpp +++ b/sensors/2.0/multihal/service.cpp @@ -23,12 +23,12 @@ using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; using android::hardware::sensors::V2_0::ISensors; -using android::hardware::sensors::V2_0::implementation::HalProxy; +using android::hardware::sensors::V2_1::implementation::HalProxyV2_0; int main(int /* argc */, char** /* argv */) { configureRpcThreadpool(1, true); - android::sp halProxy = new HalProxy(); + android::sp halProxy = new HalProxyV2_0(); if (halProxy->registerAsService() != ::android::OK) { ALOGE("Failed to register Sensors HAL instance"); return -1; diff --git a/sensors/common/default/2.X/multihal/Android.bp b/sensors/common/default/2.X/multihal/Android.bp index 6122323fd8..c80c47a4bf 100644 --- a/sensors/common/default/2.X/multihal/Android.bp +++ b/sensors/common/default/2.X/multihal/Android.bp @@ -17,6 +17,7 @@ cc_defaults { name: "android.hardware.sensors@2.X-multihal-defaults", header_libs: [ "android.hardware.sensors@2.X-multihal.header", + "android.hardware.sensors@2.X-shared-utils", ], shared_libs: [ "android.hardware.sensors@1.0", @@ -30,6 +31,9 @@ cc_defaults { "libpower", "libutils", ], + static_libs: [ + "android.hardware.sensors@1.0-convert", + ], cflags: ["-DLOG_TAG=\"SensorsMultiHal\""], } @@ -62,6 +66,7 @@ cc_library_static { ], srcs: [ "HalProxy.cpp", + "HalProxyCallback.cpp", ], vendor_available: true, export_header_lib_headers: [ diff --git a/sensors/common/default/2.X/multihal/HalProxy.cpp b/sensors/common/default/2.X/multihal/HalProxy.cpp index 869c0330f4..a09e9e938e 100644 --- a/sensors/common/default/2.X/multihal/HalProxy.cpp +++ b/sensors/common/default/2.X/multihal/HalProxy.cpp @@ -32,15 +32,17 @@ namespace android { namespace hardware { namespace sensors { -namespace V2_0 { +namespace V2_1 { namespace implementation { +using ::android::hardware::sensors::V1_0::Result; using ::android::hardware::sensors::V2_0::EventQueueFlagBits; using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits; using ::android::hardware::sensors::V2_0::implementation::getTimeNow; using ::android::hardware::sensors::V2_0::implementation::kWakelockTimeoutNs; -typedef ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*); +typedef V2_0::implementation::ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*); +typedef V2_1::implementation::ISensorsSubHal*(SensorsHalGetSubHalV2_1Func)(uint32_t*); static constexpr int32_t kBitsAfterSubHalIndex = 24; @@ -85,7 +87,24 @@ HalProxy::HalProxy() { init(); } -HalProxy::HalProxy(std::vector& subHalList) : mSubHalList(subHalList) { +HalProxy::HalProxy(std::vector& subHalList) { + for (ISensorsSubHalV2_0* subHal : subHalList) { + mSubHalList.push_back(std::make_unique(subHal)); + } + + init(); +} + +HalProxy::HalProxy(std::vector& subHalList, + std::vector& subHalListV2_1) { + for (ISensorsSubHalV2_0* subHal : subHalList) { + mSubHalList.push_back(std::make_unique(subHal)); + } + + for (ISensorsSubHalV2_1* subHal : subHalListV2_1) { + mSubHalList.push_back(std::make_unique(subHal)); + } + init(); } @@ -93,8 +112,8 @@ HalProxy::~HalProxy() { stopThreads(); } -Return HalProxy::getSensorsList(getSensorsList_cb _hidl_cb) { - std::vector sensors; +Return HalProxy::getSensorsList_2_1(ISensorsV2_1::getSensorsList_2_1_cb _hidl_cb) { + std::vector sensors; for (const auto& iter : mSensors) { sensors.push_back(iter.second); } @@ -102,22 +121,31 @@ Return HalProxy::getSensorsList(getSensorsList_cb _hidl_cb) { return Void(); } +Return HalProxy::getSensorsList(ISensorsV2_0::getSensorsList_cb _hidl_cb) { + std::vector sensors; + for (const auto& iter : mSensors) { + sensors.push_back(convertToOldSensorInfo(iter.second)); + } + _hidl_cb(sensors); + return Void(); +} + Return HalProxy::setOperationMode(OperationMode mode) { Result result = Result::OK; size_t subHalIndex; for (subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) { - ISensorsSubHal* subHal = mSubHalList[subHalIndex]; - result = subHal->setOperationMode(mode); + result = mSubHalList[subHalIndex]->setOperationMode(mode); if (result != Result::OK) { - ALOGE("setOperationMode failed for SubHal: %s", subHal->getName().c_str()); + ALOGE("setOperationMode failed for SubHal: %s", + mSubHalList[subHalIndex]->getName().c_str()); break; } } + if (result != Result::OK) { // Reset the subhal operation modes that have been flipped for (size_t i = 0; i < subHalIndex; i++) { - ISensorsSubHal* subHal = mSubHalList[i]; - subHal->setOperationMode(mCurrentOperationMode); + mSubHalList[i]->setOperationMode(mCurrentOperationMode); } } else { mCurrentOperationMode = mode; @@ -133,10 +161,42 @@ Return HalProxy::activate(int32_t sensorHandle, bool enabled) { ->activate(clearSubHalIndex(sensorHandle), enabled); } -Return HalProxy::initialize( - const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, +Return HalProxy::initialize_2_1( + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, - const sp& sensorsCallback) { + const sp& sensorsCallback) { + sp dynamicCallback = + new ISensorsCallbackWrapperV2_1(sensorsCallback); + + // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions. + auto eventQueue = + std::make_unique(eventQueueDescriptor, true /* resetPointers */); + std::unique_ptr queue = + std::make_unique(eventQueue); + + return initializeCommon(queue, wakeLockDescriptor, dynamicCallback); +} + +Return HalProxy::initialize( + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) { + sp dynamicCallback = + new ISensorsCallbackWrapperV2_0(sensorsCallback); + + // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions. + auto eventQueue = + std::make_unique(eventQueueDescriptor, true /* resetPointers */); + std::unique_ptr queue = + std::make_unique(eventQueue); + + return initializeCommon(queue, wakeLockDescriptor, dynamicCallback); +} + +Return HalProxy::initializeCommon( + std::unique_ptr& eventQueue, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) { Result result = Result::OK; stopThreads(); @@ -147,7 +207,7 @@ Return HalProxy::initialize( disableAllSensors(); // Clears the queue if any events were pending write before. - mPendingWriteEventsQueue = std::queue, size_t>>(); + mPendingWriteEventsQueue = std::queue, size_t>>(); mSizePendingWriteEventsQueue = 0; // Clears previously connected dynamic sensors @@ -156,8 +216,7 @@ Return HalProxy::initialize( mDynamicSensorsCallback = sensorsCallback; // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions. - mEventQueue = - std::make_unique(eventQueueDescriptor, true /* resetPointers */); + mEventQueue = std::move(eventQueue); // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP // events have been successfully read and handled by the framework. @@ -186,12 +245,10 @@ Return HalProxy::initialize( mWakelockThread = std::thread(startWakelockThread, this); for (size_t i = 0; i < mSubHalList.size(); i++) { - auto subHal = mSubHalList[i]; - const auto& subHalCallback = mSubHalCallbacks[i]; - Result currRes = subHal->initialize(subHalCallback); + Result currRes = mSubHalList[i]->initialize(this, this, i); if (currRes != Result::OK) { result = currRes; - ALOGE("Subhal '%s' failed to initialize.", subHal->getName().c_str()); + ALOGE("Subhal '%s' failed to initialize.", mSubHalList[i]->getName().c_str()); break; } } @@ -217,7 +274,11 @@ Return HalProxy::flush(int32_t sensorHandle) { return getSubHalForSensorHandle(sensorHandle)->flush(clearSubHalIndex(sensorHandle)); } -Return HalProxy::injectSensorData(const Event& event) { +Return HalProxy::injectSensorData_2_1(const V2_1::Event& event) { + return injectSensorData(convertToOldEvent(event)); +} + +Return HalProxy::injectSensorData(const V1_0::Event& event) { Result result = Result::OK; if (mCurrentOperationMode == OperationMode::NORMAL && event.sensorType != V1_0::SensorType::ADDITIONAL_INFO) { @@ -226,18 +287,19 @@ Return HalProxy::injectSensorData(const Event& event) { result = Result::BAD_VALUE; } if (result == Result::OK) { - Event subHalEvent = event; + V1_0::Event subHalEvent = event; if (!isSubHalIndexValid(event.sensorHandle)) { return Result::BAD_VALUE; } subHalEvent.sensorHandle = clearSubHalIndex(event.sensorHandle); - result = getSubHalForSensorHandle(event.sensorHandle)->injectSensorData(subHalEvent); + result = getSubHalForSensorHandle(event.sensorHandle) + ->injectSensorData(convertToNewEvent(subHalEvent)); } return result; } Return HalProxy::registerDirectChannel(const SharedMemInfo& mem, - registerDirectChannel_cb _hidl_cb) { + ISensorsV2_0::registerDirectChannel_cb _hidl_cb) { if (mDirectChannelSubHal == nullptr) { _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */); } else { @@ -257,7 +319,8 @@ Return HalProxy::unregisterDirectChannel(int32_t channelHandle) { } Return HalProxy::configDirectReport(int32_t sensorHandle, int32_t channelHandle, - RateLevel rate, configDirectReport_cb _hidl_cb) { + RateLevel rate, + ISensorsV2_0::configDirectReport_cb _hidl_cb) { if (mDirectChannelSubHal == nullptr) { _hidl_cb(Result::INVALID_OPERATION, -1 /* reportToken */); } else if (sensorHandle == -1 && rate != RateLevel::STOP) { @@ -302,7 +365,7 @@ Return HalProxy::debug(const hidl_handle& fd, const hidl_vec& stream << " # of non-dynamic sensors across all subhals: " << mSensors.size() << std::endl; stream << " # of dynamic sensors across all subhals: " << mDynamicSensors.size() << std::endl; stream << "SubHals (" << mSubHalList.size() << "):" << std::endl; - for (ISensorsSubHal* subHal : mSubHalList) { + for (auto& subHal : mSubHalList) { stream << " Name: " << subHal->getName() << std::endl; stream << " Debug dump: " << std::endl; android::base::WriteStringToFd(stream.str(), writeFd); @@ -369,20 +432,37 @@ void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) { } else { SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr = (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal"); - if (sensorsHalGetSubHalPtr == nullptr) { - ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s", - subHalLibraryFile.c_str()); - } else { + if (sensorsHalGetSubHalPtr != nullptr) { std::function sensorsHalGetSubHal = *sensorsHalGetSubHalPtr; uint32_t version; - ISensorsSubHal* subHal = sensorsHalGetSubHal(&version); + ISensorsSubHalV2_0* subHal = sensorsHalGetSubHal(&version); if (version != SUB_HAL_2_0_VERSION) { ALOGE("SubHal version was not 2.0 for library: %s", subHalLibraryFile.c_str()); } else { ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str()); - mSubHalList.push_back(subHal); + mSubHalList.push_back(std::make_unique(subHal)); + } + } else { + SensorsHalGetSubHalV2_1Func* getSubHalV2_1Ptr = + (SensorsHalGetSubHalV2_1Func*)dlsym(handle, "sensorsHalGetSubHal_2_1"); + + if (getSubHalV2_1Ptr == nullptr) { + ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s", + subHalLibraryFile.c_str()); + } else { + std::function sensorsHalGetSubHal_2_1 = + *getSubHalV2_1Ptr; + uint32_t version; + ISensorsSubHalV2_1* subHal = sensorsHalGetSubHal_2_1(&version); + if (version != SUB_HAL_2_1_VERSION) { + ALOGE("SubHal version was not 2.1 for library: %s", + subHalLibraryFile.c_str()); + } else { + ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str()); + mSubHalList.push_back(std::make_unique(subHal)); + } } } } @@ -390,36 +470,28 @@ void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) { } } -void HalProxy::initializeSubHalCallbacks() { - for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) { - sp callback = new HalProxyCallback(this, subHalIndex); - mSubHalCallbacks.push_back(callback); - } -} - void HalProxy::initializeSensorList() { for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) { - ISensorsSubHal* subHal = mSubHalList[subHalIndex]; - auto result = subHal->getSensorsList([&](const auto& list) { + auto result = mSubHalList[subHalIndex]->getSensorsList([&](const auto& list) { for (SensorInfo sensor : list) { if (!subHalIndexIsClear(sensor.sensorHandle)) { ALOGE("SubHal sensorHandle's first byte was not 0"); } else { ALOGV("Loaded sensor: %s", sensor.name.c_str()); sensor.sensorHandle = setSubHalIndex(sensor.sensorHandle, subHalIndex); - setDirectChannelFlags(&sensor, subHal); + setDirectChannelFlags(&sensor, mSubHalList[subHalIndex]); mSensors[sensor.sensorHandle] = sensor; } } }); if (!result.isOk()) { - ALOGE("getSensorsList call failed for SubHal: %s", subHal->getName().c_str()); + ALOGE("getSensorsList call failed for SubHal: %s", + mSubHalList[subHalIndex]->getName().c_str()); } } } void HalProxy::init() { - initializeSubHalCallbacks(); initializeSensorList(); } @@ -552,7 +624,7 @@ void HalProxy::resetSharedWakelock() { } void HalProxy::postEventsToMessageQueue(const std::vector& events, size_t numWakeupEvents, - ScopedWakelock wakelock) { + V2_0::implementation::ScopedWakelock wakelock) { size_t numToWrite = 0; std::lock_guard lock(mEventQueueWriteMutex); if (wakelock.isLocked()) { @@ -610,7 +682,8 @@ void HalProxy::decrementRefCountAndMaybeReleaseWakelock(size_t delta, } } -void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal) { +void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, + std::shared_ptr subHal) { bool sensorSupportsDirectChannel = (sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT | V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0; @@ -624,7 +697,7 @@ void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* sub } } -ISensorsSubHal* HalProxy::getSubHalForSensorHandle(int32_t sensorHandle) { +std::shared_ptr HalProxy::getSubHalForSensorHandle(int32_t sensorHandle) { return mSubHalList[extractSubHalIndex(sensorHandle)]; } @@ -651,46 +724,8 @@ bool HalProxy::subHalIndexIsClear(int32_t sensorHandle) { return (sensorHandle & kSensorHandleSubHalIndexMask) == 0; } -void HalProxyCallback::postEvents(const std::vector& events, ScopedWakelock wakelock) { - if (events.empty() || !mHalProxy->areThreadsRunning()) return; - size_t numWakeupEvents; - std::vector processedEvents = processEvents(events, &numWakeupEvents); - if (numWakeupEvents > 0) { - ALOG_ASSERT(wakelock.isLocked(), - "Wakeup events posted while wakelock unlocked for subhal" - " w/ index %" PRId32 ".", - mSubHalIndex); - } else { - ALOG_ASSERT(!wakelock.isLocked(), - "No Wakeup events posted but wakelock locked for subhal" - " w/ index %" PRId32 ".", - mSubHalIndex); - } - mHalProxy->postEventsToMessageQueue(processedEvents, numWakeupEvents, std::move(wakelock)); -} - -ScopedWakelock HalProxyCallback::createScopedWakelock(bool lock) { - ScopedWakelock wakelock(mHalProxy, lock); - return wakelock; -} - -std::vector HalProxyCallback::processEvents(const std::vector& events, - size_t* numWakeupEvents) const { - *numWakeupEvents = 0; - std::vector eventsOut; - for (Event event : events) { - event.sensorHandle = setSubHalIndex(event.sensorHandle, mSubHalIndex); - eventsOut.push_back(event); - const SensorInfo& sensor = mHalProxy->getSensorInfo(event.sensorHandle); - if ((sensor.flags & V1_0::SensorFlagBits::WAKE_UP) != 0) { - (*numWakeupEvents)++; - } - } - return eventsOut; -} - } // namespace implementation -} // namespace V2_0 +} // namespace V2_1 } // namespace sensors } // namespace hardware } // namespace android diff --git a/sensors/common/default/2.X/multihal/HalProxyCallback.cpp b/sensors/common/default/2.X/multihal/HalProxyCallback.cpp new file mode 100644 index 0000000000..a0e0c6b751 --- /dev/null +++ b/sensors/common/default/2.X/multihal/HalProxyCallback.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2019 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 "HalProxyCallback.h" + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_0 { +namespace implementation { + +static constexpr int32_t kBitsAfterSubHalIndex = 24; + +/** + * Set the subhal index as first byte of sensor handle and return this modified version. + * + * @param sensorHandle The sensor handle to modify. + * @param subHalIndex The index in the hal proxy of the sub hal this sensor belongs to. + * + * @return The modified sensor handle. + */ +int32_t setSubHalIndex(int32_t sensorHandle, size_t subHalIndex) { + return sensorHandle | (static_cast(subHalIndex) << kBitsAfterSubHalIndex); +} + +void HalProxyCallbackBase::postEvents(const std::vector& events, + ScopedWakelock wakelock) { + if (events.empty() || !mCallback->areThreadsRunning()) return; + size_t numWakeupEvents; + std::vector processedEvents = processEvents(events, &numWakeupEvents); + if (numWakeupEvents > 0) { + ALOG_ASSERT(wakelock.isLocked(), + "Wakeup events posted while wakelock unlocked for subhal" + " w/ index %" PRId32 ".", + mSubHalIndex); + } else { + ALOG_ASSERT(!wakelock.isLocked(), + "No Wakeup events posted but wakelock locked for subhal" + " w/ index %" PRId32 ".", + mSubHalIndex); + } + mCallback->postEventsToMessageQueue(processedEvents, numWakeupEvents, std::move(wakelock)); +} + +ScopedWakelock HalProxyCallbackBase::createScopedWakelock(bool lock) { + ScopedWakelock wakelock(mRefCounter, lock); + return wakelock; +} + +std::vector HalProxyCallbackBase::processEvents(const std::vector& events, + size_t* numWakeupEvents) const { + *numWakeupEvents = 0; + std::vector eventsOut; + for (V2_1::Event event : events) { + event.sensorHandle = setSubHalIndex(event.sensorHandle, mSubHalIndex); + eventsOut.push_back(event); + const V2_1::SensorInfo& sensor = mCallback->getSensorInfo(event.sensorHandle); + if ((sensor.flags & V1_0::SensorFlagBits::WAKE_UP) != 0) { + (*numWakeupEvents)++; + } + } + return eventsOut; +} + +} // namespace implementation +} // namespace V2_0 +} // namespace sensors +} // namespace hardware +} // namespace android diff --git a/sensors/common/default/2.X/multihal/include/HalProxy.h b/sensors/common/default/2.X/multihal/include/HalProxy.h index d7e8795903..fb0b806bab 100644 --- a/sensors/common/default/2.X/multihal/include/HalProxy.h +++ b/sensors/common/default/2.X/multihal/include/HalProxy.h @@ -16,12 +16,17 @@ #pragma once +#include "EventMessageQueueWrapper.h" +#include "HalProxyCallback.h" +#include "ISensorsCallbackWrapper.h" +#include "SubHalWrapper.h" #include "V2_0/ScopedWakelock.h" #include "V2_0/SubHal.h" #include "V2_1/SubHal.h" +#include "convertV2_1.h" -#include -#include +#include +#include #include #include #include @@ -38,96 +43,97 @@ namespace android { namespace hardware { namespace sensors { -namespace V2_0 { +namespace V2_1 { namespace implementation { -using ::android::sp; -using ::android::hardware::EventFlag; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::MessageQueue; -using ::android::hardware::MQDescriptor; -using ::android::hardware::Return; -using ::android::hardware::Void; - -class HalProxy : public ISensors, public IScopedWakelockRefCounter { +/** + * HalProxy is the main interface for Multi-HAL. It is responsible for managing subHALs and + * proxying function calls to/from the subHAL APIs from the sensors framework. It also manages any + * wakelocks allocated through the IHalProxyCallback and manages posting events to the sensors + * framework. + */ +class HalProxy : public V2_0::implementation::IScopedWakelockRefCounter, + public V2_0::implementation::ISubHalCallback { public: - using Event = ::android::hardware::sensors::V1_0::Event; + using Event = ::android::hardware::sensors::V2_1::Event; using OperationMode = ::android::hardware::sensors::V1_0::OperationMode; using RateLevel = ::android::hardware::sensors::V1_0::RateLevel; using Result = ::android::hardware::sensors::V1_0::Result; - using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo; + using SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo; using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; - using ISensorsSubHal = ::android::hardware::sensors::V2_0::implementation::ISensorsSubHal; + using IHalProxyCallbackV2_0 = V2_0::implementation::IHalProxyCallback; + using IHalProxyCallbackV2_1 = V2_1::implementation::IHalProxyCallback; + using ISensorsSubHalV2_0 = V2_0::implementation::ISensorsSubHal; + using ISensorsSubHalV2_1 = V2_1::implementation::ISensorsSubHal; + using ISensorsV2_0 = V2_0::ISensors; + using ISensorsV2_1 = V2_1::ISensors; + using HalProxyCallbackBase = V2_0::implementation::HalProxyCallbackBase; explicit HalProxy(); // Test only constructor. - explicit HalProxy(std::vector& subHalList); + explicit HalProxy(std::vector& subHalList); + explicit HalProxy(std::vector& subHalList, + std::vector& subHalListV2_1); ~HalProxy(); + // Methods from ::android::hardware::sensors::V2_1::ISensors follow. + Return getSensorsList_2_1(ISensorsV2_1::getSensorsList_2_1_cb _hidl_cb); + + Return initialize_2_1( + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback); + + Return injectSensorData_2_1(const Event& event); + // Methods from ::android::hardware::sensors::V2_0::ISensors follow. - Return getSensorsList(getSensorsList_cb _hidl_cb) override; + Return getSensorsList(ISensorsV2_0::getSensorsList_cb _hidl_cb); - Return setOperationMode(OperationMode mode) override; + Return setOperationMode(OperationMode mode); - Return activate(int32_t sensorHandle, bool enabled) override; + Return activate(int32_t sensorHandle, bool enabled); Return initialize( - const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, - const sp& sensorsCallback) override; + const sp& sensorsCallback); + + Return initializeCommon( + std::unique_ptr& eventQueue, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback); Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, - int64_t maxReportLatencyNs) override; + int64_t maxReportLatencyNs); - Return flush(int32_t sensorHandle) override; + Return flush(int32_t sensorHandle); - Return injectSensorData(const Event& event) override; + Return injectSensorData(const V1_0::Event& event); Return registerDirectChannel(const SharedMemInfo& mem, - registerDirectChannel_cb _hidl_cb) override; + ISensorsV2_0::registerDirectChannel_cb _hidl_cb); - Return unregisterDirectChannel(int32_t channelHandle) override; + Return unregisterDirectChannel(int32_t channelHandle); Return configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, - configDirectReport_cb _hidl_cb) override; + ISensorsV2_0::configDirectReport_cb _hidl_cb); - Return debug(const hidl_handle& fd, const hidl_vec& args) override; + Return debug(const hidl_handle& fd, const hidl_vec& args); - // Below methods from ::android::hardware::sensors::V2_0::ISensorsCallback with a minor change - // to pass in the sub-HAL index. While the above methods are invoked from the sensors framework - // via the binder, these methods are invoked from a callback provided to sub-HALs inside the - // same process as the HalProxy, but potentially running on different threads. Return onDynamicSensorsConnected(const hidl_vec& dynamicSensorsAdded, - int32_t subHalIndex); + int32_t subHalIndex) override; Return onDynamicSensorsDisconnected(const hidl_vec& dynamicSensorHandlesRemoved, - int32_t subHalIndex); + int32_t subHalIndex) override; - // Below methods are for HalProxyCallback - - /** - * Post events to the event message queue if there is room to write them. Otherwise post the - * remaining events to a background thread for a blocking write with a kPendingWriteTimeoutNs - * timeout. - * - * @param events The list of events to post to the message queue. - * @param numWakeupEvents The number of wakeup events in events. - * @param wakelock The wakelock associated with this post of events. - */ void postEventsToMessageQueue(const std::vector& events, size_t numWakeupEvents, - ScopedWakelock wakelock); + V2_0::implementation::ScopedWakelock wakelock) override; - /** - * Get the sensor info associated with that sensorHandle. - * - * @param sensorHandle The sensor handle. - * - * @return The sensor info object in the mapping. - */ - const SensorInfo& getSensorInfo(int32_t sensorHandle) { return mSensors[sensorHandle]; } + const SensorInfo& getSensorInfo(int32_t sensorHandle) override { + return mSensors[sensorHandle]; + } - bool areThreadsRunning() { return mThreadsRun.load(); } + bool areThreadsRunning() override { return mThreadsRun.load(); } // Below methods are from IScopedWakelockRefCounter interface bool incrementRefCountAndMaybeAcquireWakelock(size_t delta, @@ -136,13 +142,14 @@ class HalProxy : public ISensors, public IScopedWakelockRefCounter { void decrementRefCountAndMaybeReleaseWakelock(size_t delta, int64_t timeoutStart = -1) override; private: - using EventMessageQueue = MessageQueue; + using EventMessageQueueV2_1 = MessageQueue; + using EventMessageQueueV2_0 = MessageQueue; using WakeLockMessageQueue = MessageQueue; /** * The Event FMQ where sensor events are written */ - std::unique_ptr mEventQueue; + std::unique_ptr mEventQueue; /** * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events @@ -161,15 +168,12 @@ class HalProxy : public ISensors, public IScopedWakelockRefCounter { /** * Callback to the sensors framework to inform it that new sensors have been added or removed. */ - sp mDynamicSensorsCallback; + sp mDynamicSensorsCallback; /** - * SubHal object pointers that have been saved from vendor dynamic libraries. + * SubHal objects that have been saved from vendor dynamic libraries. */ - std::vector mSubHalList; - - //! The list of subhal callbacks for each subhal where the indices correlate with mSubHalList - std::vector> mSubHalCallbacks; + std::vector> mSubHalList; /** * Map of sensor handles to SensorInfo objects that contains the sensor info from subhals as @@ -187,7 +191,7 @@ class HalProxy : public ISensors, public IScopedWakelockRefCounter { OperationMode mCurrentOperationMode = OperationMode::NORMAL; //! The single subHal that supports directChannel reporting. - ISensorsSubHal* mDirectChannelSubHal = nullptr; + std::shared_ptr mDirectChannelSubHal; //! The timeout for each pending write on background thread for events. static const int64_t kPendingWriteTimeoutNs = 5 * INT64_C(1000000000) /* 5 seconds */; @@ -239,9 +243,9 @@ class HalProxy : public ISensors, public IScopedWakelockRefCounter { //! The refcount of how many ScopedWakelocks and pending wakeup events are active size_t mWakelockRefCount = 0; - int64_t mWakelockTimeoutStartTime = getTimeNow(); + int64_t mWakelockTimeoutStartTime = V2_0::implementation::getTimeNow(); - int64_t mWakelockTimeoutResetTime = getTimeNow(); + int64_t mWakelockTimeoutResetTime = V2_0::implementation::getTimeNow(); const char* kWakelockName = "SensorsHAL_WAKEUP"; @@ -321,7 +325,7 @@ class HalProxy : public ISensors, public IScopedWakelockRefCounter { * disabled. * @param subHal The subhal pointer that the current sensorInfo object came from. */ - void setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal); + void setDirectChannelFlags(SensorInfo* sensorInfo, std::shared_ptr subHal); /* * Get the subhal pointer which can be found by indexing into the mSubHalList vector @@ -329,7 +333,7 @@ class HalProxy : public ISensors, public IScopedWakelockRefCounter { * * @param sensorHandle The handle used to identify a sensor in one of the subhals. */ - ISensorsSubHal* getSubHalForSensorHandle(int32_t sensorHandle); + std::shared_ptr getSubHalForSensorHandle(int32_t sensorHandle); /** * Checks that sensorHandle's subhal index byte is within bounds of mSubHalList. @@ -368,39 +372,81 @@ class HalProxy : public ISensors, public IScopedWakelockRefCounter { }; /** - * Callback class used to provide the HalProxy with the index of which subHal is invoking + * Since a newer HAL can't masquerade as a older HAL, IHalProxy enables the HalProxy to be compiled + * either for HAL 2.0 or HAL 2.1 depending on the build configuration. */ -class HalProxyCallback : public IHalProxyCallback { - using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo; - - public: - HalProxyCallback(HalProxy* halProxy, int32_t subHalIndex) - : mHalProxy(halProxy), mSubHalIndex(subHalIndex) {} - - Return onDynamicSensorsConnected( - const hidl_vec& dynamicSensorsAdded) override { - return mHalProxy->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex); +template +class IHalProxy : public HalProxy, public ISensorsVersion { + Return getSensorsList(ISensorsV2_0::getSensorsList_cb _hidl_cb) override { + return HalProxy::getSensorsList(_hidl_cb); } - Return onDynamicSensorsDisconnected( - const hidl_vec& dynamicSensorHandlesRemoved) override { - return mHalProxy->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved, mSubHalIndex); + Return setOperationMode(OperationMode mode) override { + return HalProxy::setOperationMode(mode); } - void postEvents(const std::vector& events, ScopedWakelock wakelock); + Return activate(int32_t sensorHandle, bool enabled) override { + return HalProxy::activate(sensorHandle, enabled); + } - ScopedWakelock createScopedWakelock(bool lock); + Return initialize( + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) override { + return HalProxy::initialize(eventQueueDescriptor, wakeLockDescriptor, sensorsCallback); + } - private: - HalProxy* mHalProxy; - int32_t mSubHalIndex; + Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, + int64_t maxReportLatencyNs) override { + return HalProxy::batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs); + } - std::vector processEvents(const std::vector& events, - size_t* numWakeupEvents) const; + Return flush(int32_t sensorHandle) override { return HalProxy::flush(sensorHandle); } + + Return injectSensorData(const V1_0::Event& event) override { + return HalProxy::injectSensorData(event); + } + + Return registerDirectChannel(const SharedMemInfo& mem, + ISensorsV2_0::registerDirectChannel_cb _hidl_cb) override { + return HalProxy::registerDirectChannel(mem, _hidl_cb); + } + + Return unregisterDirectChannel(int32_t channelHandle) override { + return HalProxy::unregisterDirectChannel(channelHandle); + } + + Return configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, + ISensorsV2_0::configDirectReport_cb _hidl_cb) override { + return HalProxy::configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb); + } + + Return debug(const hidl_handle& fd, const hidl_vec& args) override { + return HalProxy::debug(fd, args); + } +}; + +class HalProxyV2_0 : public IHalProxy {}; + +class HalProxyV2_1 : public IHalProxy { + Return getSensorsList_2_1(ISensorsV2_1::getSensorsList_2_1_cb _hidl_cb) override { + return HalProxy::getSensorsList_2_1(_hidl_cb); + } + + Return initialize_2_1( + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) override { + return HalProxy::initialize_2_1(eventQueueDescriptor, wakeLockDescriptor, sensorsCallback); + } + + Return injectSensorData_2_1(const Event& event) override { + return HalProxy::injectSensorData_2_1(event); + } }; } // namespace implementation -} // namespace V2_0 +} // namespace V2_1 } // namespace sensors } // namespace hardware } // namespace android diff --git a/sensors/common/default/2.X/multihal/include/HalProxyCallback.h b/sensors/common/default/2.X/multihal/include/HalProxyCallback.h new file mode 100644 index 0000000000..e62b7d1c00 --- /dev/null +++ b/sensors/common/default/2.X/multihal/include/HalProxyCallback.h @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2019 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. + */ + +#pragma once + +#include "V2_0/ScopedWakelock.h" +#include "V2_0/SubHal.h" +#include "V2_1/SubHal.h" +#include "convertV2_1.h" + +#include +#include +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_0 { +namespace implementation { + +/** + * Interface used to communicate with the HalProxy when subHals interact with their provided + * callback. + */ +class ISubHalCallback { + public: + virtual ~ISubHalCallback() {} + + // Below methods from ::android::hardware::sensors::V2_0::ISensorsCallback with a minor change + // to pass in the sub-HAL index. While the above methods are invoked from the sensors framework + // via the binder, these methods are invoked from a callback provided to sub-HALs inside the + // same process as the HalProxy, but potentially running on different threads. + virtual Return onDynamicSensorsConnected( + const hidl_vec& dynamicSensorsAdded, int32_t subHalIndex) = 0; + + virtual Return onDynamicSensorsDisconnected( + const hidl_vec& dynamicSensorHandlesRemoved, int32_t subHalIndex) = 0; + + /** + * Post events to the event message queue if there is room to write them. Otherwise post the + * remaining events to a background thread for a blocking write with a kPendingWriteTimeoutNs + * timeout. + * + * @param events The list of events to post to the message queue. + * @param numWakeupEvents The number of wakeup events in events. + * @param wakelock The wakelock associated with this post of events. + */ + virtual void postEventsToMessageQueue(const std::vector& events, + size_t numWakeupEvents, + V2_0::implementation::ScopedWakelock wakelock) = 0; + + /** + * Get the sensor info associated with that sensorHandle. + * + * @param sensorHandle The sensor handle. + * + * @return The sensor info object in the mapping. + */ + virtual const V2_1::SensorInfo& getSensorInfo(int32_t sensorHandle) = 0; + + virtual bool areThreadsRunning() = 0; +}; + +/** + * Callback class given to subhals that allows the HalProxy to know which subhal a given invocation + * is coming from. + */ +class HalProxyCallbackBase : public VirtualLightRefBase { + public: + HalProxyCallbackBase(ISubHalCallback* callback, + V2_0::implementation::IScopedWakelockRefCounter* refCounter, + int32_t subHalIndex) + : mCallback(callback), mRefCounter(refCounter), mSubHalIndex(subHalIndex) {} + + void postEvents(const std::vector& events, + V2_0::implementation::ScopedWakelock wakelock); + + V2_0::implementation::ScopedWakelock createScopedWakelock(bool lock); + + protected: + ISubHalCallback* mCallback; + V2_0::implementation::IScopedWakelockRefCounter* mRefCounter; + int32_t mSubHalIndex; + + private: + std::vector processEvents(const std::vector& events, + size_t* numWakeupEvents) const; +}; + +class HalProxyCallbackV2_0 : public HalProxyCallbackBase, + public V2_0::implementation::IHalProxyCallback { + public: + HalProxyCallbackV2_0(ISubHalCallback* callback, + V2_0::implementation::IScopedWakelockRefCounter* refCounter, + int32_t subHalIndex) + : HalProxyCallbackBase(callback, refCounter, subHalIndex) {} + + Return onDynamicSensorsConnected( + const hidl_vec& dynamicSensorsAdded) override { + return mCallback->onDynamicSensorsConnected( + V2_1::implementation::convertToNewSensorInfos(dynamicSensorsAdded), mSubHalIndex); + } + + Return onDynamicSensorsDisconnected( + const hidl_vec& dynamicSensorHandlesRemoved) override { + return mCallback->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved, mSubHalIndex); + } + + void postEvents(const std::vector& events, + V2_0::implementation::ScopedWakelock wakelock) override { + HalProxyCallbackBase::postEvents(V2_1::implementation::convertToNewEvents(events), + std::move(wakelock)); + } + + V2_0::implementation::ScopedWakelock createScopedWakelock(bool lock) override { + return HalProxyCallbackBase::createScopedWakelock(lock); + } +}; + +class HalProxyCallbackV2_1 : public HalProxyCallbackBase, + public V2_1::implementation::IHalProxyCallback { + public: + HalProxyCallbackV2_1(ISubHalCallback* callback, + V2_0::implementation::IScopedWakelockRefCounter* refCounter, + int32_t subHalIndex) + : HalProxyCallbackBase(callback, refCounter, subHalIndex) {} + + Return onDynamicSensorsConnected_2_1( + const hidl_vec& dynamicSensorsAdded) override { + return mCallback->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex); + } + + Return onDynamicSensorsConnected( + const hidl_vec& /* dynamicSensorsAdded */) override { + LOG_ALWAYS_FATAL("Old dynamic sensors method can't be used"); + return Void(); + } + + Return onDynamicSensorsDisconnected( + const hidl_vec& dynamicSensorHandlesRemoved) override { + return mCallback->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved, mSubHalIndex); + } + + void postEvents(const std::vector& events, + V2_0::implementation::ScopedWakelock wakelock) override { + return HalProxyCallbackBase::postEvents(events, std::move(wakelock)); + } + + V2_0::implementation::ScopedWakelock createScopedWakelock(bool lock) override { + return HalProxyCallbackBase::createScopedWakelock(lock); + } +}; + +} // namespace implementation +} // namespace V2_0 +} // namespace sensors +} // namespace hardware +} // namespace android \ No newline at end of file diff --git a/sensors/common/default/2.X/multihal/include/SubHalWrapper.h b/sensors/common/default/2.X/multihal/include/SubHalWrapper.h new file mode 100644 index 0000000000..149bb5ea5b --- /dev/null +++ b/sensors/common/default/2.X/multihal/include/SubHalWrapper.h @@ -0,0 +1,188 @@ +/* + * 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. + */ + +#pragma once + +#include "HalProxyCallback.h" +#include "V2_0/SubHal.h" +#include "V2_1/SubHal.h" + +#include "android/hardware/sensors/1.0/ISensors.h" +#include "android/hardware/sensors/1.0/types.h" +#include "android/hardware/sensors/2.0/ISensors.h" +#include "android/hardware/sensors/2.0/ISensorsCallback.h" +#include "android/hardware/sensors/2.1/ISensors.h" +#include "android/hardware/sensors/2.1/ISensorsCallback.h" +#include "android/hardware/sensors/2.1/types.h" + +#include + +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_1 { +namespace implementation { + +/** + * The following subHal wrapper classes abstract away common functionality across V2.0 and V2.1 + * subHal interfaces. Much of the logic is common between the two versions and this allows users of + * the classes to only care about the type used at initialization and then interact with either + * version of the subHal interface without worrying about the type. + */ +class ISubHalWrapperBase { + protected: + using Event = ::android::hardware::sensors::V2_1::Event; + using OperationMode = ::android::hardware::sensors::V1_0::OperationMode; + using RateLevel = ::android::hardware::sensors::V1_0::RateLevel; + using Result = ::android::hardware::sensors::V1_0::Result; + using SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo; + using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; + + public: + virtual ~ISubHalWrapperBase() {} + + virtual bool supportsNewEvents() = 0; + + virtual Return initialize(V2_0::implementation::ISubHalCallback* callback, + V2_0::implementation::IScopedWakelockRefCounter* refCounter, + int32_t subHalIndex) = 0; + + virtual Return getSensorsList( + ::android::hardware::sensors::V2_1::ISensors::getSensorsList_2_1_cb _hidl_cb) = 0; + + virtual Return setOperationMode(OperationMode mode) = 0; + + virtual Return activate(int32_t sensorHandle, bool enabled) = 0; + + virtual Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, + int64_t maxReportLatencyNs) = 0; + + virtual Return flush(int32_t sensorHandle) = 0; + + virtual Return injectSensorData(const Event& event) = 0; + + virtual Return registerDirectChannel(const SharedMemInfo& mem, + ISensors::registerDirectChannel_cb _hidl_cb) = 0; + + virtual Return unregisterDirectChannel(int32_t channelHandle) = 0; + + virtual Return configDirectReport(int32_t sensorHandle, int32_t channelHandle, + RateLevel rate, + ISensors::configDirectReport_cb _hidl_cb) = 0; + + virtual Return debug(const hidl_handle& fd, const hidl_vec& args) = 0; + + virtual const std::string getName() = 0; +}; + +template +class SubHalWrapperBase : public ISubHalWrapperBase { + public: + SubHalWrapperBase(T* subHal) : mSubHal(subHal){}; + + virtual bool supportsNewEvents() override { return false; } + + virtual Return getSensorsList( + ::android::hardware::sensors::V2_1::ISensors::getSensorsList_2_1_cb _hidl_cb) override { + return mSubHal->getSensorsList( + [&](const auto& list) { _hidl_cb(convertToNewSensorInfos(list)); }); + } + + Return setOperationMode(OperationMode mode) override { + return mSubHal->setOperationMode(mode); + } + + Return activate(int32_t sensorHandle, bool enabled) override { + return mSubHal->activate(sensorHandle, enabled); + } + + Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, + int64_t maxReportLatencyNs) override { + return mSubHal->batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs); + } + + Return flush(int32_t sensorHandle) override { return mSubHal->flush(sensorHandle); } + + virtual Return injectSensorData(const Event& event) override { + return mSubHal->injectSensorData(convertToOldEvent(event)); + } + + Return registerDirectChannel(const SharedMemInfo& mem, + ISensors::registerDirectChannel_cb _hidl_cb) override { + return mSubHal->registerDirectChannel(mem, _hidl_cb); + } + + Return unregisterDirectChannel(int32_t channelHandle) override { + return mSubHal->unregisterDirectChannel(channelHandle); + } + + Return configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, + ISensors::configDirectReport_cb _hidl_cb) override { + return mSubHal->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb); + } + + Return debug(const hidl_handle& fd, const hidl_vec& args) override { + return mSubHal->debug(fd, args); + } + + const std::string getName() override { return mSubHal->getName(); } + + protected: + T* mSubHal; +}; + +class SubHalWrapperV2_0 : public SubHalWrapperBase { + public: + SubHalWrapperV2_0(V2_0::implementation::ISensorsSubHal* subHal) : SubHalWrapperBase(subHal){}; + + Return initialize(V2_0::implementation::ISubHalCallback* callback, + V2_0::implementation::IScopedWakelockRefCounter* refCounter, + int32_t subHalIndex) override { + return mSubHal->initialize( + new V2_0::implementation::HalProxyCallbackV2_0(callback, refCounter, subHalIndex)); + } +}; + +class SubHalWrapperV2_1 : public SubHalWrapperBase { + public: + SubHalWrapperV2_1(V2_1::implementation::ISensorsSubHal* subHal) : SubHalWrapperBase(subHal) {} + + bool supportsNewEvents() override { return true; } + + virtual Return getSensorsList( + ::android::hardware::sensors::V2_1::ISensors::getSensorsList_2_1_cb _hidl_cb) override { + return mSubHal->getSensorsList_2_1([&](const auto& list) { _hidl_cb(list); }); + } + + virtual Return injectSensorData(const Event& event) override { + return mSubHal->injectSensorData_2_1(event); + } + + Return initialize(V2_0::implementation::ISubHalCallback* callback, + V2_0::implementation::IScopedWakelockRefCounter* refCounter, + int32_t subHalIndex) override { + return mSubHal->initialize( + new V2_0::implementation::HalProxyCallbackV2_1(callback, refCounter, subHalIndex)); + } +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace sensors +} // namespace hardware +} // namespace android diff --git a/sensors/common/default/2.X/multihal/include/V2_0/ScopedWakelock.h b/sensors/common/default/2.X/multihal/include/V2_0/ScopedWakelock.h index aa6d9db3d4..1cc5cd5e9e 100644 --- a/sensors/common/default/2.X/multihal/include/V2_0/ScopedWakelock.h +++ b/sensors/common/default/2.X/multihal/include/V2_0/ScopedWakelock.h @@ -88,7 +88,7 @@ class ScopedWakelock { bool isLocked() const { return mLocked; } private: - friend class HalProxyCallback; + friend class HalProxyCallbackBase; IScopedWakelockRefCounter* mRefCounter; int64_t mCreatedAtTimeNs; bool mLocked; diff --git a/sensors/common/default/2.X/multihal/tests/Android.bp b/sensors/common/default/2.X/multihal/tests/Android.bp index 7692b51de0..cfd9e78a6f 100644 --- a/sensors/common/default/2.X/multihal/tests/Android.bp +++ b/sensors/common/default/2.X/multihal/tests/Android.bp @@ -20,6 +20,7 @@ cc_defaults { ], header_libs: [ "android.hardware.sensors@2.0-multihal.header", + "android.hardware.sensors@2.X-shared-utils", ], export_include_dirs: ["fake_subhal"], shared_libs: [ @@ -36,6 +37,7 @@ cc_defaults { "libutils", ], static_libs: [ + "android.hardware.sensors@1.0-convert", "android.hardware.sensors@2.X-multihal", ], cflags: [ @@ -78,7 +80,11 @@ cc_test { name: "android.hardware.sensors@2.X-halproxy-unit-tests", srcs: ["HalProxy_test.cpp"], vendor: true, + header_libs: [ + "android.hardware.sensors@2.X-shared-utils", + ], static_libs: [ + "android.hardware.sensors@1.0-convert", "android.hardware.sensors@2.0-ScopedWakelock.testlib", "android.hardware.sensors@2.X-multihal", "android.hardware.sensors@2.X-fakesubhal-unittest", diff --git a/sensors/common/default/2.X/multihal/tests/HalProxy_test.cpp b/sensors/common/default/2.X/multihal/tests/HalProxy_test.cpp index 867c4a149d..ce65c3cd80 100644 --- a/sensors/common/default/2.X/multihal/tests/HalProxy_test.cpp +++ b/sensors/common/default/2.X/multihal/tests/HalProxy_test.cpp @@ -40,8 +40,8 @@ using ::android::hardware::sensors::V1_0::SensorType; using ::android::hardware::sensors::V2_0::EventQueueFlagBits; using ::android::hardware::sensors::V2_0::ISensorsCallback; using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits; -using ::android::hardware::sensors::V2_0::implementation::HalProxy; -using ::android::hardware::sensors::V2_0::implementation::HalProxyCallback; +using ::android::hardware::sensors::V2_0::implementation::HalProxyCallbackBase; +using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock; using ::android::hardware::sensors::V2_0::subhal::implementation::AddAndRemoveDynamicSensorsSubHal; using ::android::hardware::sensors::V2_0::subhal::implementation::AllSensorsSubHal; using ::android::hardware::sensors::V2_0::subhal::implementation:: @@ -53,6 +53,7 @@ using ::android::hardware::sensors::V2_0::subhal::implementation::OnChangeSensor using ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal; using ::android::hardware::sensors::V2_0::subhal::implementation:: SetOperationModeFailingSensorsSubHal; +using ::android::hardware::sensors::V2_1::implementation::HalProxy; using EventMessageQueue = MessageQueue; using WakeupMessageQueue = MessageQueue; diff --git a/sensors/common/utils/EventMessageQueueWrapper.h b/sensors/common/utils/EventMessageQueueWrapper.h index bf3261ffbc..c4f92c8386 100644 --- a/sensors/common/utils/EventMessageQueueWrapper.h +++ b/sensors/common/utils/EventMessageQueueWrapper.h @@ -39,8 +39,14 @@ class EventMessageQueueWrapperBase : public RefBase { virtual std::atomic* getEventFlagWord() = 0; virtual size_t availableToRead() = 0; + virtual size_t availableToWrite() = 0; virtual bool read(V2_1::Event* events, size_t numToRead) = 0; + virtual bool write(const V2_1::Event* events, size_t numToWrite) = 0; virtual bool write(const std::vector& events) = 0; + virtual bool writeBlocking(const V2_1::Event* events, size_t count, uint32_t readNotification, + uint32_t writeNotification, int64_t timeOutNanos, + android::hardware::EventFlag* evFlag) = 0; + virtual size_t getQuantumCount() = 0; }; class EventMessageQueueWrapperV1_0 : public EventMessageQueueWrapperBase { @@ -60,15 +66,30 @@ class EventMessageQueueWrapperV1_0 : public EventMessageQueueWrapperBase { virtual size_t availableToRead() override { return mQueue->availableToRead(); } + size_t availableToWrite() override { return mQueue->availableToWrite(); } + virtual bool read(V2_1::Event* events, size_t numToRead) override { return mQueue->read(reinterpret_cast(events), numToRead); } + bool write(const V2_1::Event* events, size_t numToWrite) override { + return mQueue->write(reinterpret_cast(events), numToWrite); + } + virtual bool write(const std::vector& events) override { const std::vector& oldEvents = convertToOldEvents(events); return mQueue->write(oldEvents.data(), oldEvents.size()); } + bool writeBlocking(const V2_1::Event* events, size_t count, uint32_t readNotification, + uint32_t writeNotification, int64_t timeOutNanos, + android::hardware::EventFlag* evFlag) override { + return mQueue->writeBlocking(reinterpret_cast(events), count, + readNotification, writeNotification, timeOutNanos, evFlag); + } + + size_t getQuantumCount() override { return mQueue->getQuantumCount(); } + private: std::unique_ptr mQueue; }; @@ -88,14 +109,29 @@ class EventMessageQueueWrapperV2_1 : public EventMessageQueueWrapperBase { virtual size_t availableToRead() override { return mQueue->availableToRead(); } + size_t availableToWrite() override { return mQueue->availableToWrite(); } + virtual bool read(V2_1::Event* events, size_t numToRead) override { return mQueue->read(events, numToRead); } + bool write(const V2_1::Event* events, size_t numToWrite) override { + return mQueue->write(events, numToWrite); + } + bool write(const std::vector& events) override { return mQueue->write(events.data(), events.size()); } + bool writeBlocking(const V2_1::Event* events, size_t count, uint32_t readNotification, + uint32_t writeNotification, int64_t timeOutNanos, + android::hardware::EventFlag* evFlag) override { + return mQueue->writeBlocking(events, count, readNotification, writeNotification, + timeOutNanos, evFlag); + } + + size_t getQuantumCount() override { return mQueue->getQuantumCount(); } + private: std::unique_ptr mQueue; }; diff --git a/sensors/common/utils/ISensorsCallbackWrapper.h b/sensors/common/utils/ISensorsCallbackWrapper.h new file mode 100644 index 0000000000..816b225806 --- /dev/null +++ b/sensors/common/utils/ISensorsCallbackWrapper.h @@ -0,0 +1,96 @@ +/* + * 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_ISENSORSCALLBACKWRAPPER_H +#define ANDROID_HARDWARE_SENSORS_V2_1_ISENSORSCALLBACKWRAPPER_H + +#include "convertV2_1.h" + +#include "android/hardware/sensors/1.0/ISensors.h" +#include "android/hardware/sensors/1.0/types.h" +#include "android/hardware/sensors/2.0/ISensors.h" +#include "android/hardware/sensors/2.0/ISensorsCallback.h" +#include "android/hardware/sensors/2.1/ISensors.h" +#include "android/hardware/sensors/2.1/ISensorsCallback.h" +#include "android/hardware/sensors/2.1/types.h" + +#include + +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_1 { +namespace implementation { + +/** + * The ISensorsCallbackWrapper classes below abstract away the common logic between both the V2.0 + * and V2.1 versions of the Sensors HAL interface. This allows users of these classes to only care + * about the HAL version at init time and then interact with either version of the callback without + * worrying about the class type by utilizing the base class. + */ +class ISensorsCallbackWrapperBase : public VirtualLightRefBase { + public: + virtual Return onDynamicSensorsConnected( + const hidl_vec& sensorInfos) = 0; + + virtual Return onDynamicSensorsDisconnected(const hidl_vec& sensorHandles) = 0; +}; + +template +class SensorsCallbackWrapperBase : public ISensorsCallbackWrapperBase { + public: + SensorsCallbackWrapperBase(sp sensorsCallback) : mSensorsCallback(sensorsCallback){}; + + virtual Return onDynamicSensorsConnected( + const hidl_vec& sensorInfos) override { + return mSensorsCallback->onDynamicSensorsConnected(convertToOldSensorInfos(sensorInfos)); + } + + Return onDynamicSensorsDisconnected(const hidl_vec& sensorHandles) { + return mSensorsCallback->onDynamicSensorsDisconnected(sensorHandles); + } + + protected: + sp mSensorsCallback; +}; + +class ISensorsCallbackWrapperV2_0 + : public SensorsCallbackWrapperBase { + public: + ISensorsCallbackWrapperV2_0(sp sensorsCallback) + : SensorsCallbackWrapperBase(sensorsCallback){}; +}; + +class ISensorsCallbackWrapperV2_1 + : public SensorsCallbackWrapperBase { + public: + ISensorsCallbackWrapperV2_1(sp sensorsCallback) + : SensorsCallbackWrapperBase(sensorsCallback) {} + + Return onDynamicSensorsConnected(const hidl_vec& sensorInfos) override { + return mSensorsCallback->onDynamicSensorsConnected_2_1(sensorInfos); + } +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace sensors +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_SENSORS_V2_1_ISENSORSCALLBACKWRAPPER_H \ No newline at end of file From 82f8d466919c33d754d83b426d8679009a4f6626 Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Tue, 28 Apr 2020 12:03:18 -0400 Subject: [PATCH 2/3] Create Multi-HAL 2.1 service Bug: 149758467 Test: Verify that the new unit tests and subhals in this topic load and run on a Pixel device Change-Id: Id5ab7b606f91764a456d8e3a16f7f0f2cf9b4fef --- sensors/2.1/multihal/Android.bp | 47 +++++++++++++++++++ sensors/2.1/multihal/OWNERS | 3 ++ .../android.hardware.sensors@2.1-multihal.xml | 11 +++++ ...d.hardware.sensors@2.1-service-multihal.rc | 7 +++ sensors/2.1/multihal/service.cpp | 39 +++++++++++++++ 5 files changed, 107 insertions(+) create mode 100644 sensors/2.1/multihal/Android.bp create mode 100644 sensors/2.1/multihal/OWNERS create mode 100644 sensors/2.1/multihal/android.hardware.sensors@2.1-multihal.xml create mode 100644 sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc create mode 100644 sensors/2.1/multihal/service.cpp diff --git a/sensors/2.1/multihal/Android.bp b/sensors/2.1/multihal/Android.bp new file mode 100644 index 0000000000..6a7cac9f25 --- /dev/null +++ b/sensors/2.1/multihal/Android.bp @@ -0,0 +1,47 @@ +// +// 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_binary { + name: "android.hardware.sensors@2.1-service.multihal", + defaults: [ + "hidl_defaults", + ], + vendor: true, + relative_install_path: "hw", + srcs: [ + "service.cpp", + ], + init_rc: ["android.hardware.sensors@2.1-service-multihal.rc"], + vintf_fragments: ["android.hardware.sensors@2.1-multihal.xml"], + header_libs: [ + "android.hardware.sensors@2.X-shared-utils", + ], + shared_libs: [ + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.0-ScopedWakelock", + "android.hardware.sensors@2.1", + "libbase", + "libcutils", + "libfmq", + "libhidlbase", + "liblog", + "libpower", + "libutils", + ], + static_libs: [ + "android.hardware.sensors@1.0-convert", + "android.hardware.sensors@2.X-multihal", + ], +} diff --git a/sensors/2.1/multihal/OWNERS b/sensors/2.1/multihal/OWNERS new file mode 100644 index 0000000000..e9556700d6 --- /dev/null +++ b/sensors/2.1/multihal/OWNERS @@ -0,0 +1,3 @@ +arthuri@google.com +bduddie@google.com +stange@google.com \ No newline at end of file diff --git a/sensors/2.1/multihal/android.hardware.sensors@2.1-multihal.xml b/sensors/2.1/multihal/android.hardware.sensors@2.1-multihal.xml new file mode 100644 index 0000000000..18bd3ae83b --- /dev/null +++ b/sensors/2.1/multihal/android.hardware.sensors@2.1-multihal.xml @@ -0,0 +1,11 @@ + + + android.hardware.sensors + hwbinder + 2.1 + + ISensors + default + + + diff --git a/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc b/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc new file mode 100644 index 0000000000..fc99ee7a06 --- /dev/null +++ b/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc @@ -0,0 +1,7 @@ +service vendor.sensors-hal-2-1-multihal /vendor/bin/hw/android.hardware.sensors@2.1-service.multihal + class hal + user system + group system wakelock context_hub + writepid /dev/cpuset/system-background/tasks + capabilities BLOCK_SUSPEND + rlimit rtprio 10 10 diff --git a/sensors/2.1/multihal/service.cpp b/sensors/2.1/multihal/service.cpp new file mode 100644 index 0000000000..d68d9a3e73 --- /dev/null +++ b/sensors/2.1/multihal/service.cpp @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include "HalProxy.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::hardware::sensors::V2_1::ISensors; +using android::hardware::sensors::V2_1::implementation::HalProxyV2_1; + +int main(int /* argc */, char** /* argv */) { + configureRpcThreadpool(1, true); + + android::sp halProxy = new HalProxyV2_1(); + if (halProxy->registerAsService() != ::android::OK) { + ALOGE("Failed to register Sensors HAL instance"); + return -1; + } + + joinRpcThreadpool(); + return 1; // joinRpcThreadpool shouldn't exit +} From 67888489ce9d0a2f3a7cc29e46ef8e6c521537c1 Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Tue, 28 Apr 2020 15:12:41 -0400 Subject: [PATCH 3/3] Update tests for multihal to test HAL 2.1 Updates tests and fake subhals to support Multi-HAL 2.1 to make on-device testing feasible. Bug: 149758467 Test: Verify that the new unit tests and subhals in this topic load and run on a Pixel device Change-Id: I2be51568ba8dd99aa0588b8945d3d41bda7d9941 --- .../default/2.X/multihal/tests/Android.bp | 12 + .../2.X/multihal/tests/HalProxy_test.cpp | 331 +++++++++++------- .../fake_subhal/IHalProxyCallbackWrapper.h | 107 ++++++ .../2.X/multihal/tests/fake_subhal/Sensor.cpp | 9 +- .../2.X/multihal/tests/fake_subhal/Sensor.h | 12 +- .../tests/fake_subhal/SensorsSubHal.cpp | 120 ++++--- .../tests/fake_subhal/SensorsSubHal.h | 173 +++++++-- 7 files changed, 531 insertions(+), 233 deletions(-) create mode 100644 sensors/common/default/2.X/multihal/tests/fake_subhal/IHalProxyCallbackWrapper.h diff --git a/sensors/common/default/2.X/multihal/tests/Android.bp b/sensors/common/default/2.X/multihal/tests/Android.bp index cfd9e78a6f..6586b0b470 100644 --- a/sensors/common/default/2.X/multihal/tests/Android.bp +++ b/sensors/common/default/2.X/multihal/tests/Android.bp @@ -50,6 +50,7 @@ cc_library { vendor: true, defaults: ["android.hardware.sensors@2.X-fakesubhal-defaults"], cflags: [ + "-DSUB_HAL_VERSION_2_0", "-DSUPPORT_CONTINUOUS_SENSORS", "-DSUB_HAL_NAME=\"FakeSubHal-Continuous\"", ], @@ -59,6 +60,17 @@ cc_library { name: "android.hardware.sensors@2.X-fakesubhal-config2", vendor: true, defaults: ["android.hardware.sensors@2.X-fakesubhal-defaults"], + cflags: [ + "-DSUB_HAL_VERSION_2_0", + "-DSUPPORT_ON_CHANGE_SENSORS", + "-DSUB_HAL_NAME=\"FakeSubHal-OnChange\"", + ], +} + +cc_library { + name: "android.hardware.sensors@2.X-fakesubhal-config3", + vendor: true, + defaults: ["android.hardware.sensors@2.X-fakesubhal-defaults"], cflags: [ "-DSUPPORT_ON_CHANGE_SENSORS", "-DSUB_HAL_NAME=\"FakeSubHal-OnChange\"", diff --git a/sensors/common/default/2.X/multihal/tests/HalProxy_test.cpp b/sensors/common/default/2.X/multihal/tests/HalProxy_test.cpp index ce65c3cd80..858786af09 100644 --- a/sensors/common/default/2.X/multihal/tests/HalProxy_test.cpp +++ b/sensors/common/default/2.X/multihal/tests/HalProxy_test.cpp @@ -15,12 +15,15 @@ #include +#include #include +#include #include #include "HalProxy.h" #include "SensorsSubHal.h" #include "V2_0/ScopedWakelock.h" +#include "convertV2_1.h" #include #include @@ -38,28 +41,35 @@ using ::android::hardware::sensors::V1_0::SensorFlagBits; using ::android::hardware::sensors::V1_0::SensorInfo; using ::android::hardware::sensors::V1_0::SensorType; using ::android::hardware::sensors::V2_0::EventQueueFlagBits; -using ::android::hardware::sensors::V2_0::ISensorsCallback; using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits; using ::android::hardware::sensors::V2_0::implementation::HalProxyCallbackBase; using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock; -using ::android::hardware::sensors::V2_0::subhal::implementation::AddAndRemoveDynamicSensorsSubHal; -using ::android::hardware::sensors::V2_0::subhal::implementation::AllSensorsSubHal; -using ::android::hardware::sensors::V2_0::subhal::implementation:: - AllSupportDirectChannelSensorsSubHal; -using ::android::hardware::sensors::V2_0::subhal::implementation::ContinuousSensorsSubHal; -using ::android::hardware::sensors::V2_0::subhal::implementation:: - DoesNotSupportDirectChannelSensorsSubHal; -using ::android::hardware::sensors::V2_0::subhal::implementation::OnChangeSensorsSubHal; -using ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal; -using ::android::hardware::sensors::V2_0::subhal::implementation:: - SetOperationModeFailingSensorsSubHal; +using ::android::hardware::sensors::V2_1::implementation::convertToNewEvents; +using ::android::hardware::sensors::V2_1::implementation::convertToNewSensorInfos; using ::android::hardware::sensors::V2_1::implementation::HalProxy; +using ::android::hardware::sensors::V2_1::subhal::implementation::AddAndRemoveDynamicSensorsSubHal; +using ::android::hardware::sensors::V2_1::subhal::implementation::AllSensorsSubHal; +using ::android::hardware::sensors::V2_1::subhal::implementation:: + AllSupportDirectChannelSensorsSubHal; +using ::android::hardware::sensors::V2_1::subhal::implementation::ContinuousSensorsSubHal; +using ::android::hardware::sensors::V2_1::subhal::implementation:: + DoesNotSupportDirectChannelSensorsSubHal; +using ::android::hardware::sensors::V2_1::subhal::implementation::OnChangeSensorsSubHal; +using ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHalV2_0; +using ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHalV2_1; +using ::android::hardware::sensors::V2_1::subhal::implementation:: + SetOperationModeFailingSensorsSubHal; -using EventMessageQueue = MessageQueue; +using ISensorsCallbackV2_0 = ::android::hardware::sensors::V2_0::ISensorsCallback; +using ISensorsCallbackV2_1 = ::android::hardware::sensors::V2_1::ISensorsCallback; +using EventV1_0 = ::android::hardware::sensors::V1_0::Event; +using EventV2_1 = ::android::hardware::sensors::V2_1::Event; +using EventMessageQueueV2_1 = MessageQueue; +using EventMessageQueueV2_0 = MessageQueue; using WakeupMessageQueue = MessageQueue; // The barebones sensors callback class passed into halproxy initialize calls -class SensorsCallback : public ISensorsCallback { +class SensorsCallback : public ISensorsCallbackV2_0 { public: Return onDynamicSensorsConnected( const hidl_vec& /*dynamicSensorsAdded*/) override { @@ -74,8 +84,30 @@ class SensorsCallback : public ISensorsCallback { } }; +class SensorsCallbackV2_1 : public ISensorsCallbackV2_1 { + public: + Return onDynamicSensorsConnected_2_1( + const hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>& /*dynamicSensorsAdded*/) + override { + // Nothing yet + return Return(); + } + + Return onDynamicSensorsConnected( + const hidl_vec& /*dynamicSensorsAdded*/) override { + // Nothing yet + return Return(); + } + + Return onDynamicSensorsDisconnected( + const hidl_vec& /*dynamicSensorHandlesRemoved*/) override { + // Nothing yet + return Return(); + } +}; + // The sensors callback that expects a variable list of sensors to be added -class TestSensorsCallback : public ISensorsCallback { +class TestSensorsCallback : public ISensorsCallbackV2_0 { public: Return onDynamicSensorsConnected( const hidl_vec& dynamicSensorsAdded) override { @@ -130,10 +162,10 @@ void testSensorsListForOneDirectChannelEnabledSubHal(const std::vector& wakelockQueue, EventFlag* wakelockQueueFlag); -bool readEventsOutOfQueue(size_t numEvents, std::unique_ptr& eventQueue, +bool readEventsOutOfQueue(size_t numEvents, std::unique_ptr& eventQueue, EventFlag* eventQueueFlag); -std::unique_ptr makeEventFMQ(size_t size); +std::unique_ptr makeEventFMQ(size_t size); std::unique_ptr makeWakelockFMQ(size_t size); @@ -143,7 +175,7 @@ std::unique_ptr makeWakelockFMQ(size_t size); * * @return A proximity event. */ -Event makeProximityEvent(); +EventV1_0 makeProximityEvent(); /** * Construct and return a HIDL Event type thats sensorHandle refers to a proximity sensor @@ -151,7 +183,7 @@ Event makeProximityEvent(); * * @return A proximity event. */ -Event makeAccelerometerEvent(); +EventV1_0 makeAccelerometerEvent(); /** * Make a certain number of proximity type events with the sensorHandle field set to @@ -161,7 +193,7 @@ Event makeAccelerometerEvent(); * * @return The created list of events. */ -std::vector makeMultipleProximityEvents(size_t numEvents); +std::vector makeMultipleProximityEvents(size_t numEvents); /** * Make a certain number of accelerometer type events with the sensorHandle field set to @@ -171,7 +203,7 @@ std::vector makeMultipleProximityEvents(size_t numEvents); * * @return The created list of events. */ -std::vector makeMultipleAccelerometerEvents(size_t numEvents); +std::vector makeMultipleAccelerometerEvents(size_t numEvents); /** * Given a SensorInfo vector and a sensor handles vector populate 'sensors' with SensorInfo @@ -189,7 +221,7 @@ void makeSensorsAndSensorHandlesStartingAndOfSize(int32_t start, size_t size, // Tests follow TEST(HalProxyTest, GetSensorsListOneSubHalTest) { - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector fakeSubHals{&subHal}; HalProxy proxy(fakeSubHals); @@ -201,8 +233,8 @@ TEST(HalProxyTest, GetSensorsListOneSubHalTest) { } TEST(HalProxyTest, GetSensorsListTwoSubHalTest) { - ContinuousSensorsSubHal continuousSubHal; - OnChangeSensorsSubHal onChangeSubHal; + ContinuousSensorsSubHal continuousSubHal; + OnChangeSensorsSubHal onChangeSubHal; std::vector fakeSubHals; fakeSubHals.push_back(&continuousSubHal); fakeSubHals.push_back(&onChangeSubHal); @@ -222,8 +254,8 @@ TEST(HalProxyTest, GetSensorsListTwoSubHalTest) { } TEST(HalProxyTest, SetOperationModeTwoSubHalSuccessTest) { - ContinuousSensorsSubHal subHal1; - OnChangeSensorsSubHal subHal2; + ContinuousSensorsSubHal subHal1; + OnChangeSensorsSubHal subHal2; std::vector fakeSubHals{&subHal1, &subHal2}; HalProxy proxy(fakeSubHals); @@ -239,7 +271,7 @@ TEST(HalProxyTest, SetOperationModeTwoSubHalSuccessTest) { } TEST(HalProxyTest, SetOperationModeTwoSubHalFailTest) { - AllSensorsSubHal subHal1; + AllSensorsSubHal subHal1; SetOperationModeFailingSensorsSubHal subHal2; std::vector fakeSubHals{&subHal1, &subHal2}; @@ -280,16 +312,16 @@ TEST(HalProxyTest, InitDirectChannelThreeSubHalsUnitTest) { TEST(HalProxyTest, PostSingleNonWakeupEvent) { constexpr size_t kQueueSize = 5; - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector subHals{&subHal}; HalProxy proxy(subHals); - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); - std::vector events{makeAccelerometerEvent()}; - subHal.postEvents(events, false /* wakeup */); + std::vector events{makeAccelerometerEvent()}; + subHal.postEvents(convertToNewEvents(events), false /* wakeup */); EXPECT_EQ(eventQueue->availableToRead(), 1); } @@ -297,28 +329,28 @@ TEST(HalProxyTest, PostSingleNonWakeupEvent) { TEST(HalProxyTest, PostMultipleNonWakeupEvent) { constexpr size_t kQueueSize = 5; constexpr size_t kNumEvents = 3; - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector subHals{&subHal}; HalProxy proxy(subHals); - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); - std::vector events = makeMultipleAccelerometerEvents(kNumEvents); - subHal.postEvents(events, false /* wakeup */); + std::vector events = makeMultipleAccelerometerEvents(kNumEvents); + subHal.postEvents(convertToNewEvents(events), false /* wakeup */); EXPECT_EQ(eventQueue->availableToRead(), kNumEvents); } TEST(HalProxyTest, PostSingleWakeupEvent) { constexpr size_t kQueueSize = 5; - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector subHals{&subHal}; HalProxy proxy(subHals); - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); EventFlag* eventQueueFlag; @@ -327,8 +359,8 @@ TEST(HalProxyTest, PostSingleWakeupEvent) { EventFlag* wakelockQueueFlag; EventFlag::createEventFlag(wakeLockQueue->getEventFlagWord(), &wakelockQueueFlag); - std::vector events{makeProximityEvent()}; - subHal.postEvents(events, true /* wakeup */); + std::vector events{makeProximityEvent()}; + subHal.postEvents(convertToNewEvents(events), true /* wakeup */); EXPECT_EQ(eventQueue->availableToRead(), 1); @@ -339,12 +371,12 @@ TEST(HalProxyTest, PostSingleWakeupEvent) { TEST(HalProxyTest, PostMultipleWakeupEvents) { constexpr size_t kQueueSize = 5; constexpr size_t kNumEvents = 3; - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector subHals{&subHal}; HalProxy proxy(subHals); - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); EventFlag* eventQueueFlag; @@ -353,8 +385,8 @@ TEST(HalProxyTest, PostMultipleWakeupEvents) { EventFlag* wakelockQueueFlag; EventFlag::createEventFlag(wakeLockQueue->getEventFlagWord(), &wakelockQueueFlag); - std::vector events = makeMultipleProximityEvents(kNumEvents); - subHal.postEvents(events, true /* wakeup */); + std::vector events = makeMultipleProximityEvents(kNumEvents); + subHal.postEvents(convertToNewEvents(events), true /* wakeup */); EXPECT_EQ(eventQueue->availableToRead(), kNumEvents); @@ -365,20 +397,20 @@ TEST(HalProxyTest, PostMultipleWakeupEvents) { TEST(HalProxyTest, PostEventsMultipleSubhals) { constexpr size_t kQueueSize = 5; constexpr size_t kNumEvents = 2; - AllSensorsSubHal subHal1, subHal2; + AllSensorsSubHal subHal1, subHal2; std::vector subHals{&subHal1, &subHal2}; HalProxy proxy(subHals); - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); - std::vector events = makeMultipleAccelerometerEvents(kNumEvents); - subHal1.postEvents(events, false /* wakeup */); + std::vector events = makeMultipleAccelerometerEvents(kNumEvents); + subHal1.postEvents(convertToNewEvents(events), false /* wakeup */); EXPECT_EQ(eventQueue->availableToRead(), kNumEvents); - subHal2.postEvents(events, false /* wakeup */); + subHal2.postEvents(convertToNewEvents(events), false /* wakeup */); EXPECT_EQ(eventQueue->availableToRead(), kNumEvents * 2); } @@ -386,19 +418,19 @@ TEST(HalProxyTest, PostEventsMultipleSubhals) { TEST(HalProxyTest, PostEventsDelayedWrite) { constexpr size_t kQueueSize = 5; constexpr size_t kNumEvents = 6; - AllSensorsSubHal subHal1, subHal2; + AllSensorsSubHal subHal1, subHal2; std::vector subHals{&subHal1, &subHal2}; HalProxy proxy(subHals); - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); EventFlag* eventQueueFlag; EventFlag::createEventFlag(eventQueue->getEventFlagWord(), &eventQueueFlag); - std::vector events = makeMultipleAccelerometerEvents(kNumEvents); - subHal1.postEvents(events, false /* wakeup */); + std::vector events = makeMultipleAccelerometerEvents(kNumEvents); + subHal1.postEvents(convertToNewEvents(events), false /* wakeup */); EXPECT_EQ(eventQueue->availableToRead(), kQueueSize); @@ -414,18 +446,20 @@ TEST(HalProxyTest, PostEventsDelayedWrite) { TEST(HalProxyTest, PostEventsMultipleSubhalsThreaded) { constexpr size_t kQueueSize = 5; constexpr size_t kNumEvents = 2; - AllSensorsSubHal subHal1, subHal2; + AllSensorsSubHal subHal1, subHal2; std::vector subHals{&subHal1, &subHal2}; HalProxy proxy(subHals); - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); - std::vector events = makeMultipleAccelerometerEvents(kNumEvents); + std::vector events = makeMultipleAccelerometerEvents(kNumEvents); - std::thread t1(&AllSensorsSubHal::postEvents, &subHal1, events, false); - std::thread t2(&AllSensorsSubHal::postEvents, &subHal2, events, false); + std::thread t1(&AllSensorsSubHal::postEvents, &subHal1, + convertToNewEvents(events), false); + std::thread t2(&AllSensorsSubHal::postEvents, &subHal2, + convertToNewEvents(events), false); t1.join(); t2.join(); @@ -436,34 +470,34 @@ TEST(HalProxyTest, PostEventsMultipleSubhalsThreaded) { TEST(HalProxyTest, DestructingWithEventsPendingOnBackgroundThread) { constexpr size_t kQueueSize = 5; constexpr size_t kNumEvents = 6; - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector subHals{&subHal}; - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); HalProxy proxy(subHals); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); - std::vector events = makeMultipleAccelerometerEvents(kNumEvents); - subHal.postEvents(events, false /* wakeup */); + std::vector events = makeMultipleAccelerometerEvents(kNumEvents); + subHal.postEvents(convertToNewEvents(events), false /* wakeup */); // Destructing HalProxy object with events on the background thread } TEST(HalProxyTest, DestructingWithUnackedWakeupEventsPosted) { constexpr size_t kQueueSize = 5; - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector subHals{&subHal}; - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); HalProxy proxy(subHals); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); - std::vector events{makeProximityEvent()}; - subHal.postEvents(events, true /* wakeup */); + std::vector events{makeProximityEvent()}; + subHal.postEvents(convertToNewEvents(events), true /* wakeup */); // Not sending any acks back through wakeLockQueue @@ -473,17 +507,17 @@ TEST(HalProxyTest, DestructingWithUnackedWakeupEventsPosted) { TEST(HalProxyTest, ReinitializeWithEventsPendingOnBackgroundThread) { constexpr size_t kQueueSize = 5; constexpr size_t kNumEvents = 10; - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector subHals{&subHal}; - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); HalProxy proxy(subHals); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); - std::vector events = makeMultipleAccelerometerEvents(kNumEvents); - subHal.postEvents(events, false /* wakeup */); + std::vector events = makeMultipleAccelerometerEvents(kNumEvents); + subHal.postEvents(convertToNewEvents(events), false /* wakeup */); eventQueue = makeEventFMQ(kQueueSize); wakeLockQueue = makeWakelockFMQ(kQueueSize); @@ -493,23 +527,23 @@ TEST(HalProxyTest, ReinitializeWithEventsPendingOnBackgroundThread) { EXPECT_EQ(secondInitResult, Result::OK); // Small sleep so that pending writes thread has a change to hit writeBlocking call. std::this_thread::sleep_for(std::chrono::milliseconds(5)); - Event eventOut; + EventV1_0 eventOut; EXPECT_FALSE(eventQueue->read(&eventOut)); } TEST(HalProxyTest, ReinitializingWithUnackedWakeupEventsPosted) { constexpr size_t kQueueSize = 5; - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector subHals{&subHal}; - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); HalProxy proxy(subHals); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); - std::vector events{makeProximityEvent()}; - subHal.postEvents(events, true /* wakeup */); + std::vector events{makeProximityEvent()}; + subHal.postEvents(convertToNewEvents(events), true /* wakeup */); // Not sending any acks back through wakeLockQueue @@ -524,12 +558,12 @@ TEST(HalProxyTest, ReinitializingWithUnackedWakeupEventsPosted) { TEST(HalProxyTest, InitializeManyTimesInARow) { constexpr size_t kQueueSize = 5; constexpr size_t kNumTimesToInit = 100; - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector subHals{&subHal}; - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); HalProxy proxy(subHals); for (size_t i = 0; i < kNumTimesToInit; i++) { @@ -541,15 +575,15 @@ TEST(HalProxyTest, InitializeManyTimesInARow) { TEST(HalProxyTest, OperationModeResetOnInitialize) { constexpr size_t kQueueSize = 5; - AllSensorsSubHal subHal; + AllSensorsSubHal subHal; std::vector subHals{&subHal}; - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); HalProxy proxy(subHals); proxy.setOperationMode(OperationMode::DATA_INJECTION); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); - Event event = makeAccelerometerEvent(); + EventV1_0 event = makeAccelerometerEvent(); // Should not be able to inject a non AdditionInfo type event because operation mode should // have been reset to NORMAL EXPECT_EQ(proxy.injectSensorData(event), Result::BAD_VALUE); @@ -560,7 +594,7 @@ TEST(HalProxyTest, DynamicSensorsDiscardedOnInitialize) { constexpr size_t kNumSensors = 5; AddAndRemoveDynamicSensorsSubHal subHal; std::vector subHals{&subHal}; - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); HalProxy proxy(subHals); @@ -575,9 +609,9 @@ TEST(HalProxyTest, DynamicSensorsDiscardedOnInitialize) { } TestSensorsCallback* callback = new TestSensorsCallback(); - ::android::sp callbackPtr = callback; + ::android::sp callbackPtr = callback; proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callbackPtr); - subHal.addDynamicSensors(sensorsToConnect); + subHal.addDynamicSensors(convertToNewSensorInfos(sensorsToConnect)); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callbackPtr); subHal.removeDynamicSensors(sensorHandlesToAttemptToRemove); @@ -594,7 +628,7 @@ TEST(HalProxyTest, DynamicSensorsConnectedTest) { AddAndRemoveDynamicSensorsSubHal subHal; std::vector subHals{&subHal}; HalProxy proxy(subHals); - std::unique_ptr eventQueue = makeEventFMQ(0); + std::unique_ptr eventQueue = makeEventFMQ(0); std::unique_ptr wakeLockQueue = makeWakelockFMQ(0); std::vector sensorsToConnect; @@ -603,9 +637,9 @@ TEST(HalProxyTest, DynamicSensorsConnectedTest) { sensorHandlesToExpect); TestSensorsCallback* callback = new TestSensorsCallback(); - ::android::sp callbackPtr = callback; + ::android::sp callbackPtr = callback; proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callbackPtr); - subHal.addDynamicSensors(sensorsToConnect); + subHal.addDynamicSensors(convertToNewSensorInfos(sensorsToConnect)); std::vector sensorsSeen = callback->getSensorsConnected(); EXPECT_EQ(kNumSensors, sensorsSeen.size()); @@ -622,7 +656,7 @@ TEST(HalProxyTest, DynamicSensorsDisconnectedTest) { AddAndRemoveDynamicSensorsSubHal subHal; std::vector subHals{&subHal}; HalProxy proxy(subHals); - std::unique_ptr eventQueue = makeEventFMQ(0); + std::unique_ptr eventQueue = makeEventFMQ(0); std::unique_ptr wakeLockQueue = makeWakelockFMQ(0); std::vector sensorsToConnect; @@ -647,9 +681,9 @@ TEST(HalProxyTest, DynamicSensorsDisconnectedTest) { nonDynamicSensorHandles.end()); TestSensorsCallback* callback = new TestSensorsCallback(); - ::android::sp callbackPtr = callback; + ::android::sp callbackPtr = callback; proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callbackPtr); - subHal.addDynamicSensors(sensorsToConnect); + subHal.addDynamicSensors(convertToNewSensorInfos(sensorsToConnect)); subHal.removeDynamicSensors(sensorHandlesToAttemptToRemove); std::vector sensorHandlesSeen = callback->getSensorHandlesDisconnected(); @@ -668,15 +702,15 @@ TEST(HalProxyTest, InvalidSensorHandleSubHalIndexProxyCalls) { constexpr size_t kNumSubHals = 3; constexpr size_t kQueueSize = 5; int32_t kNumSubHalsInt32 = static_cast(kNumSubHals); - std::vector subHalObjs(kNumSubHals); + std::vector> subHalObjs(kNumSubHals); std::vector subHals; for (const auto& subHal : subHalObjs) { subHals.push_back((ISensorsSubHal*)(&subHal)); } - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); HalProxy proxy(subHals); // Initialize for the injectSensorData call so callback postEvents is valid proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); @@ -688,7 +722,7 @@ TEST(HalProxyTest, InvalidSensorHandleSubHalIndexProxyCalls) { EXPECT_EQ(proxy.activate(0x00000001 | (kNumSubHalsInt32 << 24), true), Result::BAD_VALUE); EXPECT_EQ(proxy.batch(0x00000001 | (kNumSubHalsInt32 << 24), 0, 0), Result::BAD_VALUE); EXPECT_EQ(proxy.flush(0x00000001 | (kNumSubHalsInt32 << 24)), Result::BAD_VALUE); - Event event; + EventV1_0 event; event.sensorHandle = 0x00000001 | (kNumSubHalsInt32 << 24); EXPECT_EQ(proxy.injectSensorData(event), Result::BAD_VALUE); } @@ -697,28 +731,28 @@ TEST(HalProxyTest, PostedEventSensorHandleSubHalIndexValid) { constexpr size_t kQueueSize = 5; constexpr int32_t subhal1Index = 0; constexpr int32_t subhal2Index = 1; - AllSensorsSubHal subhal1; - AllSensorsSubHal subhal2; + AllSensorsSubHal subhal1; + AllSensorsSubHal subhal2; std::vector subHals{&subhal1, &subhal2}; - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); HalProxy proxy(subHals); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); int32_t sensorHandleToPost = 0x00000001; - Event eventIn = makeAccelerometerEvent(); + EventV1_0 eventIn = makeAccelerometerEvent(); eventIn.sensorHandle = sensorHandleToPost; - std::vector eventsToPost{eventIn}; - subhal1.postEvents(eventsToPost, false); + std::vector eventsToPost{eventIn}; + subhal1.postEvents(convertToNewEvents(eventsToPost), false); - Event eventOut; + EventV1_0 eventOut; EXPECT_TRUE(eventQueue->read(&eventOut)); EXPECT_EQ(eventOut.sensorHandle, (subhal1Index << 24) | sensorHandleToPost); - subhal2.postEvents(eventsToPost, false); + subhal2.postEvents(convertToNewEvents(eventsToPost), false); EXPECT_TRUE(eventQueue->read(&eventOut)); @@ -729,22 +763,22 @@ TEST(HalProxyTest, FillAndDrainPendingQueueTest) { constexpr size_t kQueueSize = 5; // TODO: Make this constant linked to same limit in HalProxy.h constexpr size_t kMaxPendingQueueSize = 100000; - AllSensorsSubHal subhal; + AllSensorsSubHal subhal; std::vector subHals{&subhal}; - std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); + std::unique_ptr eventQueue = makeEventFMQ(kQueueSize); std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); - ::android::sp callback = new SensorsCallback(); + ::android::sp callback = new SensorsCallback(); EventFlag* eventQueueFlag; EventFlag::createEventFlag(eventQueue->getEventFlagWord(), &eventQueueFlag); HalProxy proxy(subHals); proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); // Fill pending queue - std::vector events = makeMultipleAccelerometerEvents(kQueueSize); - subhal.postEvents(events, false); + std::vector events = makeMultipleAccelerometerEvents(kQueueSize); + subhal.postEvents(convertToNewEvents(events), false); events = makeMultipleAccelerometerEvents(kMaxPendingQueueSize); - subhal.postEvents(events, false); + subhal.postEvents(convertToNewEvents(events), false); // Drain pending queue for (int i = 0; i < kMaxPendingQueueSize + kQueueSize; i += kQueueSize) { @@ -753,9 +787,9 @@ TEST(HalProxyTest, FillAndDrainPendingQueueTest) { // Put one event on pending queue events = makeMultipleAccelerometerEvents(kQueueSize); - subhal.postEvents(events, false); + subhal.postEvents(convertToNewEvents(events), false); events = {makeAccelerometerEvent()}; - subhal.postEvents(events, false); + subhal.postEvents(convertToNewEvents(events), false); // Read out to make room for one event on pending queue to write to FMQ ASSERT_TRUE(readEventsOutOfQueue(kQueueSize, eventQueue, eventQueueFlag)); @@ -764,6 +798,35 @@ TEST(HalProxyTest, FillAndDrainPendingQueueTest) { EXPECT_TRUE(readEventsOutOfQueue(1, eventQueue, eventQueueFlag)); } +TEST(HalProxyTest, PostEventsMultipleSubhalsThreadedV2_1) { + constexpr size_t kQueueSize = 5; + constexpr size_t kNumEvents = 2; + AllSensorsSubHal subHal1; + AllSensorsSubHal subHal2; + std::vector<::android::hardware::sensors::V2_0::implementation::ISensorsSubHal*> subHalsV2_0{ + &subHal1}; + std::vector<::android::hardware::sensors::V2_1::implementation::ISensorsSubHal*> subHalsV2_1{ + &subHal2}; + HalProxy proxy(subHalsV2_0, subHalsV2_1); + std::unique_ptr eventQueue = + std::make_unique(kQueueSize, true); + std::unique_ptr wakeLockQueue = makeWakelockFMQ(kQueueSize); + ::android::sp callback = new SensorsCallbackV2_1(); + proxy.initialize_2_1(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback); + + std::vector events = makeMultipleAccelerometerEvents(kNumEvents); + + std::thread t1(&AllSensorsSubHal::postEvents, &subHal1, + convertToNewEvents(events), false); + std::thread t2(&AllSensorsSubHal::postEvents, &subHal2, + convertToNewEvents(events), false); + + t1.join(); + t2.join(); + + EXPECT_EQ(eventQueue->availableToRead(), kNumEvents * 2); +} + // Helper implementations follow void testSensorsListFromProxyAndSubHal(const std::vector& proxySensorsList, const std::vector& subHalSensorsList) { @@ -802,26 +865,26 @@ void ackWakeupEventsToHalProxy(size_t numEvents, std::unique_ptrwake(static_cast(WakeLockQueueFlagBits::DATA_WRITTEN)); } -bool readEventsOutOfQueue(size_t numEvents, std::unique_ptr& eventQueue, +bool readEventsOutOfQueue(size_t numEvents, std::unique_ptr& eventQueue, EventFlag* eventQueueFlag) { constexpr int64_t kReadBlockingTimeout = INT64_C(500000000); - std::vector events(numEvents); + std::vector events(numEvents); return eventQueue->readBlocking(events.data(), numEvents, static_cast(EventQueueFlagBits::EVENTS_READ), static_cast(EventQueueFlagBits::READ_AND_PROCESS), kReadBlockingTimeout, eventQueueFlag); } -std::unique_ptr makeEventFMQ(size_t size) { - return std::make_unique(size, true); +std::unique_ptr makeEventFMQ(size_t size) { + return std::make_unique(size, true); } std::unique_ptr makeWakelockFMQ(size_t size) { return std::make_unique(size, true); } -Event makeProximityEvent() { - Event event; +EventV1_0 makeProximityEvent() { + EventV1_0 event; event.timestamp = 0xFF00FF00; // This is the sensorhandle of proximity, which is wakeup type event.sensorHandle = 0x00000008; @@ -830,8 +893,8 @@ Event makeProximityEvent() { return event; } -Event makeAccelerometerEvent() { - Event event; +EventV1_0 makeAccelerometerEvent() { + EventV1_0 event; event.timestamp = 0xFF00FF00; // This is the sensorhandle of proximity, which is wakeup type event.sensorHandle = 0x00000001; @@ -840,16 +903,16 @@ Event makeAccelerometerEvent() { return event; } -std::vector makeMultipleProximityEvents(size_t numEvents) { - std::vector events; +std::vector makeMultipleProximityEvents(size_t numEvents) { + std::vector events; for (size_t i = 0; i < numEvents; i++) { events.push_back(makeProximityEvent()); } return events; } -std::vector makeMultipleAccelerometerEvents(size_t numEvents) { - std::vector events; +std::vector makeMultipleAccelerometerEvents(size_t numEvents) { + std::vector events; for (size_t i = 0; i < numEvents; i++) { events.push_back(makeAccelerometerEvent()); } diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/IHalProxyCallbackWrapper.h b/sensors/common/default/2.X/multihal/tests/fake_subhal/IHalProxyCallbackWrapper.h new file mode 100644 index 0000000000..4542bfdc2c --- /dev/null +++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/IHalProxyCallbackWrapper.h @@ -0,0 +1,107 @@ +/* + * 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. + */ + +#pragma once + +#include "V2_0/SubHal.h" +#include "V2_1/SubHal.h" +#include "convertV2_1.h" + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_1 { +namespace subhal { +namespace implementation { + +/** + * The following callback wrapper classes abstract away common functionality across V2.0 and V2.1 + * interfaces. Much of the logic is common between the two versions and this allows users of the + * classes to only care about the type used at initialization and then interact with either version + * of the callback interface without worrying about the type. + */ +class IHalProxyCallbackWrapperBase { + protected: + using ScopedWakelock = V2_0::implementation::ScopedWakelock; + + public: + virtual ~IHalProxyCallbackWrapperBase() {} + + virtual Return onDynamicSensorsConnected( + const hidl_vec& sensorInfos) = 0; + + virtual Return onDynamicSensorsDisconnected(const hidl_vec& sensorHandles) = 0; + + virtual void postEvents(const std::vector& events, ScopedWakelock wakelock) = 0; + + virtual ScopedWakelock createScopedWakelock(bool lock) = 0; +}; + +template +class HalProxyCallbackWrapperBase : public IHalProxyCallbackWrapperBase { + public: + HalProxyCallbackWrapperBase(sp callback) : mCallback(callback){}; + + Return onDynamicSensorsDisconnected(const hidl_vec& sensorHandles) override { + return mCallback->onDynamicSensorsDisconnected(sensorHandles); + } + + ScopedWakelock createScopedWakelock(bool lock) override { + return mCallback->createScopedWakelock(lock); + } + + protected: + sp mCallback; +}; + +class HalProxyCallbackWrapperV2_0 + : public HalProxyCallbackWrapperBase { + public: + HalProxyCallbackWrapperV2_0(sp callback) + : HalProxyCallbackWrapperBase(callback){}; + + Return onDynamicSensorsConnected(const hidl_vec& sensorInfos) override { + return mCallback->onDynamicSensorsConnected( + V2_1::implementation::convertToOldSensorInfos(sensorInfos)); + } + + void postEvents(const std::vector& events, ScopedWakelock wakelock) override { + return mCallback->postEvents(V2_1::implementation::convertToOldEvents(events), + std::move(wakelock)); + } +}; + +class HalProxyCallbackWrapperV2_1 + : public HalProxyCallbackWrapperBase { + public: + HalProxyCallbackWrapperV2_1(sp callback) + : HalProxyCallbackWrapperBase(callback){}; + + Return onDynamicSensorsConnected(const hidl_vec& sensorInfos) override { + return mCallback->onDynamicSensorsConnected_2_1(sensorInfos); + } + + void postEvents(const std::vector& events, ScopedWakelock wakelock) { + return mCallback->postEvents(events, std::move(wakelock)); + } +}; + +} // namespace implementation +} // namespace subhal +} // namespace V2_1 +} // namespace sensors +} // namespace hardware +} // namespace android diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp index de89a00ef9..1efd971115 100644 --- a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp +++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.cpp @@ -24,13 +24,18 @@ namespace android { namespace hardware { namespace sensors { -namespace V2_0 { +namespace V2_1 { namespace subhal { namespace implementation { using ::android::hardware::sensors::V1_0::MetaDataEventType; +using ::android::hardware::sensors::V1_0::OperationMode; +using ::android::hardware::sensors::V1_0::Result; using ::android::hardware::sensors::V1_0::SensorFlagBits; using ::android::hardware::sensors::V1_0::SensorStatus; +using ::android::hardware::sensors::V2_1::Event; +using ::android::hardware::sensors::V2_1::SensorInfo; +using ::android::hardware::sensors::V2_1::SensorType; Sensor::Sensor(int32_t sensorHandle, ISensorsEventCallback* callback) : mIsEnabled(false), @@ -343,7 +348,7 @@ RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle, } // namespace implementation } // namespace subhal -} // namespace V2_0 +} // namespace V2_1 } // namespace sensors } // namespace hardware } // namespace android diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h index 60f5d3d40a..5cf9f837cf 100644 --- a/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h +++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/Sensor.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include @@ -24,16 +24,16 @@ #include #include -using ::android::hardware::sensors::V1_0::Event; using ::android::hardware::sensors::V1_0::OperationMode; using ::android::hardware::sensors::V1_0::Result; -using ::android::hardware::sensors::V1_0::SensorInfo; -using ::android::hardware::sensors::V1_0::SensorType; +using ::android::hardware::sensors::V2_1::Event; +using ::android::hardware::sensors::V2_1::SensorInfo; +using ::android::hardware::sensors::V2_1::SensorType; namespace android { namespace hardware { namespace sensors { -namespace V2_0 { +namespace V2_1 { namespace subhal { namespace implementation { @@ -151,7 +151,7 @@ class RelativeHumiditySensor : public OnChangeSensor { } // namespace implementation } // namespace subhal -} // namespace V2_0 +} // namespace V2_1 } // namespace sensors } // namespace hardware } // namespace android diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.cpp b/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.cpp index ff5ff38541..20a4e9de04 100644 --- a/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.cpp +++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.cpp @@ -16,33 +16,66 @@ #include "SensorsSubHal.h" -#include +#include #include -ISensorsSubHal* sensorsHalGetSubHal(uint32_t* version) { +#ifdef SUB_HAL_VERSION_2_0 +::android::hardware::sensors::V2_0::implementation::ISensorsSubHal* sensorsHalGetSubHal( + uint32_t* version) { #if defined SUPPORT_CONTINUOUS_SENSORS && defined SUPPORT_ON_CHANGE_SENSORS - static ::android::hardware::sensors::V2_0::subhal::implementation::AllSensorsSubHal subHal; + static ::android::hardware::sensors::V2_1::subhal::implementation::AllSensorsSubHal< + ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHalV2_0> + subHal; #elif defined SUPPORT_CONTINUOUS_SENSORS - static ::android::hardware::sensors::V2_0::subhal::implementation::ContinuousSensorsSubHal + static ::android::hardware::sensors::V2_1::subhal::implementation::ContinuousSensorsSubHal< + ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHalV2_0> subHal; #elif defined SUPPORT_ON_CHANGE_SENSORS - static ::android::hardware::sensors::V2_0::subhal::implementation::OnChangeSensorsSubHal subHal; + static ::android::hardware::sensors::V2_1::subhal::implementation::OnChangeSensorsSubHal< + ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHalV2_0> + subHal; #else - static ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal subHal; + static ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHal< + ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHalV2_0> + subHal; #endif // defined SUPPORT_CONTINUOUS_SENSORS && defined SUPPORT_ON_CHANGE_SENSORS *version = SUB_HAL_2_0_VERSION; return &subHal; } +#else // SUB_HAL_VERSION_2_0 + +::android::hardware::sensors::V2_1::implementation::ISensorsSubHal* sensorsHalGetSubHal_2_1( + uint32_t* version) { +#if defined SUPPORT_CONTINUOUS_SENSORS && defined SUPPORT_ON_CHANGE_SENSORS + static ::android::hardware::sensors::V2_1::subhal::implementation::AllSensorsSubHal< + ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHalV2_1> + subHal; +#elif defined SUPPORT_CONTINUOUS_SENSORS + static ::android::hardware::sensors::V2_1::subhal::implementation::ContinuousSensorsSubHal< + ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHalV2_1> + subHal; +#elif defined SUPPORT_ON_CHANGE_SENSORS + static ::android::hardware::sensors::V2_1::subhal::implementation::OnChangeSensorsSubHal< + ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHalV2_1> + subHal; +#else + static ::android::hardware::sensors::V2_1::subhal::implementation::SensorsSubHalV2_1 subHal; +#endif // defined SUPPORT_CONTINUOUS_SENSORS && defined SUPPORT_ON_CHANGE_SENSORS + *version = SUB_HAL_2_1_VERSION; + return &subHal; +} + +#endif // SUB_HAL_VERSION_2_0 + namespace android { namespace hardware { namespace sensors { -namespace V2_0 { +namespace V2_1 { namespace subhal { namespace implementation { using ::android::hardware::Void; -using ::android::hardware::sensors::V1_0::Event; using ::android::hardware::sensors::V1_0::OperationMode; using ::android::hardware::sensors::V1_0::RateLevel; using ::android::hardware::sensors::V1_0::Result; @@ -50,11 +83,12 @@ using ::android::hardware::sensors::V1_0::SharedMemInfo; using ::android::hardware::sensors::V2_0::SensorTimeout; using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits; using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock; +using ::android::hardware::sensors::V2_1::Event; -SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) {} +ISensorsSubHalBase::ISensorsSubHalBase() : mCallback(nullptr), mNextHandle(1) {} // Methods from ::android::hardware::sensors::V2_0::ISensors follow. -Return SensorsSubHal::getSensorsList(getSensorsList_cb _hidl_cb) { +Return ISensorsSubHalBase::getSensorsList(V2_1::ISensors::getSensorsList_2_1_cb _hidl_cb) { std::vector sensors; for (const auto& sensor : mSensors) { sensors.push_back(sensor.second->getSensorInfo()); @@ -64,7 +98,7 @@ Return SensorsSubHal::getSensorsList(getSensorsList_cb _hidl_cb) { return Void(); } -Return SensorsSubHal::setOperationMode(OperationMode mode) { +Return ISensorsSubHalBase::setOperationMode(OperationMode mode) { for (auto sensor : mSensors) { sensor.second->setOperationMode(mode); } @@ -72,7 +106,7 @@ Return SensorsSubHal::setOperationMode(OperationMode mode) { return Result::OK; } -Return SensorsSubHal::activate(int32_t sensorHandle, bool enabled) { +Return ISensorsSubHalBase::activate(int32_t sensorHandle, bool enabled) { auto sensor = mSensors.find(sensorHandle); if (sensor != mSensors.end()) { sensor->second->activate(enabled); @@ -81,8 +115,8 @@ Return SensorsSubHal::activate(int32_t sensorHandle, bool enabled) { return Result::BAD_VALUE; } -Return SensorsSubHal::batch(int32_t sensorHandle, int64_t samplingPeriodNs, - int64_t /* maxReportLatencyNs */) { +Return ISensorsSubHalBase::batch(int32_t sensorHandle, int64_t samplingPeriodNs, + int64_t /* maxReportLatencyNs */) { auto sensor = mSensors.find(sensorHandle); if (sensor != mSensors.end()) { sensor->second->batch(samplingPeriodNs); @@ -91,7 +125,7 @@ Return SensorsSubHal::batch(int32_t sensorHandle, int64_t samplingPeriod return Result::BAD_VALUE; } -Return SensorsSubHal::flush(int32_t sensorHandle) { +Return ISensorsSubHalBase::flush(int32_t sensorHandle) { auto sensor = mSensors.find(sensorHandle); if (sensor != mSensors.end()) { return sensor->second->flush(); @@ -99,7 +133,7 @@ Return SensorsSubHal::flush(int32_t sensorHandle) { return Result::BAD_VALUE; } -Return SensorsSubHal::injectSensorData(const Event& event) { +Return ISensorsSubHalBase::injectSensorData(const Event& event) { auto sensor = mSensors.find(event.sensorHandle); if (sensor != mSensors.end()) { return sensor->second->injectEvent(event); @@ -108,24 +142,24 @@ Return SensorsSubHal::injectSensorData(const Event& event) { return Result::BAD_VALUE; } -Return SensorsSubHal::registerDirectChannel(const SharedMemInfo& /* mem */, - registerDirectChannel_cb _hidl_cb) { +Return ISensorsSubHalBase::registerDirectChannel( + const SharedMemInfo& /* mem */, V2_0::ISensors::registerDirectChannel_cb _hidl_cb) { _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */); return Return(); } -Return SensorsSubHal::unregisterDirectChannel(int32_t /* channelHandle */) { +Return ISensorsSubHalBase::unregisterDirectChannel(int32_t /* channelHandle */) { return Result::INVALID_OPERATION; } -Return SensorsSubHal::configDirectReport(int32_t /* sensorHandle */, - int32_t /* channelHandle */, RateLevel /* rate */, - configDirectReport_cb _hidl_cb) { +Return ISensorsSubHalBase::configDirectReport( + int32_t /* sensorHandle */, int32_t /* channelHandle */, RateLevel /* rate */, + V2_0::ISensors::configDirectReport_cb _hidl_cb) { _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */); return Return(); } -Return SensorsSubHal::debug(const hidl_handle& fd, const hidl_vec& args) { +Return ISensorsSubHalBase::debug(const hidl_handle& fd, const hidl_vec& args) { if (fd.getNativeHandle() == nullptr || fd->numFds < 1) { ALOGE("%s: missing fd for writing", __FUNCTION__); return Void(); @@ -156,44 +190,18 @@ Return SensorsSubHal::debug(const hidl_handle& fd, const hidl_vec(); } -Return SensorsSubHal::initialize(const sp& halProxyCallback) { - mCallback = halProxyCallback; +Return ISensorsSubHalBase::initialize( + std::unique_ptr& halProxyCallback) { + mCallback = std::move(halProxyCallback); setOperationMode(OperationMode::NORMAL); return Result::OK; } -void SensorsSubHal::postEvents(const std::vector& events, bool wakeup) { +void ISensorsSubHalBase::postEvents(const std::vector& events, bool wakeup) { ScopedWakelock wakelock = mCallback->createScopedWakelock(wakeup); mCallback->postEvents(events, std::move(wakelock)); } -ContinuousSensorsSubHal::ContinuousSensorsSubHal() { - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); -} - -OnChangeSensorsSubHal::OnChangeSensorsSubHal() { - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); -} - -AllSensorsSubHal::AllSensorsSubHal() { - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); -} - Return SetOperationModeFailingSensorsSubHal::setOperationMode(OperationMode /*mode*/) { return Result::BAD_VALUE; } @@ -206,7 +214,7 @@ Return AllSupportDirectChannelSensorsSubHal::getSensorsList(getSensorsList sensorInfo.flags |= V1_0::SensorFlagBits::MASK_DIRECT_REPORT; sensors.push_back(sensorInfo); } - _hidl_cb(sensors); + _hidl_cb(V2_1::implementation::convertToOldSensorInfos(sensors)); return Void(); } @@ -218,7 +226,7 @@ Return DoesNotSupportDirectChannelSensorsSubHal::getSensorsList(getSensors sensorInfo.flags &= ~static_cast(V1_0::SensorFlagBits::MASK_DIRECT_REPORT); sensors.push_back(sensorInfo); } - _hidl_cb(sensors); + _hidl_cb(V2_1::implementation::convertToOldSensorInfos(sensors)); return Void(); } @@ -234,7 +242,7 @@ void AddAndRemoveDynamicSensorsSubHal::removeDynamicSensors( } // namespace implementation } // namespace subhal -} // namespace V2_0 +} // namespace V2_1 } // namespace sensors } // namespace hardware } // namespace android diff --git a/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h b/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h index 6da4404c3e..1a78e847c7 100644 --- a/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h +++ b/sensors/common/default/2.X/multihal/tests/fake_subhal/SensorsSubHal.h @@ -17,7 +17,9 @@ #pragma once #include "V2_0/SubHal.h" +#include "V2_1/SubHal.h" +#include "IHalProxyCallbackWrapper.h" #include "Sensor.h" #include @@ -25,54 +27,54 @@ namespace android { namespace hardware { namespace sensors { -namespace V2_0 { +namespace V2_1 { namespace subhal { namespace implementation { using ::android::hardware::sensors::V1_0::OperationMode; using ::android::hardware::sensors::V1_0::Result; -using ::android::hardware::sensors::V2_0::implementation::IHalProxyCallback; /** * Implementation of a ISensorsSubHal that can be used to test the implementation of multihal 2.0. * See the README file for more details on how this class can be used for testing. */ -class SensorsSubHal : public ISensorsSubHal, public ISensorsEventCallback { - using Event = ::android::hardware::sensors::V1_0::Event; +class ISensorsSubHalBase : public ISensorsEventCallback { + protected: + using Event = ::android::hardware::sensors::V2_1::Event; using RateLevel = ::android::hardware::sensors::V1_0::RateLevel; using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; public: - SensorsSubHal(); + ISensorsSubHalBase(); + + Return getSensorsList(V2_1::ISensors::getSensorsList_2_1_cb _hidl_cb); + Return injectSensorData(const Event& event); + Return initialize(std::unique_ptr& halProxyCallback); // Methods from ::android::hardware::sensors::V2_0::ISensors follow. - virtual Return getSensorsList(getSensorsList_cb _hidl_cb) override; - - virtual Return setOperationMode(OperationMode mode) override; + virtual Return setOperationMode(OperationMode mode); OperationMode getOperationMode() const { return mCurrentOperationMode; } - Return activate(int32_t sensorHandle, bool enabled) override; + Return activate(int32_t sensorHandle, bool enabled); Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, - int64_t maxReportLatencyNs) override; + int64_t maxReportLatencyNs); - Return flush(int32_t sensorHandle) override; - - Return injectSensorData(const Event& event) override; + Return flush(int32_t sensorHandle); Return registerDirectChannel(const SharedMemInfo& mem, - registerDirectChannel_cb _hidl_cb) override; + V2_0::ISensors::registerDirectChannel_cb _hidl_cb); - Return unregisterDirectChannel(int32_t channelHandle) override; + Return unregisterDirectChannel(int32_t channelHandle); Return configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, - configDirectReport_cb _hidl_cb) override; + V2_0::ISensors::configDirectReport_cb _hidl_cb); - Return debug(const hidl_handle& fd, const hidl_vec& args) override; + Return debug(const hidl_handle& fd, const hidl_vec& args); // Methods from ::android::hardware::sensors::V2_0::implementation::ISensorsSubHal follow. - const std::string getName() override { + const std::string getName() { #ifdef SUB_HAL_NAME return SUB_HAL_NAME; #else // SUB_HAL_NAME @@ -80,8 +82,6 @@ class SensorsSubHal : public ISensorsSubHal, public ISensorsEventCallback { #endif // SUB_HAL_NAME } - Return initialize(const sp& halProxyCallback) override; - // Method from ISensorsEventCallback. void postEvents(const std::vector& events, bool wakeup) override; @@ -103,7 +103,7 @@ class SensorsSubHal : public ISensorsSubHal, public ISensorsEventCallback { * disconnected, sensor events need to be sent to the framework, and when a wakelock should be * acquired. */ - sp mCallback; + std::unique_ptr mCallback; private: /** @@ -118,40 +118,143 @@ class SensorsSubHal : public ISensorsSubHal, public ISensorsEventCallback { int32_t mNextHandle; }; -// SubHal that has continuous sensors for testing purposes. -class ContinuousSensorsSubHal : public SensorsSubHal { +template +class SensorsSubHalBase : public ISensorsSubHalBase, public SubHalClass { public: - ContinuousSensorsSubHal(); + Return setOperationMode(OperationMode mode) override { + return ISensorsSubHalBase::setOperationMode(mode); + } + + Return activate(int32_t sensorHandle, bool enabled) override { + return ISensorsSubHalBase::activate(sensorHandle, enabled); + } + + Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, + int64_t maxReportLatencyNs) override { + return ISensorsSubHalBase::batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs); + } + + Return flush(int32_t sensorHandle) override { + return ISensorsSubHalBase::flush(sensorHandle); + } + + Return registerDirectChannel(const SharedMemInfo& mem, + V2_0::ISensors::registerDirectChannel_cb _hidl_cb) override { + return ISensorsSubHalBase::registerDirectChannel(mem, _hidl_cb); + } + + Return unregisterDirectChannel(int32_t channelHandle) override { + return ISensorsSubHalBase::unregisterDirectChannel(channelHandle); + } + + Return configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, + V2_0::ISensors::configDirectReport_cb _hidl_cb) override { + return ISensorsSubHalBase::configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb); + } + + Return debug(const hidl_handle& fd, const hidl_vec& args) override { + return ISensorsSubHalBase::debug(fd, args); + } + + const std::string getName() override { return ISensorsSubHalBase::getName(); } +}; + +class SensorsSubHalV2_0 : public SensorsSubHalBase { + public: + virtual Return getSensorsList(V2_0::ISensors::getSensorsList_cb _hidl_cb) override { + return ISensorsSubHalBase::getSensorsList([&](const auto& list) { + _hidl_cb(V2_1::implementation::convertToOldSensorInfos(list)); + }); + } + + Return injectSensorData(const V1_0::Event& event) override { + return ISensorsSubHalBase::injectSensorData(V2_1::implementation::convertToNewEvent(event)); + } + + Return initialize( + const sp& halProxyCallback) override { + std::unique_ptr wrapper = + std::make_unique(halProxyCallback); + return ISensorsSubHalBase::initialize(wrapper); + } +}; + +class SensorsSubHalV2_1 : public SensorsSubHalBase { + public: + Return getSensorsList_2_1(V2_1::ISensors::getSensorsList_2_1_cb _hidl_cb) override { + return ISensorsSubHalBase::getSensorsList(_hidl_cb); + } + + Return injectSensorData_2_1(const V2_1::Event& event) override { + return ISensorsSubHalBase::injectSensorData(event); + } + + Return initialize( + const sp& halProxyCallback) override { + std::unique_ptr wrapper = + std::make_unique(halProxyCallback); + return ISensorsSubHalBase::initialize(wrapper); + } +}; + +// SubHal that has continuous sensors for testing purposes. +template +class ContinuousSensorsSubHal : public SubHalVersion { + public: + ContinuousSensorsSubHal() { + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + } }; // SubHal that has on-change sensors for testing purposes. -class OnChangeSensorsSubHal : public SensorsSubHal { +template +class OnChangeSensorsSubHal : public SubHalVersion { public: - OnChangeSensorsSubHal(); + OnChangeSensorsSubHal() { + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + } }; // SubHal that has both continuous and on-change sensors for testing purposes. -class AllSensorsSubHal : public SensorsSubHal { +template +class AllSensorsSubHal : public SubHalVersion { public: - AllSensorsSubHal(); + AllSensorsSubHal() { + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + ISensorsSubHalBase::AddSensor(); + } }; -class SetOperationModeFailingSensorsSubHal : public AllSensorsSubHal { +class SetOperationModeFailingSensorsSubHal : public AllSensorsSubHal { public: Return setOperationMode(OperationMode mode) override; }; -class AllSupportDirectChannelSensorsSubHal : public AllSensorsSubHal { +class AllSupportDirectChannelSensorsSubHal : public AllSensorsSubHal { public: - Return getSensorsList(getSensorsList_cb _hidl_cb) override; + Return getSensorsList(V2_0::ISensors::getSensorsList_cb _hidl_cb) override; }; -class DoesNotSupportDirectChannelSensorsSubHal : public AllSensorsSubHal { +class DoesNotSupportDirectChannelSensorsSubHal : public AllSensorsSubHal { public: - Return getSensorsList(getSensorsList_cb _hidl_cb) override; + Return getSensorsList(V2_0::ISensors::getSensorsList_cb _hidl_cb) override; }; -class AddAndRemoveDynamicSensorsSubHal : public AllSensorsSubHal { +class AddAndRemoveDynamicSensorsSubHal : public AllSensorsSubHal { public: void addDynamicSensors(const std::vector& sensorsAdded); void removeDynamicSensors(const std::vector& sensorHandlesAdded); @@ -159,7 +262,7 @@ class AddAndRemoveDynamicSensorsSubHal : public AllSensorsSubHal { } // namespace implementation } // namespace subhal -} // namespace V2_0 +} // namespace V2_1 } // namespace sensors } // namespace hardware } // namespace android