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