Read Sensor Events from Event FMQ

Read sensor events from the Event FMQ whenever the READ_AND_PROCESS
bitmask is set from the Sensors HAL on the Event FMQ.

Bug: 111070257
Test: Compile, configured system to use sensors@2.0 and ensured that
      a_sns_test received events

Change-Id: Iad6b9ef2dc691b8d4f8ba4ae294c1371273be0ba
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index bbceba5..25ed21c 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -13,11 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include "SensorDevice.h"
+
+#include "android/hardware/sensors/2.0/types.h"
 #include "SensorService.h"
 
 #include <android-base/logging.h>
-#include <sensor/SensorEventQueue.h>
 #include <sensors/convert.h>
 #include <cutils/atomic.h>
 #include <utils/Errors.h>
@@ -30,6 +32,7 @@
 using namespace android::hardware::sensors;
 using namespace android::hardware::sensors::V1_0;
 using namespace android::hardware::sensors::V1_0::implementation;
+using android::hardware::sensors::V2_0::EventQueueFlagBits;
 using android::hardware::hidl_vec;
 using android::SensorDeviceUtils::HidlServiceRegistrationWaiter;
 
@@ -88,6 +91,13 @@
            (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
 }
 
+SensorDevice::~SensorDevice() {
+    if (mEventQueueFlag != nullptr) {
+        hardware::EventFlag::deleteEventFlag(&mEventQueueFlag);
+        mEventQueueFlag = nullptr;
+    }
+}
+
 bool SensorDevice::connectHidlService() {
     HalConnectionStatus status = connectHidlServiceV2_0();
     if (status == HalConnectionStatus::DOES_NOT_EXIST) {
@@ -147,8 +157,10 @@
                 SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
                 true /* configureEventFlagWord */);
 
+        hardware::EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag);
+
         CHECK(mSensors != nullptr && mEventQueue != nullptr &&
-              mWakeLockQueue != nullptr);
+                mWakeLockQueue != nullptr && mEventQueueFlag != nullptr);
 
         status_t status = StatusFromResult(checkReturn(mSensors->initializeMessageQueues(
                 *mEventQueue->getDesc(),
@@ -222,6 +234,19 @@
 }
 
 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
+    ssize_t eventsRead = 0;
+    if (mSensors->supportsMessageQueues()) {
+        eventsRead = pollFmq(buffer, count);
+    } else if (mSensors->supportsPolling()) {
+        eventsRead = pollHal(buffer, count);
+    } else {
+        ALOGE("Must support polling or FMQ");
+        eventsRead = -1;
+    }
+    return eventsRead;
+}
+
+ssize_t SensorDevice::pollHal(sensors_event_t* buffer, size_t count) {
     if (mSensors == nullptr) return NO_INIT;
 
     ssize_t err;
@@ -267,6 +292,46 @@
     return err;
 }
 
+ssize_t SensorDevice::pollFmq(sensors_event_t* buffer, size_t maxNumEventsToRead) {
+    if (mSensors == nullptr) {
+        return NO_INIT;
+    }
+
+    ssize_t eventsRead = 0;
+    size_t availableEvents = mEventQueue->availableToRead();
+
+    if (availableEvents == 0) {
+        uint32_t eventFlagState = 0;
+
+        // Wait for events to become available. This is necessary so that the Event FMQ's read() is
+        // able to be called with the correct number of events to read. If the specified number of
+        // events is not available, then read() would return no events, possibly introducing
+        // additional latency in delivering events to applications.
+        mEventQueueFlag->wait(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS),
+                              &eventFlagState);
+        availableEvents = mEventQueue->availableToRead();
+
+        if (availableEvents == 0) {
+            ALOGW("Event FMQ wake without any events");
+        }
+    }
+
+    size_t eventsToRead = std::min({availableEvents, maxNumEventsToRead, mEventBuffer.size()});
+    if (eventsToRead > 0) {
+        if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) {
+            for (size_t i = 0; i < eventsToRead; i++) {
+                convertToSensorEvent(mEventBuffer[i], &buffer[i]);
+            }
+            eventsRead = eventsToRead;
+        } else {
+            ALOGW("Failed to read %zu events, currently %zu events available",
+                    eventsToRead, availableEvents);
+        }
+    }
+
+    return eventsRead;
+}
+
 void SensorDevice::autoDisable(void *ident, int handle) {
     Mutex::Autolock _l(mLock);
     ssize_t activationIndex = mActivationCount.indexOfKey(handle);