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

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

Merge changes Ibbe27ced,I8f9704c5

* changes:
  inputflinger_tests: Put `FakeInputReaderPolicy` in its own file
  inputflinger_tests: Put `FakePointerController` in its own file
parents fc2e21f9 6b5fbc58
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ cc_test {
        "BlockingQueue_test.cpp",
        "EventHub_test.cpp",
        "FakeEventHub.cpp",
        "FakeInputReaderPolicy.cpp",
        "FakePointerController.cpp",
        "FocusResolver_test.cpp",
        "InputProcessor_test.cpp",
        "InputProcessorConverter_test.cpp",
+237 −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 "FakeInputReaderPolicy.h"

#include <android-base/thread_annotations.h>
#include <gtest/gtest.h>

#include "TestConstants.h"

namespace android {

void FakeInputReaderPolicy::assertInputDevicesChanged() {
    waitForInputDevices([](bool devicesChanged) {
        if (!devicesChanged) {
            FAIL() << "Timed out waiting for notifyInputDevicesChanged() to be called.";
        }
    });
}

void FakeInputReaderPolicy::assertInputDevicesNotChanged() {
    waitForInputDevices([](bool devicesChanged) {
        if (devicesChanged) {
            FAIL() << "Expected notifyInputDevicesChanged() to not be called.";
        }
    });
}

void FakeInputReaderPolicy::assertStylusGestureNotified(int32_t deviceId) {
    std::scoped_lock lock(mLock);
    ASSERT_TRUE(mStylusGestureNotified);
    ASSERT_EQ(deviceId, *mStylusGestureNotified);
    mStylusGestureNotified.reset();
}

void FakeInputReaderPolicy::assertStylusGestureNotNotified() {
    std::scoped_lock lock(mLock);
    ASSERT_FALSE(mStylusGestureNotified);
}

void FakeInputReaderPolicy::clearViewports() {
    mViewports.clear();
    mConfig.setDisplayViewports(mViewports);
}

std::optional<DisplayViewport> FakeInputReaderPolicy::getDisplayViewportByUniqueId(
        const std::string& uniqueId) const {
    return mConfig.getDisplayViewportByUniqueId(uniqueId);
}
std::optional<DisplayViewport> FakeInputReaderPolicy::getDisplayViewportByType(
        ViewportType type) const {
    return mConfig.getDisplayViewportByType(type);
}

std::optional<DisplayViewport> FakeInputReaderPolicy::getDisplayViewportByPort(
        uint8_t displayPort) const {
    return mConfig.getDisplayViewportByPort(displayPort);
}

void FakeInputReaderPolicy::addDisplayViewport(DisplayViewport viewport) {
    mViewports.push_back(std::move(viewport));
    mConfig.setDisplayViewports(mViewports);
}

void FakeInputReaderPolicy::addDisplayViewport(int32_t displayId, int32_t width, int32_t height,
                                               int32_t orientation, bool isActive,
                                               const std::string& uniqueId,
                                               std::optional<uint8_t> physicalPort,
                                               ViewportType type) {
    const bool isRotated =
            (orientation == DISPLAY_ORIENTATION_90 || orientation == DISPLAY_ORIENTATION_270);
    DisplayViewport v;
    v.displayId = displayId;
    v.orientation = orientation;
    v.logicalLeft = 0;
    v.logicalTop = 0;
    v.logicalRight = isRotated ? height : width;
    v.logicalBottom = isRotated ? width : height;
    v.physicalLeft = 0;
    v.physicalTop = 0;
    v.physicalRight = isRotated ? height : width;
    v.physicalBottom = isRotated ? width : height;
    v.deviceWidth = isRotated ? height : width;
    v.deviceHeight = isRotated ? width : height;
    v.isActive = isActive;
    v.uniqueId = uniqueId;
    v.physicalPort = physicalPort;
    v.type = type;

    addDisplayViewport(v);
}

bool FakeInputReaderPolicy::updateViewport(const DisplayViewport& viewport) {
    size_t count = mViewports.size();
    for (size_t i = 0; i < count; i++) {
        const DisplayViewport& currentViewport = mViewports[i];
        if (currentViewport.displayId == viewport.displayId) {
            mViewports[i] = viewport;
            mConfig.setDisplayViewports(mViewports);
            return true;
        }
    }
    // no viewport found.
    return false;
}

void FakeInputReaderPolicy::addExcludedDeviceName(const std::string& deviceName) {
    mConfig.excludedDeviceNames.push_back(deviceName);
}

void FakeInputReaderPolicy::addInputPortAssociation(const std::string& inputPort,
                                                    uint8_t displayPort) {
    mConfig.portAssociations.insert({inputPort, displayPort});
}

void FakeInputReaderPolicy::addInputUniqueIdAssociation(const std::string& inputUniqueId,
                                                        const std::string& displayUniqueId) {
    mConfig.uniqueIdAssociations.insert({inputUniqueId, displayUniqueId});
}

void FakeInputReaderPolicy::addDisabledDevice(int32_t deviceId) {
    mConfig.disabledDevices.insert(deviceId);
}

void FakeInputReaderPolicy::removeDisabledDevice(int32_t deviceId) {
    mConfig.disabledDevices.erase(deviceId);
}

void FakeInputReaderPolicy::setPointerController(
        std::shared_ptr<FakePointerController> controller) {
    mPointerController = std::move(controller);
}

const InputReaderConfiguration* FakeInputReaderPolicy::getReaderConfiguration() const {
    return &mConfig;
}

const std::vector<InputDeviceInfo>& FakeInputReaderPolicy::getInputDevices() const {
    return mInputDevices;
}

TouchAffineTransformation FakeInputReaderPolicy::getTouchAffineTransformation(
        const std::string& inputDeviceDescriptor, int32_t surfaceRotation) {
    return transform;
}

void FakeInputReaderPolicy::setTouchAffineTransformation(const TouchAffineTransformation t) {
    transform = t;
}

PointerCaptureRequest FakeInputReaderPolicy::setPointerCapture(bool enabled) {
    mConfig.pointerCaptureRequest = {enabled, mNextPointerCaptureSequenceNumber++};
    return mConfig.pointerCaptureRequest;
}

void FakeInputReaderPolicy::setShowTouches(bool enabled) {
    mConfig.showTouches = enabled;
}

void FakeInputReaderPolicy::setDefaultPointerDisplayId(int32_t pointerDisplayId) {
    mConfig.defaultPointerDisplayId = pointerDisplayId;
}

void FakeInputReaderPolicy::setPointerGestureEnabled(bool enabled) {
    mConfig.pointerGesturesEnabled = enabled;
}

float FakeInputReaderPolicy::getPointerGestureMovementSpeedRatio() {
    return mConfig.pointerGestureMovementSpeedRatio;
}

float FakeInputReaderPolicy::getPointerGestureZoomSpeedRatio() {
    return mConfig.pointerGestureZoomSpeedRatio;
}

void FakeInputReaderPolicy::setVelocityControlParams(const VelocityControlParameters& params) {
    mConfig.pointerVelocityControlParameters = params;
    mConfig.wheelVelocityControlParameters = params;
}

void FakeInputReaderPolicy::getReaderConfiguration(InputReaderConfiguration* outConfig) {
    *outConfig = mConfig;
}

std::shared_ptr<PointerControllerInterface> FakeInputReaderPolicy::obtainPointerController(
        int32_t /*deviceId*/) {
    return mPointerController;
}

void FakeInputReaderPolicy::notifyInputDevicesChanged(
        const std::vector<InputDeviceInfo>& inputDevices) {
    std::scoped_lock<std::mutex> lock(mLock);
    mInputDevices = inputDevices;
    mInputDevicesChanged = true;
    mDevicesChangedCondition.notify_all();
}

std::shared_ptr<KeyCharacterMap> FakeInputReaderPolicy::getKeyboardLayoutOverlay(
        const InputDeviceIdentifier&) {
    return nullptr;
}

std::string FakeInputReaderPolicy::getDeviceAlias(const InputDeviceIdentifier&) {
    return "";
}

void FakeInputReaderPolicy::waitForInputDevices(std::function<void(bool)> processDevicesChanged) {
    std::unique_lock<std::mutex> lock(mLock);
    base::ScopedLockAssertion assumeLocked(mLock);

    const bool devicesChanged =
            mDevicesChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
                return mInputDevicesChanged;
            });
    ASSERT_NO_FATAL_FAILURE(processDevicesChanged(devicesChanged));
    mInputDevicesChanged = false;
}

