Update input-monitors to accept unrotated coordinates
Inputflinger now internally always works in the orientation
the display grew-up in so the coordinates of gesture-monitors
no-longer rotate to match the display.
For now, this adds some shims to achieve previous expected
coordinates in launcher
This is behind a flag:
adb shell setprop persist.debug.per_window_input_rotation 1
Bug: 179274888
Test: use touch interactions on rotated display
Change-Id: Iecd9d233f60b86e24070d7d9055af6b8f44f0b54
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 8ebea33..c6c942a 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -38,18 +38,23 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Icon;
+import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.util.Log;
import android.view.Choreographer;
+import android.view.Display;
import android.view.InputEvent;
import android.view.MotionEvent;
+import android.view.Surface;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.BinderThread;
@@ -92,6 +97,7 @@
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
@@ -122,6 +128,9 @@
*/
private static final int SYSTEM_ACTION_ID_ALL_APPS = 14;
+ public static final boolean ENABLE_PER_WINDOW_INPUT_ROTATION =
+ SystemProperties.getBoolean("persist.debug.per_window_input_rotation", false);
+
private int mBackGestureNotificationCounter = -1;
@Nullable
private OverscrollPlugin mOverscrollPlugin;
@@ -249,6 +258,8 @@
private InputMonitorCompat mInputMonitorCompat;
private InputEventReceiver mInputEventReceiver;
+ private DisplayManager mDisplayManager;
+
@Override
public void onCreate() {
super.onCreate();
@@ -262,6 +273,7 @@
mDeviceState.addOneHandedModeChangedCallback(this::onOneHandedModeOverlayChanged);
mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
ProtoTracer.INSTANCE.get(this).add(this);
+ mDisplayManager = getSystemService(DisplayManager.class);
sConnected = true;
}
@@ -429,6 +441,15 @@
return;
}
MotionEvent event = (MotionEvent) ev;
+ if (ENABLE_PER_WINDOW_INPUT_ROTATION) {
+ final Display display = mDisplayManager.getDisplay(mDeviceState.getDisplayId());
+ int rotation = display.getRotation();
+ Point sz = new Point();
+ display.getRealSize(sz);
+ if (rotation != Surface.ROTATION_0) {
+ event.transform(InputChannelCompat.createRotationMatrix(rotation, sz.x, sz.y));
+ }
+ }
TestLogging.recordMotionEvent(
TestProtocol.SEQUENCE_TIS, "TouchInteractionService.onInputEvent", event);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index f2f9fb7..5baf518 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -38,10 +38,12 @@
import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.PointF;
+import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
+import android.view.Display;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
@@ -64,6 +66,7 @@
import com.android.quickstep.RotationTouchHelper;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.TaskUtils;
+import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
@@ -113,6 +116,8 @@
private final PointF mLastPos = new PointF();
private int mActivePointerId = INVALID_POINTER_ID;
+ private int mLastRotation = -1;
+
// Distance after which we start dragging the window.
private final float mTouchSlop;
@@ -130,6 +135,8 @@
// Might be displacement in X or Y, depending on the direction we are swiping from the nav bar.
private float mStartDisplacement;
+ private final DisplayManager mDisplayManager;
+
private Handler mMainThreadHandler;
private Runnable mCancelRecentsAnimationRunnable = () -> {
ActivityManagerWrapper.getInstance().cancelRecentsAnimation(
@@ -172,6 +179,7 @@
mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture;
mDisableHorizontalSwipe = !mPassedPilferInputSlop && disableHorizontalSwipe;
mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
+ mDisplayManager = getSystemService(DisplayManager.class);
}
@Override
@@ -197,6 +205,17 @@
return;
}
+ if (TouchInteractionService.ENABLE_PER_WINDOW_INPUT_ROTATION) {
+ final Display display = mDisplayManager.getDisplay(mDeviceState.getDisplayId());
+ final int rotation = display.getRotation();
+ if (rotation != mLastRotation) {
+ // If rotation changes, reset tracking to avoid degenerate velocities.
+ mLastPos.set(ev.getX(), ev.getY());
+ mVelocityTracker.clear();
+ mLastRotation = rotation;
+ }
+ }
+
// Proxy events to recents view
if (mPassedWindowMoveSlop && mInteractionHandler != null
&& !mRecentsViewDispatcher.hasConsumer()) {