Initialize Sensors Test Environment

Properly initialize the test environment for Sensors HAL 2.0 by
constructing and reading from FMQs.

Bug: 115969174
Test: Builds, VTS tests run (some pass) against locally modified
      sensors HAL
Change-Id: Id959e50c18b643d2693c90bac15710ed6f34b1b4
diff --git a/sensors/2.0/vts/functional/Android.bp b/sensors/2.0/vts/functional/Android.bp
index 9b8e3d4..8e8413c 100644
--- a/sensors/2.0/vts/functional/Android.bp
+++ b/sensors/2.0/vts/functional/Android.bp
@@ -26,6 +26,7 @@
         "android.hardware.graphics.mapper@2.0",
         "android.hardware.sensors@1.0",
         "android.hardware.sensors@2.0",
+        "libfmq",
         "VtsHalSensorsTargetTestUtils",
     ],
 }
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
index 20d0838..5444287 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.cpp
@@ -16,44 +16,65 @@
 
 #include "SensorsHidlEnvironmentV2_0.h"
 
+#include <android/hardware/sensors/2.0/types.h>
 #include <log/log.h>
 
+#include <algorithm>
 #include <vector>
 
+using ::android::hardware::EventFlag;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::sensors::V1_0::Result;
 using ::android::hardware::sensors::V1_0::SensorInfo;
+using ::android::hardware::sensors::V2_0::EventQueueFlagBits;
 using ::android::hardware::sensors::V2_0::ISensors;
 
