Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fdd1bb4 authored by Brian Stack's avatar Brian Stack
Browse files

Implement VTS tests for Sensors 2.0 flush

Bug: 115969174
Test: Tests pass against default implementation
Change-Id: Icb8c3d7776b8460d502bfec251ded061f978bec9
parent 1b7796d0
Loading
Loading
Loading
Loading
+166 −0
Original line number Diff line number Diff line
@@ -25,15 +25,56 @@
#include <utils/SystemClock.h>

#include <cinttypes>
#include <condition_variable>
#include <map>
#include <vector>

using ::android::sp;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::sensors::V1_0::MetaDataEventType;
using ::android::hardware::sensors::V1_0::OperationMode;
using ::android::hardware::sensors::V1_0::SensorStatus;
using ::android::hardware::sensors::V1_0::Vec3;

class EventCallback : public IEventCallback {
   public:
    void onEvent(const ::android::hardware::sensors::V1_0::Event& event) override {
        if (event.sensorType == SensorType::ADDITIONAL_INFO &&
            event.u.meta.what == MetaDataEventType::META_DATA_FLUSH_COMPLETE) {
            std::unique_lock<std::recursive_mutex> lock(mFlushMutex);
            mFlushMap[event.sensorHandle]++;
            mFlushCV.notify_all();
        }
    }

    int32_t getFlushCount(int32_t sensorHandle) {
        std::unique_lock<std::recursive_mutex> lock(mFlushMutex);
        return mFlushMap[sensorHandle];
    }

    void waitForFlushEvents(const std::vector<SensorInfo>& sensorsToWaitFor,
                            int32_t numCallsToFlush, int64_t timeoutMs) {
        std::unique_lock<std::recursive_mutex> lock(mFlushMutex);
        mFlushCV.wait_for(lock, std::chrono::milliseconds(timeoutMs),
                          [&] { return flushesReceived(sensorsToWaitFor, numCallsToFlush); });
    }

   protected:
    bool flushesReceived(const std::vector<SensorInfo>& sensorsToWaitFor, int32_t numCallsToFlush) {
        for (const SensorInfo& sensor : sensorsToWaitFor) {
            if (getFlushCount(sensor.sensorHandle) < numCallsToFlush) {
                return false;
            }
        }
        return true;
    }

    std::map<int32_t, int32_t> mFlushMap;
    std::recursive_mutex mFlushMutex;
    std::condition_variable_any mFlushCV;
};

// The main test class for SENSORS HIDL HAL.

class SensorsHidlTest : public SensorsHidlTestBase {
@@ -80,8 +121,17 @@ class SensorsHidlTest : public SensorsHidlTestBase {
        return SensorsHidlEnvironmentV2_0::Instance();
    }

    // Test helpers
    void runSingleFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
                            int32_t expectedFlushCount, Result expectedResponse);
    void runFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
                      int32_t flushCalls, int32_t expectedFlushCount, Result expectedResponse);

    // Helper functions
    void activateAllSensors(bool enable);
    std::vector<SensorInfo> getNonOneShotSensors();
    std::vector<SensorInfo> getOneShotSensors();
    int32_t getInvalidSensorHandle();
};

