Loading libs/WindowManager/Shell/res/values/config.xml +7 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,13 @@ <!-- Whether the additional education about reachability is enabled --> <bool name="config_letterboxIsReachabilityEducationEnabled">false</bool> <!-- The minimum tolerance of the percentage of activity bounds within its task to hide size compat restart button. Value lower than 0 or higher than 100 will be ignored. 100 is the default value where the activity has to fit exactly within the task to allow size compat restart button to be hidden. 0 means size compat restart button will always be hidden. --> <integer name="config_letterboxRestartButtonHideTolerance">100</integer> <!-- Whether DragAndDrop capability is enabled --> <bool name="config_enableShellDragDrop">true</bool> Loading libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIConfiguration.java +24 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,8 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi private static final String HAS_SEEN_VERTICAL_REACHABILITY_EDUCATION_KEY_PREFIX = "has_seen_vertical_reachability_education"; private static final int MAX_PERCENTAGE_VAL = 100; /** * The {@link SharedPreferences} instance for the restart dialog and the reachability * education. Loading @@ -82,6 +84,12 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi */ private final SharedPreferences mLetterboxEduSharedPreferences; /** * The minimum tolerance of the percentage of activity bounds within its task to hide * size compat restart button. */ private final int mHideSizeCompatRestartButtonTolerance; // Whether the extended restart dialog is enabled private boolean mIsRestartDialogEnabled; Loading @@ -106,6 +114,9 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi R.bool.config_letterboxIsRestartDialogEnabled); mIsReachabilityEducationEnabled = context.getResources().getBoolean( R.bool.config_letterboxIsReachabilityEducationEnabled); final int tolerance = context.getResources().getInteger( R.integer.config_letterboxRestartButtonHideTolerance); mHideSizeCompatRestartButtonTolerance = getHideSizeCompatRestartButtonTolerance(tolerance); mIsLetterboxRestartDialogAllowed = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_ENABLE_LETTERBOX_RESTART_DIALOG, DEFAULT_VALUE_ENABLE_LETTERBOX_RESTART_DIALOG); Loading Loading @@ -179,6 +190,10 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi || !hasSeenVerticalReachabilityEducation(taskInfo)); } int getHideSizeCompatRestartButtonTolerance() { return mHideSizeCompatRestartButtonTolerance; } boolean getHasSeenLetterboxEducation(int userId) { return mLetterboxEduSharedPreferences .getBoolean(dontShowLetterboxEduKey(userId), /* default= */ false); Loading Loading @@ -218,6 +233,15 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi } } // Returns the minimum tolerance of the percentage of activity bounds within its task to hide // size compat restart button. Value lower than 0 or higher than 100 will be ignored. // 100 is the default value where the activity has to fit exactly within the task to allow // size compat restart button to be hidden. 0 means size compat restart button will always // be hidden. private int getHideSizeCompatRestartButtonTolerance(int tolerance) { return tolerance < 0 || tolerance > MAX_PERCENTAGE_VAL ? MAX_PERCENTAGE_VAL : tolerance; } private boolean isReachabilityEducationEnabled() { return mIsReachabilityEducationOverrideEnabled || (mIsReachabilityEducationEnabled && mIsLetterboxReachabilityEducationAllowed); Loading libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java +39 −2 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import static android.app.AppCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPL import static android.app.AppCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED; 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; Loading @@ -33,6 +35,7 @@ import android.view.LayoutInflater; import android.view.View; import com.android.internal.annotations.VisibleForTesting; import com.android.window.flags.Flags; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayLayout; Loading Loading @@ -68,6 +71,8 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { @VisibleForTesting CompatUILayout mLayout; private final float mHideScmTolerance; CompatUIWindowManager(Context context, TaskInfo taskInfo, SyncTransactionQueue syncQueue, CompatUICallback callback, ShellTaskOrganizer.TaskListener taskListener, DisplayLayout displayLayout, Loading @@ -75,11 +80,13 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> onRestartButtonClicked) { super(context, taskInfo, syncQueue, taskListener, displayLayout); mCallback = callback; mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat; mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat && shouldShowSizeCompatRestartButton(taskInfo); mCameraCompatControlState = taskInfo.appCompatTaskInfo.cameraCompatControlState; mCompatUIHintsState = compatUIHintsState; mCompatUIConfiguration = compatUIConfiguration; mOnRestartButtonClicked = onRestartButtonClicked; mHideScmTolerance = mCompatUIConfiguration.getHideSizeCompatRestartButtonTolerance(); } @Override Loading Loading @@ -107,6 +114,11 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { mLayout = inflateLayout(); mLayout.inject(this); final TaskInfo taskInfo = getLastTaskInfo(); if (taskInfo != null) { mHasSizeCompat = mHasSizeCompat && shouldShowSizeCompatRestartButton(taskInfo); } updateVisibilityOfViews(); if (mHasSizeCompat) { Loading @@ -127,7 +139,8 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { boolean canShow) { final boolean prevHasSizeCompat = mHasSizeCompat; final int prevCameraCompatControlState = mCameraCompatControlState; mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat; mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat && shouldShowSizeCompatRestartButton(taskInfo); mCameraCompatControlState = taskInfo.appCompatTaskInfo.cameraCompatControlState; if (!super.updateCompatInfo(taskInfo, taskListener, canShow)) { Loading Loading @@ -208,6 +221,30 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { updateSurfacePosition(positionX, positionY); } @VisibleForTesting boolean shouldShowSizeCompatRestartButton(@NonNull TaskInfo taskInfo) { if (!Flags.allowHideScmButton()) { 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()); if (letterboxArea == 0 || taskArea == 0) { return false; } final float percentageAreaOfLetterboxInTask = (float) letterboxArea / taskArea * 100; 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; Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java +43 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ 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.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT; import static android.view.WindowInsets.Type.navigationBars; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; Loading @@ -27,6 +29,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; Loading @@ -39,6 +42,7 @@ import android.app.AppCompatTaskInfo; import android.app.TaskInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.platform.test.flag.junit.SetFlagsRule; import android.testing.AndroidTestingRunner; import android.util.Pair; import android.view.DisplayInfo; Loading @@ -50,6 +54,7 @@ import android.view.View; import androidx.test.filters.SmallTest; import com.android.window.flags.Flags; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.common.DisplayLayout; Loading @@ -59,6 +64,7 @@ import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState; import junit.framework.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; Loading @@ -76,6 +82,8 @@ import java.util.function.Consumer; @RunWith(AndroidTestingRunner.class) @SmallTest public class CompatUIWindowManagerTest extends ShellTestCase { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT); private static final int TASK_ID = 1; Loading Loading @@ -107,6 +115,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase { public void testCreateSizeCompatButton() { // Doesn't create layout if show is false. mWindowManager.mHasSizeCompat = true; doReturn(true).when(mWindowManager).shouldShowSizeCompatRestartButton(mTaskInfo); assertTrue(mWindowManager.createLayout(/* canShow= */ false)); verify(mWindowManager, never()).inflateLayout(); Loading Loading @@ -199,6 +208,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase { // No diff clearInvocations(mWindowManager); TaskInfo taskInfo = createTaskInfo(/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN); doReturn(true).when(mWindowManager).shouldShowSizeCompatRestartButton(any()); assertTrue(mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true)); verify(mWindowManager, never()).updateSurfacePosition(); Loading Loading @@ -284,6 +294,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase { @Test public void testUpdateCompatInfoLayoutNotInflatedYet() { mWindowManager.mHasSizeCompat = true; doReturn(true).when(mWindowManager).shouldShowSizeCompatRestartButton(any()); mWindowManager.createLayout(/* canShow= */ false); verify(mWindowManager, never()).inflateLayout(); Loading Loading @@ -353,6 +364,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase { // Create button if it is not created. mWindowManager.mLayout = null; mWindowManager.mHasSizeCompat = true; doReturn(true).when(mWindowManager).shouldShowSizeCompatRestartButton(mTaskInfo); mWindowManager.updateVisibility(/* canShow= */ true); verify(mWindowManager).createLayout(/* canShow= */ true); Loading Loading @@ -464,6 +476,37 @@ public class CompatUIWindowManagerTest extends ShellTestCase { Assert.assertTrue(mWindowManager.needsToBeRecreated(newTaskInfo, mTaskListener)); } @Test public void testShouldShowSizeCompatRestartButton() { mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_HIDE_SCM_BUTTON); doReturn(86).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance(); mWindowManager = new CompatUIWindowManager(mContext, mTaskInfo, mSyncTransactionQueue, mCallback, mTaskListener, new DisplayLayout(), 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.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN); taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1850; assertFalse(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo)); // Simulate exiting split screen/folding taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1000; assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo)); // Simulate folding taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 1000, 2000)); assertFalse(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo)); taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1000; taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 500; assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo)); } private static TaskInfo createTaskInfo(boolean hasSizeCompat, @AppCompatTaskInfo.CameraCompatControlState int cameraCompatControlState) { ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo(); Loading services/core/java/com/android/server/wm/Task.java +3 −1 Original line number Diff line number Diff line Loading @@ -3558,9 +3558,11 @@ class Task extends TaskFragment { && top.mLetterboxUiController.isSystemOverrideToFullscreenEnabled(); appCompatTaskInfo.isFromLetterboxDoubleTap = top != null && top.mLetterboxUiController.isFromDoubleTap(); if (appCompatTaskInfo.isLetterboxDoubleTapEnabled) { if (top != null) { appCompatTaskInfo.topActivityLetterboxWidth = top.getBounds().width(); appCompatTaskInfo.topActivityLetterboxHeight = top.getBounds().height(); } if (appCompatTaskInfo.isLetterboxDoubleTapEnabled) { if (appCompatTaskInfo.isTopActivityPillarboxed()) { // Pillarboxed appCompatTaskInfo.topActivityLetterboxHorizontalPosition = Loading Loading
libs/WindowManager/Shell/res/values/config.xml +7 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,13 @@ <!-- Whether the additional education about reachability is enabled --> <bool name="config_letterboxIsReachabilityEducationEnabled">false</bool> <!-- The minimum tolerance of the percentage of activity bounds within its task to hide size compat restart button. Value lower than 0 or higher than 100 will be ignored. 100 is the default value where the activity has to fit exactly within the task to allow size compat restart button to be hidden. 0 means size compat restart button will always be hidden. --> <integer name="config_letterboxRestartButtonHideTolerance">100</integer> <!-- Whether DragAndDrop capability is enabled --> <bool name="config_enableShellDragDrop">true</bool> Loading
libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIConfiguration.java +24 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,8 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi private static final String HAS_SEEN_VERTICAL_REACHABILITY_EDUCATION_KEY_PREFIX = "has_seen_vertical_reachability_education"; private static final int MAX_PERCENTAGE_VAL = 100; /** * The {@link SharedPreferences} instance for the restart dialog and the reachability * education. Loading @@ -82,6 +84,12 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi */ private final SharedPreferences mLetterboxEduSharedPreferences; /** * The minimum tolerance of the percentage of activity bounds within its task to hide * size compat restart button. */ private final int mHideSizeCompatRestartButtonTolerance; // Whether the extended restart dialog is enabled private boolean mIsRestartDialogEnabled; Loading @@ -106,6 +114,9 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi R.bool.config_letterboxIsRestartDialogEnabled); mIsReachabilityEducationEnabled = context.getResources().getBoolean( R.bool.config_letterboxIsReachabilityEducationEnabled); final int tolerance = context.getResources().getInteger( R.integer.config_letterboxRestartButtonHideTolerance); mHideSizeCompatRestartButtonTolerance = getHideSizeCompatRestartButtonTolerance(tolerance); mIsLetterboxRestartDialogAllowed = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_WINDOW_MANAGER, KEY_ENABLE_LETTERBOX_RESTART_DIALOG, DEFAULT_VALUE_ENABLE_LETTERBOX_RESTART_DIALOG); Loading Loading @@ -179,6 +190,10 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi || !hasSeenVerticalReachabilityEducation(taskInfo)); } int getHideSizeCompatRestartButtonTolerance() { return mHideSizeCompatRestartButtonTolerance; } boolean getHasSeenLetterboxEducation(int userId) { return mLetterboxEduSharedPreferences .getBoolean(dontShowLetterboxEduKey(userId), /* default= */ false); Loading Loading @@ -218,6 +233,15 @@ public class CompatUIConfiguration implements DeviceConfig.OnPropertiesChangedLi } } // Returns the minimum tolerance of the percentage of activity bounds within its task to hide // size compat restart button. Value lower than 0 or higher than 100 will be ignored. // 100 is the default value where the activity has to fit exactly within the task to allow // size compat restart button to be hidden. 0 means size compat restart button will always // be hidden. private int getHideSizeCompatRestartButtonTolerance(int tolerance) { return tolerance < 0 || tolerance > MAX_PERCENTAGE_VAL ? MAX_PERCENTAGE_VAL : tolerance; } private boolean isReachabilityEducationEnabled() { return mIsReachabilityEducationOverrideEnabled || (mIsReachabilityEducationEnabled && mIsLetterboxReachabilityEducationAllowed); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java +39 −2 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import static android.app.AppCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_APPL import static android.app.AppCompatTaskInfo.CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED; 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; Loading @@ -33,6 +35,7 @@ import android.view.LayoutInflater; import android.view.View; import com.android.internal.annotations.VisibleForTesting; import com.android.window.flags.Flags; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayLayout; Loading Loading @@ -68,6 +71,8 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { @VisibleForTesting CompatUILayout mLayout; private final float mHideScmTolerance; CompatUIWindowManager(Context context, TaskInfo taskInfo, SyncTransactionQueue syncQueue, CompatUICallback callback, ShellTaskOrganizer.TaskListener taskListener, DisplayLayout displayLayout, Loading @@ -75,11 +80,13 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> onRestartButtonClicked) { super(context, taskInfo, syncQueue, taskListener, displayLayout); mCallback = callback; mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat; mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat && shouldShowSizeCompatRestartButton(taskInfo); mCameraCompatControlState = taskInfo.appCompatTaskInfo.cameraCompatControlState; mCompatUIHintsState = compatUIHintsState; mCompatUIConfiguration = compatUIConfiguration; mOnRestartButtonClicked = onRestartButtonClicked; mHideScmTolerance = mCompatUIConfiguration.getHideSizeCompatRestartButtonTolerance(); } @Override Loading Loading @@ -107,6 +114,11 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { mLayout = inflateLayout(); mLayout.inject(this); final TaskInfo taskInfo = getLastTaskInfo(); if (taskInfo != null) { mHasSizeCompat = mHasSizeCompat && shouldShowSizeCompatRestartButton(taskInfo); } updateVisibilityOfViews(); if (mHasSizeCompat) { Loading @@ -127,7 +139,8 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { boolean canShow) { final boolean prevHasSizeCompat = mHasSizeCompat; final int prevCameraCompatControlState = mCameraCompatControlState; mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat; mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat && shouldShowSizeCompatRestartButton(taskInfo); mCameraCompatControlState = taskInfo.appCompatTaskInfo.cameraCompatControlState; if (!super.updateCompatInfo(taskInfo, taskListener, canShow)) { Loading Loading @@ -208,6 +221,30 @@ class CompatUIWindowManager extends CompatUIWindowManagerAbstract { updateSurfacePosition(positionX, positionY); } @VisibleForTesting boolean shouldShowSizeCompatRestartButton(@NonNull TaskInfo taskInfo) { if (!Flags.allowHideScmButton()) { 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()); if (letterboxArea == 0 || taskArea == 0) { return false; } final float percentageAreaOfLetterboxInTask = (float) letterboxArea / taskArea * 100; 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; Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java +43 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ 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.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT; import static android.view.WindowInsets.Type.navigationBars; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; Loading @@ -27,6 +29,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; Loading @@ -39,6 +42,7 @@ import android.app.AppCompatTaskInfo; import android.app.TaskInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.platform.test.flag.junit.SetFlagsRule; import android.testing.AndroidTestingRunner; import android.util.Pair; import android.view.DisplayInfo; Loading @@ -50,6 +54,7 @@ import android.view.View; import androidx.test.filters.SmallTest; import com.android.window.flags.Flags; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.common.DisplayLayout; Loading @@ -59,6 +64,7 @@ import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState; import junit.framework.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; Loading @@ -76,6 +82,8 @@ import java.util.function.Consumer; @RunWith(AndroidTestingRunner.class) @SmallTest public class CompatUIWindowManagerTest extends ShellTestCase { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT); private static final int TASK_ID = 1; Loading Loading @@ -107,6 +115,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase { public void testCreateSizeCompatButton() { // Doesn't create layout if show is false. mWindowManager.mHasSizeCompat = true; doReturn(true).when(mWindowManager).shouldShowSizeCompatRestartButton(mTaskInfo); assertTrue(mWindowManager.createLayout(/* canShow= */ false)); verify(mWindowManager, never()).inflateLayout(); Loading Loading @@ -199,6 +208,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase { // No diff clearInvocations(mWindowManager); TaskInfo taskInfo = createTaskInfo(/* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN); doReturn(true).when(mWindowManager).shouldShowSizeCompatRestartButton(any()); assertTrue(mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true)); verify(mWindowManager, never()).updateSurfacePosition(); Loading Loading @@ -284,6 +294,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase { @Test public void testUpdateCompatInfoLayoutNotInflatedYet() { mWindowManager.mHasSizeCompat = true; doReturn(true).when(mWindowManager).shouldShowSizeCompatRestartButton(any()); mWindowManager.createLayout(/* canShow= */ false); verify(mWindowManager, never()).inflateLayout(); Loading Loading @@ -353,6 +364,7 @@ public class CompatUIWindowManagerTest extends ShellTestCase { // Create button if it is not created. mWindowManager.mLayout = null; mWindowManager.mHasSizeCompat = true; doReturn(true).when(mWindowManager).shouldShowSizeCompatRestartButton(mTaskInfo); mWindowManager.updateVisibility(/* canShow= */ true); verify(mWindowManager).createLayout(/* canShow= */ true); Loading Loading @@ -464,6 +476,37 @@ public class CompatUIWindowManagerTest extends ShellTestCase { Assert.assertTrue(mWindowManager.needsToBeRecreated(newTaskInfo, mTaskListener)); } @Test public void testShouldShowSizeCompatRestartButton() { mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_HIDE_SCM_BUTTON); doReturn(86).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance(); mWindowManager = new CompatUIWindowManager(mContext, mTaskInfo, mSyncTransactionQueue, mCallback, mTaskListener, new DisplayLayout(), 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.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN); taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1850; assertFalse(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo)); // Simulate exiting split screen/folding taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1000; assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo)); // Simulate folding taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 1000, 2000)); assertFalse(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo)); taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = 1000; taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = 500; assertTrue(mWindowManager.shouldShowSizeCompatRestartButton(taskInfo)); } private static TaskInfo createTaskInfo(boolean hasSizeCompat, @AppCompatTaskInfo.CameraCompatControlState int cameraCompatControlState) { ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo(); Loading
services/core/java/com/android/server/wm/Task.java +3 −1 Original line number Diff line number Diff line Loading @@ -3558,9 +3558,11 @@ class Task extends TaskFragment { && top.mLetterboxUiController.isSystemOverrideToFullscreenEnabled(); appCompatTaskInfo.isFromLetterboxDoubleTap = top != null && top.mLetterboxUiController.isFromDoubleTap(); if (appCompatTaskInfo.isLetterboxDoubleTapEnabled) { if (top != null) { appCompatTaskInfo.topActivityLetterboxWidth = top.getBounds().width(); appCompatTaskInfo.topActivityLetterboxHeight = top.getBounds().height(); } if (appCompatTaskInfo.isLetterboxDoubleTapEnabled) { if (appCompatTaskInfo.isTopActivityPillarboxed()) { // Pillarboxed appCompatTaskInfo.topActivityLetterboxHorizontalPosition = Loading