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
This commit is contained in:
Evan Rosky
2021-05-20 13:47:00 -07:00
parent 4244ff3aa8
commit 3c85ed5080
5 changed files with 62 additions and 1 deletions

View File

@@ -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
*/

View File

@@ -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<IBinder> token(ibinderForJavaObject(env, tokenObj));
if (token == NULL) return;
{
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(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",

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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) {