From 3c85ed508065440588583f30c60530c7e8511db8 Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Thu, 20 May 2021 13:47:00 -0700 Subject: [PATCH] Inform SurfaceFlinger about displays which receive input Right now, multiple display devices can share a layerstack. This means that when constructing InputWindowInfo, its impossible to know which display transform matches the display viewport that inputflinger dispatches against. To remedy this, have displaymanager inform surfaceflinger which displays "receiveInput" using the same logic that controls which display viewport it sends to inputflinger. Bug: 179274888 Test: atest SetDisplayStateLockedTest Change-Id: I85f1d0ac6fcf9c37a523eb80ed02afeff555c93d --- core/java/android/view/SurfaceControl.java | 23 ++++++++++++++++++- core/jni/android_view_SurfaceControl.cpp | 13 +++++++++++ .../android/server/display/DisplayDevice.java | 15 ++++++++++++ .../server/display/LogicalDisplay.java | 7 ++++++ .../android/server/wm/StubTransaction.java | 5 ++++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 45c49352afff6..0c377bd8314a4 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -34,7 +34,6 @@ import android.annotation.Size; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; -import android.graphics.BLASTBufferQueue; import android.graphics.ColorSpace; import android.graphics.GraphicBuffer; import android.graphics.Matrix; @@ -163,6 +162,8 @@ public final class SurfaceControl implements Parcelable { IBinder displayToken, long nativeSurfaceObject); private static native void nativeSetDisplayLayerStack(long transactionObj, IBinder displayToken, int layerStack); + private static native void nativeSetDisplayFlags(long transactionObj, + IBinder displayToken, int flags); private static native void nativeSetDisplayProjection(long transactionObj, IBinder displayToken, int orientation, int l, int t, int r, int b, @@ -545,6 +546,15 @@ public final class SurfaceControl implements Parcelable { */ private static final int SURFACE_OPAQUE = 0x02; + /* flags used with setDisplayFlags() (keep in sync with DisplayDevice.h) */ + + /** + * DisplayDevice flag: This display's transform is sent to inputflinger and used for input + * dispatch. This flag is used to disambiguate displays which share a layerstack. + * @hide + */ + public static final int DISPLAY_RECEIVES_INPUT = 0x01; + // Display power modes. /** * Display power mode off: used while blanking the screen. @@ -3165,6 +3175,17 @@ public final class SurfaceControl implements Parcelable { return this; } + /** + * @hide + */ + public Transaction setDisplayFlags(IBinder displayToken, int flags) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + nativeSetDisplayFlags(mNativeObject, displayToken, flags); + return this; + } + /** * @hide */ diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index d528428a0e83f..9f6931ecdd20a 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -1006,6 +1006,17 @@ static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz, } } +static void nativeSetDisplayFlags(JNIEnv* env, jclass clazz, jlong transactionObj, jobject tokenObj, + jint flags) { + sp token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + + { + auto transaction = reinterpret_cast(transactionObj); + transaction->setDisplayFlags(token, flags); + } +} + static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz, jlong transactionObj, jobject tokenObj, jint orientation, @@ -1863,6 +1874,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetDisplaySurface }, {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V", (void*)nativeSetDisplayLayerStack }, + {"nativeSetDisplayFlags", "(JLandroid/os/IBinder;I)V", + (void*)nativeSetDisplayFlags }, {"nativeSetDisplayProjection", "(JLandroid/os/IBinder;IIIIIIIII)V", (void*)nativeSetDisplayProjection }, {"nativeSetDisplaySize", "(JLandroid/os/IBinder;II)V", diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java index 35f29579b417e..9f806af5b444f 100644 --- a/services/core/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java @@ -43,6 +43,7 @@ abstract class DisplayDevice { // The display device does not manage these properties itself, they are set by // the display manager service. The display device shouldn't really be looking at these. private int mCurrentLayerStack = -1; + private int mCurrentFlags = 0; private int mCurrentOrientation = -1; private Rect mCurrentLayerStackRect; private Rect mCurrentDisplayRect; @@ -211,6 +212,19 @@ abstract class DisplayDevice { } } + /** + * Sets the display flags while in a transaction. + * + * Valid display flags: + * {@link SurfaceControl#DISPLAY_RECEIVES_INPUT} + */ + public final void setDisplayFlagsLocked(SurfaceControl.Transaction t, int flags) { + if (mCurrentFlags != flags) { + mCurrentFlags = flags; + t.setDisplayFlags(mDisplayToken, flags); + } + } + /** * Sets the display projection while in a transaction. * @@ -298,6 +312,7 @@ abstract class DisplayDevice { pw.println("mUniqueId=" + mUniqueId); pw.println("mDisplayToken=" + mDisplayToken); pw.println("mCurrentLayerStack=" + mCurrentLayerStack); + pw.println("mCurrentFlags=" + mCurrentFlags); pw.println("mCurrentOrientation=" + mCurrentOrientation); pw.println("mCurrentLayerStackRect=" + mCurrentLayerStackRect); pw.println("mCurrentDisplayRect=" + mCurrentDisplayRect); diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 9acb4c8f471a8..5186744d5c27a 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -16,6 +16,8 @@ package com.android.server.display; +import static com.android.server.display.DisplayDeviceInfo.TOUCH_NONE; + import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -512,6 +514,11 @@ final class LogicalDisplay { boolean isBlanked) { // Set the layer stack. device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack); + // Also inform whether the device is the same one sent to inputflinger for its layerstack. + // TODO(b/188914255): Remove once input can dispatch against device vs layerstack. + device.setDisplayFlagsLocked(t, + device.getDisplayDeviceInfoLocked().touch != TOUCH_NONE + ? SurfaceControl.DISPLAY_RECEIVES_INPUT : 0); // Set the color mode and allowed display mode. if (device == mPrimaryDisplayDevice) { diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java index b89539cabbfe8..e32b2aa68b695 100644 --- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java +++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java @@ -177,6 +177,11 @@ public class StubTransaction extends SurfaceControl.Transaction { return this; } + @Override + public SurfaceControl.Transaction setDisplayFlags(IBinder displayToken, int flags) { + return this; + } + @Override public SurfaceControl.Transaction setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect) {