Loading services/inputflinger/reader/mapper/TouchInputMapper.cpp +226 −236 Original line number Diff line number Diff line Loading @@ -609,215 +609,16 @@ std::optional<DisplayViewport> TouchInputMapper::findViewport() { return std::make_optional(newViewport); } void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) { DeviceMode oldDeviceMode = mDeviceMode; resolveExternalStylusPresence(); // Determine device mode. if (mParameters.deviceType == Parameters::DeviceType::POINTER && mConfig.pointerGesturesEnabled && !mConfig.pointerCaptureRequest.enable) { mSource = AINPUT_SOURCE_MOUSE; mDeviceMode = DeviceMode::POINTER; if (hasStylus()) { mSource |= AINPUT_SOURCE_STYLUS; } } else if (isTouchScreen()) { mSource = AINPUT_SOURCE_TOUCHSCREEN; mDeviceMode = DeviceMode::DIRECT; if (hasStylus()) { mSource |= AINPUT_SOURCE_STYLUS; } if (hasExternalStylus()) { mSource |= AINPUT_SOURCE_BLUETOOTH_STYLUS; } } else if (mParameters.deviceType == Parameters::DeviceType::TOUCH_NAVIGATION) { mSource = AINPUT_SOURCE_TOUCH_NAVIGATION; mDeviceMode = DeviceMode::NAVIGATION; } else { mSource = AINPUT_SOURCE_TOUCHPAD; mDeviceMode = DeviceMode::UNSCALED; } // Ensure we have valid X and Y axes. if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) { ALOGW("Touch device '%s' did not report support for X or Y axis! " "The device will be inoperable.", getDeviceName().c_str()); mDeviceMode = DeviceMode::DISABLED; return; } // Get associated display dimensions. std::optional<DisplayViewport> newViewport = findViewport(); if (!newViewport) { ALOGI("Touch device '%s' could not query the properties of its associated " "display. The device will be inoperable until the display size " "becomes available.", getDeviceName().c_str()); mDeviceMode = DeviceMode::DISABLED; return; } if (!newViewport->isActive) { ALOGI("Disabling %s (device %i) because the associated viewport is not active", getDeviceName().c_str(), getDeviceId()); mDeviceMode = DeviceMode::DISABLED; void TouchInputMapper::initializeSizeRanges() { if (mCalibration.sizeCalibration == Calibration::SizeCalibration::NONE) { mSizeScale = 0.0f; return; } // Raw width and height in the natural orientation. const int32_t rawWidth = mRawPointerAxes.getRawWidth(); const int32_t rawHeight = mRawPointerAxes.getRawHeight(); const bool viewportChanged = mViewport != *newViewport; bool skipViewportUpdate = false; if (viewportChanged) { const bool viewportOrientationChanged = mViewport.orientation != newViewport->orientation; mViewport = *newViewport; if (mDeviceMode == DeviceMode::DIRECT || mDeviceMode == DeviceMode::POINTER) { // Convert rotated viewport to the natural orientation. int32_t naturalPhysicalWidth, naturalPhysicalHeight; int32_t naturalPhysicalLeft, naturalPhysicalTop; int32_t naturalDeviceWidth, naturalDeviceHeight; // Apply the inverse of the input device orientation so that the input device is // configured in the same orientation as the viewport. The input device orientation will // be re-applied by mInputDeviceOrientation. const int32_t naturalDeviceOrientation = (mViewport.orientation - static_cast<int32_t>(mParameters.orientation) + 4) % 4; switch (naturalDeviceOrientation) { case DISPLAY_ORIENTATION_90: naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom; naturalPhysicalTop = mViewport.physicalLeft; naturalDeviceWidth = mViewport.deviceHeight; naturalDeviceHeight = mViewport.deviceWidth; break; case DISPLAY_ORIENTATION_180: naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight; naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom; naturalDeviceWidth = mViewport.deviceWidth; naturalDeviceHeight = mViewport.deviceHeight; break; case DISPLAY_ORIENTATION_270: naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalLeft = mViewport.physicalTop; naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight; naturalDeviceWidth = mViewport.deviceHeight; naturalDeviceHeight = mViewport.deviceWidth; break; case DISPLAY_ORIENTATION_0: default: naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalLeft = mViewport.physicalLeft; naturalPhysicalTop = mViewport.physicalTop; naturalDeviceWidth = mViewport.deviceWidth; naturalDeviceHeight = mViewport.deviceHeight; break; } if (naturalPhysicalHeight == 0 || naturalPhysicalWidth == 0) { ALOGE("Viewport is not set properly: %s", mViewport.toString().c_str()); naturalPhysicalHeight = naturalPhysicalHeight == 0 ? 1 : naturalPhysicalHeight; naturalPhysicalWidth = naturalPhysicalWidth == 0 ? 1 : naturalPhysicalWidth; } mPhysicalWidth = naturalPhysicalWidth; mPhysicalHeight = naturalPhysicalHeight; mPhysicalLeft = naturalPhysicalLeft; mPhysicalTop = naturalPhysicalTop; const int32_t oldDisplayWidth = mDisplayWidth; const int32_t oldDisplayHeight = mDisplayHeight; mDisplayWidth = naturalDeviceWidth; mDisplayHeight = naturalDeviceHeight; // InputReader works in the un-rotated display coordinate space, so we don't need to do // anything if the device is already orientation-aware. If the device is not // orientation-aware, then we need to apply the inverse rotation of the display so that // when the display rotation is applied later as a part of the per-window transform, we // get the expected screen coordinates. mInputDeviceOrientation = mParameters.orientationAware ? DISPLAY_ORIENTATION_0 : getInverseRotation(mViewport.orientation); // For orientation-aware devices that work in the un-rotated coordinate space, the // viewport update should be skipped if it is only a change in the orientation. skipViewportUpdate = mParameters.orientationAware && mDisplayWidth == oldDisplayWidth && mDisplayHeight == oldDisplayHeight && viewportOrientationChanged; // Apply the input device orientation for the device. mInputDeviceOrientation = (mInputDeviceOrientation + static_cast<int32_t>(mParameters.orientation)) % 4; } else { mPhysicalWidth = rawWidth; mPhysicalHeight = rawHeight; mPhysicalLeft = 0; mPhysicalTop = 0; mDisplayWidth = rawWidth; mDisplayHeight = rawHeight; mInputDeviceOrientation = DISPLAY_ORIENTATION_0; } } // If moving between pointer modes, need to reset some state. bool deviceModeChanged = mDeviceMode != oldDeviceMode; if (deviceModeChanged) { mOrientedRanges.clear(); } // Create pointer controller if needed, and keep it around if Pointer Capture is enabled to // preserve the cursor position. if (mDeviceMode == DeviceMode::POINTER || (mDeviceMode == DeviceMode::DIRECT && mConfig.showTouches) || (mParameters.deviceType == Parameters::DeviceType::POINTER && mConfig.pointerCaptureRequest.enable)) { if (mPointerController == nullptr) { mPointerController = getContext()->getPointerController(getDeviceId()); } if (mConfig.pointerCaptureRequest.enable) { mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE); } } else { mPointerController.reset(); } if ((viewportChanged && !skipViewportUpdate) || deviceModeChanged) { ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, " "display id %d", getDeviceId(), getDeviceName().c_str(), mDisplayWidth, mDisplayHeight, mInputDeviceOrientation, mDeviceMode, mViewport.displayId); // Configure X and Y factors. mXScale = float(mDisplayWidth) / rawWidth; mYScale = float(mDisplayHeight) / rawHeight; mXPrecision = 1.0f / mXScale; mYPrecision = 1.0f / mYScale; mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X; mOrientedRanges.x.source = mSource; mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y; mOrientedRanges.y.source = mSource; configureVirtualKeys(); // Scale factor for terms that are not oriented in a particular axis. // If the pixels are square then xScale == yScale otherwise we fake it // by choosing an average. mGeometricScale = avg(mXScale, mYScale); // Size of diagonal axis. float diagonalSize = hypotf(mDisplayWidth, mDisplayHeight); const float diagonalSize = hypotf(mDisplayWidth, mDisplayHeight); // Size factors. if (mCalibration.sizeCalibration != Calibration::SizeCalibration::NONE) { if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.touchMajor.maxValue != 0) { mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue; } else if (mRawPointerAxes.toolMajor.valid && mRawPointerAxes.toolMajor.maxValue != 0) { Loading Loading @@ -859,10 +660,27 @@ void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) mOrientedRanges.size.flat = 0; mOrientedRanges.size.fuzz = 0; mOrientedRanges.size.resolution = 0; } else { mSizeScale = 0.0f; } void TouchInputMapper::initializeOrientedRanges() { // Configure X and Y factors. mXScale = float(mDisplayWidth) / mRawPointerAxes.getRawWidth(); mYScale = float(mDisplayHeight) / mRawPointerAxes.getRawHeight(); mXPrecision = 1.0f / mXScale; mYPrecision = 1.0f / mYScale; mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X; mOrientedRanges.x.source = mSource; mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y; mOrientedRanges.y.source = mSource; // Scale factor for terms that are not oriented in a particular axis. // If the pixels are square then xScale == yScale otherwise we fake it // by choosing an average. mGeometricScale = avg(mXScale, mYScale); initializeSizeRanges(); // Pressure factors. mPressureScale = 0; float pressureMax = 1.0; Loading Loading @@ -926,8 +744,7 @@ void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) mOrientedRanges.orientation.flat = 0; mOrientedRanges.orientation.fuzz = 0; mOrientedRanges.orientation.resolution = 0; } else if (mCalibration.orientationCalibration != Calibration::OrientationCalibration::NONE) { } else if (mCalibration.orientationCalibration != Calibration::OrientationCalibration::NONE) { if (mCalibration.orientationCalibration == Calibration::OrientationCalibration::INTERPOLATED) { if (mRawPointerAxes.orientation.valid) { Loading Loading @@ -1013,6 +830,197 @@ void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale; break; } } void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) { DeviceMode oldDeviceMode = mDeviceMode; resolveExternalStylusPresence(); // Determine device mode. if (mParameters.deviceType == Parameters::DeviceType::POINTER && mConfig.pointerGesturesEnabled && !mConfig.pointerCaptureRequest.enable) { mSource = AINPUT_SOURCE_MOUSE; mDeviceMode = DeviceMode::POINTER; if (hasStylus()) { mSource |= AINPUT_SOURCE_STYLUS; } } else if (isTouchScreen()) { mSource = AINPUT_SOURCE_TOUCHSCREEN; mDeviceMode = DeviceMode::DIRECT; if (hasStylus()) { mSource |= AINPUT_SOURCE_STYLUS; } if (hasExternalStylus()) { mSource |= AINPUT_SOURCE_BLUETOOTH_STYLUS; } } else if (mParameters.deviceType == Parameters::DeviceType::TOUCH_NAVIGATION) { mSource = AINPUT_SOURCE_TOUCH_NAVIGATION; mDeviceMode = DeviceMode::NAVIGATION; } else { mSource = AINPUT_SOURCE_TOUCHPAD; mDeviceMode = DeviceMode::UNSCALED; } // Ensure we have valid X and Y axes. if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) { ALOGW("Touch device '%s' did not report support for X or Y axis! " "The device will be inoperable.", getDeviceName().c_str()); mDeviceMode = DeviceMode::DISABLED; return; } // Get associated display dimensions. std::optional<DisplayViewport> newViewport = findViewport(); if (!newViewport) { ALOGI("Touch device '%s' could not query the properties of its associated " "display. The device will be inoperable until the display size " "becomes available.", getDeviceName().c_str()); mDeviceMode = DeviceMode::DISABLED; return; } if (!newViewport->isActive) { ALOGI("Disabling %s (device %i) because the associated viewport is not active", getDeviceName().c_str(), getDeviceId()); mDeviceMode = DeviceMode::DISABLED; return; } // Raw width and height in the natural orientation. const int32_t rawWidth = mRawPointerAxes.getRawWidth(); const int32_t rawHeight = mRawPointerAxes.getRawHeight(); const bool viewportChanged = mViewport != *newViewport; bool skipViewportUpdate = false; if (viewportChanged) { const bool viewportOrientationChanged = mViewport.orientation != newViewport->orientation; mViewport = *newViewport; if (mDeviceMode == DeviceMode::DIRECT || mDeviceMode == DeviceMode::POINTER) { // Convert rotated viewport to the natural orientation. int32_t naturalPhysicalWidth, naturalPhysicalHeight; int32_t naturalPhysicalLeft, naturalPhysicalTop; int32_t naturalDeviceWidth, naturalDeviceHeight; // Apply the inverse of the input device orientation so that the input device is // configured in the same orientation as the viewport. The input device orientation will // be re-applied by mInputDeviceOrientation. const int32_t naturalDeviceOrientation = (mViewport.orientation - static_cast<int32_t>(mParameters.orientation) + 4) % 4; switch (naturalDeviceOrientation) { case DISPLAY_ORIENTATION_90: naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom; naturalPhysicalTop = mViewport.physicalLeft; naturalDeviceWidth = mViewport.deviceHeight; naturalDeviceHeight = mViewport.deviceWidth; break; case DISPLAY_ORIENTATION_180: naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight; naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom; naturalDeviceWidth = mViewport.deviceWidth; naturalDeviceHeight = mViewport.deviceHeight; break; case DISPLAY_ORIENTATION_270: naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalLeft = mViewport.physicalTop; naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight; naturalDeviceWidth = mViewport.deviceHeight; naturalDeviceHeight = mViewport.deviceWidth; break; case DISPLAY_ORIENTATION_0: default: naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalLeft = mViewport.physicalLeft; naturalPhysicalTop = mViewport.physicalTop; naturalDeviceWidth = mViewport.deviceWidth; naturalDeviceHeight = mViewport.deviceHeight; break; } if (naturalPhysicalHeight == 0 || naturalPhysicalWidth == 0) { ALOGE("Viewport is not set properly: %s", mViewport.toString().c_str()); naturalPhysicalHeight = naturalPhysicalHeight == 0 ? 1 : naturalPhysicalHeight; naturalPhysicalWidth = naturalPhysicalWidth == 0 ? 1 : naturalPhysicalWidth; } mPhysicalWidth = naturalPhysicalWidth; mPhysicalHeight = naturalPhysicalHeight; mPhysicalLeft = naturalPhysicalLeft; mPhysicalTop = naturalPhysicalTop; const int32_t oldDisplayWidth = mDisplayWidth; const int32_t oldDisplayHeight = mDisplayHeight; mDisplayWidth = naturalDeviceWidth; mDisplayHeight = naturalDeviceHeight; // InputReader works in the un-rotated display coordinate space, so we don't need to do // anything if the device is already orientation-aware. If the device is not // orientation-aware, then we need to apply the inverse rotation of the display so that // when the display rotation is applied later as a part of the per-window transform, we // get the expected screen coordinates. mInputDeviceOrientation = mParameters.orientationAware ? DISPLAY_ORIENTATION_0 : getInverseRotation(mViewport.orientation); // For orientation-aware devices that work in the un-rotated coordinate space, the // viewport update should be skipped if it is only a change in the orientation. skipViewportUpdate = mParameters.orientationAware && mDisplayWidth == oldDisplayWidth && mDisplayHeight == oldDisplayHeight && viewportOrientationChanged; // Apply the input device orientation for the device. mInputDeviceOrientation = (mInputDeviceOrientation + static_cast<int32_t>(mParameters.orientation)) % 4; } else { mPhysicalWidth = rawWidth; mPhysicalHeight = rawHeight; mPhysicalLeft = 0; mPhysicalTop = 0; mDisplayWidth = rawWidth; mDisplayHeight = rawHeight; mInputDeviceOrientation = DISPLAY_ORIENTATION_0; } } // If moving between pointer modes, need to reset some state. bool deviceModeChanged = mDeviceMode != oldDeviceMode; if (deviceModeChanged) { mOrientedRanges.clear(); } // Create pointer controller if needed, and keep it around if Pointer Capture is enabled to // preserve the cursor position. if (mDeviceMode == DeviceMode::POINTER || (mDeviceMode == DeviceMode::DIRECT && mConfig.showTouches) || (mParameters.deviceType == Parameters::DeviceType::POINTER && mConfig.pointerCaptureRequest.enable)) { if (mPointerController == nullptr) { mPointerController = getContext()->getPointerController(getDeviceId()); } if (mConfig.pointerCaptureRequest.enable) { mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE); } } else { mPointerController.reset(); } if ((viewportChanged && !skipViewportUpdate) || deviceModeChanged) { ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, " "display id %d", getDeviceId(), getDeviceName().c_str(), mDisplayWidth, mDisplayHeight, mInputDeviceOrientation, mDeviceMode, mViewport.displayId); configureVirtualKeys(); initializeOrientedRanges(); // Location updateAffineTransformation(); Loading Loading @@ -1267,26 +1275,8 @@ void TouchInputMapper::resolveCalibration() { void TouchInputMapper::dumpCalibration(std::string& dump) { dump += INDENT3 "Calibration:\n"; // Size switch (mCalibration.sizeCalibration) { case Calibration::SizeCalibration::NONE: dump += INDENT4 "touch.size.calibration: none\n"; break; case Calibration::SizeCalibration::GEOMETRIC: dump += INDENT4 "touch.size.calibration: geometric\n"; break; case Calibration::SizeCalibration::DIAMETER: dump += INDENT4 "touch.size.calibration: diameter\n"; break; case Calibration::SizeCalibration::BOX: dump += INDENT4 "touch.size.calibration: box\n"; break; case Calibration::SizeCalibration::AREA: dump += INDENT4 "touch.size.calibration: area\n"; break; default: ALOG_ASSERT(false); } dump += INDENT4 "touch.size.calibration: "; dump += ftl::enum_string(mCalibration.sizeCalibration) + "\n"; if (mCalibration.haveSizeScale) { dump += StringPrintf(INDENT4 "touch.size.scale: %0.3f\n", mCalibration.sizeScale); Loading services/inputflinger/reader/mapper/TouchInputMapper.h +4 −0 Original line number Diff line number Diff line Loading @@ -243,6 +243,7 @@ protected: DIAMETER, BOX, AREA, ftl_last = AREA }; SizeCalibration sizeCalibration; Loading Loading @@ -732,6 +733,9 @@ private: void resetExternalStylus(); void clearStylusDataPendingFlags(); void initializeOrientedRanges(); void initializeSizeRanges(); void sync(nsecs_t when, nsecs_t readTime); bool consumeRawTouches(nsecs_t when, nsecs_t readTime, uint32_t policyFlags); Loading Loading
services/inputflinger/reader/mapper/TouchInputMapper.cpp +226 −236 Original line number Diff line number Diff line Loading @@ -609,215 +609,16 @@ std::optional<DisplayViewport> TouchInputMapper::findViewport() { return std::make_optional(newViewport); } void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) { DeviceMode oldDeviceMode = mDeviceMode; resolveExternalStylusPresence(); // Determine device mode. if (mParameters.deviceType == Parameters::DeviceType::POINTER && mConfig.pointerGesturesEnabled && !mConfig.pointerCaptureRequest.enable) { mSource = AINPUT_SOURCE_MOUSE; mDeviceMode = DeviceMode::POINTER; if (hasStylus()) { mSource |= AINPUT_SOURCE_STYLUS; } } else if (isTouchScreen()) { mSource = AINPUT_SOURCE_TOUCHSCREEN; mDeviceMode = DeviceMode::DIRECT; if (hasStylus()) { mSource |= AINPUT_SOURCE_STYLUS; } if (hasExternalStylus()) { mSource |= AINPUT_SOURCE_BLUETOOTH_STYLUS; } } else if (mParameters.deviceType == Parameters::DeviceType::TOUCH_NAVIGATION) { mSource = AINPUT_SOURCE_TOUCH_NAVIGATION; mDeviceMode = DeviceMode::NAVIGATION; } else { mSource = AINPUT_SOURCE_TOUCHPAD; mDeviceMode = DeviceMode::UNSCALED; } // Ensure we have valid X and Y axes. if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) { ALOGW("Touch device '%s' did not report support for X or Y axis! " "The device will be inoperable.", getDeviceName().c_str()); mDeviceMode = DeviceMode::DISABLED; return; } // Get associated display dimensions. std::optional<DisplayViewport> newViewport = findViewport(); if (!newViewport) { ALOGI("Touch device '%s' could not query the properties of its associated " "display. The device will be inoperable until the display size " "becomes available.", getDeviceName().c_str()); mDeviceMode = DeviceMode::DISABLED; return; } if (!newViewport->isActive) { ALOGI("Disabling %s (device %i) because the associated viewport is not active", getDeviceName().c_str(), getDeviceId()); mDeviceMode = DeviceMode::DISABLED; void TouchInputMapper::initializeSizeRanges() { if (mCalibration.sizeCalibration == Calibration::SizeCalibration::NONE) { mSizeScale = 0.0f; return; } // Raw width and height in the natural orientation. const int32_t rawWidth = mRawPointerAxes.getRawWidth(); const int32_t rawHeight = mRawPointerAxes.getRawHeight(); const bool viewportChanged = mViewport != *newViewport; bool skipViewportUpdate = false; if (viewportChanged) { const bool viewportOrientationChanged = mViewport.orientation != newViewport->orientation; mViewport = *newViewport; if (mDeviceMode == DeviceMode::DIRECT || mDeviceMode == DeviceMode::POINTER) { // Convert rotated viewport to the natural orientation. int32_t naturalPhysicalWidth, naturalPhysicalHeight; int32_t naturalPhysicalLeft, naturalPhysicalTop; int32_t naturalDeviceWidth, naturalDeviceHeight; // Apply the inverse of the input device orientation so that the input device is // configured in the same orientation as the viewport. The input device orientation will // be re-applied by mInputDeviceOrientation. const int32_t naturalDeviceOrientation = (mViewport.orientation - static_cast<int32_t>(mParameters.orientation) + 4) % 4; switch (naturalDeviceOrientation) { case DISPLAY_ORIENTATION_90: naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom; naturalPhysicalTop = mViewport.physicalLeft; naturalDeviceWidth = mViewport.deviceHeight; naturalDeviceHeight = mViewport.deviceWidth; break; case DISPLAY_ORIENTATION_180: naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight; naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom; naturalDeviceWidth = mViewport.deviceWidth; naturalDeviceHeight = mViewport.deviceHeight; break; case DISPLAY_ORIENTATION_270: naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalLeft = mViewport.physicalTop; naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight; naturalDeviceWidth = mViewport.deviceHeight; naturalDeviceHeight = mViewport.deviceWidth; break; case DISPLAY_ORIENTATION_0: default: naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalLeft = mViewport.physicalLeft; naturalPhysicalTop = mViewport.physicalTop; naturalDeviceWidth = mViewport.deviceWidth; naturalDeviceHeight = mViewport.deviceHeight; break; } if (naturalPhysicalHeight == 0 || naturalPhysicalWidth == 0) { ALOGE("Viewport is not set properly: %s", mViewport.toString().c_str()); naturalPhysicalHeight = naturalPhysicalHeight == 0 ? 1 : naturalPhysicalHeight; naturalPhysicalWidth = naturalPhysicalWidth == 0 ? 1 : naturalPhysicalWidth; } mPhysicalWidth = naturalPhysicalWidth; mPhysicalHeight = naturalPhysicalHeight; mPhysicalLeft = naturalPhysicalLeft; mPhysicalTop = naturalPhysicalTop; const int32_t oldDisplayWidth = mDisplayWidth; const int32_t oldDisplayHeight = mDisplayHeight; mDisplayWidth = naturalDeviceWidth; mDisplayHeight = naturalDeviceHeight; // InputReader works in the un-rotated display coordinate space, so we don't need to do // anything if the device is already orientation-aware. If the device is not // orientation-aware, then we need to apply the inverse rotation of the display so that // when the display rotation is applied later as a part of the per-window transform, we // get the expected screen coordinates. mInputDeviceOrientation = mParameters.orientationAware ? DISPLAY_ORIENTATION_0 : getInverseRotation(mViewport.orientation); // For orientation-aware devices that work in the un-rotated coordinate space, the // viewport update should be skipped if it is only a change in the orientation. skipViewportUpdate = mParameters.orientationAware && mDisplayWidth == oldDisplayWidth && mDisplayHeight == oldDisplayHeight && viewportOrientationChanged; // Apply the input device orientation for the device. mInputDeviceOrientation = (mInputDeviceOrientation + static_cast<int32_t>(mParameters.orientation)) % 4; } else { mPhysicalWidth = rawWidth; mPhysicalHeight = rawHeight; mPhysicalLeft = 0; mPhysicalTop = 0; mDisplayWidth = rawWidth; mDisplayHeight = rawHeight; mInputDeviceOrientation = DISPLAY_ORIENTATION_0; } } // If moving between pointer modes, need to reset some state. bool deviceModeChanged = mDeviceMode != oldDeviceMode; if (deviceModeChanged) { mOrientedRanges.clear(); } // Create pointer controller if needed, and keep it around if Pointer Capture is enabled to // preserve the cursor position. if (mDeviceMode == DeviceMode::POINTER || (mDeviceMode == DeviceMode::DIRECT && mConfig.showTouches) || (mParameters.deviceType == Parameters::DeviceType::POINTER && mConfig.pointerCaptureRequest.enable)) { if (mPointerController == nullptr) { mPointerController = getContext()->getPointerController(getDeviceId()); } if (mConfig.pointerCaptureRequest.enable) { mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE); } } else { mPointerController.reset(); } if ((viewportChanged && !skipViewportUpdate) || deviceModeChanged) { ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, " "display id %d", getDeviceId(), getDeviceName().c_str(), mDisplayWidth, mDisplayHeight, mInputDeviceOrientation, mDeviceMode, mViewport.displayId); // Configure X and Y factors. mXScale = float(mDisplayWidth) / rawWidth; mYScale = float(mDisplayHeight) / rawHeight; mXPrecision = 1.0f / mXScale; mYPrecision = 1.0f / mYScale; mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X; mOrientedRanges.x.source = mSource; mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y; mOrientedRanges.y.source = mSource; configureVirtualKeys(); // Scale factor for terms that are not oriented in a particular axis. // If the pixels are square then xScale == yScale otherwise we fake it // by choosing an average. mGeometricScale = avg(mXScale, mYScale); // Size of diagonal axis. float diagonalSize = hypotf(mDisplayWidth, mDisplayHeight); const float diagonalSize = hypotf(mDisplayWidth, mDisplayHeight); // Size factors. if (mCalibration.sizeCalibration != Calibration::SizeCalibration::NONE) { if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.touchMajor.maxValue != 0) { mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue; } else if (mRawPointerAxes.toolMajor.valid && mRawPointerAxes.toolMajor.maxValue != 0) { Loading Loading @@ -859,10 +660,27 @@ void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) mOrientedRanges.size.flat = 0; mOrientedRanges.size.fuzz = 0; mOrientedRanges.size.resolution = 0; } else { mSizeScale = 0.0f; } void TouchInputMapper::initializeOrientedRanges() { // Configure X and Y factors. mXScale = float(mDisplayWidth) / mRawPointerAxes.getRawWidth(); mYScale = float(mDisplayHeight) / mRawPointerAxes.getRawHeight(); mXPrecision = 1.0f / mXScale; mYPrecision = 1.0f / mYScale; mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X; mOrientedRanges.x.source = mSource; mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y; mOrientedRanges.y.source = mSource; // Scale factor for terms that are not oriented in a particular axis. // If the pixels are square then xScale == yScale otherwise we fake it // by choosing an average. mGeometricScale = avg(mXScale, mYScale); initializeSizeRanges(); // Pressure factors. mPressureScale = 0; float pressureMax = 1.0; Loading Loading @@ -926,8 +744,7 @@ void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) mOrientedRanges.orientation.flat = 0; mOrientedRanges.orientation.fuzz = 0; mOrientedRanges.orientation.resolution = 0; } else if (mCalibration.orientationCalibration != Calibration::OrientationCalibration::NONE) { } else if (mCalibration.orientationCalibration != Calibration::OrientationCalibration::NONE) { if (mCalibration.orientationCalibration == Calibration::OrientationCalibration::INTERPOLATED) { if (mRawPointerAxes.orientation.valid) { Loading Loading @@ -1013,6 +830,197 @@ void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale; break; } } void TouchInputMapper::configureInputDevice(nsecs_t when, bool* outResetNeeded) { DeviceMode oldDeviceMode = mDeviceMode; resolveExternalStylusPresence(); // Determine device mode. if (mParameters.deviceType == Parameters::DeviceType::POINTER && mConfig.pointerGesturesEnabled && !mConfig.pointerCaptureRequest.enable) { mSource = AINPUT_SOURCE_MOUSE; mDeviceMode = DeviceMode::POINTER; if (hasStylus()) { mSource |= AINPUT_SOURCE_STYLUS; } } else if (isTouchScreen()) { mSource = AINPUT_SOURCE_TOUCHSCREEN; mDeviceMode = DeviceMode::DIRECT; if (hasStylus()) { mSource |= AINPUT_SOURCE_STYLUS; } if (hasExternalStylus()) { mSource |= AINPUT_SOURCE_BLUETOOTH_STYLUS; } } else if (mParameters.deviceType == Parameters::DeviceType::TOUCH_NAVIGATION) { mSource = AINPUT_SOURCE_TOUCH_NAVIGATION; mDeviceMode = DeviceMode::NAVIGATION; } else { mSource = AINPUT_SOURCE_TOUCHPAD; mDeviceMode = DeviceMode::UNSCALED; } // Ensure we have valid X and Y axes. if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) { ALOGW("Touch device '%s' did not report support for X or Y axis! " "The device will be inoperable.", getDeviceName().c_str()); mDeviceMode = DeviceMode::DISABLED; return; } // Get associated display dimensions. std::optional<DisplayViewport> newViewport = findViewport(); if (!newViewport) { ALOGI("Touch device '%s' could not query the properties of its associated " "display. The device will be inoperable until the display size " "becomes available.", getDeviceName().c_str()); mDeviceMode = DeviceMode::DISABLED; return; } if (!newViewport->isActive) { ALOGI("Disabling %s (device %i) because the associated viewport is not active", getDeviceName().c_str(), getDeviceId()); mDeviceMode = DeviceMode::DISABLED; return; } // Raw width and height in the natural orientation. const int32_t rawWidth = mRawPointerAxes.getRawWidth(); const int32_t rawHeight = mRawPointerAxes.getRawHeight(); const bool viewportChanged = mViewport != *newViewport; bool skipViewportUpdate = false; if (viewportChanged) { const bool viewportOrientationChanged = mViewport.orientation != newViewport->orientation; mViewport = *newViewport; if (mDeviceMode == DeviceMode::DIRECT || mDeviceMode == DeviceMode::POINTER) { // Convert rotated viewport to the natural orientation. int32_t naturalPhysicalWidth, naturalPhysicalHeight; int32_t naturalPhysicalLeft, naturalPhysicalTop; int32_t naturalDeviceWidth, naturalDeviceHeight; // Apply the inverse of the input device orientation so that the input device is // configured in the same orientation as the viewport. The input device orientation will // be re-applied by mInputDeviceOrientation. const int32_t naturalDeviceOrientation = (mViewport.orientation - static_cast<int32_t>(mParameters.orientation) + 4) % 4; switch (naturalDeviceOrientation) { case DISPLAY_ORIENTATION_90: naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom; naturalPhysicalTop = mViewport.physicalLeft; naturalDeviceWidth = mViewport.deviceHeight; naturalDeviceHeight = mViewport.deviceWidth; break; case DISPLAY_ORIENTATION_180: naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight; naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom; naturalDeviceWidth = mViewport.deviceWidth; naturalDeviceHeight = mViewport.deviceHeight; break; case DISPLAY_ORIENTATION_270: naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalLeft = mViewport.physicalTop; naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight; naturalDeviceWidth = mViewport.deviceHeight; naturalDeviceHeight = mViewport.deviceWidth; break; case DISPLAY_ORIENTATION_0: default: naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft; naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop; naturalPhysicalLeft = mViewport.physicalLeft; naturalPhysicalTop = mViewport.physicalTop; naturalDeviceWidth = mViewport.deviceWidth; naturalDeviceHeight = mViewport.deviceHeight; break; } if (naturalPhysicalHeight == 0 || naturalPhysicalWidth == 0) { ALOGE("Viewport is not set properly: %s", mViewport.toString().c_str()); naturalPhysicalHeight = naturalPhysicalHeight == 0 ? 1 : naturalPhysicalHeight; naturalPhysicalWidth = naturalPhysicalWidth == 0 ? 1 : naturalPhysicalWidth; } mPhysicalWidth = naturalPhysicalWidth; mPhysicalHeight = naturalPhysicalHeight; mPhysicalLeft = naturalPhysicalLeft; mPhysicalTop = naturalPhysicalTop; const int32_t oldDisplayWidth = mDisplayWidth; const int32_t oldDisplayHeight = mDisplayHeight; mDisplayWidth = naturalDeviceWidth; mDisplayHeight = naturalDeviceHeight; // InputReader works in the un-rotated display coordinate space, so we don't need to do // anything if the device is already orientation-aware. If the device is not // orientation-aware, then we need to apply the inverse rotation of the display so that // when the display rotation is applied later as a part of the per-window transform, we // get the expected screen coordinates. mInputDeviceOrientation = mParameters.orientationAware ? DISPLAY_ORIENTATION_0 : getInverseRotation(mViewport.orientation); // For orientation-aware devices that work in the un-rotated coordinate space, the // viewport update should be skipped if it is only a change in the orientation. skipViewportUpdate = mParameters.orientationAware && mDisplayWidth == oldDisplayWidth && mDisplayHeight == oldDisplayHeight && viewportOrientationChanged; // Apply the input device orientation for the device. mInputDeviceOrientation = (mInputDeviceOrientation + static_cast<int32_t>(mParameters.orientation)) % 4; } else { mPhysicalWidth = rawWidth; mPhysicalHeight = rawHeight; mPhysicalLeft = 0; mPhysicalTop = 0; mDisplayWidth = rawWidth; mDisplayHeight = rawHeight; mInputDeviceOrientation = DISPLAY_ORIENTATION_0; } } // If moving between pointer modes, need to reset some state. bool deviceModeChanged = mDeviceMode != oldDeviceMode; if (deviceModeChanged) { mOrientedRanges.clear(); } // Create pointer controller if needed, and keep it around if Pointer Capture is enabled to // preserve the cursor position. if (mDeviceMode == DeviceMode::POINTER || (mDeviceMode == DeviceMode::DIRECT && mConfig.showTouches) || (mParameters.deviceType == Parameters::DeviceType::POINTER && mConfig.pointerCaptureRequest.enable)) { if (mPointerController == nullptr) { mPointerController = getContext()->getPointerController(getDeviceId()); } if (mConfig.pointerCaptureRequest.enable) { mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE); } } else { mPointerController.reset(); } if ((viewportChanged && !skipViewportUpdate) || deviceModeChanged) { ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, " "display id %d", getDeviceId(), getDeviceName().c_str(), mDisplayWidth, mDisplayHeight, mInputDeviceOrientation, mDeviceMode, mViewport.displayId); configureVirtualKeys(); initializeOrientedRanges(); // Location updateAffineTransformation(); Loading Loading @@ -1267,26 +1275,8 @@ void TouchInputMapper::resolveCalibration() { void TouchInputMapper::dumpCalibration(std::string& dump) { dump += INDENT3 "Calibration:\n"; // Size switch (mCalibration.sizeCalibration) { case Calibration::SizeCalibration::NONE: dump += INDENT4 "touch.size.calibration: none\n"; break; case Calibration::SizeCalibration::GEOMETRIC: dump += INDENT4 "touch.size.calibration: geometric\n"; break; case Calibration::SizeCalibration::DIAMETER: dump += INDENT4 "touch.size.calibration: diameter\n"; break; case Calibration::SizeCalibration::BOX: dump += INDENT4 "touch.size.calibration: box\n"; break; case Calibration::SizeCalibration::AREA: dump += INDENT4 "touch.size.calibration: area\n"; break; default: ALOG_ASSERT(false); } dump += INDENT4 "touch.size.calibration: "; dump += ftl::enum_string(mCalibration.sizeCalibration) + "\n"; if (mCalibration.haveSizeScale) { dump += StringPrintf(INDENT4 "touch.size.scale: %0.3f\n", mCalibration.sizeScale); Loading
services/inputflinger/reader/mapper/TouchInputMapper.h +4 −0 Original line number Diff line number Diff line Loading @@ -243,6 +243,7 @@ protected: DIAMETER, BOX, AREA, ftl_last = AREA }; SizeCalibration sizeCalibration; Loading Loading @@ -732,6 +733,9 @@ private: void resetExternalStylus(); void clearStylusDataPendingFlags(); void initializeOrientedRanges(); void initializeSizeRanges(); void sync(nsecs_t when, nsecs_t readTime); bool consumeRawTouches(nsecs_t when, nsecs_t readTime, uint32_t policyFlags); Loading