+template <typename EnumType>
+constexpr typename std::underlying_type<EnumType>::type asBaseType(EnumType value) {
+    return static_cast<typename std::underlying_type<EnumType>::type>(value);
+}
+
+constexpr size_t SensorsHidlEnvironmentV2_0::MAX_RECEIVE_BUFFER_EVENT_COUNT;
+
 bool SensorsHidlEnvironmentV2_0::resetHal() {
-    std::string step;
     bool succeed = false;
     do {
-        step = "getService()";
-        sensors = ISensors::getService(
+        mSensors = ISensors::getService(
             SensorsHidlEnvironmentV2_0::Instance()->getServiceName<ISensors>());
-        if (sensors == nullptr) {
+        if (mSensors == nullptr) {
             break;
         }
 
-        step = "getSensorList";
+        // Initialize FMQs
+        mEventQueue = std::make_unique<EventMessageQueue>(MAX_RECEIVE_BUFFER_EVENT_COUNT,
+                                                          true /* configureEventFlagWord */);
+
+        mWakeLockQueue = std::make_unique<WakeLockQueue>(MAX_RECEIVE_BUFFER_EVENT_COUNT,
+                                                         true /* configureEventFlagWord */);
+
+        if (mEventQueue == nullptr || mWakeLockQueue == nullptr) {
+            break;
+        }
+
+        EventFlag::deleteEventFlag(&mEventQueueFlag);
+        EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag);
+        if (mEventQueueFlag == nullptr) {
+            break;
+        }
+
+        mSensors->initialize(*mEventQueue->getDesc(), *mWakeLockQueue->getDesc(),
+                             nullptr /* TODO: callback */);
+
         std::vector<SensorInfo> sensorList;
-        if (!sensors
-                 ->getSensorsList([&](const hidl_vec<SensorInfo>& list) {
-                     sensorList.reserve(list.size());
-                     for (size_t i = 0; i < list.size(); ++i) {
-                         sensorList.push_back(list[i]);
-                     }
-                 })
+        if (!mSensors->getSensorsList([&](const hidl_vec<SensorInfo>& list) { sensorList = list; })
                  .isOk()) {
             break;
         }
 
         // stop each sensor individually
-        step = "stop each sensor";
         bool ok = true;
         for (const auto& i : sensorList) {
-            if (!sensors->activate(i.sensorHandle, false).isOk()) {
+            if (!mSensors->activate(i.sensorHandle, false).isOk()) {
                 ok = false;
                 break;
             }
@@ -63,31 +84,58 @@
         }
 
         // mark it done
-        step = "done";
         succeed = true;
     } while (0);
 
-    if (succeed) {
-        return true;
+    if (!succeed) {
+        mSensors = nullptr;
     }
 
-    sensors = nullptr;
-    return false;
+    return succeed;
+}
+
+void SensorsHidlEnvironmentV2_0::HidlTearDown() {
+    stopThread = true;
+
+    // Wake up the event queue so the poll thread can exit
+    mEventQueueFlag->wake(asBaseType(EventQueueFlagBits::READ_AND_PROCESS));
+    pollThread.join();
+
+    EventFlag::deleteEventFlag(&mEventQueueFlag);
 }
 
 void SensorsHidlEnvironmentV2_0::startPollingThread() {
     stopThread = false;
-    pollThread = std::thread(pollingThread, this, std::ref(stopThread));
-    events.reserve(128);
+    pollThread = std::thread(pollingThread, this);
+    events.reserve(MAX_RECEIVE_BUFFER_EVENT_COUNT);
 }
 
-void SensorsHidlEnvironmentV2_0::pollingThread(SensorsHidlEnvironmentV2_0* /*env*/,
-                                               std::atomic_bool& stop) {
+void SensorsHidlEnvironmentV2_0::readEvents() {
+    size_t availableEvents = mEventQueue->availableToRead();
+
+    if (availableEvents == 0) {
+        uint32_t eventFlagState = 0;
+
+        mEventQueueFlag->wait(asBaseType(EventQueueFlagBits::READ_AND_PROCESS), &eventFlagState);
+        availableEvents = mEventQueue->availableToRead();
+    }
+
+    size_t eventsToRead = std::min(availableEvents, mEventBuffer.size());
+    if (eventsToRead > 0) {
+        if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) {
+            for (const auto& e : mEventBuffer) {
+                addEvent(e);
+            }
+        }
+    }
+}
+
+void SensorsHidlEnvironmentV2_0::pollingThread(SensorsHidlEnvironmentV2_0* env) {
     ALOGD("polling thread start");
 
-    while (!stop) {
-        // TODO: implement reading event queue
-        stop = true;
+    while (!env->stopThread.load()) {
+        env->readEvents();
     }
+
     ALOGD("polling thread end");
 }
diff --git a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
index 43ddd23..7241923 100644
--- a/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
+++ b/sensors/2.0/vts/functional/SensorsHidlEnvironmentV2_0.h
@@ -21,12 +21,15 @@
 
 #include <android/hardware/sensors/1.0/types.h>
 #include <android/hardware/sensors/2.0/ISensors.h>
+#include <fmq/MessageQueue.h>
 #include <utils/StrongPointer.h>
 
+#include <array>
 #include <atomic>
 #include <memory>
 
 using ::android::sp;
+using ::android::hardware::MessageQueue;
 
 class SensorsHidlTest;
 class SensorsHidlEnvironmentV2_0 : public SensorsHidlEnvironmentBase {
@@ -42,18 +45,81 @@
         registerTestService<android::hardware::sensors::V2_0::ISensors>();
     }
 
+    virtual void HidlTearDown() override;
+
    private:
     friend SensorsHidlTest;
-    // sensors hidl service
-    sp<android::hardware::sensors::V2_0::ISensors> sensors;
 
-    SensorsHidlEnvironmentV2_0() {}
+    SensorsHidlEnvironmentV2_0() : mEventQueueFlag(nullptr) {}
 
+    /**
+     * Resets the HAL with new FMQs and a new Event Flag
+     *
+     * @return bool true if successful, false otherwise
+     */
     bool resetHal() override;
+
+    /**
+     * Starts the polling thread that reads sensor events from the Event FMQ
+     */
     void startPollingThread() override;
-    static void pollingThread(SensorsHidlEnvironmentV2_0* env, std::atomic_bool& stop);
+
+    /**
+     * Thread responsible for calling functions to read Event FMQ
+     *
+     * @param env SensorEnvironment to being polling for events on
+     */
+    static void pollingThread(SensorsHidlEnvironmentV2_0* env);
+
+    /**
+     * Reads and saves sensor events from the Event FMQ
+     */
+    void readEvents();
 
     GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentV2_0);
+
+    /**
+     * Pointer to the Sensors HAL Interface that allows the test to call HAL functions.
+     */
+    sp<android::hardware::sensors::V2_0::ISensors> mSensors;
+
+    /**
+     * Type used to simplify the creation of the Event FMQ
+     */
+    typedef MessageQueue<Event, ::android::hardware::kSynchronizedReadWrite> EventMessageQueue;
+
+    /**
+     * Type used to simplify the creation of the Wake Lock FMQ
+     */
+    typedef MessageQueue<uint32_t, ::android::hardware::kSynchronizedReadWrite> WakeLockQueue;
+
+    /**
+     * The Event FMQ where the test framework is able to read sensor events that the Sensors HAL
+     * has written.
+     */
+    std::unique_ptr<EventMessageQueue> mEventQueue;
+
+    /**
+     * The Wake Lock FMQ is used by the test to notify the Sensors HAL whenever it has processed
+     * WAKE_UP sensor events.
+     */
+    std::unique_ptr<WakeLockQueue> mWakeLockQueue;
+
+    /**
+     * The Event Queue Flag notifies the test framework when sensor events have been written to the
+     * Event FMQ by the Sensors HAL.
+     */
+    ::android::hardware::EventFlag* mEventQueueFlag;
+
+    /**
+     * The maximum number of sensor events that can be read from the Event FMQ at one time.
+     */
+    static constexpr size_t MAX_RECEIVE_BUFFER_EVENT_COUNT = 128;
+
+    /**
+     * An array that is used to store sensor events read from the Event FMQ
+     */
+    std::array<Event, MAX_RECEIVE_BUFFER_EVENT_COUNT> mEventBuffer;
 };
 
 #endif  // ANDROID_SENSORS_HIDL_ENVIRONMENT_V2_0_H
diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
index 204d7b2..7c6f010 100644
--- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
+++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp
@@ -42,36 +42,38 @@
     std::vector<SensorInfo> getSensorsList();
     // implementation wrapper
     Return<void> getSensorsList(ISensors::getSensorsList_cb _hidl_cb) override {
-        return S()->getSensorsList(_hidl_cb);
+        return getSensors()->getSensorsList(_hidl_cb);
     }
 
     Return<Result> activate(int32_t sensorHandle, bool enabled) override;
 
     Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
                          int64_t maxReportLatencyNs) override {
-        return S()->batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs);
+        return getSensors()->batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs);
     }
 
