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

Commit d8dab8a7 authored by Graciela Wissen Putri's avatar Graciela Wissen Putri
Browse files

Allow display letterbox if starting or base application

If there are two windows of TYPE_APPLICATION_STARTING and
TYPE_BASE_APPLICATION, we should allow letterbox to be shown if one of
the windows are letterboxed even though it's not on the top z order.
This will prevent flickering when the letterboxed window is brought to
top.

Bug: 317319213
Test: atest SizeCompatTests
      Open YT video in explore page
Change-Id: I4fcf4785a6b6a50e7baeabf28efd83a3dd11b7f4
parent 6b135b01
Loading
Loading
Loading
Loading
+17 −13
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@ import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
@@ -927,8 +929,7 @@ final class LetterboxUiController {
    }

    void updateLetterboxSurface(WindowState winHint, Transaction t) {
        final WindowState w = mActivityRecord.findMainWindow();
        if (w != winHint && winHint != null && w != null) {
        if (shouldNotLayoutLetterbox(winHint)) {
            return;
        }
        layoutLetterbox(winHint);
@@ -937,20 +938,11 @@ final class LetterboxUiController {
        }
    }

    void layoutLetterbox(WindowState winHint) {
        final WindowState w = mActivityRecord.findMainWindow();
        if (w == null || winHint != null && w != winHint) {
    void layoutLetterbox(WindowState w) {
        if (shouldNotLayoutLetterbox(w)) {
            return;
        }
        updateRoundedCornersIfNeeded(w);
        // If there is another main window that is not an application-starting window, we should
        // update rounded corners for it as well, to avoid flickering rounded corners.
        final WindowState nonStartingAppW = mActivityRecord.findMainWindow(
                /* includeStartingApp= */ false);
        if (nonStartingAppW != null && nonStartingAppW != w) {
            updateRoundedCornersIfNeeded(nonStartingAppW);
        }

        updateWallpaperForLetterbox(w);
        if (shouldShowLetterboxUi(w)) {
            if (mLetterbox == null) {
@@ -1023,6 +1015,18 @@ final class LetterboxUiController {
        return mActivityRecord.getSurfaceControl();
    }

    private static boolean shouldNotLayoutLetterbox(WindowState w) {
        if (w == null) {
            return true;
        }
        final int type = w.mAttrs.type;
        // Allow letterbox to be displayed early for base application or application starting
        // windows even if it is not on the top z order to prevent flickering when the
        // letterboxed window is brought to the top
        return (type != TYPE_BASE_APPLICATION && type != TYPE_APPLICATION_STARTING)
                || w.mAnimatingExit;
    }

    private boolean shouldLetterboxHaveRoundedCorners() {
        // TODO(b/214030873): remove once background is drawn for transparent activities
        // Letterbox shouldn't have rounded corners if the activity is transparent
+29 −1
Original line number Diff line number Diff line
@@ -844,6 +844,30 @@ public class SizeCompatTests extends WindowTestsBase {
                mActivity.getBounds(), appWindow.getBounds());
    }

    @Test
    public void testLetterboxDisplayedForWindowBelow() {
        setUpDisplaySizeWithApp(1000, 2500);
        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
        // Prepare two windows, one base app window below the splash screen
        final WindowState appWindow = addWindowToActivity(mActivity);
        final WindowState startWindow = addWindowToActivity(mActivity, TYPE_APPLICATION_STARTING);
        spyOn(appWindow);
        // Base app window is letterboxed for display cutout and splash screen is fullscreen
        doReturn(true).when(appWindow).isLetterboxedForDisplayCutout();

        mActivity.mRootWindowContainer.performSurfacePlacement();

        assertEquals(2, mActivity.mChildren.size());
        // Splash screen is still the activity's main window
        assertEquals(startWindow, mActivity.findMainWindow());
        assertFalse(startWindow.isLetterboxedForDisplayCutout());

        final Rect letterboxInnerBounds = new Rect();
        mActivity.getLetterboxInnerBounds(letterboxInnerBounds);
        // Letterboxed is still displayed for app window below splash screen
        assertFalse(letterboxInnerBounds.isEmpty());
    }

    @Test
    public void testLetterboxFullscreenBoundsAndNotImeAttachable() {
        final int displayWidth = 2500;
@@ -4773,8 +4797,12 @@ public class SizeCompatTests extends WindowTestsBase {
    }

    private WindowState addWindowToActivity(ActivityRecord activity) {
        return addWindowToActivity(activity, WindowManager.LayoutParams.TYPE_BASE_APPLICATION);
    }

    private WindowState addWindowToActivity(ActivityRecord activity, int type) {
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
        params.type = type;
        params.setFitInsetsSides(0);
        params.setFitInsetsTypes(0);
        final TestWindowState w = new TestWindowState(