Return<Result> SensorsHidlTest::activate(int32_t sensorHandle, bool enabled) {
@@ -140,6 +190,35 @@ std::vector<SensorInfo> SensorsHidlTest::getSensorsList() {
    return ret;
}

std::vector<SensorInfo> SensorsHidlTest::getNonOneShotSensors() {
    std::vector<SensorInfo> sensors;
    for (const SensorInfo& info : getSensorsList()) {
        if (extractReportMode(info.flags) != SensorFlagBits::ONE_SHOT_MODE) {
            sensors.push_back(info);
        }
    }
    return sensors;
}

std::vector<SensorInfo> SensorsHidlTest::getOneShotSensors() {
    std::vector<SensorInfo> sensors;
    for (const SensorInfo& info : getSensorsList()) {
        if (extractReportMode(info.flags) == SensorFlagBits::ONE_SHOT_MODE) {
            sensors.push_back(info);
        }
    }
    return sensors;
}

int32_t SensorsHidlTest::getInvalidSensorHandle() {
    // Find a sensor handle that does not exist in the sensor list
    int32_t maxHandle = 0;
    for (const SensorInfo& sensor : getSensorsList()) {
        maxHandle = max(maxHandle, sensor.sensorHandle);
    }
    return maxHandle + 1;
}

// Test if sensor list returned is valid
TEST_F(SensorsHidlTest, SensorListValid) {
    getSensors()->getSensorsList([&](const auto& list) {
@@ -488,6 +567,93 @@ TEST_F(SensorsHidlTest, CallInitializeTwice) {
    activateAllSensors(false);
}

void SensorsHidlTest::runSingleFlushTest(const std::vector<SensorInfo>& sensors,
                                         bool activateSensor, int32_t expectedFlushCount,
                                         Result expectedResponse) {
    runFlushTest(sensors, activateSensor, 1 /* flushCalls */, expectedFlushCount, expectedResponse);
}

void SensorsHidlTest::runFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
                                   int32_t flushCalls, int32_t expectedFlushCount,
                                   Result expectedResponse) {
    EventCallback callback;
    getEnvironment()->registerCallback(&callback);

    for (const SensorInfo& sensor : sensors) {
        // Configure and activate the sensor
        batch(sensor.sensorHandle, sensor.maxDelay, 0 /* maxReportLatencyNs */);
        activate(sensor.sensorHandle, activateSensor);

        // Flush the sensor
        for (int32_t i = 0; i < flushCalls; i++) {
            Result flushResult = flush(sensor.sensorHandle);
            ASSERT_EQ(flushResult, expectedResponse);
        }
        activate(sensor.sensorHandle, false);
    }

    // Wait up to one second for the flush events
    callback.waitForFlushEvents(sensors, flushCalls, 1000 /* timeoutMs */);
    getEnvironment()->unregisterCallback();

    // Check that the correct number of flushes are present for each sensor
    for (const SensorInfo& sensor : sensors) {
        ASSERT_EQ(callback.getFlushCount(sensor.sensorHandle), expectedFlushCount);
    }
}

TEST_F(SensorsHidlTest, FlushSensor) {
    // Find a sensor that is not a one-shot sensor
    std::vector<SensorInfo> sensors = getNonOneShotSensors();
    if (sensors.size() == 0) {
        return;
    }

    constexpr int32_t kFlushes = 5;
    runSingleFlushTest(sensors, true /* activateSensor */, 1 /* expectedFlushCount */, Result::OK);
    runFlushTest(sensors, true /* activateSensor */, kFlushes, kFlushes, Result::OK);
}

TEST_F(SensorsHidlTest, FlushOneShotSensor) {
    // Find a sensor that is a one-shot sensor
    std::vector<SensorInfo> sensors = getOneShotSensors();
    if (sensors.size() == 0) {
        return;
    }

    runSingleFlushTest(sensors, true /* activateSensor */, 0 /* expectedFlushCount */,
                       Result::BAD_VALUE);
}

TEST_F(SensorsHidlTest, FlushInactiveSensor) {
    // Attempt to find a non-one shot sensor, then a one-shot sensor if necessary
    std::vector<SensorInfo> sensors = getNonOneShotSensors();
    if (sensors.size() == 0) {
        sensors = getOneShotSensors();
        if (sensors.size() == 0) {
            return;
        }
    }

    runSingleFlushTest(sensors, false /* activateSensor */, 0 /* expectedFlushCount */,
                       Result::BAD_VALUE);
}

TEST_F(SensorsHidlTest, FlushNonexistentSensor) {
    SensorInfo sensor;
    std::vector<SensorInfo> sensors = getNonOneShotSensors();
    if (sensors.size() == 0) {
        sensors = getOneShotSensors();
        if (sensors.size() == 0) {
            return;
        }
    }
    sensor = sensors.front();
    sensor.sensorHandle = getInvalidSensorHandle();
    runSingleFlushTest(std::vector<SensorInfo>{sensor}, false /* activateSensor */,
                       0 /* expectedFlushCount */, Result::BAD_VALUE);
}

int main(int argc, char** argv) {
    ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironmentV2_0::Instance());
    ::testing::InitGoogleTest(&argc, argv);
+14 −0
Original line number Diff line number Diff line
@@ -50,4 +50,18 @@ void SensorsHidlEnvironmentBase::addEvent(const Event& ev) {
    if (collectionEnabled) {
        events.push_back(ev);
    }

    if (mCallback != nullptr) {
        mCallback->onEvent(ev);
    }
}

void SensorsHidlEnvironmentBase::registerCallback(IEventCallback* callback) {
    std::lock_guard<std::mutex> lock(events_mutex);
    mCallback = callback;
}

void SensorsHidlEnvironmentBase::unregisterCallback() {
    std::lock_guard<std::mutex> lock(events_mutex);
    mCallback = nullptr;
}
 No newline at end of file
+12 −1
Original line number Diff line number Diff line
@@ -27,6 +27,12 @@
#include <thread>
#include <vector>

class IEventCallback {
   public:
    virtual ~IEventCallback() = default;
    virtual void onEvent(const ::android::hardware::sensors::V1_0::Event& event) = 0;
};

class SensorsHidlEnvironmentBase : public ::testing::VtsHalHidlTargetTestEnvBase {
   public:
    using Event = ::android::hardware::sensors::V1_0::Event;
@@ -40,8 +46,11 @@ class SensorsHidlEnvironmentBase : public ::testing::VtsHalHidlTargetTestEnvBase
    // set sensor event collection status
    void setCollection(bool enable);

    void registerCallback(IEventCallback* callback);
    void unregisterCallback();

   protected:
    SensorsHidlEnvironmentBase() {}
    SensorsHidlEnvironmentBase() : collectionEnabled(false), mCallback(nullptr) {}

    void addEvent(const Event& ev);

@@ -54,6 +63,8 @@ class SensorsHidlEnvironmentBase : public ::testing::VtsHalHidlTargetTestEnvBase
    std::vector<Event> events;
    std::mutex events_mutex;

    IEventCallback* mCallback;

    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironmentBase);
};