blob: 9e9371248e44939408b4333fd3cdc81b69f89ebd [file] [log] [blame]
/*
* 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"
#include "ui/Rotation.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::unique_lock lock(mLock);
base::ScopedLockAssertion assumeLocked(mLock);
const bool success =
mStylusGestureNotifiedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
return mDeviceIdOfNotifiedStylusGesture.has_value();
});
ASSERT_TRUE(success) << "Timed out waiting for stylus gesture to be notified";
ASSERT_EQ(deviceId, *mDeviceIdOfNotifiedStylusGesture);
mDeviceIdOfNotifiedStylusGesture.reset();
}
void FakeInputReaderPolicy::assertStylusGestureNotNotified() {
std::scoped_lock lock(mLock);
ASSERT_FALSE(mDeviceIdOfNotifiedStylusGesture);
}
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,
ui::Rotation orientation, bool isActive,
const std::string& uniqueId,
std::optional<uint8_t> physicalPort,
ViewportType type) {
const bool isRotated = orientation == ui::ROTATION_90 || orientation == ui::ROTATION_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::addDeviceTypeAssociation(const std::string& inputPort,
const std::string& type) {
mConfig.deviceTypeAssociations.insert({inputPort, type});
}
void FakeInputReaderPolicy::addInputUniqueIdAssociation(const std::string& inputUniqueId,
const std::string& displayUniqueId) {
mConfig.uniqueIdAssociations.insert({inputUniqueId, displayUniqueId});
}
void FakeInputReaderPolicy::addKeyboardLayoutAssociation(const std::string& inputUniqueId,
const KeyboardLayoutInfo& layoutInfo) {
mConfig.keyboardLayoutAssociations.insert({inputUniqueId, layoutInfo});
}
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 {
std::scoped_lock lock(mLock);
return mInputDevices;
}
TouchAffineTransformation FakeInputReaderPolicy::getTouchAffineTransformation(
const std::string& inputDeviceDescriptor, ui::Rotation 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::setStylusButtonMotionEventsEnabled(bool enabled) {
mConfig.stylusButtonMotionEventsEnabled = enabled;
}
void FakeInputReaderPolicy::setStylusPointerIconEnabled(bool enabled) {
mConfig.stylusPointerIconEnabled = enabled;
}
void FakeInputReaderPolicy::setIsInputMethodConnectionActive(bool active) {
mIsInputMethodConnectionActive = active;
}
bool FakeInputReaderPolicy::isInputMethodConnectionActive() {
return mIsInputMethodConnectionActive;
}
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 lock(mLock);
mInputDevices = inputDevices;
mInputDevicesChanged = true;
mDevicesChangedCondition.notify_all();
}
std::shared_ptr<KeyCharacterMap> FakeInputReaderPolicy::getKeyboardLayoutOverlay(
const InputDeviceIdentifier&, const std::optional<KeyboardLayoutInfo>) {
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 lock(mLock);
mDeviceIdOfNotifiedStylusGesture = deviceId;
mStylusGestureNotifiedCondition.notify_all();
}
std::optional<DisplayViewport> FakeInputReaderPolicy::getPointerViewportForAssociatedDisplay(
int32_t associatedDisplayId) {
if (associatedDisplayId == ADISPLAY_ID_NONE) {
associatedDisplayId = mConfig.defaultPointerDisplayId;
}
for (auto& viewport : mViewports) {
if (viewport.displayId == associatedDisplayId) {
return std::make_optional(viewport);
}
}
return std::nullopt;
}
} // namespace android