Merge "Initialize Sensors Test Environment"

This commit is contained in:
TreeHugger Robot
2018-10-18 03:19:34 +00:00
committed by Android (Google) Code Review
5 changed files with 169 additions and 52 deletions

View File

@@ -26,6 +26,7 @@ cc_test {
"android.hardware.graphics.mapper@2.0",
"android.hardware.sensors@1.0",
"android.hardware.sensors@2.0",
"libfmq",
"VtsHalSensorsTargetTestUtils",
],
}

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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

View File

@@ -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.