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 17 package com.android.wm.shell.util; 18 19 import android.annotation.IntDef; 20 import android.app.ActivityManager; 21 import android.app.WindowConfiguration; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 25 import androidx.annotation.NonNull; 26 import androidx.annotation.Nullable; 27 28 import java.util.Arrays; 29 import java.util.List; 30 31 /** 32 * Simple container for recent tasks. May contain either a single or pair of tasks. 33 */ 34 public class GroupedRecentTaskInfo implements Parcelable { 35 36 public static final int TYPE_SINGLE = 1; 37 public static final int TYPE_SPLIT = 2; 38 public static final int TYPE_FREEFORM = 3; 39 40 @IntDef(prefix = {"TYPE_"}, value = { 41 TYPE_SINGLE, 42 TYPE_SPLIT, 43 TYPE_FREEFORM 44 }) 45 public @interface GroupType {} 46 47 @NonNull 48 private final ActivityManager.RecentTaskInfo[] mTasks; 49 @Nullable 50 private final SplitBounds mSplitBounds; 51 @GroupType 52 private final int mType; 53 54 /** 55 * Create new for a single task 56 */ forSingleTask( @onNull ActivityManager.RecentTaskInfo task)57 public static GroupedRecentTaskInfo forSingleTask( 58 @NonNull ActivityManager.RecentTaskInfo task) { 59 return new GroupedRecentTaskInfo(new ActivityManager.RecentTaskInfo[]{task}, null, 60 TYPE_SINGLE); 61 } 62 63 /** 64 * Create new for a pair of tasks in split screen 65 */ forSplitTasks(@onNull ActivityManager.RecentTaskInfo task1, @NonNull ActivityManager.RecentTaskInfo task2, @Nullable SplitBounds splitBounds)66 public static GroupedRecentTaskInfo forSplitTasks(@NonNull ActivityManager.RecentTaskInfo task1, 67 @NonNull ActivityManager.RecentTaskInfo task2, @Nullable SplitBounds splitBounds) { 68 return new GroupedRecentTaskInfo(new ActivityManager.RecentTaskInfo[]{task1, task2}, 69 splitBounds, TYPE_SPLIT); 70 } 71 72 /** 73 * Create new for a group of freeform tasks 74 */ forFreeformTasks( @onNull ActivityManager.RecentTaskInfo... tasks)75 public static GroupedRecentTaskInfo forFreeformTasks( 76 @NonNull ActivityManager.RecentTaskInfo... tasks) { 77 return new GroupedRecentTaskInfo(tasks, null, TYPE_FREEFORM); 78 } 79 GroupedRecentTaskInfo(@onNull ActivityManager.RecentTaskInfo[] tasks, @Nullable SplitBounds splitBounds, @GroupType int type)80 private GroupedRecentTaskInfo(@NonNull ActivityManager.RecentTaskInfo[] tasks, 81 @Nullable SplitBounds splitBounds, @GroupType int type) { 82 mTasks = tasks; 83 mSplitBounds = splitBounds; 84 mType = type; 85 } 86 GroupedRecentTaskInfo(Parcel parcel)87 GroupedRecentTaskInfo(Parcel parcel) { 88 mTasks = parcel.createTypedArray(ActivityManager.RecentTaskInfo.CREATOR); 89 mSplitBounds = parcel.readTypedObject(SplitBounds.CREATOR); 90 mType = parcel.readInt(); 91 } 92 93 /** 94 * Get primary {@link ActivityManager.RecentTaskInfo} 95 */ 96 @NonNull getTaskInfo1()97 public ActivityManager.RecentTaskInfo getTaskInfo1() { 98 return mTasks[0]; 99 } 100 101 /** 102 * Get secondary {@link ActivityManager.RecentTaskInfo}. 103 * 104 * Used in split screen. 105 */ 106 @Nullable getTaskInfo2()107 public ActivityManager.RecentTaskInfo getTaskInfo2() { 108 if (mTasks.length > 1) { 109 return mTasks[1]; 110 } 111 return null; 112 } 113 114 /** 115 * Get all {@link ActivityManager.RecentTaskInfo}s grouped together. 116 */ 117 @NonNull getTaskInfoList()118 public List<ActivityManager.RecentTaskInfo> getTaskInfoList() { 119 return Arrays.asList(mTasks); 120 } 121 122 /** 123 * Return {@link SplitBounds} if this is a split screen entry or {@code null} 124 */ 125 @Nullable getSplitBounds()126 public SplitBounds getSplitBounds() { 127 return mSplitBounds; 128 } 129 130 /** 131 * Get type of this recents entry. One of {@link GroupType} 132 */ 133 @GroupType getType()134 public int getType() { 135 return mType; 136 } 137 138 @Override toString()139 public String toString() { 140 StringBuilder taskString = new StringBuilder(); 141 for (int i = 0; i < mTasks.length; i++) { 142 if (i == 0) { 143 taskString.append("Task"); 144 } else { 145 taskString.append(", Task"); 146 } 147 taskString.append(i + 1).append(": ").append(getTaskInfo(mTasks[i])); 148 } 149 if (mSplitBounds != null) { 150 taskString.append(", SplitBounds: ").append(mSplitBounds); 151 } 152 taskString.append(", Type="); 153 switch (mType) { 154 case TYPE_SINGLE: 155 taskString.append("TYPE_SINGLE"); 156 break; 157 case TYPE_SPLIT: 158 taskString.append("TYPE_SPLIT"); 159 break; 160 case TYPE_FREEFORM: 161 taskString.append("TYPE_FREEFORM"); 162 break; 163 } 164 return taskString.toString(); 165 } 166 getTaskInfo(ActivityManager.RecentTaskInfo taskInfo)167 private String getTaskInfo(ActivityManager.RecentTaskInfo taskInfo) { 168 if (taskInfo == null) { 169 return null; 170 } 171 return "id=" + taskInfo.taskId 172 + " baseIntent=" + (taskInfo.baseIntent != null 173 ? taskInfo.baseIntent.getComponent() 174 : "null") 175 + " winMode=" + WindowConfiguration.windowingModeToString( 176 taskInfo.getWindowingMode()); 177 } 178 179 @Override writeToParcel(Parcel parcel, int flags)180 public void writeToParcel(Parcel parcel, int flags) { 181 parcel.writeTypedArray(mTasks, flags); 182 parcel.writeTypedObject(mSplitBounds, flags); 183 parcel.writeInt(mType); 184 } 185 186 @Override describeContents()187 public int describeContents() { 188 return 0; 189 } 190 191 public static final @android.annotation.NonNull Creator<GroupedRecentTaskInfo> CREATOR = 192 new Creator<GroupedRecentTaskInfo>() { 193 public GroupedRecentTaskInfo createFromParcel(Parcel source) { 194 return new GroupedRecentTaskInfo(source); 195 } 196 public GroupedRecentTaskInfo[] newArray(int size) { 197 return new GroupedRecentTaskInfo[size]; 198 } 199 }; 200 }