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? = null,
87     topActivity: ComponentName? = null,
88     topActivityType: ActivityType = Standard,
89     numActivities: Int? = null,
90     childTaskListBuilder: RootTaskInfo.() -> List<ChildTaskModel>,
91 ): RootTaskInfo {
92     return RootTaskInfo().apply {
93         configuration.windowConfiguration.apply {
94             setWindowingMode(windowingMode.toInt())
95             setActivityType(activityType.toInt())
96             setBounds(bounds)
97         }
98         this.bounds = bounds
99         this.displayId = displayId
100         this.userId = userId
101         this.taskId = taskId
102         this.visible = visible
103         this.isVisible = visible
104         this.isRunning = running
105         this.topActivity = topActivity
106         this.topActivityType = topActivityType.toInt()
107         // NOTE: topActivityInfo is _not_ populated by this code
108 
109         val childTasks = childTaskListBuilder(this)
110         this.numActivities = numActivities ?: childTasks.size
111 
112         childTaskNames = childTasks.map { it.name }.toTypedArray()
113         childTaskIds = childTasks.map { it.id }.toIntArray()
114         childTaskBounds = childTasks.map { it.bounds }.toTypedArray()
115         childTaskUserIds = childTasks.map { it.userId }.toIntArray()
116     }
117 }
118