1 /* 2 * Copyright (C) 2018 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 android.app; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.TestApi; 22 import android.compat.annotation.UnsupportedAppUsage; 23 import android.content.ComponentName; 24 import android.content.Intent; 25 import android.content.pm.ActivityInfo; 26 import android.content.res.Configuration; 27 import android.os.Parcel; 28 import android.os.RemoteException; 29 import android.util.Log; 30 import android.window.WindowContainerToken; 31 32 /** 33 * Stores information about a particular Task. 34 */ 35 public class TaskInfo { 36 private static final String TAG = "TaskInfo"; 37 38 /** 39 * The id of the user the task was running as. 40 * @hide 41 */ 42 @UnsupportedAppUsage 43 public int userId; 44 45 /** 46 * The id of the ActivityStack that currently contains this task. 47 * @hide 48 */ 49 @UnsupportedAppUsage 50 public int stackId; 51 52 /** 53 * The identifier for this task. 54 */ 55 public int taskId; 56 57 /** 58 * Whether or not this task has any running activities. 59 */ 60 public boolean isRunning; 61 62 /** 63 * The base intent of the task (generally the intent that launched the task). This intent can 64 * be used to relaunch the task (if it is no longer running) or brought to the front if it is. 65 */ 66 @NonNull 67 public Intent baseIntent; 68 69 /** 70 * The component of the first activity in the task, can be considered the "application" of this 71 * task. 72 */ 73 @Nullable 74 public ComponentName baseActivity; 75 76 /** 77 * The component of the top activity in the task, currently showing to the user. 78 */ 79 @Nullable 80 public ComponentName topActivity; 81 82 /** 83 * The component of the target activity if this task was started from an activity alias. 84 * Otherwise, this is null. 85 */ 86 @Nullable 87 public ComponentName origActivity; 88 89 /** 90 * The component of the activity that started this task (may be the component of the activity 91 * alias). 92 * @hide 93 */ 94 @Nullable 95 public ComponentName realActivity; 96 97 /** 98 * The number of activities in this task (including running). 99 */ 100 public int numActivities; 101 102 /** 103 * The last time this task was active since boot (including time spent in sleep). 104 * @hide 105 */ 106 @UnsupportedAppUsage 107 public long lastActiveTime; 108 109 /** 110 * The id of the display this task is associated with. 111 * @hide 112 */ 113 public int displayId; 114 115 /** 116 * The recent activity values for the highest activity in the stack to have set the values. 117 * {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}. 118 */ 119 @Nullable 120 public ActivityManager.TaskDescription taskDescription; 121 122 /** 123 * True if the task can go in the split-screen primary stack. 124 * @hide 125 */ 126 @UnsupportedAppUsage 127 public boolean supportsSplitScreenMultiWindow; 128 129 /** 130 * The resize mode of the task. See {@link ActivityInfo#resizeMode}. 131 * @hide 132 */ 133 @UnsupportedAppUsage 134 public int resizeMode; 135 136 /** 137 * The current configuration of the task. 138 * @hide 139 */ 140 @NonNull 141 @UnsupportedAppUsage 142 public final Configuration configuration = new Configuration(); 143 144 /** 145 * Used as an opaque identifier for this task. 146 * @hide 147 */ 148 @NonNull 149 public WindowContainerToken token; 150 151 /** 152 * The PictureInPictureParams for the Task, if set. 153 * @hide 154 */ 155 @Nullable 156 public PictureInPictureParams pictureInPictureParams; 157 158 /** 159 * The activity type of the top activity in this task. 160 * @hide 161 */ 162 public @WindowConfiguration.ActivityType int topActivityType; 163 164 /** 165 * The {@link ActivityInfo} of the top activity in this task. 166 * @hide 167 */ 168 @Nullable 169 public ActivityInfo topActivityInfo; 170 171 /** 172 * Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity 173 * supports), this is what the system actually uses for resizability based on other policy and 174 * developer options. 175 * @hide 176 */ 177 public boolean isResizeable; 178 TaskInfo()179 TaskInfo() { 180 // Do nothing 181 } 182 TaskInfo(Parcel source)183 private TaskInfo(Parcel source) { 184 readFromParcel(source); 185 } 186 187 /** 188 * @param isLowResolution 189 * @return 190 * @hide 191 */ getTaskSnapshot(boolean isLowResolution)192 public ActivityManager.TaskSnapshot getTaskSnapshot(boolean isLowResolution) { 193 try { 194 return ActivityManager.getService().getTaskSnapshot(taskId, isLowResolution); 195 } catch (RemoteException e) { 196 Log.e(TAG, "Failed to get task snapshot, taskId=" + taskId, e); 197 return null; 198 } 199 } 200 201 /** @hide */ 202 @NonNull 203 @TestApi getToken()204 public WindowContainerToken getToken() { 205 return token; 206 } 207 208 /** @hide */ 209 @NonNull 210 @TestApi getConfiguration()211 public Configuration getConfiguration() { 212 return configuration; 213 } 214 215 /** 216 * Reads the TaskInfo from a parcel. 217 */ readFromParcel(Parcel source)218 void readFromParcel(Parcel source) { 219 userId = source.readInt(); 220 stackId = source.readInt(); 221 taskId = source.readInt(); 222 displayId = source.readInt(); 223 isRunning = source.readBoolean(); 224 baseIntent = source.readInt() != 0 225 ? Intent.CREATOR.createFromParcel(source) 226 : null; 227 baseActivity = ComponentName.readFromParcel(source); 228 topActivity = ComponentName.readFromParcel(source); 229 origActivity = ComponentName.readFromParcel(source); 230 realActivity = ComponentName.readFromParcel(source); 231 232 numActivities = source.readInt(); 233 lastActiveTime = source.readLong(); 234 235 taskDescription = source.readInt() != 0 236 ? ActivityManager.TaskDescription.CREATOR.createFromParcel(source) 237 : null; 238 supportsSplitScreenMultiWindow = source.readBoolean(); 239 resizeMode = source.readInt(); 240 configuration.readFromParcel(source); 241 token = WindowContainerToken.CREATOR.createFromParcel(source); 242 topActivityType = source.readInt(); 243 pictureInPictureParams = source.readInt() != 0 244 ? PictureInPictureParams.CREATOR.createFromParcel(source) 245 : null; 246 topActivityInfo = source.readInt() != 0 247 ? ActivityInfo.CREATOR.createFromParcel(source) 248 : null; 249 isResizeable = source.readBoolean(); 250 } 251 252 /** 253 * Writes the TaskInfo to a parcel. 254 */ writeToParcel(Parcel dest, int flags)255 void writeToParcel(Parcel dest, int flags) { 256 dest.writeInt(userId); 257 dest.writeInt(stackId); 258 dest.writeInt(taskId); 259 dest.writeInt(displayId); 260 dest.writeBoolean(isRunning); 261 262 if (baseIntent != null) { 263 dest.writeInt(1); 264 baseIntent.writeToParcel(dest, 0); 265 } else { 266 dest.writeInt(0); 267 } 268 ComponentName.writeToParcel(baseActivity, dest); 269 ComponentName.writeToParcel(topActivity, dest); 270 ComponentName.writeToParcel(origActivity, dest); 271 ComponentName.writeToParcel(realActivity, dest); 272 273 dest.writeInt(numActivities); 274 dest.writeLong(lastActiveTime); 275 276 if (taskDescription != null) { 277 dest.writeInt(1); 278 taskDescription.writeToParcel(dest, flags); 279 } else { 280 dest.writeInt(0); 281 } 282 dest.writeBoolean(supportsSplitScreenMultiWindow); 283 dest.writeInt(resizeMode); 284 configuration.writeToParcel(dest, flags); 285 token.writeToParcel(dest, flags); 286 dest.writeInt(topActivityType); 287 if (pictureInPictureParams == null) { 288 dest.writeInt(0); 289 } else { 290 dest.writeInt(1); 291 pictureInPictureParams.writeToParcel(dest, flags); 292 } 293 if (topActivityInfo == null) { 294 dest.writeInt(0); 295 } else { 296 dest.writeInt(1); 297 topActivityInfo.writeToParcel(dest, flags); 298 } 299 dest.writeBoolean(isResizeable); 300 } 301 302 @Override toString()303 public String toString() { 304 return "TaskInfo{userId=" + userId + " stackId=" + stackId + " taskId=" + taskId 305 + " displayId=" + displayId 306 + " isRunning=" + isRunning 307 + " baseIntent=" + baseIntent + " baseActivity=" + baseActivity 308 + " topActivity=" + topActivity + " origActivity=" + origActivity 309 + " realActivity=" + realActivity 310 + " numActivities=" + numActivities 311 + " lastActiveTime=" + lastActiveTime 312 + " supportsSplitScreenMultiWindow=" + supportsSplitScreenMultiWindow 313 + " resizeMode=" + resizeMode 314 + " isResizeable=" + isResizeable 315 + " token=" + token 316 + " topActivityType=" + topActivityType 317 + " pictureInPictureParams=" + pictureInPictureParams 318 + " topActivityInfo=" + topActivityInfo; 319 } 320 } 321