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

Commit 7444d85f authored by Harry Cutts's avatar Harry Cutts Committed by Android (Google) Code Review
Browse files

Merge "inputflinger_tests: Put `InstrumentedInputReader` in its own file"

parents 3d54c455 144ff545
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ cc_test {
        "InputProcessorConverter_test.cpp",
        "InputDispatcher_test.cpp",
        "InputReader_test.cpp",
        "InstrumentedInputReader.cpp",
        "LatencyTracker_test.cpp",
        "NotifyArgs_test.cpp",
        "PreferStylusOverTouch_test.cpp",
+1 −111
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include "FakeEventHub.h"
#include "FakeInputReaderPolicy.h"
#include "FakePointerController.h"
#include "InstrumentedInputReader.h"
#include "TestConstants.h"
#include "android/hardware/input/InputDeviceCountryCode.h"
#include "input/DisplayViewport.h"
@@ -345,117 +346,6 @@ private:
    }
};


// --- InstrumentedInputReader ---

class InstrumentedInputReader : public InputReader {
    std::queue<std::shared_ptr<InputDevice>> mNextDevices;

public:
    InstrumentedInputReader(std::shared_ptr<EventHubInterface> eventHub,
                            const sp<InputReaderPolicyInterface>& policy,
                            InputListenerInterface& listener)
          : InputReader(eventHub, policy, listener), mFakeContext(this) {}

    virtual ~InstrumentedInputReader() {}

    void pushNextDevice(std::shared_ptr<InputDevice> device) { mNextDevices.push(device); }

    std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
                                           const std::string& location = "") {
        InputDeviceIdentifier identifier;
        identifier.name = name;
        identifier.location = location;
        int32_t generation = deviceId + 1;
        return std::make_shared<InputDevice>(&mFakeContext, deviceId, generation, identifier);
    }

    // Make the protected loopOnce method accessible to tests.
    using InputReader::loopOnce;

protected:
    virtual std::shared_ptr<InputDevice> createDeviceLocked(int32_t eventHubId,
                                                            const InputDeviceIdentifier& identifier)
            REQUIRES(mLock) {
        if (!mNextDevices.empty()) {
            std::shared_ptr<InputDevice> device(std::move(mNextDevices.front()));
            mNextDevices.pop();
            return device;
        }
        return InputReader::createDeviceLocked(eventHubId, identifier);
    }

    // --- FakeInputReaderContext ---
    class FakeInputReaderContext : public ContextImpl {
        int32_t mGlobalMetaState;
        bool mUpdateGlobalMetaStateWasCalled;
        int32_t mGeneration;
        std::optional<nsecs_t> mRequestedTimeout;
        std::vector<InputDeviceInfo> mExternalStylusDevices;

    public:
        FakeInputReaderContext(InputReader* reader)
              : ContextImpl(reader),
                mGlobalMetaState(0),
                mUpdateGlobalMetaStateWasCalled(false),
                mGeneration(1) {}

        virtual ~FakeInputReaderContext() {}

        void assertUpdateGlobalMetaStateWasCalled() {
            ASSERT_TRUE(mUpdateGlobalMetaStateWasCalled)
                    << "Expected updateGlobalMetaState() to have been called.";
            mUpdateGlobalMetaStateWasCalled = false;
        }

        void setGlobalMetaState(int32_t state) { mGlobalMetaState = state; }

        uint32_t getGeneration() { return mGeneration; }

        void updateGlobalMetaState() override {
            mUpdateGlobalMetaStateWasCalled = true;
            ContextImpl::updateGlobalMetaState();
        }

        int32_t getGlobalMetaState() override {
            return mGlobalMetaState | ContextImpl::getGlobalMetaState();
        }

        int32_t bumpGeneration() override {
            mGeneration = ContextImpl::bumpGeneration();
            return mGeneration;
        }

        void requestTimeoutAtTime(nsecs_t when) override { mRequestedTimeout = when; }

        void assertTimeoutWasRequested(nsecs_t when) {
            ASSERT_TRUE(mRequestedTimeout) << "Expected timeout at time " << when
                                           << " but there was no timeout requested.";
            ASSERT_EQ(when, *mRequestedTimeout);
            mRequestedTimeout.reset();
        }

        void assertTimeoutWasNotRequested() {
            ASSERT_FALSE(mRequestedTimeout) << "Expected no timeout to have been requested,"
                                               " but one was requested at time "
                                            << *mRequestedTimeout;
        }

        void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) override {
            outDevices = mExternalStylusDevices;
        }

        void setExternalStylusDevices(std::vector<InputDeviceInfo>&& devices) {
            mExternalStylusDevices = devices;
        }
    } mFakeContext;

    friend class InputReaderTest;

public:
    FakeInputReaderContext* getContext() { return &mFakeContext; }
};

