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

Commit 511dc4a1 authored by Graciela Wissen Putri's avatar Graciela Wissen Putri
Browse files

Refine size compat restart button visibility heuristics

With the status bar decoupled change reverted, we need to tweak the
tolerance slightly lower to hide size compat restart button in all
rotations when unfolded.

Landscape app with any aspect ratio should also have size compat restart
button hidden if the app fills the available width.

Bug: 330359576
Test: atest CompatUIWindowManagerTest

Merged-In: I2da5060b3c52c15e07d46a472615f68b1a495060
Change-Id: I2da5060b3c52c15e07d46a472615f68b1a495060
parent 4a5835b5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -194,6 +194,10 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi
        return mHideSizeCompatRestartButtonTolerance;
    }

    int getDefaultHideRestartButtonTolerance() {
        return MAX_PERCENTAGE_VAL;
    }

    boolean getHasSeenLetterboxEducation(int userId) {
        return mLetterboxEduSharedPreferences
                .getBoolean(dontShowLetterboxEduKey(userId), /* default= */ false);
+23 −14
Original line number Diff line number Diff line
@@ -20,11 +20,11 @@ import static android.app.AppCompatTaskInfo.CAMERA_COMPAT_CONTROL_DISMISSED;
import static android.app.AppCompatTaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
import static android.app.AppCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
import static android.app.AppCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
import static android.view.WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
import static android.window.TaskConstants.TASK_CHILD_LAYER_COMPAT_UI;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppCompatTaskInfo;
import android.app.AppCompatTaskInfo.CameraCompatControlState;
import android.app.TaskInfo;
import android.content.Context;
@@ -217,14 +217,30 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {

    @VisibleForTesting
    boolean shouldShowSizeCompatRestartButton(@NonNull TaskInfo taskInfo) {
        if (!Flags.allowHideScmButton()) {
        // Always show button if display is phone sized.
        if (!Flags.allowHideScmButton() || taskInfo.configuration.smallestScreenWidthDp
                < LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP) {
            return true;
        }
        final AppCompatTaskInfo appCompatTaskInfo = taskInfo.appCompatTaskInfo;
        final Rect taskBounds = taskInfo.configuration.windowConfiguration.getBounds();
        final int letterboxArea = computeArea(appCompatTaskInfo.topActivityLetterboxWidth,
                appCompatTaskInfo.topActivityLetterboxHeight);
        final int taskArea = computeArea(taskBounds.width(), taskBounds.height());

        final int letterboxWidth = taskInfo.appCompatTaskInfo.topActivityLetterboxWidth;
        final int letterboxHeight = taskInfo.appCompatTaskInfo.topActivityLetterboxHeight;
        final Rect stableBounds = getTaskStableBounds();
        final int appWidth = stableBounds.width();
        final int appHeight = stableBounds.height();
        // App is floating, should always show restart button.
        if (appWidth > letterboxWidth && appHeight > letterboxHeight) {
            return true;
        }
        // If app fills the width of the display, don't show restart button (for landscape apps)
        // if device has a custom tolerance value.
        if (mHideScmTolerance != mCompatUIConfiguration.getDefaultHideRestartButtonTolerance()
                && appWidth == letterboxWidth)  {
            return false;
        }

        final int letterboxArea = letterboxWidth * letterboxHeight;
        final int taskArea = appWidth * appHeight;
        if (letterboxArea == 0 || taskArea == 0) {
            return false;
        }
@@ -232,13 +248,6 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
        return percentageAreaOfLetterboxInTask < mHideScmTolerance;
    }

    private int computeArea(int width, int height) {
        if (width == 0 || height == 0) {
            return 0;
        }
        return width * height;
    }

    private void updateVisibilityOfViews() {
        if (mLayout == null) {
            return;
+37 −14
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.app.AppCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPL
import static android.app.AppCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;

@@ -98,14 +99,28 @@ public class CompatUIWindowManagerTest extends ShellTestCase {

    private CompatUIWindowManager mWindowManager;
    private TaskInfo mTaskInfo;
    private DisplayLayout mDisplayLayout;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        doReturn(100).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance();
        mTaskInfo = createTaskInfo(/* hasSizeCompat= */ false, CAMERA_COMPAT_CONTROL_HIDDEN);

        final DisplayInfo displayInfo = new DisplayInfo();
        displayInfo.logicalWidth = TASK_WIDTH;
        displayInfo.logicalHeight = TASK_HEIGHT;
        mDisplayLayout = new DisplayLayout(displayInfo,
                mContext.getResources(), /* hasNavigationBar= */ true, /* hasStatusBar= */ false);
        final InsetsState insetsState = new InsetsState();
        insetsState.setDisplayFrame(new Rect(0, 0, TASK_WIDTH, TASK_HEIGHT));
        final InsetsSource insetsSource = new InsetsSource(
                InsetsSource.createId(null, 0, navigationBars()), navigationBars());
        insetsSource.setFrame(0, TASK_HEIGHT - 200, TASK_WIDTH, TASK_HEIGHT);
        insetsState.addSource(insetsSource);
        mDisplayLayout.setInsets(mContext.getResources(), insetsState);
        mWindowManager = new CompatUIWindowManager(mContext, mTaskInfo, mSyncTransactionQueue,
                mCallback, mTaskListener, new DisplayLayout(), new CompatUIHintsState(),
                mCallback, mTaskListener, mDisplayLayout, new CompatUIHintsState(),
                mCompatUIConfiguration, mOnRestartButtonClicked);

        spyOn(mWindowManager);
@@ -363,9 +378,9 @@ public class CompatUIWindowManagerTest extends ShellTestCase {

        // Update if the insets change on the existing display layout
        clearInvocations(mWindowManager);
        InsetsState insetsState = new InsetsState();
        final InsetsState insetsState = new InsetsState();
        insetsState.setDisplayFrame(new Rect(0, 0, 1000, 2000));
        InsetsSource insetsSource = new InsetsSource(
        final InsetsSource insetsSource = new InsetsSource(
                InsetsSource.createId(null, 0, navigationBars()), navigationBars());
        insetsSource.setFrame(0, 1800, 1000, 2000);
        insetsState.addSource(insetsSource);
@@ -493,16 +508,14 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
    @Test
    public void testShouldShowSizeCompatRestartButton() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_HIDE_SCM_BUTTON);

        doReturn(86).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance();
        doReturn(85).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance();
        mWindowManager = new CompatUIWindowManager(mContext, mTaskInfo, mSyncTransactionQueue,
                mCallback, mTaskListener, new DisplayLayout(), new CompatUIHintsState(),
                mCallback, mTaskListener, mDisplayLayout, new CompatUIHintsState(),
                mCompatUIConfiguration, mOnRestartButtonClicked);

        // Simulate rotation of activity in square display
        TaskInfo taskInfo = createTaskInfo(true, CAMERA_COMPAT_CONTROL_HIDDEN);
        taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 2000, 2000));
        taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 2000;
        taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = TASK_HEIGHT;
        taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1850;

        assertFalse(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));
@@ -512,11 +525,21 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
        assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));

        // Simulate folding
        taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 1000, 2000));
        assertFalse(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));
        final InsetsState insetsState = new InsetsState();
        insetsState.setDisplayFrame(new Rect(0, 0, 1000, TASK_HEIGHT));
        final InsetsSource insetsSource = new InsetsSource(
                InsetsSource.createId(null, 0, navigationBars()), navigationBars());
        insetsSource.setFrame(0, TASK_HEIGHT - 200, 1000, TASK_HEIGHT);
        insetsState.addSource(insetsSource);
        mDisplayLayout.setInsets(mContext.getResources(), insetsState);
        mWindowManager.updateDisplayLayout(mDisplayLayout);
        taskInfo.configuration.smallestScreenWidthDp = LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP - 100;
        assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));

        taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1000;
        taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 500;
        // Simulate floating app with 90& area, more than tolerance
        taskInfo.configuration.smallestScreenWidthDp = LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
        taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 950;
        taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 1900;
        assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo));
    }

@@ -528,10 +551,10 @@ public class CompatUIWindowManagerTest extends ShellTestCase {
        taskInfo.appCompatTaskInfo.cameraCompatControlState = cameraCompatControlState;
        taskInfo.configuration.uiMode &= ~Configuration.UI_MODE_TYPE_DESK;
        // Letterboxed activity that takes half the screen should show size compat restart button
        taskInfo.configuration.windowConfiguration.setBounds(
                new Rect(0, 0, TASK_WIDTH, TASK_HEIGHT));
        taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 1000;
        taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1000;
        // Screen width dp larger than a normal phone.
        taskInfo.configuration.smallestScreenWidthDp = LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
        return taskInfo;
    }
}