Compat-rotate motion-events injected into dispatcher

With the flag, dispatcher operates in physical space, so
if injecting into dispatcher, the events need to be 'un'rotated.

Bug: 179274888
Test: atest Launcher3Tests:com.android.launcher3.ui.TaplTestsLauncher3
Change-Id: I9abdfd0540354ab6e3eac34ae15b784c0fcf6e2e
This commit is contained in:
Evan Rosky
2021-05-03 20:14:04 -07:00
parent 327db7857d
commit 1476d63b2b
3 changed files with 54 additions and 0 deletions

View File

@@ -1569,6 +1569,8 @@ public final class MotionEvent extends InputEvent implements Parcelable {
int axis, int pointerIndex, int historyPos);
@FastNative
private static native void nativeTransform(long nativePtr, Matrix matrix);
@FastNative
private static native void nativeApplyTransform(long nativePtr, Matrix matrix);
// -------------- @CriticalNative ----------------------
@@ -3265,6 +3267,21 @@ public final class MotionEvent extends InputEvent implements Parcelable {
nativeTransform(mNativePtr, matrix);
}
/**
* Transforms all of the points in the event directly instead of modifying the event's
* internal transform.
*
* @param matrix The transformation matrix to apply.
* @hide
*/
public void applyTransform(Matrix matrix) {
if (matrix == null) {
throw new IllegalArgumentException("matrix must not be null");
}
nativeApplyTransform(mNativePtr, matrix);
}
/**
* Add a new movement to the batch of movements in this event. The event's
* current location, position and size is updated to the new values.

View File

@@ -578,6 +578,15 @@ static void android_view_MotionEvent_nativeTransform(JNIEnv* env, jclass clazz,
event->transform(matrix);
}
static void android_view_MotionEvent_nativeApplyTransform(JNIEnv* env, jclass clazz,
jlong nativePtr, jobject matrixObj) {
MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
std::array<float, 9> matrix;
AMatrix_getContents(env, matrixObj, matrix.data());
event->applyTransform(matrix);
}
// ----------------- @CriticalNative ------------------------------
static jlong android_view_MotionEvent_nativeCopy(jlong destNativePtr, jlong sourceNativePtr,
@@ -790,6 +799,8 @@ static const JNINativeMethod gMotionEventMethods[] = {
{"nativeGetAxisValue", "(JIII)F", (void*)android_view_MotionEvent_nativeGetAxisValue},
{"nativeTransform", "(JLandroid/graphics/Matrix;)V",
(void*)android_view_MotionEvent_nativeTransform},
{"nativeApplyTransform", "(JLandroid/graphics/Matrix;)V",
(void*)android_view_MotionEvent_nativeApplyTransform},
// --------------- @CriticalNative ------------------

View File

@@ -16,6 +16,8 @@
package com.android.server.input;
import static android.view.Surface.ROTATION_0;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
@@ -38,6 +40,7 @@ import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.database.ContentObserver;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayViewport;
@@ -97,6 +100,7 @@ import android.view.InputDevice;
import android.view.InputEvent;
import android.view.InputMonitor;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.view.Surface;
import android.view.VerifiedInputEvent;
@@ -820,6 +824,28 @@ public class InputManagerService extends IInputManager.Stub
&& mode != InputEventInjectionSync.WAIT_FOR_RESULT) {
throw new IllegalArgumentException("mode is invalid");
}
if (ENABLE_PER_WINDOW_INPUT_ROTATION) {
if (event instanceof MotionEvent) {
final Context dispCtx = getContextForDisplay(event.getDisplayId());
final Display display = dispCtx.getDisplay();
final int rotation = display.getRotation();
if (rotation != ROTATION_0) {
final MotionEvent motion = (MotionEvent) event;
// Injections are currently expected to be in the space of the injector (ie.
// usually assumed to be post-rotated). Thus we need to unrotate into raw
// input coordinates for dispatch.
final Point sz = new Point();
display.getRealSize(sz);
if ((rotation % 2) != 0) {
final int tmpX = sz.x;
sz.x = sz.y;
sz.y = tmpX;
}
motion.applyTransform(MotionEvent.createRotateMatrix(
(4 - rotation), sz.x, sz.y));
}
}
}
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();