From 1d71acc129331cca3bedbfd6c1b350682f0d2fae Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Wed, 5 Feb 2020 19:27:16 -0500 Subject: [PATCH] Add default impl of Sensors HAL 2.1 Create a default implementation of HAL 2.1 that shares 90% of the underlying code with HAL 2.0 since the interfaces are very similar. Bug: 144139857 Test: compile Change-Id: Ic6b139df98ddb1f92833b1f2d65e1cecc297fd41 --- sensors/2.0/default/Android.bp | 12 +- sensors/2.0/default/Sensors.cpp | 259 ------------ sensors/2.0/default/Sensors.h | 191 --------- sensors/2.0/default/SensorsV2_0.h | 39 ++ sensors/2.0/default/service.cpp | 6 +- sensors/2.1/default/Android.bp | 45 +++ sensors/2.1/default/OWNERS | 3 + sensors/2.1/default/SensorsV2_1.cpp | 58 +++ sensors/2.1/default/SensorsV2_1.h | 72 ++++ ...droid.hardware.sensors@2.1-service-mock.rc | 7 + .../default/android.hardware.sensors@2.1.xml | 11 + sensors/2.1/default/service.cpp | 41 ++ sensors/common/default/2.X/Android.bp | 36 ++ sensors/common/default/2.X/OWNERS | 3 + .../default => common/default/2.X}/Sensor.cpp | 27 +- .../default => common/default/2.X}/Sensor.h | 54 +-- sensors/common/default/2.X/Sensors.h | 376 ++++++++++++++++++ 17 files changed, 748 insertions(+), 492 deletions(-) delete mode 100644 sensors/2.0/default/Sensors.cpp delete mode 100644 sensors/2.0/default/Sensors.h create mode 100644 sensors/2.0/default/SensorsV2_0.h create mode 100644 sensors/2.1/default/Android.bp create mode 100644 sensors/2.1/default/OWNERS create mode 100644 sensors/2.1/default/SensorsV2_1.cpp create mode 100644 sensors/2.1/default/SensorsV2_1.h create mode 100644 sensors/2.1/default/android.hardware.sensors@2.1-service-mock.rc create mode 100644 sensors/2.1/default/android.hardware.sensors@2.1.xml create mode 100644 sensors/2.1/default/service.cpp create mode 100644 sensors/common/default/2.X/Android.bp create mode 100644 sensors/common/default/2.X/OWNERS rename sensors/{2.0/default => common/default/2.X}/Sensor.cpp (94%) rename sensors/{2.0/default => common/default/2.X}/Sensor.h (81%) create mode 100644 sensors/common/default/2.X/Sensors.h diff --git a/sensors/2.0/default/Android.bp b/sensors/2.0/default/Android.bp index 62c9487319..bb383273a6 100644 --- a/sensors/2.0/default/Android.bp +++ b/sensors/2.0/default/Android.bp @@ -20,13 +20,17 @@ cc_binary { relative_install_path: "hw", srcs: [ "service.cpp", - "Sensor.cpp", - "Sensors.cpp", ], init_rc: ["android.hardware.sensors@2.0-service-mock.rc"], + header_libs: [ + "android.hardware.sensors@2.X-shared-utils", + ], shared_libs: [ "android.hardware.sensors@1.0", "android.hardware.sensors@2.0", + // Needed to compile some shared utilities for both 2.0/2.1 impls, but + // isn't normally needed for a HAL that only supports 2.0. + "android.hardware.sensors@2.1", "libcutils", "libfmq", "libhidlbase", @@ -34,5 +38,9 @@ cc_binary { "libpower", "libutils", ], + static_libs: [ + "android.hardware.sensors@1.0-convert", + "android.hardware.sensors@2.X-shared-impl", + ], vintf_fragments: ["android.hardware.sensors@2.0.xml"], } diff --git a/sensors/2.0/default/Sensors.cpp b/sensors/2.0/default/Sensors.cpp deleted file mode 100644 index 23dd26bccb..0000000000 --- a/sensors/2.0/default/Sensors.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Sensors.h" - -#include -#include - -namespace android { -namespace hardware { -namespace sensors { -namespace V2_0 { -namespace implementation { - -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; -using ::android::hardware::sensors::V1_0::SharedMemInfo; -using ::android::hardware::sensors::V2_0::SensorTimeout; -using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits; - -constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP"; - -Sensors::Sensors() - : mEventQueueFlag(nullptr), - mNextHandle(1), - mOutstandingWakeUpEvents(0), - mReadWakeLockQueueRun(false), - mAutoReleaseWakeLockTime(0), - mHasWakeLock(false) { - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); - AddSensor(); -} - -Sensors::~Sensors() { - deleteEventFlag(); - mReadWakeLockQueueRun = false; - mWakeLockThread.join(); -} - -// Methods from ::android::hardware::sensors::V2_0::ISensors follow. -Return Sensors::getSensorsList(getSensorsList_cb _hidl_cb) { - std::vector sensors; - for (const auto& sensor : mSensors) { - sensors.push_back(sensor.second->getSensorInfo()); - } - - // Call the HIDL callback with the SensorInfo - _hidl_cb(sensors); - - return Void(); -} - -Return Sensors::setOperationMode(OperationMode mode) { - for (auto sensor : mSensors) { - sensor.second->setOperationMode(mode); - } - return Result::OK; -} - -Return Sensors::activate(int32_t sensorHandle, bool enabled) { - auto sensor = mSensors.find(sensorHandle); - if (sensor != mSensors.end()) { - sensor->second->activate(enabled); - return Result::OK; - } - return Result::BAD_VALUE; -} - -Return Sensors::initialize( - const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, - const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, - const sp& sensorsCallback) { - Result result = Result::OK; - - // Ensure that all sensors are disabled - for (auto sensor : mSensors) { - sensor.second->activate(false /* enable */); - } - - // Stop the Wake Lock thread if it is currently running - if (mReadWakeLockQueueRun.load()) { - mReadWakeLockQueueRun = false; - mWakeLockThread.join(); - } - - // Save a reference to the callback - mCallback = sensorsCallback; - - // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions. - mEventQueue = - std::make_unique(eventQueueDescriptor, true /* resetPointers */); - - // Ensure that any existing EventFlag is properly deleted - deleteEventFlag(); - - // Create the EventFlag that is used to signal to the framework that sensor events have been - // written to the Event FMQ - if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) { - result = Result::BAD_VALUE; - } - - // 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. - mWakeLockQueue = - std::make_unique(wakeLockDescriptor, true /* resetPointers */); - - if (!mCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) { - result = Result::BAD_VALUE; - } - - // Start the thread to read events from the Wake Lock FMQ - mReadWakeLockQueueRun = true; - mWakeLockThread = std::thread(startReadWakeLockThread, this); - - return result; -} - -Return Sensors::batch(int32_t sensorHandle, int64_t samplingPeriodNs, - int64_t /* maxReportLatencyNs */) { - auto sensor = mSensors.find(sensorHandle); - if (sensor != mSensors.end()) { - sensor->second->batch(samplingPeriodNs); - return Result::OK; - } - return Result::BAD_VALUE; -} - -Return Sensors::flush(int32_t sensorHandle) { - auto sensor = mSensors.find(sensorHandle); - if (sensor != mSensors.end()) { - return sensor->second->flush(); - } - return Result::BAD_VALUE; -} - -Return Sensors::injectSensorData(const Event& event) { - auto sensor = mSensors.find(event.sensorHandle); - if (sensor != mSensors.end()) { - return sensor->second->injectEvent(event); - } - - return Result::BAD_VALUE; -} - -Return Sensors::registerDirectChannel(const SharedMemInfo& /* mem */, - registerDirectChannel_cb _hidl_cb) { - _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */); - return Return(); -} - -Return Sensors::unregisterDirectChannel(int32_t /* channelHandle */) { - return Result::INVALID_OPERATION; -} - -Return Sensors::configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */, - RateLevel /* rate */, configDirectReport_cb _hidl_cb) { - _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */); - return Return(); -} - -void Sensors::postEvents(const std::vector& events, bool wakeup) { - std::lock_guard lock(mWriteLock); - if (mEventQueue->write(events.data(), events.size())) { - mEventQueueFlag->wake(static_cast(EventQueueFlagBits::READ_AND_PROCESS)); - - if (wakeup) { - // Keep track of the number of outstanding WAKE_UP events in order to properly hold - // a wake lock until the framework has secured a wake lock - updateWakeLock(events.size(), 0 /* eventsHandled */); - } - } -} - -void Sensors::updateWakeLock(int32_t eventsWritten, int32_t eventsHandled) { - std::lock_guard lock(mWakeLockLock); - int32_t newVal = mOutstandingWakeUpEvents + eventsWritten - eventsHandled; - if (newVal < 0) { - mOutstandingWakeUpEvents = 0; - } else { - mOutstandingWakeUpEvents = newVal; - } - - if (eventsWritten > 0) { - // Update the time at which the last WAKE_UP event was sent - mAutoReleaseWakeLockTime = ::android::uptimeMillis() + - static_cast(SensorTimeout::WAKE_LOCK_SECONDS) * 1000; - } - - if (!mHasWakeLock && mOutstandingWakeUpEvents > 0 && - acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName) == 0) { - mHasWakeLock = true; - } else if (mHasWakeLock) { - // Check if the wake lock should be released automatically if - // SensorTimeout::WAKE_LOCK_SECONDS has elapsed since the last WAKE_UP event was written to - // the Wake Lock FMQ. - if (::android::uptimeMillis() > mAutoReleaseWakeLockTime) { - ALOGD("No events read from wake lock FMQ for %d seconds, auto releasing wake lock", - SensorTimeout::WAKE_LOCK_SECONDS); - mOutstandingWakeUpEvents = 0; - } - - if (mOutstandingWakeUpEvents == 0 && release_wake_lock(kWakeLockName) == 0) { - mHasWakeLock = false; - } - } -} - -void Sensors::readWakeLockFMQ() { - while (mReadWakeLockQueueRun.load()) { - constexpr int64_t kReadTimeoutNs = 500 * 1000 * 1000; // 500 ms - uint32_t eventsHandled = 0; - - // Read events from the Wake Lock FMQ. Timeout after a reasonable amount of time to ensure - // that any held wake lock is able to be released if it is held for too long. - mWakeLockQueue->readBlocking(&eventsHandled, 1 /* count */, 0 /* readNotification */, - static_cast(WakeLockQueueFlagBits::DATA_WRITTEN), - kReadTimeoutNs); - updateWakeLock(0 /* eventsWritten */, eventsHandled); - } -} - -void Sensors::startReadWakeLockThread(Sensors* sensors) { - sensors->readWakeLockFMQ(); -} - -void Sensors::deleteEventFlag() { - status_t status = EventFlag::deleteEventFlag(&mEventQueueFlag); - if (status != OK) { - ALOGI("Failed to delete event flag: %d", status); - } -} - -} // namespace implementation -} // namespace V2_0 -} // namespace sensors -} // namespace hardware -} // namespace android diff --git a/sensors/2.0/default/Sensors.h b/sensors/2.0/default/Sensors.h deleted file mode 100644 index d06dd78dad..0000000000 --- a/sensors/2.0/default/Sensors.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2018 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_0_SENSORS_H -#define ANDROID_HARDWARE_SENSORS_V2_0_SENSORS_H - -#include "Sensor.h" - -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace android { -namespace hardware { -namespace sensors { -namespace V2_0 { -namespace implementation { - -using ::android::sp; -using ::android::hardware::EventFlag; -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_memory; -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; - -struct Sensors : public ISensors, public ISensorsEventCallback { - using Event = ::android::hardware::sensors::V1_0::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 SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; - - Sensors(); - virtual ~Sensors(); - - // Methods from ::android::hardware::sensors::V2_0::ISensors follow. - Return getSensorsList(getSensorsList_cb _hidl_cb) override; - - Return setOperationMode(OperationMode mode) override; - - Return activate(int32_t sensorHandle, bool enabled) override; - - Return initialize( - const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, - const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, - const sp& sensorsCallback) override; - - Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, - int64_t maxReportLatencyNs) override; - - Return flush(int32_t sensorHandle) override; - - Return injectSensorData(const Event& event) override; - - Return registerDirectChannel(const SharedMemInfo& mem, - registerDirectChannel_cb _hidl_cb) override; - - Return unregisterDirectChannel(int32_t channelHandle) override; - - Return configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, - configDirectReport_cb _hidl_cb) override; - - void postEvents(const std::vector& events, bool wakeup) override; - - private: - /** - * Add a new sensor - */ - template - void AddSensor() { - std::shared_ptr sensor = - std::make_shared(mNextHandle++ /* sensorHandle */, this /* callback */); - mSensors[sensor->getSensorInfo().sensorHandle] = sensor; - } - - /** - * Utility function to delete the Event Flag - */ - void deleteEventFlag(); - - /** - * Function to read the Wake Lock FMQ and release the wake lock when appropriate - */ - void readWakeLockFMQ(); - - static void startReadWakeLockThread(Sensors* sensors); - - /** - * Responsible for acquiring and releasing a wake lock when there are unhandled WAKE_UP events - */ - void updateWakeLock(int32_t eventsWritten, int32_t eventsHandled); - - using EventMessageQueue = MessageQueue; - using WakeLockMessageQueue = MessageQueue; - - /** - * The Event FMQ where sensor events are written - */ - std::unique_ptr mEventQueue; - - /** - * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events - */ - std::unique_ptr mWakeLockQueue; - - /** - * Event Flag to signal to the framework when sensor events are available to be read - */ - EventFlag* mEventQueueFlag; - - /** - * Callback for asynchronous events, such as dynamic sensor connections. - */ - sp mCallback; - - /** - * A map of the available sensors - */ - std::map> mSensors; - - /** - * The next available sensor handle - */ - int32_t mNextHandle; - - /** - * Lock to protect writes to the FMQs - */ - std::mutex mWriteLock; - - /** - * Lock to protect acquiring and releasing the wake lock - */ - std::mutex mWakeLockLock; - - /** - * Track the number of WAKE_UP events that have not been handled by the framework - */ - uint32_t mOutstandingWakeUpEvents; - - /** - * A thread to read the Wake Lock FMQ - */ - std::thread mWakeLockThread; - - /** - * Flag to indicate that the Wake Lock Thread should continue to run - */ - std::atomic_bool mReadWakeLockQueueRun; - - /** - * Track the time when the wake lock should automatically be released - */ - int64_t mAutoReleaseWakeLockTime; - - /** - * Flag to indicate if a wake lock has been acquired - */ - bool mHasWakeLock; -}; - -} // namespace implementation -} // namespace V2_0 -} // namespace sensors -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_SENSORS_V2_0_SENSORS_H diff --git a/sensors/2.0/default/SensorsV2_0.h b/sensors/2.0/default/SensorsV2_0.h new file mode 100644 index 0000000000..345835a186 --- /dev/null +++ b/sensors/2.0/default/SensorsV2_0.h @@ -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. + */ + +#ifndef ANDROID_HARDWARE_SENSORS_V2_0_H +#define ANDROID_HARDWARE_SENSORS_V2_0_H + +#include "Sensors.h" + +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_0 { +namespace implementation { + +struct SensorsV2_0 : public ::android::hardware::sensors::V2_X::implementation::Sensors { +}; + +} // namespace implementation +} // namespace V2_0 +} // namespace sensors +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_SENSORS_V2_0_H \ No newline at end of file diff --git a/sensors/2.0/default/service.cpp b/sensors/2.0/default/service.cpp index 5c13e331d0..e20bf85df3 100644 --- a/sensors/2.0/default/service.cpp +++ b/sensors/2.0/default/service.cpp @@ -20,17 +20,17 @@ #include #include #include -#include "Sensors.h" +#include "SensorsV2_0.h" using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; using android::hardware::sensors::V2_0::ISensors; -using android::hardware::sensors::V2_0::implementation::Sensors; +using android::hardware::sensors::V2_0::implementation::SensorsV2_0; int main(int /* argc */, char** /* argv */) { configureRpcThreadpool(1, true); - android::sp sensors = new Sensors(); + android::sp sensors = new SensorsV2_0(); if (sensors->registerAsService() != ::android::OK) { ALOGE("Failed to register Sensors HAL instance"); return -1; diff --git a/sensors/2.1/default/Android.bp b/sensors/2.1/default/Android.bp new file mode 100644 index 0000000000..27b439d422 --- /dev/null +++ b/sensors/2.1/default/Android.bp @@ -0,0 +1,45 @@ +// +// Copyright (C) 2018 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.mock", + defaults: ["hidl_defaults"], + vendor: true, + relative_install_path: "hw", + srcs: [ + "SensorsV2_1.cpp", + "service.cpp", + ], + init_rc: ["android.hardware.sensors@2.1-service-mock.rc"], + header_libs: [ + "android.hardware.sensors@2.X-shared-utils", + ], + shared_libs: [ + "android.hardware.sensors@1.0", + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.1", + "libcutils", + "libfmq", + "libhidlbase", + "liblog", + "libpower", + "libutils", + ], + static_libs: [ + "android.hardware.sensors@1.0-convert", + "android.hardware.sensors@2.X-shared-impl", + ], + vintf_fragments: ["android.hardware.sensors@2.1.xml"], +} diff --git a/sensors/2.1/default/OWNERS b/sensors/2.1/default/OWNERS new file mode 100644 index 0000000000..90c233030e --- /dev/null +++ b/sensors/2.1/default/OWNERS @@ -0,0 +1,3 @@ +arthuri@google.com +bduddie@google.com +stange@google.com diff --git a/sensors/2.1/default/SensorsV2_1.cpp b/sensors/2.1/default/SensorsV2_1.cpp new file mode 100644 index 0000000000..adf874ebac --- /dev/null +++ b/sensors/2.1/default/SensorsV2_1.cpp @@ -0,0 +1,58 @@ +/* + * 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 "SensorsV2_1.h" + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_1 { +namespace implementation { + +// Methods from ::android::hardware::sensors::V2_1::ISensors follow. +Return SensorsV2_1::getSensorsList_2_1(ISensors::getSensorsList_2_1_cb _hidl_cb) { + std::vector sensors; + for (const auto& sensor : mSensors) { + sensors.push_back(convertToNewSensorInfo(sensor.second->getSensorInfo())); + } + + // Call the HIDL callback with the SensorInfo + _hidl_cb(sensors); + + return Void(); +} + +Return SensorsV2_1::initialize_2_1( + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) { + auto eventQueue = std::make_unique>( + eventQueueDescriptor, true /* resetPointers */); + std::unique_ptr wrapper = + std::make_unique(eventQueue); + mCallbackWrapper = new ISensorsCallbackWrapper(sensorsCallback); + return initializeBase(wrapper, wakeLockDescriptor, mCallbackWrapper); +} + +Return SensorsV2_1::injectSensorData_2_1(const V2_1::Event& event) { + return injectSensorData(convertToOldEvent(event)); +} + +} // namespace implementation +} // namespace V2_1 +} // namespace sensors +} // namespace hardware +} // namespace android \ No newline at end of file diff --git a/sensors/2.1/default/SensorsV2_1.h b/sensors/2.1/default/SensorsV2_1.h new file mode 100644 index 0000000000..9cd16a7ec3 --- /dev/null +++ b/sensors/2.1/default/SensorsV2_1.h @@ -0,0 +1,72 @@ +/* + * 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_H +#define ANDROID_HARDWARE_SENSORS_V2_1_H + +#include "Sensors.h" + +#include "EventMessageQueueWrapper.h" + +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_1 { +namespace implementation { + +using Result = ::android::hardware::sensors::V1_0::Result; +using Sensors = ::android::hardware::sensors::V2_X::implementation::Sensors; + +class ISensorsCallbackWrapper : public V2_0::ISensorsCallback { + public: + ISensorsCallbackWrapper(const sp& callback) : mCallback(callback) {} + + Return onDynamicSensorsConnected(const hidl_vec& sensorInfos) override { + return mCallback->onDynamicSensorsConnected_2_1(convertToNewSensorInfos(sensorInfos)); + } + + Return onDynamicSensorsDisconnected(const hidl_vec& sensorHandles) override { + return mCallback->onDynamicSensorsDisconnected(sensorHandles); + } + + private: + sp mCallback; +}; + +struct SensorsV2_1 : public Sensors { + // Methods from ::android::hardware::sensors::V2_1::ISensors follow. + Return getSensorsList_2_1(ISensors::getSensorsList_2_1_cb _hidl_cb) override; + + Return initialize_2_1( + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) override; + + Return injectSensorData_2_1(const V2_1::Event& event) override; + + private: + sp mCallbackWrapper; +}; + +} // namespace implementation +} // namespace V2_1 +} // namespace sensors +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_SENSORS_V2_1_H \ No newline at end of file diff --git a/sensors/2.1/default/android.hardware.sensors@2.1-service-mock.rc b/sensors/2.1/default/android.hardware.sensors@2.1-service-mock.rc new file mode 100644 index 0000000000..d4147e75da --- /dev/null +++ b/sensors/2.1/default/android.hardware.sensors@2.1-service-mock.rc @@ -0,0 +1,7 @@ +service vendor.sensors-hal-2-1-mock /vendor/bin/hw/android.hardware.sensors@2.1-service.mock + interface android.hardware.sensors@2.0::ISensors default + interface android.hardware.sensors@2.1::ISensors default + class hal + user system + group system + rlimit rtprio 10 10 diff --git a/sensors/2.1/default/android.hardware.sensors@2.1.xml b/sensors/2.1/default/android.hardware.sensors@2.1.xml new file mode 100644 index 0000000000..18bd3ae83b --- /dev/null +++ b/sensors/2.1/default/android.hardware.sensors@2.1.xml @@ -0,0 +1,11 @@ + + + android.hardware.sensors + hwbinder + 2.1 + + ISensors + default + + + diff --git a/sensors/2.1/default/service.cpp b/sensors/2.1/default/service.cpp new file mode 100644 index 0000000000..1f3087c1fd --- /dev/null +++ b/sensors/2.1/default/service.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2018 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. + */ + +#define LOG_TAG "android.hardware.sensors@2.1-service" + +#include +#include +#include +#include +#include "SensorsV2_1.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::hardware::sensors::V2_1::ISensors; +using android::hardware::sensors::V2_1::implementation::SensorsV2_1; + +int main(int /* argc */, char** /* argv */) { + configureRpcThreadpool(1, true); + + android::sp sensors = new SensorsV2_1(); + if (sensors->registerAsService() != ::android::OK) { + ALOGE("Failed to register Sensors HAL instance"); + return -1; + } + + joinRpcThreadpool(); + return 1; // joinRpcThreadpool shouldn't exit +} diff --git a/sensors/common/default/2.X/Android.bp b/sensors/common/default/2.X/Android.bp new file mode 100644 index 0000000000..ea75a104bd --- /dev/null +++ b/sensors/common/default/2.X/Android.bp @@ -0,0 +1,36 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +cc_library_static { + name: "android.hardware.sensors@2.X-shared-impl", + vendor: true, + export_include_dirs: ["."], + srcs: [ + "Sensor.cpp", + ], + header_libs: [ + "android.hardware.sensors@2.X-shared-utils", + ], + shared_libs: [ + "android.hardware.sensors@1.0", + "android.hardware.sensors@2.0", + "libcutils", + "libfmq", + "libhidlbase", + "liblog", + "libpower", + "libutils", + ], +} diff --git a/sensors/common/default/2.X/OWNERS b/sensors/common/default/2.X/OWNERS new file mode 100644 index 0000000000..90c233030e --- /dev/null +++ b/sensors/common/default/2.X/OWNERS @@ -0,0 +1,3 @@ +arthuri@google.com +bduddie@google.com +stange@google.com diff --git a/sensors/2.0/default/Sensor.cpp b/sensors/common/default/2.X/Sensor.cpp similarity index 94% rename from sensors/2.0/default/Sensor.cpp rename to sensors/common/default/2.X/Sensor.cpp index c09173f7ce..4c40d1f33b 100644 --- a/sensors/2.0/default/Sensor.cpp +++ b/sensors/common/default/2.X/Sensor.cpp @@ -23,12 +23,17 @@ namespace android { namespace hardware { namespace sensors { -namespace V2_0 { +namespace V2_X { namespace implementation { +using ::android::hardware::sensors::V1_0::Event; 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::SensorInfo; using ::android::hardware::sensors::V1_0::SensorStatus; +using ::android::hardware::sensors::V1_0::SensorType; static constexpr float kDefaultMaxDelayUs = 10 * 1000 * 1000; @@ -204,8 +209,8 @@ AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback) mSensorInfo.typeAsString = ""; mSensorInfo.maxRange = 78.4f; // +/- 8g mSensorInfo.resolution = 1.52e-5; - mSensorInfo.power = 0.001f; // mA - mSensorInfo.minDelay = 20 * 1000; // microseconds + mSensorInfo.power = 0.001f; // mA + mSensorInfo.minDelay = 20 * 1000; // microseconds mSensorInfo.maxDelay = kDefaultMaxDelayUs; mSensorInfo.fifoReservedEventCount = 0; mSensorInfo.fifoMaxEventCount = 0; @@ -221,9 +226,9 @@ PressureSensor::PressureSensor(int32_t sensorHandle, ISensorsEventCallback* call mSensorInfo.version = 1; mSensorInfo.type = SensorType::PRESSURE; mSensorInfo.typeAsString = ""; - mSensorInfo.maxRange = 1100.0f; // hPa - mSensorInfo.resolution = 0.005f; // hPa - mSensorInfo.power = 0.001f; // mA + mSensorInfo.maxRange = 1100.0f; // hPa + mSensorInfo.resolution = 0.005f; // hPa + mSensorInfo.power = 0.001f; // mA mSensorInfo.minDelay = 100 * 1000; // microseconds mSensorInfo.maxDelay = kDefaultMaxDelayUs; mSensorInfo.fifoReservedEventCount = 0; @@ -242,7 +247,7 @@ MagnetometerSensor::MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallba mSensorInfo.typeAsString = ""; mSensorInfo.maxRange = 1300.0f; mSensorInfo.resolution = 0.01f; - mSensorInfo.power = 0.001f; // mA + mSensorInfo.power = 0.001f; // mA mSensorInfo.minDelay = 20 * 1000; // microseconds mSensorInfo.maxDelay = kDefaultMaxDelayUs; mSensorInfo.fifoReservedEventCount = 0; @@ -261,8 +266,8 @@ LightSensor::LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback) mSensorInfo.typeAsString = ""; mSensorInfo.maxRange = 43000.0f; mSensorInfo.resolution = 10.0f; - mSensorInfo.power = 0.001f; // mA - mSensorInfo.minDelay = 200 * 1000; // microseconds + mSensorInfo.power = 0.001f; // mA + mSensorInfo.minDelay = 200 * 1000; // microseconds mSensorInfo.maxDelay = kDefaultMaxDelayUs; mSensorInfo.fifoReservedEventCount = 0; mSensorInfo.fifoMaxEventCount = 0; @@ -280,7 +285,7 @@ ProximitySensor::ProximitySensor(int32_t sensorHandle, ISensorsEventCallback* ca mSensorInfo.typeAsString = ""; mSensorInfo.maxRange = 5.0f; mSensorInfo.resolution = 1.0f; - mSensorInfo.power = 0.012f; // mA + mSensorInfo.power = 0.012f; // mA mSensorInfo.minDelay = 200 * 1000; // microseconds mSensorInfo.maxDelay = kDefaultMaxDelayUs; mSensorInfo.fifoReservedEventCount = 0; @@ -367,7 +372,7 @@ RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle, } } // namespace implementation -} // namespace V2_0 +} // namespace V2_X } // namespace sensors } // namespace hardware } // namespace android diff --git a/sensors/2.0/default/Sensor.h b/sensors/common/default/2.X/Sensor.h similarity index 81% rename from sensors/2.0/default/Sensor.h rename to sensors/common/default/2.X/Sensor.h index 61900fa436..8592c412a4 100644 --- a/sensors/2.0/default/Sensor.h +++ b/sensors/common/default/2.X/Sensor.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ANDROID_HARDWARE_SENSORS_V2_0_SENSOR_H -#define ANDROID_HARDWARE_SENSORS_V2_0_SENSOR_H +#ifndef ANDROID_HARDWARE_SENSORS_V2_X_SENSOR_H +#define ANDROID_HARDWARE_SENSORS_V2_X_SENSOR_H #include @@ -25,26 +25,28 @@ #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; - namespace android { namespace hardware { namespace sensors { -namespace V2_0 { +namespace V2_X { namespace implementation { class ISensorsEventCallback { - public: + public: + using Event = ::android::hardware::sensors::V1_0::Event; + virtual ~ISensorsEventCallback(){}; virtual void postEvents(const std::vector& events, bool wakeup) = 0; }; class Sensor { - public: + public: + using Event = ::android::hardware::sensors::V1_0::Event; + using OperationMode = ::android::hardware::sensors::V1_0::OperationMode; + using Result = ::android::hardware::sensors::V1_0::Result; + using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo; + using SensorType = ::android::hardware::sensors::V1_0::SensorType; + Sensor(ISensorsEventCallback* callback); virtual ~Sensor(); @@ -57,7 +59,7 @@ class Sensor { bool supportsDataInjection() const; Result injectEvent(const Event& event); - protected: + protected: void run(); virtual std::vector readEvents(); static void startThread(Sensor* sensor); @@ -80,68 +82,68 @@ class Sensor { }; class OnChangeSensor : public Sensor { - public: + public: OnChangeSensor(ISensorsEventCallback* callback); virtual void activate(bool enable) override; - protected: + protected: virtual std::vector readEvents() override; - protected: + protected: Event mPreviousEvent; bool mPreviousEventSet; }; class AccelSensor : public Sensor { - public: + public: AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback); }; class GyroSensor : public Sensor { - public: + public: GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback); }; class AmbientTempSensor : public OnChangeSensor { - public: + public: AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback); }; class DeviceTempSensor : public OnChangeSensor { - public: + public: DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback); }; class PressureSensor : public Sensor { - public: + public: PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback); }; class MagnetometerSensor : public Sensor { - public: + public: MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback); }; class LightSensor : public OnChangeSensor { - public: + public: LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback); }; class ProximitySensor : public OnChangeSensor { - public: + public: ProximitySensor(int32_t sensorHandle, ISensorsEventCallback* callback); }; class RelativeHumiditySensor : public OnChangeSensor { - public: + public: RelativeHumiditySensor(int32_t sensorHandle, ISensorsEventCallback* callback); }; } // namespace implementation -} // namespace V2_0 +} // namespace V2_X } // namespace sensors } // namespace hardware } // namespace android -#endif // ANDROID_HARDWARE_SENSORS_V2_0_SENSOR_H +#endif // ANDROID_HARDWARE_SENSORS_V2_X_SENSOR_H diff --git a/sensors/common/default/2.X/Sensors.h b/sensors/common/default/2.X/Sensors.h new file mode 100644 index 0000000000..de998ebb05 --- /dev/null +++ b/sensors/common/default/2.X/Sensors.h @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2018 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_X_SENSORS_H +#define ANDROID_HARDWARE_SENSORS_V2_X_SENSORS_H + +#include "EventMessageQueueWrapper.h" +#include "Sensor.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_X { +namespace implementation { + +template +struct Sensors : public ISensorsInterface, public ISensorsEventCallback { + using Event = ::android::hardware::sensors::V1_0::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 SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; + using EventQueueFlagBits = ::android::hardware::sensors::V2_0::EventQueueFlagBits; + using SensorTimeout = ::android::hardware::sensors::V2_0::SensorTimeout; + using WakeLockQueueFlagBits = ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits; + using ISensorsCallback = ::android::hardware::sensors::V2_0::ISensorsCallback; + using EventMessageQueue = MessageQueue; + using WakeLockMessageQueue = MessageQueue; + + static constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP"; + + Sensors() + : mEventQueueFlag(nullptr), + mNextHandle(1), + mOutstandingWakeUpEvents(0), + mReadWakeLockQueueRun(false), + mAutoReleaseWakeLockTime(0), + mHasWakeLock(false) { + AddSensor(); + AddSensor(); + AddSensor(); + AddSensor(); + AddSensor(); + AddSensor(); + AddSensor(); + AddSensor(); + AddSensor(); + } + + virtual ~Sensors() { + deleteEventFlag(); + mReadWakeLockQueueRun = false; + mWakeLockThread.join(); + } + + // Methods from ::android::hardware::sensors::V2_0::ISensors follow. + Return getSensorsList(V2_0::ISensors::getSensorsList_cb _hidl_cb) override { + std::vector sensors; + for (const auto& sensor : mSensors) { + sensors.push_back(sensor.second->getSensorInfo()); + } + + // Call the HIDL callback with the SensorInfo + _hidl_cb(sensors); + + return Void(); + } + + Return setOperationMode(OperationMode mode) override { + for (auto sensor : mSensors) { + sensor.second->setOperationMode(mode); + } + return Result::OK; + } + + Return activate(int32_t sensorHandle, bool enabled) override { + auto sensor = mSensors.find(sensorHandle); + if (sensor != mSensors.end()) { + sensor->second->activate(enabled); + return Result::OK; + } + return Result::BAD_VALUE; + } + + Return initialize( + const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) override { + auto eventQueue = + std::make_unique(eventQueueDescriptor, true /* resetPointers */); + std::unique_ptr wrapper = + std::make_unique(eventQueue); + return initializeBase(wrapper, wakeLockDescriptor, sensorsCallback); + } + + Return initializeBase( + std::unique_ptr& eventQueue, + const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, + const sp& sensorsCallback) { + Result result = Result::OK; + + // Ensure that all sensors are disabled + for (auto sensor : mSensors) { + sensor.second->activate(false /* enable */); + } + + // Stop the Wake Lock thread if it is currently running + if (mReadWakeLockQueueRun.load()) { + mReadWakeLockQueueRun = false; + mWakeLockThread.join(); + } + + // Save a reference to the callback + mCallback = sensorsCallback; + + // Save the event queue. + mEventQueue = std::move(eventQueue); + + // Ensure that any existing EventFlag is properly deleted + deleteEventFlag(); + + // Create the EventFlag that is used to signal to the framework that sensor events have been + // written to the Event FMQ + if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) { + result = Result::BAD_VALUE; + } + + // 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. + mWakeLockQueue = std::make_unique(wakeLockDescriptor, + true /* resetPointers */); + + if (!mCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) { + result = Result::BAD_VALUE; + } + + // Start the thread to read events from the Wake Lock FMQ + mReadWakeLockQueueRun = true; + mWakeLockThread = std::thread(startReadWakeLockThread, this); + + return result; + } + + Return batch(int32_t sensorHandle, int64_t samplingPeriodNs, + int64_t /* maxReportLatencyNs */) override { + auto sensor = mSensors.find(sensorHandle); + if (sensor != mSensors.end()) { + sensor->second->batch(samplingPeriodNs); + return Result::OK; + } + return Result::BAD_VALUE; + } + + Return flush(int32_t sensorHandle) override { + auto sensor = mSensors.find(sensorHandle); + if (sensor != mSensors.end()) { + return sensor->second->flush(); + } + return Result::BAD_VALUE; + } + + Return injectSensorData(const Event& event) override { + auto sensor = mSensors.find(event.sensorHandle); + if (sensor != mSensors.end()) { + return sensor->second->injectEvent(event); + } + + return Result::BAD_VALUE; + } + + Return registerDirectChannel(const SharedMemInfo& /* mem */, + V2_0::ISensors::registerDirectChannel_cb _hidl_cb) override { + _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */); + return Return(); + } + + Return unregisterDirectChannel(int32_t /* channelHandle */) override { + return Result::INVALID_OPERATION; + } + + Return configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */, + RateLevel /* rate */, + V2_0::ISensors::configDirectReport_cb _hidl_cb) override { + _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */); + return Return(); + } + + void postEvents(const std::vector& events, bool wakeup) override { + std::lock_guard lock(mWriteLock); + if (mEventQueue->write(V2_1::implementation::convertToNewEvents(events))) { + mEventQueueFlag->wake(static_cast(EventQueueFlagBits::READ_AND_PROCESS)); + + if (wakeup) { + // Keep track of the number of outstanding WAKE_UP events in order to properly hold + // a wake lock until the framework has secured a wake lock + updateWakeLock(events.size(), 0 /* eventsHandled */); + } + } + } + + protected: + /** + * Add a new sensor + */ + template + void AddSensor() { + std::shared_ptr sensor = + std::make_shared(mNextHandle++ /* sensorHandle */, this /* callback */); + mSensors[sensor->getSensorInfo().sensorHandle] = sensor; + } + + /** + * Utility function to delete the Event Flag + */ + void deleteEventFlag() { + status_t status = EventFlag::deleteEventFlag(&mEventQueueFlag); + if (status != OK) { + ALOGI("Failed to delete event flag: %d", status); + } + } + + static void startReadWakeLockThread(Sensors* sensors) { sensors->readWakeLockFMQ(); } + + /** + * Function to read the Wake Lock FMQ and release the wake lock when appropriate + */ + void readWakeLockFMQ() { + while (mReadWakeLockQueueRun.load()) { + constexpr int64_t kReadTimeoutNs = 500 * 1000 * 1000; // 500 ms + uint32_t eventsHandled = 0; + + // Read events from the Wake Lock FMQ. Timeout after a reasonable amount of time to + // ensure that any held wake lock is able to be released if it is held for too long. + mWakeLockQueue->readBlocking(&eventsHandled, 1 /* count */, 0 /* readNotification */, + static_cast(WakeLockQueueFlagBits::DATA_WRITTEN), + kReadTimeoutNs); + updateWakeLock(0 /* eventsWritten */, eventsHandled); + } + } + + /** + * Responsible for acquiring and releasing a wake lock when there are unhandled WAKE_UP events + */ + void updateWakeLock(int32_t eventsWritten, int32_t eventsHandled) { + std::lock_guard lock(mWakeLockLock); + int32_t newVal = mOutstandingWakeUpEvents + eventsWritten - eventsHandled; + if (newVal < 0) { + mOutstandingWakeUpEvents = 0; + } else { + mOutstandingWakeUpEvents = newVal; + } + + if (eventsWritten > 0) { + // Update the time at which the last WAKE_UP event was sent + mAutoReleaseWakeLockTime = + ::android::uptimeMillis() + + static_cast(SensorTimeout::WAKE_LOCK_SECONDS) * 1000; + } + + if (!mHasWakeLock && mOutstandingWakeUpEvents > 0 && + acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName) == 0) { + mHasWakeLock = true; + } else if (mHasWakeLock) { + // Check if the wake lock should be released automatically if + // SensorTimeout::WAKE_LOCK_SECONDS has elapsed since the last WAKE_UP event was written + // to the Wake Lock FMQ. + if (::android::uptimeMillis() > mAutoReleaseWakeLockTime) { + ALOGD("No events read from wake lock FMQ for %d seconds, auto releasing wake lock", + SensorTimeout::WAKE_LOCK_SECONDS); + mOutstandingWakeUpEvents = 0; + } + + if (mOutstandingWakeUpEvents == 0 && release_wake_lock(kWakeLockName) == 0) { + mHasWakeLock = false; + } + } + } + + /** + * The Event FMQ where sensor events are written + */ + std::unique_ptr mEventQueue; + + /** + * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events + */ + std::unique_ptr mWakeLockQueue; + + /** + * Event Flag to signal to the framework when sensor events are available to be read + */ + EventFlag* mEventQueueFlag; + + /** + * Callback for asynchronous events, such as dynamic sensor connections. + */ + sp mCallback; + + /** + * A map of the available sensors + */ + std::map> mSensors; + + /** + * The next available sensor handle + */ + int32_t mNextHandle; + + /** + * Lock to protect writes to the FMQs + */ + std::mutex mWriteLock; + + /** + * Lock to protect acquiring and releasing the wake lock + */ + std::mutex mWakeLockLock; + + /** + * Track the number of WAKE_UP events that have not been handled by the framework + */ + uint32_t mOutstandingWakeUpEvents; + + /** + * A thread to read the Wake Lock FMQ + */ + std::thread mWakeLockThread; + + /** + * Flag to indicate that the Wake Lock Thread should continue to run + */ + std::atomic_bool mReadWakeLockQueueRun; + + /** + * Track the time when the wake lock should automatically be released + */ + int64_t mAutoReleaseWakeLockTime; + + /** + * Flag to indicate if a wake lock has been acquired + */ + bool mHasWakeLock; +}; + +} // namespace implementation +} // namespace V2_X +} // namespace sensors +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_SENSORS_V2_X_SENSORS_H