void FakeInputReaderPolicy::notifyStylusGestureStarted(int32_t deviceId, nsecs_t eventTime) {
    std::scoped_lock<std::mutex> lock(mLock);
    mStylusGestureNotified = deviceId;
}

} // namespace android
+101 −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 <condition_variable>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <vector>

#include <InputDevice.h>
#include <InputReaderBase.h>

#include "FakePointerController.h"
#include "input/DisplayViewport.h"
#include "input/InputDevice.h"

namespace android {

class FakeInputReaderPolicy : public InputReaderPolicyInterface {
protected:
    virtual ~FakeInputReaderPolicy() {}

public:
    FakeInputReaderPolicy() {}

    void assertInputDevicesChanged();
    void assertInputDevicesNotChanged();
    void assertStylusGestureNotified(int32_t deviceId);
    void assertStylusGestureNotNotified();

    virtual void clearViewports();
    std::optional<DisplayViewport> getDisplayViewportByUniqueId(const std::string& uniqueId) const;
    std::optional<DisplayViewport> getDisplayViewportByType(ViewportType type) const;
    std::optional<DisplayViewport> getDisplayViewportByPort(uint8_t displayPort) const;
    void addDisplayViewport(DisplayViewport viewport);
    void addDisplayViewport(int32_t displayId, int32_t width, int32_t height, int32_t orientation,
                            bool isActive, const std::string& uniqueId,
                            std::optional<uint8_t> physicalPort, ViewportType type);
    bool updateViewport(const DisplayViewport& viewport);
    void addExcludedDeviceName(const std::string& deviceName);
    void addInputPortAssociation(const std::string& inputPort, uint8_t displayPort);
    void addInputUniqueIdAssociation(const std::string& inputUniqueId,
                                     const std::string& displayUniqueId);
    void addDisabledDevice(int32_t deviceId);
    void removeDisabledDevice(int32_t deviceId);
    void setPointerController(std::shared_ptr<FakePointerController> controller);
    const InputReaderConfiguration* getReaderConfiguration() const;
    const std::vector<InputDeviceInfo>& getInputDevices() const;
    TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
                                                           int32_t surfaceRotation);
    void setTouchAffineTransformation(const TouchAffineTransformation t);
    PointerCaptureRequest setPointerCapture(bool enabled);
    void setShowTouches(bool enabled);
    void setDefaultPointerDisplayId(int32_t pointerDisplayId);
    void setPointerGestureEnabled(bool enabled);
    float getPointerGestureMovementSpeedRatio();
    float getPointerGestureZoomSpeedRatio();
    void setVelocityControlParams(const VelocityControlParameters& params);

private:
    void getReaderConfiguration(InputReaderConfiguration* outConfig) override;
    std::shared_ptr<PointerControllerInterface> obtainPointerController(
            int32_t /*deviceId*/) override;
    void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override;
    std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
            const InputDeviceIdentifier&) override;
    std::string getDeviceAlias(const InputDeviceIdentifier&) override;
    void waitForInputDevices(std::function<void(bool)> processDevicesChanged);
    void notifyStylusGestureStarted(int32_t deviceId, nsecs_t eventTime) override;

    std::mutex mLock;
    std::condition_variable mDevicesChangedCondition;

    InputReaderConfiguration mConfig;
    std::shared_ptr<FakePointerController> mPointerController;
    std::vector<InputDeviceInfo> mInputDevices GUARDED_BY(mLock);
    bool mInputDevicesChanged GUARDED_BY(mLock){false};
    std::vector<DisplayViewport> mViewports;
    TouchAffineTransformation transform;
    std::optional<int32_t /*deviceId*/> mStylusGestureNotified GUARDED_BY(mLock){};

    uint32_t mNextPointerCaptureSequenceNumber{0};
};

} // namespace android
+93 −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 "FakePointerController.h"

