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:
@@ -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.
|
||||
|
||||
@@ -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 ------------------
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user