diff options
6 files changed, 144 insertions, 2 deletions
diff --git a/core/java/android/app/AppCompatTaskInfo.java b/core/java/android/app/AppCompatTaskInfo.java index 599f1a8be233..ea4646aa9eb9 100644 --- a/core/java/android/app/AppCompatTaskInfo.java +++ b/core/java/android/app/AppCompatTaskInfo.java @@ -102,6 +102,8 @@ public class AppCompatTaskInfo implements Parcelable { private static final int FLAG_FULLSCREEN_OVERRIDE_USER = FLAG_BASE << 8; /** Top activity flag for whether min aspect ratio of the activity has been overridden.*/ public static final int FLAG_HAS_MIN_ASPECT_RATIO_OVERRIDE = FLAG_BASE << 9; + /** Top activity flag for whether restart menu is shown due to display move. */ + private static final int FLAG_ENABLE_RESTART_MENU_FOR_DISPLAY_MOVE = FLAG_BASE << 10; @Retention(RetentionPolicy.SOURCE) @IntDef(flag = true, value = { @@ -115,7 +117,8 @@ public class AppCompatTaskInfo implements Parcelable { FLAG_ELIGIBLE_FOR_USER_ASPECT_RATIO_BUTTON, FLAG_FULLSCREEN_OVERRIDE_SYSTEM, FLAG_FULLSCREEN_OVERRIDE_USER, - FLAG_HAS_MIN_ASPECT_RATIO_OVERRIDE + FLAG_HAS_MIN_ASPECT_RATIO_OVERRIDE, + FLAG_ENABLE_RESTART_MENU_FOR_DISPLAY_MOVE }) public @interface TopActivityFlag {} @@ -133,7 +136,8 @@ public class AppCompatTaskInfo implements Parcelable { @TopActivityFlag private static final int FLAGS_COMPAT_UI_INTERESTED = FLAGS_ORGANIZER_INTERESTED - | FLAG_IN_SIZE_COMPAT | FLAG_ELIGIBLE_FOR_LETTERBOX_EDU | FLAG_LETTERBOX_EDU_ENABLED; + | FLAG_IN_SIZE_COMPAT | FLAG_ELIGIBLE_FOR_LETTERBOX_EDU | FLAG_LETTERBOX_EDU_ENABLED + | FLAG_ENABLE_RESTART_MENU_FOR_DISPLAY_MOVE; private AppCompatTaskInfo() { // Do nothing @@ -300,6 +304,21 @@ public class AppCompatTaskInfo implements Parcelable { } /** + * @return {@code true} if the restart menu is enabled for the top activity due to display move. + */ + public boolean isRestartMenuEnabledForDisplayMove() { + return isTopActivityFlagEnabled(FLAG_ENABLE_RESTART_MENU_FOR_DISPLAY_MOVE); + } + + /** + * Sets the top activity flag for whether the restart menu is enabled for the top activity due + * to display move. + */ + public void setRestartMenuEnabledForDisplayMove(boolean enable) { + setTopActivityFlag(FLAG_ENABLE_RESTART_MENU_FOR_DISPLAY_MOVE, enable); + } + + /** * @return {@code true} if the top activity bounds are letterboxed. */ public boolean isTopActivityLetterboxed() { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 452d60aecace..e91d88901751 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1716,6 +1716,7 @@ final class ActivityRecord extends WindowToken { } mAppCompatController.getLetterboxPolicy().onMovedToDisplay(mDisplayContent.getDisplayId()); + mAppCompatController.getDisplayCompatModePolicy().onMovedToDisplay(); } void layoutLetterboxIfNeeded(WindowState winHint) { @@ -8966,6 +8967,7 @@ final class ActivityRecord extends WindowToken { // Reset the existing override configuration so it can be updated according to the latest // configuration. mAppCompatController.getSizeCompatModePolicy().clearSizeCompatMode(); + mAppCompatController.getDisplayCompatModePolicy().onProcessRestarted(); if (!attachedToProcess()) { return; diff --git a/services/core/java/com/android/server/wm/AppCompatController.java b/services/core/java/com/android/server/wm/AppCompatController.java index 48f08e945a59..c479591a5e0d 100644 --- a/services/core/java/com/android/server/wm/AppCompatController.java +++ b/services/core/java/com/android/server/wm/AppCompatController.java @@ -46,6 +46,8 @@ class AppCompatController { private final AppCompatSizeCompatModePolicy mSizeCompatModePolicy; @NonNull private final AppCompatSandboxingPolicy mSandboxingPolicy; + @NonNull + private final AppCompatDisplayCompatModePolicy mDisplayCompatModePolicy; AppCompatController(@NonNull WindowManagerService wmService, @NonNull ActivityRecord activityRecord) { @@ -69,6 +71,7 @@ class AppCompatController { mSizeCompatModePolicy = new AppCompatSizeCompatModePolicy(activityRecord, mAppCompatOverrides); mSandboxingPolicy = new AppCompatSandboxingPolicy(activityRecord); + mDisplayCompatModePolicy = new AppCompatDisplayCompatModePolicy(); } @NonNull @@ -151,6 +154,11 @@ class AppCompatController { return mSandboxingPolicy; } + @NonNull + AppCompatDisplayCompatModePolicy getDisplayCompatModePolicy() { + return mDisplayCompatModePolicy; + } + void dump(@NonNull PrintWriter pw, @NonNull String prefix) { getTransparentPolicy().dump(pw, prefix); getLetterboxPolicy().dump(pw, prefix); diff --git a/services/core/java/com/android/server/wm/AppCompatDisplayCompatModePolicy.java b/services/core/java/com/android/server/wm/AppCompatDisplayCompatModePolicy.java new file mode 100644 index 000000000000..acf51707c894 --- /dev/null +++ b/services/core/java/com/android/server/wm/AppCompatDisplayCompatModePolicy.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm; + +import com.android.window.flags.Flags; + +/** + * Encapsulate app-compat logic for multi-display environments. + */ +class AppCompatDisplayCompatModePolicy { + + private boolean mIsRestartMenuEnabledForDisplayMove; + + boolean isRestartMenuEnabledForDisplayMove() { + return Flags.enableRestartMenuForConnectedDisplays() && mIsRestartMenuEnabledForDisplayMove; + } + + void onMovedToDisplay() { + mIsRestartMenuEnabledForDisplayMove = true; + } + + void onProcessRestarted() { + mIsRestartMenuEnabledForDisplayMove = false; + } +} diff --git a/services/core/java/com/android/server/wm/AppCompatUtils.java b/services/core/java/com/android/server/wm/AppCompatUtils.java index 146044008b3f..b91a12598e01 100644 --- a/services/core/java/com/android/server/wm/AppCompatUtils.java +++ b/services/core/java/com/android/server/wm/AppCompatUtils.java @@ -161,6 +161,9 @@ final class AppCompatUtils { top.mAppCompatController.getLetterboxOverrides() .isLetterboxEducationEnabled()); + appCompatTaskInfo.setRestartMenuEnabledForDisplayMove(top.mAppCompatController + .getDisplayCompatModePolicy().isRestartMenuEnabledForDisplayMove()); + final AppCompatAspectRatioOverrides aspectRatioOverrides = top.mAppCompatController.getAspectRatioOverrides(); appCompatTaskInfo.setUserFullscreenOverrideEnabled( diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayCompatTests.java new file mode 100644 index 000000000000..1445a6982c60 --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayCompatTests.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm; + +import static android.view.Display.DEFAULT_DISPLAY; + +import static com.android.window.flags.Flags.FLAG_ENABLE_RESTART_MENU_FOR_CONNECTED_DISPLAYS; + +import static junit.framework.Assert.assertFalse; + +import static org.junit.Assert.assertTrue; + +import android.compat.testing.PlatformCompatChangeRule; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.annotations.Presubmit; +import android.view.DisplayInfo; + +import androidx.test.filters.MediumTest; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +/** + * Build/Install/Run: + * atest WmTests:DisplayCompatTests + */ +@MediumTest +@Presubmit +@RunWith(WindowTestRunner.class) +public class DisplayCompatTests extends WindowTestsBase { + + @Rule + public TestRule compatChangeRule = new PlatformCompatChangeRule(); + + @EnableFlags(FLAG_ENABLE_RESTART_MENU_FOR_CONNECTED_DISPLAYS) + @Test + public void testFixedMiscConfigurationWhenMovingToDisplay() { + // Create an app on the default display, at which point the restart menu isn't enabled. + final Task task = createTask(mDefaultDisplay); + final ActivityRecord activity = createActivityRecord(task); + assertFalse(task.getTaskInfo().appCompatTaskInfo.isRestartMenuEnabledForDisplayMove()); + + // Move the app to a secondary display, and the restart menu must get enabled. + final DisplayInfo displayInfo = new DisplayInfo(); + displayInfo.copyFrom(mDisplayInfo); + displayInfo.displayId = DEFAULT_DISPLAY + 1; + final DisplayContent secondaryDisplay = createNewDisplay(displayInfo); + task.reparent(secondaryDisplay.getDefaultTaskDisplayArea(), true); + assertTrue(task.getTaskInfo().appCompatTaskInfo.isRestartMenuEnabledForDisplayMove()); + + // Once the app gets restarted, the restart menu must be gone. + activity.restartProcessIfVisible(); + assertFalse(task.getTaskInfo().appCompatTaskInfo.isRestartMenuEnabledForDisplayMove()); + } +} |