MH2 | Implement wakelock processing thread
Bug: 136511617
Test: Unit tests cannot be written for this change. Integration testing
will be performed later.
Change-Id: I651b5fde77c6017b3270413de896a947d95ff5f8
diff --git a/sensors/2.0/multihal/include/HalProxy.h b/sensors/2.0/multihal/include/HalProxy.h
index 47571a6..6592afe 100644
--- a/sensors/2.0/multihal/include/HalProxy.h
+++ b/sensors/2.0/multihal/include/HalProxy.h
@@ -16,9 +16,11 @@
#pragma once
+#include "ScopedWakelock.h"
#include "SubHal.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>
@@ -30,6 +32,7 @@
#include <mutex>
#include <queue>
#include <thread>
+#include <utility>
namespace android {
namespace hardware {
@@ -100,45 +103,41 @@
Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& dynamicSensorHandlesRemoved,
int32_t subHalIndex);
- // Below methods follow IScopedWakelockRefCounter
-
- /**
- * Increment ref count and maybe acquire wakelock.
- */
- void incrementRefCountAndMaybeAcquireWakelock() override;
-
- /**
- * Decrement ref count and maybe release wakelock.
- */
- void decrementRefCountAndMaybeReleaseWakelock() override;
-
// Below methods are for HalProxyCallback
/**
* Post events to the event message queue if there is room to write them. Otherwise post the
- * remaining events to a background thread for a blocking write with a 5 second timeout.
+ * remaining events to a background thread for a blocking write with a kPendingWriteTimeoutNs
+ * timeout.
*
* @param events The list of events to post to the message queue.
+ * @param numWakeupEvents The number of wakeup events in events.
+ * @param wakelock The wakelock associated with this post of events.
*/
- void postEventsToMessageQueue(const std::vector<Event>& events);
+ void postEventsToMessageQueue(const std::vector<Event>& events, size_t numWakeupEvents,
+ ScopedWakelock wakelock);
/**
- * Get the SensorInfo object associated with the sensorHandle.
+ * Get the sensor info associated with that sensorHandle.
*
- * @param sensorHandle The sensorHandle for the sensor.
+ * @param sensorHandle The sensor handle.
*
- * @return The sensor info for the sensor.
+ * @return The sensor info object in the mapping.
*/
- const SensorInfo& getSensorInfo(uint32_t sensorHandle) const {
- return mSensors.at(sensorHandle);
- }
+ const SensorInfo& getSensorInfo(uint32_t sensorHandle) { return mSensors[sensorHandle]; }
+
+ bool areThreadsRunning() { return mThreadsRun.load(); }
+
+ // Below methods are from IScopedWakelockRefCounter interface
+ bool incrementRefCountAndMaybeAcquireWakelock(size_t delta,
+ int64_t* timeoutStart = nullptr) override;
+
+ void decrementRefCountAndMaybeReleaseWakelock(size_t delta, int64_t timeoutStart = -1) override;
private:
using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;
- const char* kWakeLockName = "SensorsHAL_WAKEUP";
-
/**
* The Event FMQ where sensor events are written
*/
@@ -185,23 +184,17 @@
//! The single subHal that supports directChannel reporting.
ISensorsSubHal* mDirectChannelSubHal = nullptr;
- //! The mutex for the event queue.
- std::mutex mEventQueueMutex;
-
//! The timeout for each pending write on background thread for events.
- static const int64_t kWakelockTimeoutNs = 5 * INT64_C(1000000000) /* 5 seconds */;
-
- //! The scoped wakelock ref count.
- size_t mWakelockRefCount = 0;
-
- //! The mutex guarding the mWakelockRefCount variable
- std::mutex mWakelockRefCountMutex;
+ static const int64_t kPendingWriteTimeoutNs = 5 * INT64_C(1000000000) /* 5 seconds */;
//! The bit mask used to get the subhal index from a sensor handle.
static constexpr uint32_t kSensorHandleSubHalIndexMask = 0xFF000000;
- //! The events that were not able to be written to fmq right away
- std::queue<std::vector<Event>> mPendingWriteEventsQueue;
+ /**
+ * A FIFO queue of pairs of vector of events and the number of wakeup events in that vector
+ * which are waiting to be written to the events fmq in the background thread.
+ */
+ std::queue<std::pair<std::vector<Event>, size_t>> mPendingWriteEventsQueue;
//! The mutex protecting writing to the fmq and the pending events queue
std::mutex mEventQueueWriteMutex;
@@ -212,12 +205,32 @@
//! The thread object ptr that handles pending writes
std::thread mPendingWritesThread;
- //! The bool indicating whether to end the pending writes background thread or not
- bool mPendingWritesRun = true;
+ //! The thread object that handles wakelocks
+ std::thread mWakelockThread;
+
+ //! The bool indicating whether to end the threads started in initialize
+ std::atomic_bool mThreadsRun = true;
//! The mutex protecting access to the dynamic sensors added and removed methods.
std::mutex mDynamicSensorsMutex;
+ // WakelockRefCount membar vars below
+
+ //! The mutex protecting the wakelock refcount and subsequent wakelock releases and
+ //! acquisitions
+ std::recursive_mutex mWakelockMutex;
+
+ std::condition_variable_any mWakelockCV;
+
+ //! The refcount of how many ScopedWakelocks and pending wakeup events are active
+ size_t mWakelockRefCount = 0;
+
+ int64_t mWakelockTimeoutStartTime = getTimeNow();
+
+ int64_t mWakelockTimeoutResetTime = getTimeNow();
+
+ const char* kWakelockName = "SensorsMultiHal";
+
/**
* Initialize the list of SubHal objects in mSubHalList by reading from dynamic libraries
* listed in a config file.
@@ -236,9 +249,9 @@
void initializeSensorList();
/**
- * Calls the above two helper methods which are shared in both ctors.
+ * Calls the helper methods that all ctors use.
*/
- void initializeSubHalCallbacksAndSensorList();
+ void init();
/**
* Starts the thread that handles pending writes to event fmq.
@@ -251,6 +264,31 @@
void handlePendingWrites();
/**
+ * Starts the thread that handles decrementing the ref count on wakeup events processed by the
+ * framework and timing out wakelocks.
+ *
+ * @param halProxy The HalProxy object pointer.
+ */
+ static void startWakelockThread(HalProxy* halProxy);
+
+ //! Handles the wakelocks.
+ void handleWakelocks();
+
+ /**
+ * @param timeLeft The variable that should be set to the timeleft before timeout will occur or
+ * unmodified if timeout occurred.
+ *
+ * @return true if the shared wakelock has been held passed the timeout and should be released
+ */
+ bool sharedWakelockDidTimeout(int64_t* timeLeft);
+
+ /**
+ * Reset all the member variables associated with the wakelock ref count and maybe release
+ * the shared wakelock.
+ */
+ void resetSharedWakelock();
+
+ /**
* Clear direct channel flags if the HalProxy has already chosen a subhal as its direct channel
* subhal. Set the directChannelSubHal pointer to the subHal passed in if this is the first
* direct channel enabled sensor seen.
@@ -269,6 +307,16 @@
*/
ISensorsSubHal* getSubHalForSensorHandle(uint32_t sensorHandle);
+ /**
+ * Count the number of wakeup events in the first n events of the vector.
+ *
+ * @param events The vector of Event objects.
+ * @param n The end index not inclusive of events to consider.
+ *
+ * @return The number of wakeup events of the considered events.
+ */
+ size_t countNumWakeupEvents(const std::vector<Event>& events, size_t n);
+
/*
* Clear out the subhal index bytes from a sensorHandle.
*