namespace android {

void FakePointerController::setBounds(float minX, float minY, float maxX, float maxY) {
    mHaveBounds = true;
    mMinX = minX;
    mMinY = minY;
    mMaxX = maxX;
    mMaxY = maxY;
}

const std::map<int32_t, std::vector<int32_t>>& FakePointerController::getSpots() {
    return mSpotsByDisplay;
}

void FakePointerController::setPosition(float x, float y) {
    mX = x;
    mY = y;
}

void FakePointerController::setButtonState(int32_t buttonState) {
    mButtonState = buttonState;
}

int32_t FakePointerController::getButtonState() const {
    return mButtonState;
}

void FakePointerController::getPosition(float* outX, float* outY) const {
    *outX = mX;
    *outY = mY;
}

int32_t FakePointerController::getDisplayId() const {
    return mDisplayId;
}

void FakePointerController::setDisplayViewport(const DisplayViewport& viewport) {
    mDisplayId = viewport.displayId;
}

bool FakePointerController::getBounds(float* outMinX, float* outMinY, float* outMaxX,
                                      float* outMaxY) const {
    *outMinX = mMinX;
    *outMinY = mMinY;
    *outMaxX = mMaxX;
    *outMaxY = mMaxY;
    return mHaveBounds;
}

void FakePointerController::move(float deltaX, float deltaY) {
    mX += deltaX;
    if (mX < mMinX) mX = mMinX;
    if (mX > mMaxX) mX = mMaxX;
    mY += deltaY;
    if (mY < mMinY) mY = mMinY;
    if (mY > mMaxY) mY = mMaxY;
}

void FakePointerController::setSpots(const PointerCoords*, const uint32_t*, BitSet32 spotIdBits,
                                     int32_t displayId) {
    std::vector<int32_t> newSpots;
    // Add spots for fingers that are down.
    for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) {
        uint32_t id = idBits.clearFirstMarkedBit();
        newSpots.push_back(id);
    }

