/* * 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 #include #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 FakeInputReaderPolicy::getDisplayViewportByUniqueId( const std::string& uniqueId) const { return mConfig.getDisplayViewportByUniqueId(uniqueId); } std::optional FakeInputReaderPolicy::getDisplayViewportByType( ViewportType type) const { return mConfig.getDisplayViewportByType(type); } std::optional 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(ui::LogicalDisplayId displayId, int32_t width, int32_t height, ui::Rotation orientation, bool isActive, const std::string& uniqueId, std::optional 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.inputPortToDisplayPortAssociations.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.inputPortToDisplayUniqueIdAssociations.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); } const InputReaderConfiguration& FakeInputReaderPolicy::getReaderConfiguration() const { return mConfig; } const std::vector 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(const sp& window) { mConfig.pointerCaptureRequest = {window, mNextPointerCaptureSequenceNumber++}; return mConfig.pointerCaptureRequest; } void FakeInputReaderPolicy::setDefaultPointerDisplayId(ui::LogicalDisplayId 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; } void FakeInputReaderPolicy::notifyInputDevicesChanged( const std::vector& inputDevices) { std::scoped_lock lock(mLock); mInputDevices = inputDevices; mInputDevicesChanged = true; mDevicesChangedCondition.notify_all(); } std::shared_ptr FakeInputReaderPolicy::getKeyboardLayoutOverlay( const InputDeviceIdentifier&, const std::optional) { return nullptr; } std::string FakeInputReaderPolicy::getDeviceAlias(const InputDeviceIdentifier&) { return ""; } void FakeInputReaderPolicy::waitForInputDevices(std::function processDevicesChanged) { std::unique_lock 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 FakeInputReaderPolicy::getPointerViewportForAssociatedDisplay( ui::LogicalDisplayId associatedDisplayId) { if (!associatedDisplayId.isValid()) { associatedDisplayId = mConfig.defaultPointerDisplayId; } for (auto& viewport : mViewports) { if (viewport.displayId == associatedDisplayId) { return std::make_optional(viewport); } } return std::nullopt; } } // namespace android