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

Commit 3d8a3946 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Initialize Sensors Test Environment"

parents a95adb1d 85c8b319
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ cc_test {
        "android.hardware.graphics.mapper@2.0",
        "android.hardware.sensors@1.0",
        "android.hardware.sensors@2.0",
        "libfmq",
        "VtsHalSensorsTargetTestUtils",
    ],
}
+74 −26
Original line number Diff line number Diff line
@@ -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";
        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]);
        // 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 (!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::readEvents() {
    size_t availableEvents = mEventQueue->availableToRead();

    if (availableEvents == 0) {
        uint32_t eventFlagState = 0;

        mEventQueueFlag->wait(asBaseType(EventQueueFlagBits::READ_AND_PROCESS), &eventFlagState);
        availableEvents = mEventQueue->availableToRead();
    }

void SensorsHidlEnvironmentV2_0::pollingThread(SensorsHidlEnvironmentV2_0* /*env*/,
                                               std::atomic_bool& stop) {
    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");
}
+70 −4
Original line number Diff line number Diff line
@@ -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
+22 −20
Original line number Diff line number Diff line
@@ -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
+2 −2
Original line number Diff line number Diff line
@@ -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.