1 /* 2 * Copyright (C) 2021 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 package com.android.quickstep.util 17 18 import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_TASK 19 import com.android.launcher3.model.data.TaskItemInfo 20 import com.android.launcher3.model.data.WorkspaceItemInfo 21 import com.android.launcher3.util.SplitConfigurationOptions 22 import com.android.quickstep.views.TaskViewType 23 import com.android.systemui.shared.recents.model.Task 24 import java.util.Objects 25 26 /** 27 * An abstract class for creating [Task] containers that can be [SingleTask]s, [SplitTask]s, or 28 * [DesktopTask]s in the recent tasks list. 29 */ 30 abstract class GroupTask(val tasks: List<Task>, @JvmField val taskViewType: TaskViewType) { <lambda>null31 fun containsTask(taskId: Int) = tasks.any { it.key.id == taskId } 32 33 /** 34 * Returns true if a task in this group has a package name that matches the given `packageName`. 35 */ <lambda>null36 fun containsPackage(packageName: String?) = tasks.any { it.key.packageName == packageName } 37 38 /** 39 * Returns true if a task in this group has a package name that matches the given `packageName`, 40 * and its user ID matches the given `userId`. 41 */ containsPackagenull42 fun containsPackage(packageName: String?, userId: Int) = 43 tasks.any { it.key.packageName == packageName && it.key.userId == userId } 44 isEmptynull45 fun isEmpty() = tasks.isEmpty() 46 47 /** Creates a copy of this instance */ 48 abstract fun copy(): GroupTask 49 50 override fun equals(o: Any?): Boolean { 51 if (this === o) return true 52 if (o !is GroupTask) return false 53 return taskViewType == o.taskViewType && tasks == o.tasks 54 } 55 hashCodenull56 override fun hashCode() = Objects.hash(tasks, taskViewType) 57 } 58 59 /** A [Task] container that must contain exactly one task in the recent tasks list. */ 60 class SingleTask(task: Task) : GroupTask(listOf(task), TaskViewType.SINGLE) { 61 62 val task: Task 63 get() = tasks[0] 64 65 override fun copy() = SingleTask(task) 66 67 override fun toString() = "type=$taskViewType task=$task" 68 69 override fun equals(o: Any?): Boolean { 70 if (this === o) return true 71 if (o !is SingleTask) return false 72 return super.equals(o) 73 } 74 75 companion object { 76 /** Creates a [TaskItemInfo] using the information of the SingleTask */ 77 fun createTaskItemInfo(task: SingleTask): TaskItemInfo { 78 // TODO: b/344657629 - Support GroupTask in addition to SingleTask. 79 val wii = 80 WorkspaceItemInfo().apply { 81 title = task.task.title 82 intent = task.task.key.baseIntent 83 itemType = ITEM_TYPE_TASK 84 contentDescription = task.task.titleDescription 85 } 86 return TaskItemInfo(task.task.key.id, wii) 87 } 88 } 89 90 override fun hashCode() = super.hashCode() 91 } 92 93 /** 94 * A [Task] container that must contain exactly two tasks and split bounds to represent an app-pair 95 * in the recent tasks list. 96 */ 97 class SplitTask(task1: Task, task2: Task, val splitBounds: SplitConfigurationOptions.SplitBounds) : 98 GroupTask(listOf(task1, task2), TaskViewType.GROUPED) { 99 100 val topLeftTask: Task 101 get() = if (splitBounds.leftTopTaskId == tasks[0].key.id) tasks[0] else tasks[1] 102 103 val bottomRightTask: Task 104 get() = if (topLeftTask == tasks[0]) tasks[1] else tasks[0] 105 copynull106 override fun copy() = SplitTask(tasks[0], tasks[1], splitBounds) 107 108 override fun toString() = 109 "type=$taskViewType topLeftTask=$topLeftTask bottomRightTask=$bottomRightTask" 110 111 override fun equals(o: Any?): Boolean { 112 if (this === o) return true 113 if (o !is SplitTask) return false 114 if (splitBounds != o.splitBounds) return false 115 return super.equals(o) 116 } 117 hashCodenull118 override fun hashCode() = Objects.hash(super.hashCode(), splitBounds) 119 } 120