summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Prabir Pradhan <prabirmsp@google.com> 2021-04-21 13:47:42 -0700
committer Prabir Pradhan <prabirmsp@google.com> 2021-04-23 12:18:55 -0700
commit93a0f91b555bc3e914885bbfc4e86211e97bfa33 (patch)
tree66a013da917a6a506b9997ddd502badcfb83486c
parent6a9a83129025758ce6438197f402e3b56a115dfc (diff)
Cancel touchscreen gestures from Dispatcher when display rotates
When the display rotates, previously, touchscreen devices were reset, and a notifyDeviceReset is sent to Displatcher. When that happens, Dispatcher cancells all active gestures from that device. With this CL, we skip a device reset when the display rotates because there is nothing that changes for the touchscreen device. Instead, when we get a new set of input windows from SF in dispatcher, we track if the orientation changes, and if it does, issue a cancellation for all pointer events. Bug: 185943742 Test: manual Change-Id: Ic8ff19c0dc9cca7b1053a137ea041e5a0da82a76
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp34
-rw-r--r--services/inputflinger/reader/mapper/TouchInputMapper.cpp11
2 files changed, 44 insertions, 1 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 6d405d8200..16abd483e6 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -90,6 +90,14 @@ using com::android::internal::compat::IPlatformCompatNative;
namespace android::inputdispatcher {
+// When per-window-input-rotation is enabled, InputFlinger works in the un-rotated display
+// coordinates and SurfaceFlinger includes the display rotation in the input window transforms.
+static bool isPerWindowInputRotationEnabled() {
+ static const bool PER_WINDOW_INPUT_ROTATION =
+ base::GetBoolProperty("persist.debug.per_window_input_rotation", false);
+ return PER_WINDOW_INPUT_ROTATION;
+}
+
// Default input dispatching timeout if there is no focused application or paused window
// from which to determine an appropriate dispatching timeout.
const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
@@ -4441,6 +4449,13 @@ void InputDispatcher::setInputWindowsLocked(
// Copy old handles for release if they are no longer present.
const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
+ // Save the old windows' orientation by ID before it gets updated.
+ std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
+ for (const sp<InputWindowHandle>& handle : oldWindowHandles) {
+ oldWindowOrientations.emplace(handle->getId(),
+ handle->getInfo()->transform.getOrientation());
+ }
+
updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
@@ -4489,6 +4504,25 @@ void InputDispatcher::setInputWindowsLocked(
}
}
+ if (isPerWindowInputRotationEnabled()) {
+ // Determine if the orientation of any of the input windows have changed, and cancel all
+ // pointer events if necessary.
+ for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
+ const sp<InputWindowHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
+ if (newWindowHandle != nullptr &&
+ newWindowHandle->getInfo()->transform.getOrientation() !=
+ oldWindowOrientations[oldWindowHandle->getId()]) {
+ std::shared_ptr<InputChannel> inputChannel =
+ getInputChannelLocked(newWindowHandle->getToken());
+ if (inputChannel != nullptr) {
+ CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
+ "touched window's orientation changed");
+ synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
+ }
+ }
+ }
+ }
+
// Release information for windows that are no longer present.
// This ensures that unused input channels are released promptly.
// Otherwise, they might stick around until the window handle is destroyed
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 13712eee53..09e1c05ae9 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -682,7 +682,9 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
int32_t rawHeight = mRawPointerAxes.getRawHeight();
bool viewportChanged = mViewport != *newViewport;
+ bool skipViewportUpdate = false;
if (viewportChanged) {
+ bool viewportOrientationChanged = mViewport.orientation != newViewport->orientation;
mViewport = *newViewport;
if (mDeviceMode == DeviceMode::DIRECT || mDeviceMode == DeviceMode::POINTER) {
@@ -746,6 +748,8 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
mPhysicalLeft = naturalPhysicalLeft;
mPhysicalTop = naturalPhysicalTop;
+ const int32_t oldSurfaceWidth = mRawSurfaceWidth;
+ const int32_t oldSurfaceHeight = mRawSurfaceHeight;
mRawSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
mRawSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
@@ -763,6 +767,11 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
mSurfaceOrientation = 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 &&
+ mRawSurfaceWidth == oldSurfaceWidth &&
+ mRawSurfaceHeight == oldSurfaceHeight && viewportOrientationChanged;
} else {
mSurfaceOrientation = mParameters.orientationAware ? mViewport.orientation
: DISPLAY_ORIENTATION_0;
@@ -802,7 +811,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
mPointerController.reset();
}
- if (viewportChanged || deviceModeChanged) {
+ 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(), mRawSurfaceWidth, mRawSurfaceHeight,