Loading libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java +32 −5 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.wm.shell.compatui; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static com.android.wm.shell.compatui.impl.CompatUIRequestsKt.DISPLAY_COMPAT_SHOW_RESTART_DIALOG; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.TaskInfo; Loading Loading @@ -53,7 +55,9 @@ import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.compatui.api.CompatUIEvent; import com.android.wm.shell.compatui.api.CompatUIHandler; import com.android.wm.shell.compatui.api.CompatUIInfo; import com.android.wm.shell.compatui.api.CompatUIRequest; import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonClicked; import com.android.wm.shell.compatui.impl.CompatUIRequests; import com.android.wm.shell.desktopmode.DesktopUserRepositories; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import com.android.wm.shell.sysui.KeyguardChangeListener; Loading Loading @@ -245,6 +249,21 @@ public class CompatUIController implements OnDisplaysChangedListener, mCallback = callback; } @Override public void sendCompatUIRequest(CompatUIRequest compatUIRequest) { switch(compatUIRequest.getRequestId()) { case DISPLAY_COMPAT_SHOW_RESTART_DIALOG: handleDisplayCompatShowRestartDialog(compatUIRequest.asType()); break; default: } } private void handleDisplayCompatShowRestartDialog( CompatUIRequests.DisplayCompatShowRestartDialog request) { onRestartButtonClicked(new Pair<>(request.getTaskInfo(), request.getTaskListener())); } /** * Called when the Task info changed. Creates and updates the compat UI if there is an * activity in size compat, or removes the UI if there is no size compat activity. Loading @@ -254,13 +273,17 @@ public class CompatUIController implements OnDisplaysChangedListener, public void onCompatInfoChanged(@NonNull CompatUIInfo compatUIInfo) { final TaskInfo taskInfo = compatUIInfo.getTaskInfo(); final ShellTaskOrganizer.TaskListener taskListener = compatUIInfo.getListener(); if (taskInfo != null && !taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat()) { final boolean isInDisplayCompatMode = taskInfo.appCompatTaskInfo.isRestartMenuEnabledForDisplayMove(); if (taskInfo != null && !taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat() && !isInDisplayCompatMode) { mSetOfTaskIdsShowingRestartDialog.remove(taskInfo.taskId); } mIsInDesktopMode = isInDesktopMode(taskInfo); // We close all the Compat UI educations in case TaskInfo has no configuration or // TaskListener or in desktop mode. if (taskInfo.configuration == null || taskListener == null || mIsInDesktopMode) { if (taskInfo.configuration == null || taskListener == null || (mIsInDesktopMode && !isInDisplayCompatMode)) { // Null token means the current foreground activity is not in compatibility mode. removeLayouts(taskInfo.taskId); return; Loading Loading @@ -552,8 +575,11 @@ public class CompatUIController implements OnDisplaysChangedListener, @Nullable ShellTaskOrganizer.TaskListener taskListener) { RestartDialogWindowManager layout = mTaskIdToRestartDialogWindowManagerMap.get(taskInfo.taskId); final boolean isInNonDisplayCompatDesktopMode = mIsInDesktopMode && !taskInfo.appCompatTaskInfo.isRestartMenuEnabledForDisplayMove(); if (layout != null) { if (layout.needsToBeRecreated(taskInfo, taskListener) || mIsInDesktopMode) { if (layout.needsToBeRecreated(taskInfo, taskListener) || isInNonDisplayCompatDesktopMode) { mTaskIdToRestartDialogWindowManagerMap.remove(taskInfo.taskId); layout.release(); } else { Loading @@ -568,8 +594,9 @@ public class CompatUIController implements OnDisplaysChangedListener, return; } } if (mIsInDesktopMode) { // Return if in desktop mode. if (isInNonDisplayCompatDesktopMode) { // No restart dialog can be shown in desktop mode unless the task is in display compat // mode. return; } // Create a new UI layout. Loading libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIHandler.kt +5 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,11 @@ interface CompatUIHandler { */ fun onCompatInfoChanged(compatUIInfo: CompatUIInfo) /** * Invoked when another component in Shell requests a CompatUI state change. */ fun sendCompatUIRequest(compatUIRequest: CompatUIRequest) /** * Optional reference to the object responsible to send {@link CompatUIEvent} */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIRequest.kt 0 → 100644 +34 −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.wm.shell.compatui.api /** * Abstraction for all the possible Compat UI Component requests. */ interface CompatUIRequest { /** * Unique request identifier */ val requestId: Int @Suppress("UNCHECKED_CAST") fun <T : CompatUIRequest> asType(): T? = this as? T fun <T : CompatUIRequest> asType(clazz: Class<T>): T? { return if (clazz.isInstance(this)) clazz.cast(this) else null } } No newline at end of file libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIRequests.kt 0 → 100644 +33 −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.wm.shell.compatui.impl import android.app.TaskInfo import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.compatui.api.CompatUIRequest internal const val DISPLAY_COMPAT_SHOW_RESTART_DIALOG = 0 /** * All the {@link CompatUIRequest} the Compat UI Framework can handle */ sealed class CompatUIRequests(override val requestId: Int) : CompatUIRequest { /** Sent when the restart handle menu is clicked, and a restart dialog is requested. */ data class DisplayCompatShowRestartDialog(val taskInfo: TaskInfo, val taskListener: ShellTaskOrganizer.TaskListener) : CompatUIRequests(DISPLAY_COMPAT_SHOW_RESTART_DIALOG) } libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt +3 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import com.android.wm.shell.compatui.api.CompatUIEvent import com.android.wm.shell.compatui.api.CompatUIHandler import com.android.wm.shell.compatui.api.CompatUIInfo import com.android.wm.shell.compatui.api.CompatUIRepository import com.android.wm.shell.compatui.api.CompatUIRequest import com.android.wm.shell.compatui.api.CompatUIState import java.util.function.Consumer Loading Loading @@ -102,4 +103,6 @@ class DefaultCompatUIHandler( override fun setCallback(compatUIEventSender: Consumer<CompatUIEvent>?) { this.compatUIEventSender = compatUIEventSender } override fun sendCompatUIRequest(compatUIRequest: CompatUIRequest) {} } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java +32 −5 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.wm.shell.compatui; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static com.android.wm.shell.compatui.impl.CompatUIRequestsKt.DISPLAY_COMPAT_SHOW_RESTART_DIALOG; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.TaskInfo; Loading Loading @@ -53,7 +55,9 @@ import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.compatui.api.CompatUIEvent; import com.android.wm.shell.compatui.api.CompatUIHandler; import com.android.wm.shell.compatui.api.CompatUIInfo; import com.android.wm.shell.compatui.api.CompatUIRequest; import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonClicked; import com.android.wm.shell.compatui.impl.CompatUIRequests; import com.android.wm.shell.desktopmode.DesktopUserRepositories; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import com.android.wm.shell.sysui.KeyguardChangeListener; Loading Loading @@ -245,6 +249,21 @@ public class CompatUIController implements OnDisplaysChangedListener, mCallback = callback; } @Override public void sendCompatUIRequest(CompatUIRequest compatUIRequest) { switch(compatUIRequest.getRequestId()) { case DISPLAY_COMPAT_SHOW_RESTART_DIALOG: handleDisplayCompatShowRestartDialog(compatUIRequest.asType()); break; default: } } private void handleDisplayCompatShowRestartDialog( CompatUIRequests.DisplayCompatShowRestartDialog request) { onRestartButtonClicked(new Pair<>(request.getTaskInfo(), request.getTaskListener())); } /** * Called when the Task info changed. Creates and updates the compat UI if there is an * activity in size compat, or removes the UI if there is no size compat activity. Loading @@ -254,13 +273,17 @@ public class CompatUIController implements OnDisplaysChangedListener, public void onCompatInfoChanged(@NonNull CompatUIInfo compatUIInfo) { final TaskInfo taskInfo = compatUIInfo.getTaskInfo(); final ShellTaskOrganizer.TaskListener taskListener = compatUIInfo.getListener(); if (taskInfo != null && !taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat()) { final boolean isInDisplayCompatMode = taskInfo.appCompatTaskInfo.isRestartMenuEnabledForDisplayMove(); if (taskInfo != null && !taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat() && !isInDisplayCompatMode) { mSetOfTaskIdsShowingRestartDialog.remove(taskInfo.taskId); } mIsInDesktopMode = isInDesktopMode(taskInfo); // We close all the Compat UI educations in case TaskInfo has no configuration or // TaskListener or in desktop mode. if (taskInfo.configuration == null || taskListener == null || mIsInDesktopMode) { if (taskInfo.configuration == null || taskListener == null || (mIsInDesktopMode && !isInDisplayCompatMode)) { // Null token means the current foreground activity is not in compatibility mode. removeLayouts(taskInfo.taskId); return; Loading Loading @@ -552,8 +575,11 @@ public class CompatUIController implements OnDisplaysChangedListener, @Nullable ShellTaskOrganizer.TaskListener taskListener) { RestartDialogWindowManager layout = mTaskIdToRestartDialogWindowManagerMap.get(taskInfo.taskId); final boolean isInNonDisplayCompatDesktopMode = mIsInDesktopMode && !taskInfo.appCompatTaskInfo.isRestartMenuEnabledForDisplayMove(); if (layout != null) { if (layout.needsToBeRecreated(taskInfo, taskListener) || mIsInDesktopMode) { if (layout.needsToBeRecreated(taskInfo, taskListener) || isInNonDisplayCompatDesktopMode) { mTaskIdToRestartDialogWindowManagerMap.remove(taskInfo.taskId); layout.release(); } else { Loading @@ -568,8 +594,9 @@ public class CompatUIController implements OnDisplaysChangedListener, return; } } if (mIsInDesktopMode) { // Return if in desktop mode. if (isInNonDisplayCompatDesktopMode) { // No restart dialog can be shown in desktop mode unless the task is in display compat // mode. return; } // Create a new UI layout. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIHandler.kt +5 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,11 @@ interface CompatUIHandler { */ fun onCompatInfoChanged(compatUIInfo: CompatUIInfo) /** * Invoked when another component in Shell requests a CompatUI state change. */ fun sendCompatUIRequest(compatUIRequest: CompatUIRequest) /** * Optional reference to the object responsible to send {@link CompatUIEvent} */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIRequest.kt 0 → 100644 +34 −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.wm.shell.compatui.api /** * Abstraction for all the possible Compat UI Component requests. */ interface CompatUIRequest { /** * Unique request identifier */ val requestId: Int @Suppress("UNCHECKED_CAST") fun <T : CompatUIRequest> asType(): T? = this as? T fun <T : CompatUIRequest> asType(clazz: Class<T>): T? { return if (clazz.isInstance(this)) clazz.cast(this) else null } } No newline at end of file
libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIRequests.kt 0 → 100644 +33 −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.wm.shell.compatui.impl import android.app.TaskInfo import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.compatui.api.CompatUIRequest internal const val DISPLAY_COMPAT_SHOW_RESTART_DIALOG = 0 /** * All the {@link CompatUIRequest} the Compat UI Framework can handle */ sealed class CompatUIRequests(override val requestId: Int) : CompatUIRequest { /** Sent when the restart handle menu is clicked, and a restart dialog is requested. */ data class DisplayCompatShowRestartDialog(val taskInfo: TaskInfo, val taskListener: ShellTaskOrganizer.TaskListener) : CompatUIRequests(DISPLAY_COMPAT_SHOW_RESTART_DIALOG) }
libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt +3 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import com.android.wm.shell.compatui.api.CompatUIEvent import com.android.wm.shell.compatui.api.CompatUIHandler import com.android.wm.shell.compatui.api.CompatUIInfo import com.android.wm.shell.compatui.api.CompatUIRepository import com.android.wm.shell.compatui.api.CompatUIRequest import com.android.wm.shell.compatui.api.CompatUIState import java.util.function.Consumer Loading Loading @@ -102,4 +103,6 @@ class DefaultCompatUIHandler( override fun setCallback(compatUIEventSender: Consumer<CompatUIEvent>?) { this.compatUIEventSender = compatUIEventSender } override fun sendCompatUIRequest(compatUIRequest: CompatUIRequest) {} }