// --- InputReaderPolicyTest ---
class InputReaderPolicyTest : public testing::Test {
protected:
+50 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "InstrumentedInputReader.h"

namespace android {

InstrumentedInputReader::InstrumentedInputReader(std::shared_ptr<EventHubInterface> eventHub,
                                                 const sp<InputReaderPolicyInterface>& policy,
                                                 InputListenerInterface& listener)
      : InputReader(eventHub, policy, listener), mFakeContext(this) {}

void InstrumentedInputReader::pushNextDevice(std::shared_ptr<InputDevice> device) {
    mNextDevices.push(device);
}

std::shared_ptr<InputDevice> InstrumentedInputReader::newDevice(int32_t deviceId,
                                                                const std::string& name,
                                                                const std::string& location) {
    InputDeviceIdentifier identifier;
    identifier.name = name;
    identifier.location = location;
    int32_t generation = deviceId + 1;
    return std::make_shared<InputDevice>(&mFakeContext, deviceId, generation, identifier);
}

std::shared_ptr<InputDevice> InstrumentedInputReader::createDeviceLocked(
        int32_t eventHubId, const InputDeviceIdentifier& identifier) REQUIRES(mLock) {
    if (!mNextDevices.empty()) {
        std::shared_ptr<InputDevice> device(std::move(mNextDevices.front()));
        mNextDevices.pop();
        return device;
    }
    return InputReader::createDeviceLocked(eventHubId, identifier);
}

} // namespace android
+123 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <memory>
#include <queue>
#include <string>

#include <InputDevice.h>
#include <InputReader.h>
#include <gtest/gtest.h>
#include <utils/StrongPointer.h>

namespace android {

class InstrumentedInputReader : public InputReader {
public:
    InstrumentedInputReader(std::shared_ptr<EventHubInterface> eventHub,
                            const sp<InputReaderPolicyInterface>& policy,
                            InputListenerInterface& listener);
    virtual ~InstrumentedInputReader() {}

    void pushNextDevice(std::shared_ptr<InputDevice> device);

    std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
                                           const std::string& location = "");

    // Make the protected loopOnce method accessible to tests.
    using InputReader::loopOnce;

protected:
    virtual std::shared_ptr<InputDevice> createDeviceLocked(
            int32_t eventHubId, const InputDeviceIdentifier& identifier);

    class FakeInputReaderContext : public ContextImpl {
    public:
        FakeInputReaderContext(InputReader* reader)
              : ContextImpl(reader),
                mGlobalMetaState(0),
                mUpdateGlobalMetaStateWasCalled(false),
                mGeneration(1) {}

        virtual ~FakeInputReaderContext() {}

        void assertUpdateGlobalMetaStateWasCalled() {
            ASSERT_TRUE(mUpdateGlobalMetaStateWasCalled)
                    << "Expected updateGlobalMetaState() to have been called.";
            mUpdateGlobalMetaStateWasCalled = false;
        }

        void setGlobalMetaState(int32_t state) { mGlobalMetaState = state; }

        uint32_t getGeneration() { return mGeneration; }

        void updateGlobalMetaState() override {
            mUpdateGlobalMetaStateWasCalled = true;
            ContextImpl::updateGlobalMetaState();
        }

        int32_t getGlobalMetaState() override {
            return mGlobalMetaState | ContextImpl::getGlobalMetaState();
        }

        int32_t bumpGeneration() override {
            mGeneration = ContextImpl::bumpGeneration();
            return mGeneration;
        }

        void requestTimeoutAtTime(nsecs_t when) override { mRequestedTimeout = when; }

        void assertTimeoutWasRequested(nsecs_t when) {
            ASSERT_TRUE(mRequestedTimeout) << "Expected timeout at time " << when
                                           << " but there was no timeout requested.";
            ASSERT_EQ(when, *mRequestedTimeout);
            mRequestedTimeout.reset();
        }

        void assertTimeoutWasNotRequested() {
            ASSERT_FALSE(mRequestedTimeout) << "Expected no timeout to have been requested,"
                                               " but one was requested at time "
                                            << *mRequestedTimeout;
        }

        void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) override {
            outDevices = mExternalStylusDevices;
        }

        void setExternalStylusDevices(std::vector<InputDeviceInfo>&& devices) {
            mExternalStylusDevices = devices;
        }

    private:
        int32_t mGlobalMetaState;
        bool mUpdateGlobalMetaStateWasCalled;
        int32_t mGeneration;
        std::optional<nsecs_t> mRequestedTimeout;
        std::vector<InputDeviceInfo> mExternalStylusDevices;
    } mFakeContext;

    friend class InputReaderTest;

public:
    FakeInputReaderContext* getContext() { return &mFakeContext; }

private:
    std::queue<std::shared_ptr<InputDevice>> mNextDevices;
};

} // namespace android