Loading libs/WindowManager/Shell/Android.bp +19 −18 Original line number Diff line number Diff line Loading @@ -26,8 +26,8 @@ package { java_library { name: "wm_shell_protolog-groups", srcs: [ "src/com/android/wm/shell/protolog/ShellProtoLogGroup.java", ":protolog-common-src", "src/com/android/wm/shell/protolog/ShellProtoLogGroup.java", ], } Loading Loading @@ -61,8 +61,8 @@ java_genrule { name: "wm_shell_protolog_src", srcs: [ ":protolog-impl", ":wm_shell_protolog-groups", ":wm_shell-sources", ":wm_shell_protolog-groups", ], tools: ["protologtool"], cmd: "$(location protologtool) transform-protolog-calls " + Loading @@ -80,8 +80,8 @@ java_genrule { java_genrule { name: "generate-wm_shell_protolog.json", srcs: [ ":wm_shell_protolog-groups", ":wm_shell-sources", ":wm_shell_protolog-groups", ], tools: ["protologtool"], cmd: "$(location protologtool) generate-viewer-config " + Loading @@ -97,8 +97,8 @@ java_genrule { java_genrule { name: "gen-wmshell.protolog.pb", srcs: [ ":wm_shell_protolog-groups", ":wm_shell-sources", ":wm_shell_protolog-groups", ], tools: ["protologtool"], cmd: "$(location protologtool) generate-viewer-config " + Loading Loading @@ -159,38 +159,39 @@ java_library { android_library { name: "WindowManager-Shell", srcs: [ "src/com/android/wm/shell/EventLogTags.logtags", ":wm_shell_protolog_src", // TODO(b/168581922) protologtool do not support kotlin(*.kt) ":wm_shell-sources-kt", "src/com/android/wm/shell/EventLogTags.logtags", ":wm_shell-aidls", ":wm_shell-shared-aidls", ":wm_shell-sources-kt", ], resource_dirs: [ "res", ], static_libs: [ "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib", "//frameworks/libs/systemui:iconloader_base", "//packages/apps/Car/SystemUI/aconfig:com_android_systemui_car_flags_lib", "PlatformAnimationLib", "WindowManager-Shell-lite-proto", "WindowManager-Shell-proto", "WindowManager-Shell-shared", "androidx-constraintlayout_constraintlayout", "androidx.appcompat_appcompat", "androidx.core_core-ktx", "androidx.arch.core_core-runtime", "androidx.datastore_datastore", "androidx.compose.material3_material3", "androidx-constraintlayout_constraintlayout", "androidx.core_core-ktx", "androidx.datastore_datastore", "androidx.dynamicanimation_dynamicanimation", "androidx.recyclerview_recyclerview", "kotlinx-coroutines-android", "kotlinx-coroutines-core", "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib", "//frameworks/libs/systemui:iconloader_base", "com_android_launcher3_flags_lib", "com_android_wm_shell_flags_lib", "PlatformAnimationLib", "WindowManager-Shell-proto", "WindowManager-Shell-lite-proto", "WindowManager-Shell-shared", "perfetto_trace_java_protos", "dagger2", "jsr330", "kotlinx-coroutines-android", "kotlinx-coroutines-core", "perfetto_trace_java_protos", ], libs: [ // Soong fails to automatically add this dependency because all the Loading libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java +5 −0 Original line number Diff line number Diff line Loading @@ -230,6 +230,11 @@ public class RootTaskDisplayAreaOrganizer extends DisplayAreaOrganizer { return mDisplayAreasInfo.get(displayId); } @Nullable public SurfaceControl getDisplayAreaLeash(int displayId) { return mLeashes.get(displayId); } /** * Applies the {@link DisplayAreaInfo} to the {@link DisplayAreaContext} specified by * {@link DisplayAreaInfo#displayId}. Loading libs/WindowManager/Shell/src/com/android/wm/shell/automotive/AutoShellModule.java 0 → 100644 +30 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.automotive; import com.android.wm.shell.dagger.WMSingleton; import dagger.Binds; import dagger.Module; @Module public abstract class AutoShellModule { @WMSingleton @Binds abstract AutoTaskStackController provideTaskStackController(AutoTaskStackControllerImpl impl); } libs/WindowManager/Shell/src/com/android/wm/shell/automotive/AutoTaskStack.kt 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.automotive import android.app.ActivityManager import android.graphics.Rect import android.view.SurfaceControl /** * Represents an auto task stack, which is always in multi-window mode. * * @property id The ID of the task stack. * @property displayId The ID of the display the task stack is on. * @property leash The surface control leash of the task stack. */ interface AutoTaskStack { val id: Int val displayId: Int var leash: SurfaceControl } /** * Data class representing the state of an auto task stack. * * @property bounds The bounds of the task stack. * @property childrenTasksVisible Whether the child tasks of the stack are visible. * @property layer The layer of the task stack. */ data class AutoTaskStackState( val bounds: Rect = Rect(), val childrenTasksVisible: Boolean, val layer: Int ) /** * Data class representing a root task stack. * * @property id The ID of the root task stack * @property displayId The ID of the display the root task stack is on. * @property leash The surface control leash of the root task stack. * @property rootTaskInfo The running task info of the root task. */ data class RootTaskStack( override val id: Int, override val displayId: Int, override var leash: SurfaceControl, var rootTaskInfo: ActivityManager.RunningTaskInfo ) : AutoTaskStack libs/WindowManager/Shell/src/com/android/wm/shell/automotive/AutoTaskStackController.kt 0 → 100644 +229 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.automotive import android.app.PendingIntent import android.content.Intent import android.os.Bundle import android.os.IBinder import android.view.SurfaceControl import android.window.TransitionInfo import android.window.TransitionRequestInfo import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.transition.Transitions import com.android.wm.shell.transition.Transitions.TransitionFinishCallback /** * Delegate interface for handling auto task stack transitions. */ interface AutoTaskStackTransitionHandlerDelegate { /** * Handles a transition request. * * @param transition The transition identifier. * @param request The transition request information. * @return An [AutoTaskStackTransaction] to be applied for the transition, or null if the * animation is not handled by this delegate. */ fun handleRequest( transition: IBinder, request: TransitionRequestInfo ): AutoTaskStackTransaction? /** * See [Transitions.TransitionHandler.startAnimation] for more details. * * @param changedTaskStacks Contains the states of the task stacks that were changed as a * result of this transition. The key is the [AutoTaskStack.id] and the value is the * corresponding [AutoTaskStackState]. */ fun startAnimation( transition: IBinder, changedTaskStacks: Map<Int, AutoTaskStackState>, info: TransitionInfo, startTransaction: SurfaceControl.Transaction, finishTransaction: SurfaceControl.Transaction, finishCallback: TransitionFinishCallback ): Boolean /** * See [Transitions.TransitionHandler.onTransitionConsumed] for more details. * * @param requestedTaskStacks contains the states of the task stacks that were requested in * the transition. The key is the [AutoTaskStack.id] and the value is the corresponding * [AutoTaskStackState]. */ fun onTransitionConsumed( transition: IBinder, requestedTaskStacks: Map<Int, AutoTaskStackState>, aborted: Boolean, finishTransaction: SurfaceControl.Transaction? ) /** * See [Transitions.TransitionHandler.mergeAnimation] for more details. * * @param changedTaskStacks Contains the states of the task stacks that were changed as a * result of this transition. The key is the [AutoTaskStack.id] and the value is the * corresponding [AutoTaskStackState]. */ fun mergeAnimation( transition: IBinder, changedTaskStacks: Map<Int, AutoTaskStackState>, info: TransitionInfo, surfaceTransaction: SurfaceControl.Transaction, mergeTarget: IBinder, finishCallback: TransitionFinishCallback ) } /** * Controller for managing auto task stacks. */ interface AutoTaskStackController { var autoTransitionHandlerDelegate: AutoTaskStackTransitionHandlerDelegate? set /** * Map of task stack IDs to their states. * * This gets updated right before [AutoTaskStackTransitionHandlerDelegate.startAnimation] or * [AutoTaskStackTransitionHandlerDelegate.onTransitionConsumed] is called. */ val taskStackStateMap: Map<Int, AutoTaskStackState> get /** * Creates a new multi-window root task. * * A root task stack is placed in the default TDA of the specified display by default. * Once the root task is removed, the [AutoTaskStackController] no longer holds a reference to * it. * * @param displayId The ID of the display to create the root task stack on. * @param listener The listener for root task stack events. */ @ShellMainThread fun createRootTaskStack(displayId: Int, listener: RootTaskStackListener) /** * Sets the default root task stack (launch root) on a display. Calling it again with a * different [rootTaskStackId] will simply replace the default root task stack on the display. * * Note: This is helpful for passively routing tasks to a specified container. If a display * doesn't have a default root task stack set, all tasks will open in fullscreen and cover * the entire default TDA by default. * * @param displayId The ID of the display. * @param rootTaskStackId The ID of the root task stack, or null to clear the default. */ @ShellMainThread fun setDefaultRootTaskStackOnDisplay(displayId: Int, rootTaskStackId: Int?) /** * Starts a transaction with the specified [transaction]. * Returns the transition identifier. */ @ShellMainThread fun startTransition(transaction: AutoTaskStackTransaction): IBinder? } internal sealed class TaskStackOperation { data class ReparentTask( val taskId: Int, val parentTaskStackId: Int, val onTop: Boolean ) : TaskStackOperation() data class SendPendingIntent( val sender: PendingIntent, val intent: Intent, val options: Bundle? ) : TaskStackOperation() data class SetTaskStackState( val taskStackId: Int, val state: AutoTaskStackState ) : TaskStackOperation() } data class AutoTaskStackTransaction internal constructor( internal val operations: MutableList<TaskStackOperation> = mutableListOf() ) { constructor() : this( mutableListOf() ) /** See [WindowContainerTransaction.reparent] for more details. */ fun reparentTask( taskId: Int, parentTaskStackId: Int, onTop: Boolean ): AutoTaskStackTransaction { operations.add(TaskStackOperation.ReparentTask(taskId, parentTaskStackId, onTop)) return this } /** See [WindowContainerTransaction.sendPendingIntent] for more details. */ fun sendPendingIntent( sender: PendingIntent, intent: Intent, options: Bundle? ): AutoTaskStackTransaction { operations.add(TaskStackOperation.SendPendingIntent(sender, intent, options)) return this } /** * Adds a set task stack state operation to the transaction. * * If an operation with the same task stack ID already exists, it is replaced with the new one. * * @param taskStackId The ID of the task stack. * @param state The new state of the task stack. * @return The transaction with the added operation. */ fun setTaskStackState(taskStackId: Int, state: AutoTaskStackState): AutoTaskStackTransaction { val existingOperation = operations.find { it is TaskStackOperation.SetTaskStackState && it.taskStackId == taskStackId } if (existingOperation != null) { val index = operations.indexOf(existingOperation) operations[index] = TaskStackOperation.SetTaskStackState(taskStackId, state) } else { operations.add(TaskStackOperation.SetTaskStackState(taskStackId, state)) } return this } /** * Returns a map of task stack IDs to their states from the set task stack state operations. * * @return The map of task stack IDs to states. */ fun getTaskStackStates(): Map<Int, AutoTaskStackState> { val states = mutableMapOf<Int, AutoTaskStackState>() operations.forEach { operation -> if (operation is TaskStackOperation.SetTaskStackState) { states[operation.taskStackId] = operation.state } } return states } } Loading
libs/WindowManager/Shell/Android.bp +19 −18 Original line number Diff line number Diff line Loading @@ -26,8 +26,8 @@ package { java_library { name: "wm_shell_protolog-groups", srcs: [ "src/com/android/wm/shell/protolog/ShellProtoLogGroup.java", ":protolog-common-src", "src/com/android/wm/shell/protolog/ShellProtoLogGroup.java", ], } Loading Loading @@ -61,8 +61,8 @@ java_genrule { name: "wm_shell_protolog_src", srcs: [ ":protolog-impl", ":wm_shell_protolog-groups", ":wm_shell-sources", ":wm_shell_protolog-groups", ], tools: ["protologtool"], cmd: "$(location protologtool) transform-protolog-calls " + Loading @@ -80,8 +80,8 @@ java_genrule { java_genrule { name: "generate-wm_shell_protolog.json", srcs: [ ":wm_shell_protolog-groups", ":wm_shell-sources", ":wm_shell_protolog-groups", ], tools: ["protologtool"], cmd: "$(location protologtool) generate-viewer-config " + Loading @@ -97,8 +97,8 @@ java_genrule { java_genrule { name: "gen-wmshell.protolog.pb", srcs: [ ":wm_shell_protolog-groups", ":wm_shell-sources", ":wm_shell_protolog-groups", ], tools: ["protologtool"], cmd: "$(location protologtool) generate-viewer-config " + Loading Loading @@ -159,38 +159,39 @@ java_library { android_library { name: "WindowManager-Shell", srcs: [ "src/com/android/wm/shell/EventLogTags.logtags", ":wm_shell_protolog_src", // TODO(b/168581922) protologtool do not support kotlin(*.kt) ":wm_shell-sources-kt", "src/com/android/wm/shell/EventLogTags.logtags", ":wm_shell-aidls", ":wm_shell-shared-aidls", ":wm_shell-sources-kt", ], resource_dirs: [ "res", ], static_libs: [ "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib", "//frameworks/libs/systemui:iconloader_base", "//packages/apps/Car/SystemUI/aconfig:com_android_systemui_car_flags_lib", "PlatformAnimationLib", "WindowManager-Shell-lite-proto", "WindowManager-Shell-proto", "WindowManager-Shell-shared", "androidx-constraintlayout_constraintlayout", "androidx.appcompat_appcompat", "androidx.core_core-ktx", "androidx.arch.core_core-runtime", "androidx.datastore_datastore", "androidx.compose.material3_material3", "androidx-constraintlayout_constraintlayout", "androidx.core_core-ktx", "androidx.datastore_datastore", "androidx.dynamicanimation_dynamicanimation", "androidx.recyclerview_recyclerview", "kotlinx-coroutines-android", "kotlinx-coroutines-core", "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib", "//frameworks/libs/systemui:iconloader_base", "com_android_launcher3_flags_lib", "com_android_wm_shell_flags_lib", "PlatformAnimationLib", "WindowManager-Shell-proto", "WindowManager-Shell-lite-proto", "WindowManager-Shell-shared", "perfetto_trace_java_protos", "dagger2", "jsr330", "kotlinx-coroutines-android", "kotlinx-coroutines-core", "perfetto_trace_java_protos", ], libs: [ // Soong fails to automatically add this dependency because all the Loading
libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java +5 −0 Original line number Diff line number Diff line Loading @@ -230,6 +230,11 @@ public class RootTaskDisplayAreaOrganizer extends DisplayAreaOrganizer { return mDisplayAreasInfo.get(displayId); } @Nullable public SurfaceControl getDisplayAreaLeash(int displayId) { return mLeashes.get(displayId); } /** * Applies the {@link DisplayAreaInfo} to the {@link DisplayAreaContext} specified by * {@link DisplayAreaInfo#displayId}. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/automotive/AutoShellModule.java 0 → 100644 +30 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.automotive; import com.android.wm.shell.dagger.WMSingleton; import dagger.Binds; import dagger.Module; @Module public abstract class AutoShellModule { @WMSingleton @Binds abstract AutoTaskStackController provideTaskStackController(AutoTaskStackControllerImpl impl); }
libs/WindowManager/Shell/src/com/android/wm/shell/automotive/AutoTaskStack.kt 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.automotive import android.app.ActivityManager import android.graphics.Rect import android.view.SurfaceControl /** * Represents an auto task stack, which is always in multi-window mode. * * @property id The ID of the task stack. * @property displayId The ID of the display the task stack is on. * @property leash The surface control leash of the task stack. */ interface AutoTaskStack { val id: Int val displayId: Int var leash: SurfaceControl } /** * Data class representing the state of an auto task stack. * * @property bounds The bounds of the task stack. * @property childrenTasksVisible Whether the child tasks of the stack are visible. * @property layer The layer of the task stack. */ data class AutoTaskStackState( val bounds: Rect = Rect(), val childrenTasksVisible: Boolean, val layer: Int ) /** * Data class representing a root task stack. * * @property id The ID of the root task stack * @property displayId The ID of the display the root task stack is on. * @property leash The surface control leash of the root task stack. * @property rootTaskInfo The running task info of the root task. */ data class RootTaskStack( override val id: Int, override val displayId: Int, override var leash: SurfaceControl, var rootTaskInfo: ActivityManager.RunningTaskInfo ) : AutoTaskStack
libs/WindowManager/Shell/src/com/android/wm/shell/automotive/AutoTaskStackController.kt 0 → 100644 +229 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.automotive import android.app.PendingIntent import android.content.Intent import android.os.Bundle import android.os.IBinder import android.view.SurfaceControl import android.window.TransitionInfo import android.window.TransitionRequestInfo import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.transition.Transitions import com.android.wm.shell.transition.Transitions.TransitionFinishCallback /** * Delegate interface for handling auto task stack transitions. */ interface AutoTaskStackTransitionHandlerDelegate { /** * Handles a transition request. * * @param transition The transition identifier. * @param request The transition request information. * @return An [AutoTaskStackTransaction] to be applied for the transition, or null if the * animation is not handled by this delegate. */ fun handleRequest( transition: IBinder, request: TransitionRequestInfo ): AutoTaskStackTransaction? /** * See [Transitions.TransitionHandler.startAnimation] for more details. * * @param changedTaskStacks Contains the states of the task stacks that were changed as a * result of this transition. The key is the [AutoTaskStack.id] and the value is the * corresponding [AutoTaskStackState]. */ fun startAnimation( transition: IBinder, changedTaskStacks: Map<Int, AutoTaskStackState>, info: TransitionInfo, startTransaction: SurfaceControl.Transaction, finishTransaction: SurfaceControl.Transaction, finishCallback: TransitionFinishCallback ): Boolean /** * See [Transitions.TransitionHandler.onTransitionConsumed] for more details. * * @param requestedTaskStacks contains the states of the task stacks that were requested in * the transition. The key is the [AutoTaskStack.id] and the value is the corresponding * [AutoTaskStackState]. */ fun onTransitionConsumed( transition: IBinder, requestedTaskStacks: Map<Int, AutoTaskStackState>, aborted: Boolean, finishTransaction: SurfaceControl.Transaction? ) /** * See [Transitions.TransitionHandler.mergeAnimation] for more details. * * @param changedTaskStacks Contains the states of the task stacks that were changed as a * result of this transition. The key is the [AutoTaskStack.id] and the value is the * corresponding [AutoTaskStackState]. */ fun mergeAnimation( transition: IBinder, changedTaskStacks: Map<Int, AutoTaskStackState>, info: TransitionInfo, surfaceTransaction: SurfaceControl.Transaction, mergeTarget: IBinder, finishCallback: TransitionFinishCallback ) } /** * Controller for managing auto task stacks. */ interface AutoTaskStackController { var autoTransitionHandlerDelegate: AutoTaskStackTransitionHandlerDelegate? set /** * Map of task stack IDs to their states. * * This gets updated right before [AutoTaskStackTransitionHandlerDelegate.startAnimation] or * [AutoTaskStackTransitionHandlerDelegate.onTransitionConsumed] is called. */ val taskStackStateMap: Map<Int, AutoTaskStackState> get /** * Creates a new multi-window root task. * * A root task stack is placed in the default TDA of the specified display by default. * Once the root task is removed, the [AutoTaskStackController] no longer holds a reference to * it. * * @param displayId The ID of the display to create the root task stack on. * @param listener The listener for root task stack events. */ @ShellMainThread fun createRootTaskStack(displayId: Int, listener: RootTaskStackListener) /** * Sets the default root task stack (launch root) on a display. Calling it again with a * different [rootTaskStackId] will simply replace the default root task stack on the display. * * Note: This is helpful for passively routing tasks to a specified container. If a display * doesn't have a default root task stack set, all tasks will open in fullscreen and cover * the entire default TDA by default. * * @param displayId The ID of the display. * @param rootTaskStackId The ID of the root task stack, or null to clear the default. */ @ShellMainThread fun setDefaultRootTaskStackOnDisplay(displayId: Int, rootTaskStackId: Int?) /** * Starts a transaction with the specified [transaction]. * Returns the transition identifier. */ @ShellMainThread fun startTransition(transaction: AutoTaskStackTransaction): IBinder? } internal sealed class TaskStackOperation { data class ReparentTask( val taskId: Int, val parentTaskStackId: Int, val onTop: Boolean ) : TaskStackOperation() data class SendPendingIntent( val sender: PendingIntent, val intent: Intent, val options: Bundle? ) : TaskStackOperation() data class SetTaskStackState( val taskStackId: Int, val state: AutoTaskStackState ) : TaskStackOperation() } data class AutoTaskStackTransaction internal constructor( internal val operations: MutableList<TaskStackOperation> = mutableListOf() ) { constructor() : this( mutableListOf() ) /** See [WindowContainerTransaction.reparent] for more details. */ fun reparentTask( taskId: Int, parentTaskStackId: Int, onTop: Boolean ): AutoTaskStackTransaction { operations.add(TaskStackOperation.ReparentTask(taskId, parentTaskStackId, onTop)) return this } /** See [WindowContainerTransaction.sendPendingIntent] for more details. */ fun sendPendingIntent( sender: PendingIntent, intent: Intent, options: Bundle? ): AutoTaskStackTransaction { operations.add(TaskStackOperation.SendPendingIntent(sender, intent, options)) return this } /** * Adds a set task stack state operation to the transaction. * * If an operation with the same task stack ID already exists, it is replaced with the new one. * * @param taskStackId The ID of the task stack. * @param state The new state of the task stack. * @return The transaction with the added operation. */ fun setTaskStackState(taskStackId: Int, state: AutoTaskStackState): AutoTaskStackTransaction { val existingOperation = operations.find { it is TaskStackOperation.SetTaskStackState && it.taskStackId == taskStackId } if (existingOperation != null) { val index = operations.indexOf(existingOperation) operations[index] = TaskStackOperation.SetTaskStackState(taskStackId, state) } else { operations.add(TaskStackOperation.SetTaskStackState(taskStackId, state)) } return this } /** * Returns a map of task stack IDs to their states from the set task stack state operations. * * @return The map of task stack IDs to states. */ fun getTaskStackStates(): Map<Int, AutoTaskStackState> { val states = mutableMapOf<Int, AutoTaskStackState>() operations.forEach { operation -> if (operation is TaskStackOperation.SetTaskStackState) { states[operation.taskStackId] = operation.state } } return states } }