mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 10:44:41 +00:00
Merge "Initialize Sensors Test Environment"
This commit is contained in:
committed by
Android (Google) Code Review
commit
3d8a394623
@@ -26,6 +26,7 @@ cc_test {
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.sensors@1.0",
|
||||
"android.hardware.sensors@2.0",
|
||||
"libfmq",
|
||||
"VtsHalSensorsTargetTestUtils",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -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 @@ bool SensorsHidlEnvironmentV2_0::resetHal() {
|
||||
}
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
@@ -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 @@ class SensorsHidlEnvironmentV2_0 : public SensorsHidlEnvironmentBase {
|
||||
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
|
||||
|
||||
@@ -42,36 +42,38 @@ class SensorsHidlTest : public SensorsHidlTestBase {
|
||||
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 @@ Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
|
||||
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 @@ Return<void> SensorsHidlTest::registerDirectChannel(const SharedMemInfo& mem,
|
||||
// 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 SensorsHidlTest::defaultSensorByType(SensorType type) {
|
||||
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 @@ SensorInfo SensorsHidlTest::defaultSensorByType(SensorType type) {
|
||||
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 @@ std::vector<SensorInfo> SensorsHidlTest::getSensorsList() {
|
||||
|
||||
// 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 @@ TEST_F(SensorsHidlTest, SetOperationMode) {
|
||||
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 @@ TEST_F(SensorsHidlTest, InjectSensorEventData) {
|
||||
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 @@ TEST_F(SensorsHidlTest, InjectSensorEventData) {
|
||||
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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user