diff options
author | 2024-11-01 18:43:09 +0000 | |
---|---|---|
committer | 2024-12-18 13:57:56 +0000 | |
commit | 8298aef71cd3af38f2ed8fe025d08e602f5b0d8f (patch) | |
tree | af891809d453963400e94a078f3de65332138c5a | |
parent | b353840b17415db25033878e16b18a23a5f87598 (diff) |
Fix missing Input when letterbox surfaces are recreated
In the case the letterbox surfaces are recreated after a applySurfaceChanges
the InputEventReceiver needs to be reinitialized.
This happens, for instance, when we update the rounded corners size
using the adb command "adb shell wm set-letterbox-style --cornerRadius <value>"
Flag: EXEMPT Bug fixing
Bug: 308914914
Test: atest WmTests:LetterboxTest
Test: atest WmTests:LetterboxAttachInputTest
Test: follow steps on the bug description
Change-Id: Ibbf6da5f5fe018d292ee6a8251831f5ede08808f
4 files changed, 36 insertions, 47 deletions
diff --git a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java index 4e390df14131..e929fb414340 100644 --- a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java +++ b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java @@ -281,7 +281,6 @@ class AppCompatLetterboxPolicy { mActivityRecord.mWmService.mTransactionFactory, reachabilityPolicy, letterboxOverrides, this::getLetterboxParentSurface); - mLetterbox.attachInput(w); mActivityRecord.mAppCompatController.getAppCompatReachabilityPolicy() .setLetterboxInnerBoundsSupplier(mLetterbox::getInnerFrame); } @@ -335,7 +334,7 @@ class AppCompatLetterboxPolicy { } start(winHint); if (isRunning() && mLetterbox.needsApplySurfaceChanges()) { - mLetterbox.applySurfaceChanges(t, inputT); + mLetterbox.applySurfaceChanges(t, inputT, winHint); } } diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java index ca47133a0674..29c0c7b2035e 100644 --- a/services/core/java/com/android/server/wm/Letterbox.java +++ b/services/core/java/com/android/server/wm/Letterbox.java @@ -22,6 +22,7 @@ import static android.window.TaskConstants.TASK_CHILD_LAYER_LETTERBOX_BACKGROUND import static android.window.TaskConstants.TASK_CHILD_LAYER_TASK_OVERLAY; import android.annotation.NonNull; +import android.annotation.Nullable; import android.graphics.Color; import android.graphics.Point; import android.graphics.Rect; @@ -174,11 +175,12 @@ public class Letterbox { public void destroy() { mOuter.setEmpty(); mInner.setEmpty(); - + final SurfaceControl.Transaction tx = mTransactionFactory.get(); for (LetterboxSurface surface : mSurfaces) { - surface.remove(); + surface.remove(tx); } - mFullWindowSurface.remove(); + mFullWindowSurface.remove(tx); + tx.apply(); } /** Returns whether a call to {@link #applySurfaceChanges} would change the surface. */ @@ -196,30 +198,19 @@ public class Letterbox { /** Applies surface changes such as colour, window crop, position and input info. */ public void applySurfaceChanges(@NonNull SurfaceControl.Transaction t, - @NonNull SurfaceControl.Transaction inputT) { + @NonNull SurfaceControl.Transaction inputT, @NonNull WindowState windowState) { if (useFullWindowSurface()) { - mFullWindowSurface.applySurfaceChanges(t, inputT); - for (LetterboxSurface surface : mSurfaces) { - surface.remove(); + surface.remove(t); } + mFullWindowSurface.attachInput(windowState); + mFullWindowSurface.applySurfaceChanges(t, inputT); } else { + mFullWindowSurface.remove(t); for (LetterboxSurface surface : mSurfaces) { + surface.attachInput(windowState); surface.applySurfaceChanges(t, inputT); } - - mFullWindowSurface.remove(); - } - } - - /** Enables touches to slide into other neighboring surfaces. */ - void attachInput(WindowState win) { - if (useFullWindowSurface()) { - mFullWindowSurface.attachInput(win); - } else { - for (LetterboxSurface surface : mSurfaces) { - surface.attachInput(win); - } } } @@ -358,9 +349,10 @@ public class Letterbox { private final Rect mLayoutFrameGlobal = new Rect(); private final Rect mLayoutFrameRelative = new Rect(); + @Nullable private InputInterceptor mInputInterceptor; - public LetterboxSurface(String type) { + LetterboxSurface(@NonNull String type) { mType = type; } @@ -394,28 +386,28 @@ public class Letterbox { t.setLayer(mInputSurface, TASK_CHILD_LAYER_TASK_OVERLAY); } - void attachInput(WindowState win) { - if (mInputInterceptor != null) { - mInputInterceptor.dispose(); + void attachInput(@NonNull WindowState windowState) { + if (mInputInterceptor != null || windowState.mDisplayContent == null) { + return; } // TODO(b/371179559): only detect double tap on LB surfaces not used for cutout area. // Potentially, the input interceptor may still be needed for slippery feature. - mInputInterceptor = new InputInterceptor("Letterbox_" + mType + "_", win); + mInputInterceptor = new InputInterceptor("Letterbox_" + mType + "_", windowState); } - public void remove() { - if (mSurface != null) { - mTransactionFactory.get().remove(mSurface).apply(); - mSurface = null; - } - if (mInputSurface != null) { - mTransactionFactory.get().remove(mInputSurface).apply(); - mInputSurface = null; - } + void remove(@NonNull SurfaceControl.Transaction t) { if (mInputInterceptor != null) { mInputInterceptor.dispose(); mInputInterceptor = null; } + if (mSurface != null) { + t.remove(mSurface); + } + if (mInputSurface != null) { + t.remove(mInputSurface); + } + mInputSurface = null; + mSurface = null; } public int getWidth() { diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxAttachInputTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxAttachInputTest.java index 7e1de4762681..51e02405e489 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxAttachInputTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxAttachInputTest.java @@ -62,6 +62,8 @@ public class LetterboxAttachInputTest extends WindowTestsBase { private Letterbox mLetterbox; private LetterboxTest.SurfaceControlMocker mSurfaces; + private WindowState mWindowState; + @Before public void setUp() throws Exception { mSurfaces = new LetterboxTest.SurfaceControlMocker(); @@ -72,6 +74,7 @@ public class LetterboxAttachInputTest extends WindowTestsBase { doReturn(false).when(letterboxOverrides).hasWallpaperBackgroundForLetterbox(); doReturn(0).when(letterboxOverrides).getLetterboxWallpaperBlurRadiusPx(); doReturn(0.5f).when(letterboxOverrides).getLetterboxWallpaperDarkScrimAlpha(); + mWindowState = createWindowState(); mLetterbox = new Letterbox(mSurfaces, StubTransaction::new, mock(AppCompatReachabilityPolicy.class), letterboxOverrides, () -> mock(SurfaceControl.class)); @@ -83,7 +86,6 @@ public class LetterboxAttachInputTest extends WindowTestsBase { public void testSurface_createdHasSlipperyInput_scrollingFromLetterboxDisabled() { mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000)); - attachInput(); applySurfaceChanges(); assertNotNull(mSurfaces.top); @@ -100,7 +102,6 @@ public class LetterboxAttachInputTest extends WindowTestsBase { public void testInputSurface_notCreated_scrollingFromLetterboxDisabled() { mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000)); - attachInput(); applySurfaceChanges(); assertNull(mSurfaces.topInput); @@ -111,7 +112,6 @@ public class LetterboxAttachInputTest extends WindowTestsBase { public void testSurface_createdHasNoInput_scrollingFromLetterboxEnabled() { mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000)); - attachInput(); applySurfaceChanges(); assertNotNull(mSurfaces.top); @@ -124,7 +124,6 @@ public class LetterboxAttachInputTest extends WindowTestsBase { public void testInputSurface_createdHasSpyInput_scrollingFromLetterboxEnabled() { mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000)); - attachInput(); applySurfaceChanges(); assertNotNull(mSurfaces.topInput); @@ -141,7 +140,6 @@ public class LetterboxAttachInputTest extends WindowTestsBase { public void testInputSurfaceOrigin_applied_scrollingFromLetterboxEnabled() { mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000)); - attachInput(); applySurfaceChanges(); verify(mTransaction).setPosition(mSurfaces.topInput, -1000, -2000); @@ -152,7 +150,6 @@ public class LetterboxAttachInputTest extends WindowTestsBase { public void testInputSurfaceOrigin_changeCausesReapply_scrollingFromLetterboxEnabled() { mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000)); - attachInput(); applySurfaceChanges(); clearInvocations(mTransaction); mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(0, 0)); @@ -166,13 +163,12 @@ public class LetterboxAttachInputTest extends WindowTestsBase { private void applySurfaceChanges() { mLetterbox.applySurfaceChanges(/* syncTransaction */ mTransaction, - /* pendingTransaction */ mTransaction); + /* pendingTransaction */ mTransaction, mWindowState); } - private void attachInput() { + private WindowState createWindowState() { final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(); final WindowToken windowToken = createTestWindowToken(0, mDisplayContent); - WindowState windowState = createWindowState(attrs, windowToken); - mLetterbox.attachInput(windowState); + return createWindowState(attrs, windowToken); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java index 0baa5171a541..a51a44f6167b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java @@ -70,6 +70,7 @@ public class LetterboxTest { private SurfaceControl mParentSurface = mock(SurfaceControl.class); private AppCompatLetterboxOverrides mLetterboxOverrides; + private WindowState mWindowState; @Before public void setUp() throws Exception { @@ -81,6 +82,7 @@ public class LetterboxTest { doReturn(false).when(mLetterboxOverrides).hasWallpaperBackgroundForLetterbox(); doReturn(0).when(mLetterboxOverrides).getLetterboxWallpaperBlurRadiusPx(); doReturn(0.5f).when(mLetterboxOverrides).getLetterboxWallpaperDarkScrimAlpha(); + mWindowState = mock(WindowState.class); mLetterbox = new Letterbox(mSurfaces, StubTransaction::new, mock(AppCompatReachabilityPolicy.class), mLetterboxOverrides, () -> mParentSurface); mTransaction = spy(StubTransaction.class); @@ -320,7 +322,7 @@ public class LetterboxTest { private void applySurfaceChanges() { mLetterbox.applySurfaceChanges(/* syncTransaction */ mTransaction, - /* pendingTransaction */ mTransaction); + /* pendingTransaction */ mTransaction, mWindowState); } static class SurfaceControlMocker implements Supplier<SurfaceControl.Builder> { |