Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8298aef7 authored by Massimo Carli's avatar Massimo Carli
Browse files

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
parent b353840b
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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);
            }
        }

+26 −34
Original line number Diff line number Diff line
@@ -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() {
+6 −10
Original line number Diff line number Diff line
@@ -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);
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -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> {