diff options
author | Anthony Stange <stange@google.com> | 2020-02-05 19:27:16 -0500 |
---|---|---|
committer | Anthony Stange <stange@google.com> | 2020-02-18 15:24:35 -0500 |
commit | 1d71acc129331cca3bedbfd6c1b350682f0d2fae (patch) | |
tree | 09a8a67ea06d43401c2c9a671b0ba599ecda9571 /sensors | |
parent | c002dd9ecaa5f2dc29e1f488ed6d0b14adbdedb7 (diff) | |
download | platform_hardware_interfaces-1d71acc129331cca3bedbfd6c1b350682f0d2fae.tar.gz platform_hardware_interfaces-1d71acc129331cca3bedbfd6c1b350682f0d2fae.tar.bz2 platform_hardware_interfaces-1d71acc129331cca3bedbfd6c1b350682f0d2fae.zip |
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
Diffstat (limited to 'sensors')
-rw-r--r-- | sensors/2.0/default/Android.bp | 12 | ||||
-rw-r--r-- | sensors/2.0/default/Sensors.cpp | 259 | ||||
-rw-r--r-- | sensors/2.0/default/Sensors.h | 191 | ||||
-rw-r--r-- | sensors/2.0/default/SensorsV2_0.h | 39 | ||||
-rw-r--r-- | sensors/2.0/default/service.cpp | 6 | ||||
-rw-r--r-- | sensors/2.1/default/Android.bp | 45 | ||||
-rw-r--r-- | sensors/2.1/default/OWNERS | 3 | ||||
-rw-r--r-- | sensors/2.1/default/SensorsV2_1.cpp | 58 | ||||
-rw-r--r-- | sensors/2.1/default/SensorsV2_1.h | 72 | ||||
-rw-r--r-- | sensors/2.1/default/android.hardware.sensors@2.1-service-mock.rc | 7 | ||||
-rw-r--r-- | sensors/2.1/default/android.hardware.sensors@2.1.xml | 11 | ||||
-rw-r--r-- | sensors/2.1/default/service.cpp | 41 | ||||
-rw-r--r-- | sensors/common/default/2.X/Android.bp | 36 | ||||
-rw-r--r-- | sensors/common/default/2.X/OWNERS | 3 | ||||
-rw-r--r-- | sensors/common/default/2.X/Sensor.cpp (renamed from sensors/2.0/default/Sensor.cpp) | 27 | ||||
-rw-r--r-- | sensors/common/default/2.X/Sensor.h (renamed from sensors/2.0/default/Sensor.h) | 54 | ||||
-rw-r--r-- | sensors/common/default/2.X/Sensors.h | 376 |
17 files changed, 748 insertions, 492 deletions
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 <android/hardware/sensors/2.0/types.h> -#include <log/log.h> - -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<AccelSensor>(); - AddSensor<GyroSensor>(); - AddSensor<AmbientTempSensor>(); - AddSensor<DeviceTempSensor>(); - AddSensor<PressureSensor>(); - AddSensor<MagnetometerSensor>(); - AddSensor<LightSensor>(); - AddSensor<ProximitySensor>(); - AddSensor<RelativeHumiditySensor>(); -} - -Sensors::~Sensors() { - deleteEventFlag(); - mReadWakeLockQueueRun = false; - mWakeLockThread.join(); -} - -// Methods from ::android::hardware::sensors::V2_0::ISensors follow. -Return<void> Sensors::getSensorsList(getSensorsList_cb _hidl_cb) { - std::vector<SensorInfo> 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<Result> Sensors::setOperationMode(OperationMode mode) { - for (auto sensor : mSensors) { - sensor.second->setOperationMode(mode); - } - return Result::OK; -} - -Return<Result> 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<Result> Sensors::initialize( - const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor, - const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, - const sp<ISensorsCallback>& 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<EventMessageQueue>(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<WakeLockMessageQueue>(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<Result> 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<Result> Sensors::flush(int32_t sensorHandle) { - auto sensor = mSensors.find(sensorHandle); - if (sensor != mSensors.end()) { - return sensor->second->flush(); - } - return Result::BAD_VALUE; -} - -Return<Result> 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<void> Sensors::registerDirectChannel(const SharedMemInfo& /* mem */, - registerDirectChannel_cb _hidl_cb) { - _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */); - return Return<void>(); -} - -Return<Result> Sensors::unregisterDirectChannel(int32_t /* channelHandle */) { - return Result::INVALID_OPERATION; -} - -Return<void> Sensors::configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */, - RateLevel /* rate */, configDirectReport_cb _hidl_cb) { - _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */); - return Return<void>(); -} - -void Sensors::postEvents(const std::vector<Event>& events, bool wakeup) { - std::lock_guard<std::mutex> lock(mWriteLock); - if (mEventQueue->write(events.data(), events.size())) { - mEventQueueFlag->wake(static_cast<uint32_t>(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<std::mutex> 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<uint32_t>(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<uint32_t>(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 <android/hardware/sensors/2.0/ISensors.h> -#include <fmq/MessageQueue.h> -#include <hardware_legacy/power.h> -#include <hidl/MQDescriptor.h> -#include <hidl/Status.h> - -#include <atomic> -#include <memory> -#include <thread> - -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<void> getSensorsList(getSensorsList_cb _hidl_cb) override; - - Return<Result> setOperationMode(OperationMode mode) override; - - Return<Result> activate(int32_t sensorHandle, bool enabled) override; - - Return<Result> initialize( - const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor, - const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, - const sp<ISensorsCallback>& sensorsCallback) override; - - Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs, - int64_t maxReportLatencyNs) override; - - Return<Result> flush(int32_t sensorHandle) override; - - Return<Result> injectSensorData(const Event& event) override; - - Return<void> registerDirectChannel(const SharedMemInfo& mem, - registerDirectChannel_cb _hidl_cb) override; - - Return<Result> unregisterDirectChannel(int32_t channelHandle) override; - - Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, - configDirectReport_cb _hidl_cb) override; - - void postEvents(const std::vector<Event>& events, bool wakeup) override; - - private: - /** - * Add a new sensor - */ - template <class SensorType> - void AddSensor() { - std::shared_ptr<SensorType> sensor = - std::make_shared<SensorType>(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<Event, kSynchronizedReadWrite>; - using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>; - - /** - * The Event FMQ where sensor events are written - */ - std::unique_ptr<EventMessageQueue> mEventQueue; - - /** - * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events - */ - std::unique_ptr<WakeLockMessageQueue> 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<ISensorsCallback> mCallback; - - /** - * A map of the available sensors - */ - std::map<int32_t, std::shared_ptr<Sensor>> 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 <android/hardware/sensors/2.0/ISensors.h> + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_0 { +namespace implementation { + +struct SensorsV2_0 : public ::android::hardware::sensors::V2_X::implementation::Sensors<ISensors> { +}; + +} // 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 <hidl/HidlTransportSupport.h> #include <log/log.h> #include <utils/StrongPointer.h> -#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<ISensors> sensors = new Sensors(); + android::sp<ISensors> 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<void> SensorsV2_1::getSensorsList_2_1(ISensors::getSensorsList_2_1_cb _hidl_cb) { + std::vector<SensorInfo> 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<Result> SensorsV2_1::initialize_2_1( + const ::android::hardware::MQDescriptorSync<V2_1::Event>& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, + const sp<V2_1::ISensorsCallback>& sensorsCallback) { + auto eventQueue = std::make_unique<MessageQueue<V2_1::Event, kSynchronizedReadWrite>>( + eventQueueDescriptor, true /* resetPointers */); + std::unique_ptr<EventMessageQueueWrapperBase> wrapper = + std::make_unique<EventMessageQueueWrapperV2_1>(eventQueue); + mCallbackWrapper = new ISensorsCallbackWrapper(sensorsCallback); + return initializeBase(wrapper, wakeLockDescriptor, mCallbackWrapper); +} + +Return<Result> 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 <android/hardware/sensors/2.1/ISensors.h> + +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<ISensors>; + +class ISensorsCallbackWrapper : public V2_0::ISensorsCallback { + public: + ISensorsCallbackWrapper(const sp<V2_1::ISensorsCallback>& callback) : mCallback(callback) {} + + Return<void> onDynamicSensorsConnected(const hidl_vec<V1_0::SensorInfo>& sensorInfos) override { + return mCallback->onDynamicSensorsConnected_2_1(convertToNewSensorInfos(sensorInfos)); + } + + Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& sensorHandles) override { + return mCallback->onDynamicSensorsDisconnected(sensorHandles); + } + + private: + sp<V2_1::ISensorsCallback> mCallback; +}; + +struct SensorsV2_1 : public Sensors { + // Methods from ::android::hardware::sensors::V2_1::ISensors follow. + Return<void> getSensorsList_2_1(ISensors::getSensorsList_2_1_cb _hidl_cb) override; + + Return<Result> initialize_2_1( + const ::android::hardware::MQDescriptorSync<V2_1::Event>& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, + const sp<V2_1::ISensorsCallback>& sensorsCallback) override; + + Return<Result> injectSensorData_2_1(const V2_1::Event& event) override; + + private: + sp<ISensorsCallbackWrapper> 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 @@ +<manifest version="1.0" type="device"> + <hal format="hidl"> + <name>android.hardware.sensors</name> + <transport>hwbinder</transport> + <version>2.1</version> + <interface> + <name>ISensors</name> + <instance>default</instance> + </interface> + </hal> +</manifest> 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 <android/hardware/sensors/2.1/ISensors.h> +#include <hidl/HidlTransportSupport.h> +#include <log/log.h> +#include <utils/StrongPointer.h> +#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<ISensors> 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 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 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 <android/hardware/sensors/1.0/types.h> @@ -25,26 +25,28 @@ #include <thread> #include <vector> -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<Event>& 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<Event> 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<Event> 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 <android/hardware/sensors/2.0/ISensors.h> +#include <android/hardware/sensors/2.0/types.h> +#include <fmq/MessageQueue.h> +#include <hardware_legacy/power.h> +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> +#include <log/log.h> + +#include <atomic> +#include <memory> +#include <thread> + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_X { +namespace implementation { + +template <class ISensorsInterface> +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<Event, kSynchronizedReadWrite>; + using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>; + + static constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP"; + + Sensors() + : mEventQueueFlag(nullptr), + mNextHandle(1), + mOutstandingWakeUpEvents(0), + mReadWakeLockQueueRun(false), + mAutoReleaseWakeLockTime(0), + mHasWakeLock(false) { + AddSensor<AccelSensor>(); + AddSensor<GyroSensor>(); + AddSensor<AmbientTempSensor>(); + AddSensor<DeviceTempSensor>(); + AddSensor<PressureSensor>(); + AddSensor<MagnetometerSensor>(); + AddSensor<LightSensor>(); + AddSensor<ProximitySensor>(); + AddSensor<RelativeHumiditySensor>(); + } + + virtual ~Sensors() { + deleteEventFlag(); + mReadWakeLockQueueRun = false; + mWakeLockThread.join(); + } + + // Methods from ::android::hardware::sensors::V2_0::ISensors follow. + Return<void> getSensorsList(V2_0::ISensors::getSensorsList_cb _hidl_cb) override { + std::vector<V1_0::SensorInfo> 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<Result> setOperationMode(OperationMode mode) override { + for (auto sensor : mSensors) { + sensor.second->setOperationMode(mode); + } + return Result::OK; + } + + Return<Result> 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<Result> initialize( + const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor, + const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, + const sp<ISensorsCallback>& sensorsCallback) override { + auto eventQueue = + std::make_unique<EventMessageQueue>(eventQueueDescriptor, true /* resetPointers */); + std::unique_ptr<V2_1::implementation::EventMessageQueueWrapperBase> wrapper = + std::make_unique<V2_1::implementation::EventMessageQueueWrapperV1_0>(eventQueue); + return initializeBase(wrapper, wakeLockDescriptor, sensorsCallback); + } + + Return<Result> initializeBase( + std::unique_ptr<V2_1::implementation::EventMessageQueueWrapperBase>& eventQueue, + const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, + const sp<ISensorsCallback>& 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<WakeLockMessageQueue>(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<Result> 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<Result> flush(int32_t sensorHandle) override { + auto sensor = mSensors.find(sensorHandle); + if (sensor != mSensors.end()) { + return sensor->second->flush(); + } + return Result::BAD_VALUE; + } + + Return<Result> 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<void> registerDirectChannel(const SharedMemInfo& /* mem */, + V2_0::ISensors::registerDirectChannel_cb _hidl_cb) override { + _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */); + return Return<void>(); + } + + Return<Result> unregisterDirectChannel(int32_t /* channelHandle */) override { + return Result::INVALID_OPERATION; + } + + Return<void> 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>(); + } + + void postEvents(const std::vector<Event>& events, bool wakeup) override { + std::lock_guard<std::mutex> lock(mWriteLock); + if (mEventQueue->write(V2_1::implementation::convertToNewEvents(events))) { + mEventQueueFlag->wake(static_cast<uint32_t>(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 <class SensorType> + void AddSensor() { + std::shared_ptr<SensorType> sensor = + std::make_shared<SensorType>(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<uint32_t>(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<std::mutex> 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<uint32_t>(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<V2_1::implementation::EventMessageQueueWrapperBase> mEventQueue; + + /** + * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events + */ + std::unique_ptr<WakeLockMessageQueue> 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<ISensorsCallback> mCallback; + + /** + * A map of the available sensors + */ + std::map<int32_t, std::shared_ptr<Sensor>> 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 |