-    Return<Result> flush(int32_t sensorHandle) override { return S()->flush(sensorHandle); }
+    Return<Result> flush(int32_t sensorHandle) override {
+        return getSensors()->flush(sensorHandle);
+    }
 
     Return<Result> injectSensorData(const Event& event) override {
-        return S()->injectSensorData(event);
+        return getSensors()->injectSensorData(event);
     }
 
     Return<void> registerDirectChannel(const SharedMemInfo& mem,
                                        ISensors::registerDirectChannel_cb _hidl_cb) override;
 
     Return<Result> unregisterDirectChannel(int32_t channelHandle) override {
-        return S()->unregisterDirectChannel(channelHandle);
+        return getSensors()->unregisterDirectChannel(channelHandle);
     }
 
     Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
                                     ISensors::configDirectReport_cb _hidl_cb) override {
-        return S()->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb);
+        return getSensors()->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb);
     }
 
-    inline sp<::android::hardware::sensors::V2_0::ISensors>& S() {
-        return SensorsHidlEnvironmentV2_0::Instance()->sensors;
+    inline sp<::android::hardware::sensors::V2_0::ISensors>& getSensors() {
+        return SensorsHidlEnvironmentV2_0::Instance()->mSensors;
     }
 
     SensorsHidlEnvironmentBase* getEnvironment() override {
@@ -87,7 +89,7 @@
     if (enabled) {
         mSensorHandles.insert(sensorHandle);
     }
-    return S()->activate(sensorHandle, enabled);
+    return getSensors()->activate(sensorHandle, enabled);
 }
 
 Return<void> SensorsHidlTest::registerDirectChannel(const SharedMemInfo& mem,
@@ -95,7 +97,7 @@
     // If registeration of a channel succeeds, add the handle of channel to a set so that it can be
     // unregistered when test fails. Unregister a channel does not remove the handle on purpose.
     // Unregistering a channel more than once should not have negative effect.
-    S()->registerDirectChannel(mem, [&](auto result, auto channelHandle) {
+    getSensors()->registerDirectChannel(mem, [&](auto result, auto channelHandle) {
         if (result == Result::OK) {
             mDirectChannelHandles.insert(channelHandle);
         }
@@ -108,7 +110,7 @@
     SensorInfo ret;
 
     ret.type = (SensorType)-1;
-    S()->getSensorsList([&](const auto& list) {
+    getSensors()->getSensorsList([&](const auto& list) {
         const size_t count = list.size();
         for (size_t i = 0; i < count; ++i) {
             if (list[i].type == type) {
@@ -124,7 +126,7 @@
 std::vector<SensorInfo> SensorsHidlTest::getSensorsList() {
     std::vector<SensorInfo> ret;
 
-    S()->getSensorsList([&](const auto& list) {
+    getSensors()->getSensorsList([&](const auto& list) {
         const size_t count = list.size();
         ret.reserve(list.size());
         for (size_t i = 0; i < count; ++i) {
@@ -137,7 +139,7 @@
 
 // Test if sensor list returned is valid
 TEST_F(SensorsHidlTest, SensorListValid) {
-    S()->getSensorsList([&](const auto& list) {
+    getSensors()->getSensorsList([&](const auto& list) {
         const size_t count = list.size();
         for (size_t i = 0; i < count; ++i) {
             const auto& s = list[i];
@@ -191,9 +193,9 @@
         return;
     }
 
-    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
-    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::DATA_INJECTION));
-    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
+    ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
+    ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::DATA_INJECTION));
+    ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
 }
 
 // Test if sensor list returned is valid
@@ -213,8 +215,8 @@
         return;
     }
 
-    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
-    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::DATA_INJECTION));
+    ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
+    ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::DATA_INJECTION));
 
     for (const auto& s : sensorSupportInjection) {
         switch (s.type) {
@@ -230,14 +232,14 @@
                 Vec3 v = {1, 2, 3, SensorStatus::ACCURACY_HIGH};
                 dummy.u.vec3 = v;
 
-                EXPECT_EQ(Result::OK, S()->injectSensorData(dummy));
+                EXPECT_EQ(Result::OK, getSensors()->injectSensorData(dummy));
                 break;
             }
             default:
                 break;
         }
     }
-    ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
+    ASSERT_EQ(Result::OK, getSensors()->setOperationMode(OperationMode::NORMAL));
 }
 
 // Test if sensor hal can do UI speed accelerometer streaming properly
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
index 4a6f713..96e6085 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlEnvironmentBase.h
@@ -30,8 +30,8 @@
 class SensorsHidlEnvironmentBase : public ::testing::VtsHalHidlTargetTestEnvBase {
    public:
     using Event = ::android::hardware::sensors::V1_0::Event;
-    void HidlSetUp() override;
-    void HidlTearDown() override;
+    virtual void HidlSetUp() override;
+    virtual void HidlTearDown() override;
 
     // Get and clear all events collected so far (like "cat" shell command).
     // If output is nullptr, it clears all collected events.