    mSpotsByDisplay[displayId] = newSpots;
}

void FakePointerController::clearSpots() {
    mSpotsByDisplay.clear();
}

} // namespace android
+60 −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 <PointerControllerInterface.h>
#include <gui/constants.h>
#include <input/DisplayViewport.h>
#include <input/Input.h>
#include <utils/BitSet.h>

namespace android {

class FakePointerController : public PointerControllerInterface {
public:
    virtual ~FakePointerController() {}

    void setBounds(float minX, float minY, float maxX, float maxY);
    const std::map<int32_t, std::vector<int32_t>>& getSpots();

    void setPosition(float x, float y) override;
    void setButtonState(int32_t buttonState) override;
    int32_t getButtonState() const override;
    void getPosition(float* outX, float* outY) const override;
    int32_t getDisplayId() const override;
    void setDisplayViewport(const DisplayViewport& viewport) override;

private:
    bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const override;
    void move(float deltaX, float deltaY) override;
    void fade(Transition) override {}
    void unfade(Transition) override {}
    void setPresentation(Presentation) override {}
    void setSpots(const PointerCoords*, const uint32_t*, BitSet32 spotIdBits,
                  int32_t displayId) override;
    void clearSpots() override;

    bool mHaveBounds{false};
    float mMinX{0}, mMinY{0}, mMaxX{0}, mMaxY{0};
    float mX{0}, mY{0};
    int32_t mButtonState{0};
    int32_t mDisplayId{ADISPLAY_ID_DEFAULT};

    std::map<int32_t, std::vector<int32_t>> mSpotsByDisplay;
};

} // namespace android
Loading