Loading sensors/2.0/default/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ cc_binary { "libhidlbase", "libhidltransport", "liblog", "libpower", "libutils", ], } sensors/2.0/default/Sensor.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -86,7 +86,7 @@ Result Sensor::flush() { ev.sensorType = SensorType::ADDITIONAL_INFO; ev.u.meta.what = MetaDataEventType::META_DATA_FLUSH_COMPLETE; std::vector<Event> evs{ev}; mCallback->postEvents(evs); mCallback->postEvents(evs, isWakeUpSensor()); return Result::OK; } Loading @@ -113,7 +113,7 @@ void Sensor::run() { if (now >= nextSampleTime) { mLastSampleTimeNs = now; nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs; mCallback->postEvents(readEvents()); mCallback->postEvents(readEvents(), isWakeUpSensor()); } mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now)); Loading @@ -121,6 +121,10 @@ void Sensor::run() { } } bool Sensor::isWakeUpSensor() { return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::WAKE_UP); } std::vector<Event> Sensor::readEvents() { std::vector<Event> events; Event event; Loading Loading @@ -155,7 +159,7 @@ Result Sensor::injectEvent(const Event& event) { } else if (!supportsDataInjection()) { result = Result::INVALID_OPERATION; } else if (mMode == OperationMode::DATA_INJECTION) { mCallback->postEvents(std::vector<Event>{event}); mCallback->postEvents(std::vector<Event>{event}, isWakeUpSensor()); } else { result = Result::BAD_VALUE; } Loading sensors/2.0/default/Sensor.h +3 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ namespace implementation { class ISensorsEventCallback { public: virtual ~ISensorsEventCallback(){}; virtual void postEvents(const std::vector<Event>& events) = 0; virtual void postEvents(const std::vector<Event>& events, bool wakeup) = 0; }; class Sensor { Loading @@ -62,6 +62,8 @@ class Sensor { virtual std::vector<Event> readEvents(); static void startThread(Sensor* sensor); bool isWakeUpSensor(); bool mIsEnabled; int64_t mSamplingPeriodNs; int64_t mLastSampleTimeNs; Loading sensors/2.0/default/Sensors.cpp +74 −8 Original line number Diff line number Diff line Loading @@ -30,8 +30,16 @@ 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; Sensors::Sensors() : mEventQueueFlag(nullptr) { constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP"; Sensors::Sensors() : mEventQueueFlag(nullptr), mOutstandingWakeUpEvents(0), mReadWakeLockQueueRun(false), mAutoReleaseWakeLockTime(0), mHasWakeLock(false) { std::shared_ptr<AccelSensor> accel = std::make_shared<AccelSensor>(1 /* sensorHandle */, this /* callback */); mSensors[accel->getSensorInfo().sensorHandle] = accel; Loading @@ -39,6 +47,8 @@ Sensors::Sensors() : mEventQueueFlag(nullptr) { Sensors::~Sensors() { deleteEventFlag(); mReadWakeLockQueueRun = false; mWakeLockThread.join(); } // Methods from ::android::hardware::sensors::V2_0::ISensors follow. Loading Loading @@ -101,6 +111,10 @@ Return<Result> Sensors::initialize( result = Result::BAD_VALUE; } // Start the thread to read events from the Wake Lock FMQ mReadWakeLockQueueRun = true; mWakeLockThread = std::thread(startReadWakeLockThread, this); return result; } Loading Loading @@ -147,15 +161,67 @@ Return<void> Sensors::configDirectReport(int32_t /* sensorHandle */, int32_t /* return Return<void>(); } void Sensors::postEvents(const std::vector<Event>& events) { std::lock_guard<std::mutex> l(mLock); 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)); // TODO: read events from the Wake Lock FMQ in the right place std::vector<uint32_t> tmp(mWakeLockQueue->availableToRead()); mWakeLockQueue->read(tmp.data(), mWakeLockQueue->availableToRead()); 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 */); } } } mEventQueue->write(events.data(), events.size()); mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS)); 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 */, kReadTimeoutNs); updateWakeLock(0 /* eventsWritten */, eventsHandled); } } void Sensors::startReadWakeLockThread(Sensors* sensors) { sensors->readWakeLockFMQ(); } void Sensors::deleteEventFlag() { Loading sensors/2.0/default/Sensors.h +48 −3 Original line number Diff line number Diff line Loading @@ -21,10 +21,13 @@ #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 { Loading Loading @@ -80,7 +83,7 @@ struct Sensors : public ISensors, public ISensorsEventCallback { Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, configDirectReport_cb _hidl_cb) override; void postEvents(const std::vector<Event>& events) override; void postEvents(const std::vector<Event>& events, bool wakeup) override; private: /** Loading @@ -88,6 +91,18 @@ struct Sensors : public ISensors, public ISensorsEventCallback { */ 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>; Loading Loading @@ -117,9 +132,39 @@ struct Sensors : public ISensors, public ISensorsEventCallback { std::map<int32_t, std::shared_ptr<Sensor>> mSensors; /** * Lock to protect writes and reads to the FMQs * 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 */ std::mutex mLock; bool mHasWakeLock; }; } // namespace implementation Loading Loading
sensors/2.0/default/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ cc_binary { "libhidlbase", "libhidltransport", "liblog", "libpower", "libutils", ], }
sensors/2.0/default/Sensor.cpp +7 −3 Original line number Diff line number Diff line Loading @@ -86,7 +86,7 @@ Result Sensor::flush() { ev.sensorType = SensorType::ADDITIONAL_INFO; ev.u.meta.what = MetaDataEventType::META_DATA_FLUSH_COMPLETE; std::vector<Event> evs{ev}; mCallback->postEvents(evs); mCallback->postEvents(evs, isWakeUpSensor()); return Result::OK; } Loading @@ -113,7 +113,7 @@ void Sensor::run() { if (now >= nextSampleTime) { mLastSampleTimeNs = now; nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs; mCallback->postEvents(readEvents()); mCallback->postEvents(readEvents(), isWakeUpSensor()); } mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now)); Loading @@ -121,6 +121,10 @@ void Sensor::run() { } } bool Sensor::isWakeUpSensor() { return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::WAKE_UP); } std::vector<Event> Sensor::readEvents() { std::vector<Event> events; Event event; Loading Loading @@ -155,7 +159,7 @@ Result Sensor::injectEvent(const Event& event) { } else if (!supportsDataInjection()) { result = Result::INVALID_OPERATION; } else if (mMode == OperationMode::DATA_INJECTION) { mCallback->postEvents(std::vector<Event>{event}); mCallback->postEvents(std::vector<Event>{event}, isWakeUpSensor()); } else { result = Result::BAD_VALUE; } Loading
sensors/2.0/default/Sensor.h +3 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ namespace implementation { class ISensorsEventCallback { public: virtual ~ISensorsEventCallback(){}; virtual void postEvents(const std::vector<Event>& events) = 0; virtual void postEvents(const std::vector<Event>& events, bool wakeup) = 0; }; class Sensor { Loading @@ -62,6 +62,8 @@ class Sensor { virtual std::vector<Event> readEvents(); static void startThread(Sensor* sensor); bool isWakeUpSensor(); bool mIsEnabled; int64_t mSamplingPeriodNs; int64_t mLastSampleTimeNs; Loading
sensors/2.0/default/Sensors.cpp +74 −8 Original line number Diff line number Diff line Loading @@ -30,8 +30,16 @@ 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; Sensors::Sensors() : mEventQueueFlag(nullptr) { constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP"; Sensors::Sensors() : mEventQueueFlag(nullptr), mOutstandingWakeUpEvents(0), mReadWakeLockQueueRun(false), mAutoReleaseWakeLockTime(0), mHasWakeLock(false) { std::shared_ptr<AccelSensor> accel = std::make_shared<AccelSensor>(1 /* sensorHandle */, this /* callback */); mSensors[accel->getSensorInfo().sensorHandle] = accel; Loading @@ -39,6 +47,8 @@ Sensors::Sensors() : mEventQueueFlag(nullptr) { Sensors::~Sensors() { deleteEventFlag(); mReadWakeLockQueueRun = false; mWakeLockThread.join(); } // Methods from ::android::hardware::sensors::V2_0::ISensors follow. Loading Loading @@ -101,6 +111,10 @@ Return<Result> Sensors::initialize( result = Result::BAD_VALUE; } // Start the thread to read events from the Wake Lock FMQ mReadWakeLockQueueRun = true; mWakeLockThread = std::thread(startReadWakeLockThread, this); return result; } Loading Loading @@ -147,15 +161,67 @@ Return<void> Sensors::configDirectReport(int32_t /* sensorHandle */, int32_t /* return Return<void>(); } void Sensors::postEvents(const std::vector<Event>& events) { std::lock_guard<std::mutex> l(mLock); 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)); // TODO: read events from the Wake Lock FMQ in the right place std::vector<uint32_t> tmp(mWakeLockQueue->availableToRead()); mWakeLockQueue->read(tmp.data(), mWakeLockQueue->availableToRead()); 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 */); } } } mEventQueue->write(events.data(), events.size()); mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS)); 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 */, kReadTimeoutNs); updateWakeLock(0 /* eventsWritten */, eventsHandled); } } void Sensors::startReadWakeLockThread(Sensors* sensors) { sensors->readWakeLockFMQ(); } void Sensors::deleteEventFlag() { Loading
sensors/2.0/default/Sensors.h +48 −3 Original line number Diff line number Diff line Loading @@ -21,10 +21,13 @@ #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 { Loading Loading @@ -80,7 +83,7 @@ struct Sensors : public ISensors, public ISensorsEventCallback { Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, configDirectReport_cb _hidl_cb) override; void postEvents(const std::vector<Event>& events) override; void postEvents(const std::vector<Event>& events, bool wakeup) override; private: /** Loading @@ -88,6 +91,18 @@ struct Sensors : public ISensors, public ISensorsEventCallback { */ 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>; Loading Loading @@ -117,9 +132,39 @@ struct Sensors : public ISensors, public ISensorsEventCallback { std::map<int32_t, std::shared_ptr<Sensor>> mSensors; /** * Lock to protect writes and reads to the FMQs * 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 */ std::mutex mLock; bool mHasWakeLock; }; } // namespace implementation Loading