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

Commit 41877c0c authored by Kazuki Takise's avatar Kazuki Takise
Browse files

WMCore-side infra for showing restart menu

This change introduces a new class AppCompatDisplayCompatModePolicy
, which encapsulates all our compat logic related to CD (WM part).
Currently, the class only owns the policy as to when the restart
menu should be shown. It targets all apps for now, and if they are
moved to a different display, the restart menu gets enabled, and
once they are restarted, it becomes invisible. This policy is
subject to change as we're finalizing the UX of the feature.

This policy is routed to WMShell via AppCompatTaskInfo and
accessible as isRestartMenuEnabledForDisplayMove() just like other
information on app-compat.

Flag: com.android.window.flags.enable_restart_menu_for_connected_displays
Bug: 400546294
Test: WmTests:DisplayCompatTests
Change-Id: I952c0dee9802a9288af170ff62d8818aec662aec
parent 0f223887
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -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
@@ -299,6 +303,21 @@ public class AppCompatTaskInfo implements Parcelable {
        setTopActivityFlag(FLAG_IN_SIZE_COMPAT, enable);
    }

    /**
     * @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.
     */
+2 −0
Original line number Diff line number Diff line
@@ -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;
+8 −0
Original line number Diff line number Diff line
@@ -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);
+39 −0
Original line number Diff line number Diff line
/*
 * 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;
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -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(
Loading