From 80f7f10efc589e928802d79b0afaf51324d71295 Mon Sep 17 00:00:00 2001 From: chaviw Date: Wed, 21 Apr 2021 13:28:59 -0500 Subject: [PATCH] Change remaining trusted layers from BQL to Blast layer All BQL have now have an underlying BSL that will render the content. This causes issues with trusted layers since the input info is not propagated down from the top layer to the BSL that contains the buffer. This causes touch issues since a non trusted layer is blocking another layer. Since trusted layers can only be created by the system, convert all BQL that are trusted layers to be BSL so we can specificy the input directly on the layer that contains the buffer. Test: Accessibility no longer blocks input Bug: 185973018 Change-Id: Ia208c570f2a694fb65c73ef0bec0ab34b0bcc8a0 --- .../server/wm/AccessibilityController.java | 16 ++- .../server/wm/EmulatorDisplayOverlay.java | 35 +++--- .../android/server/wm/StrictModeFlash.java | 32 +++--- .../java/com/android/server/wm/Watermark.java | 105 +++++++++--------- .../server/wm/WindowManagerService.java | 10 +- 5 files changed, 101 insertions(+), 97 deletions(-) diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index e6d49e406803a..fc0b1f6194d1e 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -47,6 +47,7 @@ import android.annotation.NonNull; import android.app.Application; import android.content.Context; import android.content.pm.PackageManagerInternal; +import android.graphics.BLASTBufferQueue; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; @@ -1112,7 +1113,8 @@ final class AccessibilityController { private final Paint mPaint = new Paint(); private final SurfaceControl mSurfaceControl; - private final Surface mSurface = mService.mSurfaceFactory.get(); + private final BLASTBufferQueue mBlastBufferQueue; + private final Surface mSurface; private final AnimationController mAnimationController; @@ -1124,11 +1126,10 @@ final class AccessibilityController { ViewportWindow(Context context) { SurfaceControl surfaceControl = null; try { - mDisplay.getRealSize(mTempPoint); surfaceControl = mDisplayContent .makeOverlay() .setName(SURFACE_TITLE) - .setBufferSize(mTempPoint.x, mTempPoint.y) // not a typo + .setBLASTLayer() .setFormat(PixelFormat.TRANSLUCENT) .setCallsite("ViewportWindow") .build(); @@ -1136,6 +1137,9 @@ final class AccessibilityController { /* ignore */ } mSurfaceControl = surfaceControl; + mDisplay.getRealSize(mTempPoint); + mBlastBufferQueue = new BLASTBufferQueue(SURFACE_TITLE, mSurfaceControl, + mTempPoint.x, mTempPoint.y, PixelFormat.RGBA_8888); final SurfaceControl.Transaction t = mService.mTransactionFactory.get(); final int layer = @@ -1145,8 +1149,7 @@ final class AccessibilityController { InputMonitor.setTrustedOverlayInputInfo(mSurfaceControl, t, mDisplayContent.getDisplayId(), "Magnification Overlay"); t.apply(); - - mSurface.copyFrom(mSurfaceControl); + mSurface = mBlastBufferQueue.createSurface(); mAnimationController = new AnimationController(context, mService.mH.getLooper()); @@ -1271,6 +1274,9 @@ final class AccessibilityController { } void releaseSurface() { + if (mBlastBufferQueue != null) { + mBlastBufferQueue.destroy(); + } mService.mTransactionFactory.get().remove(mSurfaceControl).apply(); mSurface.release(); } diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java index 724747daaa5b5..02a7db19f4057 100644 --- a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java +++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java @@ -20,38 +20,39 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.content.Context; +import android.graphics.BLASTBufferQueue; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PorterDuff; -import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.view.Display; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; -import java.util.function.Supplier; - class EmulatorDisplayOverlay { private static final String TAG = TAG_WITH_CLASS_NAME ? "EmulatorDisplayOverlay" : TAG_WM; + private static final String TITLE = "EmulatorDisplayOverlay"; + // Display dimensions private Point mScreenSize; private final SurfaceControl mSurfaceControl; private final Surface mSurface; + private final BLASTBufferQueue mBlastBufferQueue; + private int mLastDW; private int mLastDH; private boolean mDrawNeeded; - private Drawable mOverlay; + private final Drawable mOverlay; private int mRotation; private boolean mVisible; - EmulatorDisplayOverlay(Supplier surfaceFactory, Context context, DisplayContent dc, - int zOrder, SurfaceControl.Transaction t) { - mSurface = surfaceFactory.get(); + EmulatorDisplayOverlay(Context context, DisplayContent dc, int zOrder, + SurfaceControl.Transaction t) { final Display display = dc.getDisplay(); mScreenSize = new Point(); display.getSize(mScreenSize); @@ -59,24 +60,26 @@ class EmulatorDisplayOverlay { SurfaceControl ctrl = null; try { ctrl = dc.makeOverlay() - .setName("EmulatorDisplayOverlay") - .setBufferSize(mScreenSize.x, mScreenSize.y) + .setName(TITLE) + .setBLASTLayer() .setFormat(PixelFormat.TRANSLUCENT) - .setCallsite("EmulatorDisplayOverlay") + .setCallsite(TITLE) .build(); t.setLayer(ctrl, zOrder); t.setPosition(ctrl, 0, 0); t.show(ctrl); // Ensure we aren't considered as obscuring for Input purposes. - InputMonitor.setTrustedOverlayInputInfo(ctrl, t, - dc.getDisplayId(), "EmulatorDisplayOverlay"); - mSurface.copyFrom(ctrl); + InputMonitor.setTrustedOverlayInputInfo(ctrl, t, dc.getDisplayId(), TITLE); } catch (OutOfResourcesException e) { } mSurfaceControl = ctrl; mDrawNeeded = true; mOverlay = context.getDrawable( com.android.internal.R.drawable.emulator_circular_window_overlay); + + mBlastBufferQueue = new BLASTBufferQueue(TITLE, mSurfaceControl, mScreenSize.x, + mScreenSize.y, PixelFormat.RGBA_8888); + mSurface = mBlastBufferQueue.createSurface(); } private void drawIfNeeded(SurfaceControl.Transaction t) { @@ -85,12 +88,10 @@ class EmulatorDisplayOverlay { } mDrawNeeded = false; - Rect dirty = new Rect(0, 0, mScreenSize.x, mScreenSize.y); Canvas c = null; try { - c = mSurface.lockCanvas(dirty); - } catch (IllegalArgumentException e) { - } catch (OutOfResourcesException e) { + c = mSurface.lockCanvas(null); + } catch (IllegalArgumentException | OutOfResourcesException e) { } if (c == null) { return; diff --git a/services/core/java/com/android/server/wm/StrictModeFlash.java b/services/core/java/com/android/server/wm/StrictModeFlash.java index 39ac16a2f5d33..48a7bdec2b948 100644 --- a/services/core/java/com/android/server/wm/StrictModeFlash.java +++ b/services/core/java/com/android/server/wm/StrictModeFlash.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import android.graphics.BLASTBufferQueue; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.PixelFormat; @@ -27,28 +28,27 @@ import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; -import java.util.function.Supplier; - class StrictModeFlash { private static final String TAG = TAG_WITH_CLASS_NAME ? "StrictModeFlash" : TAG_WM; + private static final String TITLE = "StrictModeFlash"; private final SurfaceControl mSurfaceControl; private final Surface mSurface; + private final BLASTBufferQueue mBlastBufferQueue; + private int mLastDW; private int mLastDH; private boolean mDrawNeeded; private final int mThickness = 20; - StrictModeFlash(Supplier surfaceFactory, DisplayContent dc, - SurfaceControl.Transaction t) { - mSurface = surfaceFactory.get(); + StrictModeFlash(DisplayContent dc, SurfaceControl.Transaction t) { SurfaceControl ctrl = null; try { ctrl = dc.makeOverlay() - .setName("StrictModeFlash") - .setBufferSize(1, 1) + .setName(TITLE) + .setBLASTLayer() .setFormat(PixelFormat.TRANSLUCENT) - .setCallsite("StrictModeFlash") + .setCallsite(TITLE) .build(); // one more than Watermark? arbitrary. @@ -56,14 +56,15 @@ class StrictModeFlash { t.setPosition(ctrl, 0, 0); t.show(ctrl); // Ensure we aren't considered as obscuring for Input purposes. - InputMonitor.setTrustedOverlayInputInfo(ctrl, t, dc.getDisplayId(), - "StrictModeFlash"); - - mSurface.copyFrom(ctrl); + InputMonitor.setTrustedOverlayInputInfo(ctrl, t, dc.getDisplayId(), TITLE); } catch (OutOfResourcesException e) { } mSurfaceControl = ctrl; mDrawNeeded = true; + + mBlastBufferQueue = new BLASTBufferQueue(TITLE, mSurfaceControl, 1 /* width */, + 1 /* height */, PixelFormat.RGBA_8888); + mSurface = mBlastBufferQueue.createSurface(); } private void drawIfNeeded() { @@ -73,13 +74,12 @@ class StrictModeFlash { mDrawNeeded = false; final int dw = mLastDW; final int dh = mLastDH; + mBlastBufferQueue.update(mSurfaceControl, dw, dh, PixelFormat.RGBA_8888); - Rect dirty = new Rect(0, 0, dw, dh); Canvas c = null; try { - c = mSurface.lockCanvas(dirty); - } catch (IllegalArgumentException e) { - } catch (Surface.OutOfResourcesException e) { + c = mSurface.lockCanvas(null); + } catch (IllegalArgumentException | OutOfResourcesException e) { } if (c == null) { return; diff --git a/services/core/java/com/android/server/wm/Watermark.java b/services/core/java/com/android/server/wm/Watermark.java index 7f28ffc5634ca..66ab094f0994d 100644 --- a/services/core/java/com/android/server/wm/Watermark.java +++ b/services/core/java/com/android/server/wm/Watermark.java @@ -18,30 +18,26 @@ package com.android.server.wm; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import android.graphics.BLASTBufferQueue; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.FontMetricsInt; import android.graphics.PixelFormat; import android.graphics.PorterDuff; -import android.graphics.Rect; import android.graphics.Typeface; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; -import android.view.Display; -import android.view.InputWindowHandle; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; -import java.util.function.Supplier; - /** * Displays a watermark on top of the window manager's windows. */ class Watermark { - private final Display mDisplay; - private final String[] mTokens; + private static final String TITLE = "WatermarkSurface"; + private final String mText; private final Paint mTextPaint; private final int mTextWidth; @@ -51,28 +47,26 @@ class Watermark { private final SurfaceControl mSurfaceControl; private final Surface mSurface; + private final BLASTBufferQueue mBlastBufferQueue; + private int mLastDW; private int mLastDH; private boolean mDrawNeeded; - Watermark(Supplier surfaceFactory, DisplayContent dc, DisplayMetrics dm, - String[] tokens, SurfaceControl.Transaction t) { + Watermark(DisplayContent dc, DisplayMetrics dm, String[] tokens, SurfaceControl.Transaction t) { if (false) { Log.i(TAG_WM, "*********************** WATERMARK"); for (int i=0; i= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10; else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10; else c1 -= '0'; @@ -118,20 +112,22 @@ class Watermark { SurfaceControl ctrl = null; try { ctrl = dc.makeOverlay() - .setName("WatermarkSurface") - .setBufferSize(1, 1) + .setName(TITLE) + .setBLASTLayer() .setFormat(PixelFormat.TRANSLUCENT) - .setCallsite("Watermark") + .setCallsite(TITLE) .build(); t.setLayer(ctrl, WindowManagerService.TYPE_LAYER_MULTIPLIER * 100) .setPosition(ctrl, 0, 0) .show(ctrl); // Ensure we aren't considered as obscuring for Input purposes. - InputMonitor.setTrustedOverlayInputInfo(ctrl, t, dc.getDisplayId(), "Watermark"); - mSurface.copyFrom(ctrl); + InputMonitor.setTrustedOverlayInputInfo(ctrl, t, dc.getDisplayId(), TITLE); } catch (OutOfResourcesException e) { } mSurfaceControl = ctrl; + mBlastBufferQueue = new BLASTBufferQueue(TITLE, mSurfaceControl, 1 /* width */, + 1 /* height */, PixelFormat.RGBA_8888); + mSurface = mBlastBufferQueue.createSurface(); } void positionSurface(int dw, int dh, SurfaceControl.Transaction t) { @@ -144,45 +140,46 @@ class Watermark { } void drawIfNeeded() { - if (mDrawNeeded) { - final int dw = mLastDW; - final int dh = mLastDH; + if (!mDrawNeeded) { + return; + } - mDrawNeeded = false; - Rect dirty = new Rect(0, 0, dw, dh); - Canvas c = null; - try { - c = mSurface.lockCanvas(dirty); - } catch (IllegalArgumentException e) { - } catch (Surface.OutOfResourcesException e) { + final int dw = mLastDW; + final int dh = mLastDH; + + mDrawNeeded = false; + mBlastBufferQueue.update(mSurfaceControl, dw, dh, PixelFormat.RGBA_8888); + Canvas c = null; + try { + c = mSurface.lockCanvas(null); + } catch (IllegalArgumentException | OutOfResourcesException e) { + } + if (c != null) { + c.drawColor(0, PorterDuff.Mode.CLEAR); + + int deltaX = mDeltaX; + int deltaY = mDeltaY; + + // deltaX shouldn't be close to a round fraction of our + // x step, or else things will line up too much. + int div = (dw + mTextWidth) / deltaX; + int rem = (dw + mTextWidth) - (div * deltaX); + int qdelta = deltaX / 4; + if (rem < qdelta || rem > (deltaX - qdelta)) { + deltaX += deltaX / 3; } - if (c != null) { - c.drawColor(0, PorterDuff.Mode.CLEAR); - int deltaX = mDeltaX; - int deltaY = mDeltaY; - - // deltaX shouldn't be close to a round fraction of our - // x step, or else things will line up too much. - int div = (dw+mTextWidth)/deltaX; - int rem = (dw+mTextWidth) - (div*deltaX); - int qdelta = deltaX/4; - if (rem < qdelta || rem > (deltaX-qdelta)) { - deltaX += deltaX/3; + int y = -mTextHeight; + int x = -mTextWidth; + while (y < (dh + mTextHeight)) { + c.drawText(mText, x, y, mTextPaint); + x += deltaX; + if (x >= dw) { + x -= (dw + mTextWidth); + y += deltaY; } - - int y = -mTextHeight; - int x = -mTextWidth; - while (y < (dh+mTextHeight)) { - c.drawText(mText, x, y, mTextPaint); - x += deltaX; - if (x >= dw) { - x -= (dw+mTextWidth); - y += deltaY; - } - } - mSurface.unlockCanvasAndPost(c); } + mSurface.unlockCanvasAndPost(c); } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 12c9b972ceccf..3d84ca7212f15 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3659,7 +3659,7 @@ public class WindowManagerService extends IWindowManager.Stub if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, ">>> showEmulatorDisplayOverlay"); if (mEmulatorDisplayOverlay == null) { - mEmulatorDisplayOverlay = new EmulatorDisplayOverlay(mSurfaceFactory, mContext, + mEmulatorDisplayOverlay = new EmulatorDisplayOverlay(mContext, getDefaultDisplayContentLocked(), mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_POINTER) * TYPE_LAYER_MULTIPLIER + 10, mTransaction); @@ -3699,8 +3699,8 @@ public class WindowManagerService extends IWindowManager.Stub // b/31532461 // TODO(multi-display): support multiple displays if (mStrictModeFlash == null) { - mStrictModeFlash = new StrictModeFlash(mSurfaceFactory, - getDefaultDisplayContentLocked(), mTransaction); + mStrictModeFlash = new StrictModeFlash(getDefaultDisplayContentLocked(), + mTransaction); } mStrictModeFlash.setVisibility(on, mTransaction); mTransaction.apply(); @@ -5895,8 +5895,8 @@ public class WindowManagerService extends IWindowManager.Stub if (toks != null && toks.length > 0) { // TODO(multi-display): Show watermarks on secondary displays. final DisplayContent displayContent = getDefaultDisplayContentLocked(); - mWatermark = new Watermark(mSurfaceFactory, displayContent, - displayContent.mRealDisplayMetrics, toks, mTransaction); + mWatermark = new Watermark(displayContent, displayContent.mRealDisplayMetrics, + toks, mTransaction); mTransaction.apply(); } }