1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.screenshot.policy
18 
19 import android.app.ActivityTaskManager.RootTaskInfo
20 import android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT
21 import android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM
22 import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
23 import android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS
24 import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
25 import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED
26 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
27 import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
28 import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
29 import android.app.WindowConfiguration.WINDOWING_MODE_PINNED
30 import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
31 import android.content.ComponentName
32 import android.graphics.Rect
33 import android.os.UserHandle
34 import android.view.Display
35 import com.android.systemui.screenshot.data.model.ChildTaskModel
36 import com.android.systemui.screenshot.policy.ActivityType.Standard
37 import com.android.systemui.screenshot.policy.WindowingMode.FullScreen
38 
39 /** An enum mapping to [android.app.WindowConfiguration] constants via [toInt]. */
40 enum class ActivityType(private val intValue: Int) {
41     Undefined(ACTIVITY_TYPE_UNDEFINED),
42     Standard(ACTIVITY_TYPE_STANDARD),
43     Home(ACTIVITY_TYPE_HOME),
44     Recents(ACTIVITY_TYPE_RECENTS),
45     Assistant(ACTIVITY_TYPE_ASSISTANT),
46     Dream(ACTIVITY_TYPE_DREAM);
47 
48     /** Returns the [android.app.WindowConfiguration] int constant for the type. */
toIntnull49     fun toInt() = intValue
50 }
51 
52 /** An enum mapping to [android.app.WindowConfiguration] constants via [toInt]. */
53 enum class WindowingMode(private val intValue: Int) {
54     Undefined(WINDOWING_MODE_UNDEFINED),
55     FullScreen(WINDOWING_MODE_FULLSCREEN),
56     PictureInPicture(WINDOWING_MODE_PINNED),
57     Freeform(WINDOWING_MODE_FREEFORM),
58     MultiWindow(WINDOWING_MODE_MULTI_WINDOW);
59 
60     /** Returns the [android.app.WindowConfiguration] int constant for the mode. */
61     fun toInt() = intValue
62 }
63 
64 /**
65  * Constructs a child task for a [RootTaskInfo], copying [RootTaskInfo.bounds] and
66  * [RootTaskInfo.userId] from the parent by default.
67  */
RootTaskInfonull68 fun RootTaskInfo.newChildTask(
69     taskId: Int,
70     name: String,
71     bounds: Rect? = null,
72     userId: Int? = null,
73 ): ChildTaskModel {
74     return ChildTaskModel(taskId, name, bounds ?: this.bounds, userId ?: this.userId)
75 }
76 
77 /** Constructs a new [RootTaskInfo]. */
newRootTaskInfonull78 fun newRootTaskInfo(
79     taskId: Int,
80     userId: Int = UserHandle.USER_SYSTEM,
81     displayId: Int = Display.DEFAULT_DISPLAY,
82     visible: Boolean = true,
83     running: Boolean = true,
84     activityType: ActivityType = Standard,
85     windowingMode: WindowingMode = FullScreen,
86     bounds: Rect = Rect(),
87     maxBounds: Rect = bounds,
88     topActivity: ComponentName? = null,
89     topActivityType: ActivityType = Standard,
90     numActivities: Int? = null,
91     childTaskListBuilder: RootTaskInfo.() -> List<ChildTaskModel>,
92 ): RootTaskInfo {
93     return RootTaskInfo().apply {
94         configuration.windowConfiguration.apply {
95             setWindowingMode(windowingMode.toInt())
96             setActivityType(activityType.toInt())
97             setBounds(bounds)
98             setMaxBounds(maxBounds)
99         }
100         this.bounds = bounds
101         this.displayId = displayId
102         this.userId = userId
103         this.taskId = taskId
104         this.visible = visible
105         this.isVisible = visible
106         this.isRunning = running
107         this.topActivity = topActivity
108         this.topActivityType = topActivityType.toInt()
109         // NOTE: topActivityInfo is _not_ populated by this code
110 
111         val childTasks = childTaskListBuilder(this)
112         this.numActivities = numActivities ?: childTasks.size
113 
114         childTaskNames = childTasks.map { it.name }.toTypedArray()
115         childTaskIds = childTasks.map { it.id }.toIntArray()
116         childTaskBounds = childTasks.map { it.bounds }.toTypedArray()
117         childTaskUserIds = childTasks.map { it.userId }.toIntArray()
118     }
119 }
120