• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static android.app.ActivityTaskManager.INVALID_TASK_ID;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.TestApi;
24 import android.compat.annotation.UnsupportedAppUsage;
25 import android.content.ComponentName;
26 import android.content.Intent;
27 import android.content.LocusId;
28 import android.content.pm.ActivityInfo;
29 import android.content.res.Configuration;
30 import android.graphics.Point;
31 import android.graphics.Rect;
32 import android.os.Build;
33 import android.os.IBinder;
34 import android.os.Parcel;
35 import android.os.RemoteException;
36 import android.util.Log;
37 import android.view.DisplayCutout;
38 import android.window.TaskSnapshot;
39 import android.window.WindowContainerToken;
40 
41 import java.util.ArrayList;
42 import java.util.Objects;
43 
44 /**
45  * Stores information about a particular Task.
46  */
47 public class TaskInfo {
48     private static final String TAG = "TaskInfo";
49 
50     /**
51      * The id of the user the task was running as if this is a leaf task. The id of the current
52      * running user of the system otherwise.
53      * @hide
54      */
55     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
56     public int userId;
57 
58     /**
59      * The identifier for this task.
60      */
61     public int taskId;
62 
63     /**
64      * Whether or not this task has any running activities.
65      */
66     public boolean isRunning;
67 
68     /**
69      * The base intent of the task (generally the intent that launched the task). This intent can
70      * be used to relaunch the task (if it is no longer running) or brought to the front if it is.
71      */
72     @NonNull
73     public Intent baseIntent;
74 
75     /**
76      * The component of the first activity in the task, can be considered the "application" of this
77      * task.
78      */
79     @Nullable
80     public ComponentName baseActivity;
81 
82     /**
83      * The component of the top activity in the task, currently showing to the user.
84      */
85     @Nullable
86     public ComponentName topActivity;
87 
88     /**
89      * The component of the target activity if this task was started from an activity alias.
90      * Otherwise, this is null.
91      */
92     @Nullable
93     public ComponentName origActivity;
94 
95     /**
96      * The component of the activity that started this task (may be the component of the activity
97      * alias).
98      * @hide
99      */
100     @Nullable
101     public ComponentName realActivity;
102 
103     /**
104      * The number of activities in this task (including running).
105      */
106     public int numActivities;
107 
108     /**
109      * The last time this task was active since boot (including time spent in sleep).
110      * @hide
111      */
112     @UnsupportedAppUsage
113     public long lastActiveTime;
114 
115     /**
116      * The id of the display this task is associated with.
117      * @hide
118      */
119     public int displayId;
120 
121     /**
122      * The recent activity values for the highest activity in the stack to have set the values.
123      * {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}.
124      */
125     @Nullable
126     public ActivityManager.TaskDescription taskDescription;
127 
128     /**
129      * The locusId of the task.
130      * @hide
131      */
132     @Nullable
133     public LocusId mTopActivityLocusId;
134 
135     /**
136      * True if the task can go in the split-screen primary stack.
137      * @hide
138      */
139     @UnsupportedAppUsage
140     public boolean supportsSplitScreenMultiWindow;
141 
142     /**
143      * Whether this task supports multi windowing modes based on the device settings and the
144      * root activity resizability and configuration.
145      * @hide
146      */
147     public boolean supportsMultiWindow;
148 
149     /**
150      * The resize mode of the task. See {@link ActivityInfo#resizeMode}.
151      * @hide
152      */
153     @UnsupportedAppUsage
154     public int resizeMode;
155 
156     /**
157      * The current configuration of the task.
158      * @hide
159      */
160     @NonNull
161     @UnsupportedAppUsage
162     public final Configuration configuration = new Configuration();
163 
164     /**
165      * Used as an opaque identifier for this task.
166      * @hide
167      */
168     @NonNull
169     public WindowContainerToken token;
170 
171     /**
172      * The PictureInPictureParams for the Task, if set.
173      * @hide
174      */
175     @Nullable
176     public PictureInPictureParams pictureInPictureParams;
177 
178     /**
179      * The {@link Rect} copied from {@link DisplayCutout#getSafeInsets()} if the cutout is not of
180      * (LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS),
181      * {@code null} otherwise.
182      * @hide
183      */
184     @Nullable
185     public Rect displayCutoutInsets;
186 
187     /**
188      * The activity type of the top activity in this task.
189      * @hide
190      */
191     public @WindowConfiguration.ActivityType int topActivityType;
192 
193     /**
194      * The {@link ActivityInfo} of the top activity in this task.
195      * @hide
196      */
197     @Nullable
198     public ActivityInfo topActivityInfo;
199 
200     /**
201      * Whether the direct top activity is in size compat mode on foreground.
202      * @hide
203      */
204     public boolean topActivityInSizeCompat;
205 
206     /**
207      * Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity
208      * supports), this is what the system actually uses for resizability based on other policy and
209      * developer options.
210      * @hide
211      */
212     public boolean isResizeable;
213 
214     /**
215      * Relative position of the task's top left corner in the parent container.
216      * @hide
217      */
218     public Point positionInParent;
219 
220     /**
221      * The launch cookies associated with activities in this task if any.
222      * @see ActivityOptions#setLaunchCookie(IBinder)
223      * @hide
224      */
225     public ArrayList<IBinder> launchCookies = new ArrayList<>();
226 
227     /**
228      * The identifier of the parent task that is created by organizer, otherwise
229      * {@link ActivityTaskManager#INVALID_TASK_ID}.
230      * @hide
231      */
232     public int parentTaskId;
233 
234     /**
235      * Whether this task is focused.
236      * @hide
237      */
238     public boolean isFocused;
239 
240     /**
241      * Whether this task is visible.
242      * @hide
243      */
244     public boolean isVisible;
245 
TaskInfo()246     TaskInfo() {
247         // Do nothing
248     }
249 
TaskInfo(Parcel source)250     private TaskInfo(Parcel source) {
251         readFromParcel(source);
252     }
253 
254     /**
255      * @param isLowResolution
256      * @return
257      * @hide
258      */
getTaskSnapshot(boolean isLowResolution)259     public TaskSnapshot getTaskSnapshot(boolean isLowResolution) {
260         try {
261             return ActivityTaskManager.getService().getTaskSnapshot(taskId, isLowResolution);
262         } catch (RemoteException e) {
263             Log.e(TAG, "Failed to get task snapshot, taskId=" + taskId, e);
264             return null;
265         }
266     }
267 
268     /** @hide */
269     @NonNull
270     @TestApi
getToken()271     public WindowContainerToken getToken() {
272         return token;
273     }
274 
275     /** @hide */
276     @NonNull
277     @TestApi
getConfiguration()278     public Configuration getConfiguration() {
279         return configuration;
280     }
281 
282     /** @hide */
283     @Nullable
284     @TestApi
getPictureInPictureParams()285     public PictureInPictureParams getPictureInPictureParams() {
286         return pictureInPictureParams;
287     }
288 
289     /** @hide */
290     @WindowConfiguration.WindowingMode
getWindowingMode()291     public int getWindowingMode() {
292         return configuration.windowConfiguration.getWindowingMode();
293     }
294 
295     /** @hide */
296     @WindowConfiguration.ActivityType
getActivityType()297     public int getActivityType() {
298         return configuration.windowConfiguration.getActivityType();
299     }
300 
301     /** @hide */
addLaunchCookie(IBinder cookie)302     public void addLaunchCookie(IBinder cookie) {
303         if (cookie == null || launchCookies.contains(cookie)) return;
304         launchCookies.add(cookie);
305     }
306 
307     /**
308      * @return {@code true} if this task contains the launch cookie.
309      * @hide
310      */
311     @TestApi
containsLaunchCookie(@onNull IBinder cookie)312     public boolean containsLaunchCookie(@NonNull IBinder cookie) {
313         return launchCookies.contains(cookie);
314     }
315 
316     /**
317      * @return The parent task id of this task.
318      * @hide
319      */
320     @TestApi
getParentTaskId()321     public int getParentTaskId() {
322         return parentTaskId;
323     }
324 
325     /** @hide */
326     @TestApi
hasParentTask()327     public boolean hasParentTask() {
328         return parentTaskId != INVALID_TASK_ID;
329     }
330 
331     /**
332       * Returns {@code true} if parameters that are important for task organizers have changed
333       * and {@link com.android.server.wm.TaskOrginizerController} needs to notify listeners
334       * about that.
335       * @hide
336       */
equalsForTaskOrganizer(@ullable TaskInfo that)337     public boolean equalsForTaskOrganizer(@Nullable TaskInfo that) {
338         if (that == null) {
339             return false;
340         }
341         return topActivityType == that.topActivityType
342                 && isResizeable == that.isResizeable
343                 && supportsMultiWindow == that.supportsMultiWindow
344                 && Objects.equals(positionInParent, that.positionInParent)
345                 && Objects.equals(pictureInPictureParams, that.pictureInPictureParams)
346                 && Objects.equals(displayCutoutInsets, that.displayCutoutInsets)
347                 && getWindowingMode() == that.getWindowingMode()
348                 && Objects.equals(taskDescription, that.taskDescription)
349                 && isFocused == that.isFocused
350                 && isVisible == that.isVisible;
351     }
352 
353     /**
354      * @return {@code true} if parameters that are important for size compat have changed.
355      * @hide
356      */
equalsForSizeCompat(@ullable TaskInfo that)357     public boolean equalsForSizeCompat(@Nullable TaskInfo that) {
358         if (that == null) {
359             return false;
360         }
361         return displayId == that.displayId
362                 && taskId == that.taskId
363                 && topActivityInSizeCompat == that.topActivityInSizeCompat
364                 // Bounds are important if top activity is in size compat
365                 && (!topActivityInSizeCompat || configuration.windowConfiguration.getBounds()
366                     .equals(that.configuration.windowConfiguration.getBounds()))
367                 && (!topActivityInSizeCompat || configuration.getLayoutDirection()
368                     == that.configuration.getLayoutDirection())
369                 && (!topActivityInSizeCompat || isVisible == that.isVisible);
370     }
371 
372     /**
373      * Reads the TaskInfo from a parcel.
374      */
readFromParcel(Parcel source)375     void readFromParcel(Parcel source) {
376         userId = source.readInt();
377         taskId = source.readInt();
378         displayId = source.readInt();
379         isRunning = source.readBoolean();
380         baseIntent = source.readTypedObject(Intent.CREATOR);
381         baseActivity = ComponentName.readFromParcel(source);
382         topActivity = ComponentName.readFromParcel(source);
383         origActivity = ComponentName.readFromParcel(source);
384         realActivity = ComponentName.readFromParcel(source);
385 
386         numActivities = source.readInt();
387         lastActiveTime = source.readLong();
388 
389         taskDescription = source.readTypedObject(ActivityManager.TaskDescription.CREATOR);
390         supportsSplitScreenMultiWindow = source.readBoolean();
391         supportsMultiWindow = source.readBoolean();
392         resizeMode = source.readInt();
393         configuration.readFromParcel(source);
394         token = WindowContainerToken.CREATOR.createFromParcel(source);
395         topActivityType = source.readInt();
396         pictureInPictureParams = source.readTypedObject(PictureInPictureParams.CREATOR);
397         displayCutoutInsets = source.readTypedObject(Rect.CREATOR);
398         topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR);
399         isResizeable = source.readBoolean();
400         source.readBinderList(launchCookies);
401         positionInParent = source.readTypedObject(Point.CREATOR);
402         parentTaskId = source.readInt();
403         isFocused = source.readBoolean();
404         isVisible = source.readBoolean();
405         topActivityInSizeCompat = source.readBoolean();
406         mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR);
407     }
408 
409     /**
410      * Writes the TaskInfo to a parcel.
411      */
writeToParcel(Parcel dest, int flags)412     void writeToParcel(Parcel dest, int flags) {
413         dest.writeInt(userId);
414         dest.writeInt(taskId);
415         dest.writeInt(displayId);
416         dest.writeBoolean(isRunning);
417         dest.writeTypedObject(baseIntent, 0);
418 
419         ComponentName.writeToParcel(baseActivity, dest);
420         ComponentName.writeToParcel(topActivity, dest);
421         ComponentName.writeToParcel(origActivity, dest);
422         ComponentName.writeToParcel(realActivity, dest);
423 
424         dest.writeInt(numActivities);
425         dest.writeLong(lastActiveTime);
426 
427         dest.writeTypedObject(taskDescription, flags);
428         dest.writeBoolean(supportsSplitScreenMultiWindow);
429         dest.writeBoolean(supportsMultiWindow);
430         dest.writeInt(resizeMode);
431         configuration.writeToParcel(dest, flags);
432         token.writeToParcel(dest, flags);
433         dest.writeInt(topActivityType);
434         dest.writeTypedObject(pictureInPictureParams, flags);
435         dest.writeTypedObject(displayCutoutInsets, flags);
436         dest.writeTypedObject(topActivityInfo, flags);
437         dest.writeBoolean(isResizeable);
438         dest.writeBinderList(launchCookies);
439         dest.writeTypedObject(positionInParent, flags);
440         dest.writeInt(parentTaskId);
441         dest.writeBoolean(isFocused);
442         dest.writeBoolean(isVisible);
443         dest.writeBoolean(topActivityInSizeCompat);
444         dest.writeTypedObject(mTopActivityLocusId, flags);
445     }
446 
447     @Override
toString()448     public String toString() {
449         return "TaskInfo{userId=" + userId + " taskId=" + taskId
450                 + " displayId=" + displayId
451                 + " isRunning=" + isRunning
452                 + " baseIntent=" + baseIntent + " baseActivity=" + baseActivity
453                 + " topActivity=" + topActivity + " origActivity=" + origActivity
454                 + " realActivity=" + realActivity
455                 + " numActivities=" + numActivities
456                 + " lastActiveTime=" + lastActiveTime
457                 + " supportsSplitScreenMultiWindow=" + supportsSplitScreenMultiWindow
458                 + " supportsMultiWindow=" + supportsMultiWindow
459                 + " resizeMode=" + resizeMode
460                 + " isResizeable=" + isResizeable
461                 + " token=" + token
462                 + " topActivityType=" + topActivityType
463                 + " pictureInPictureParams=" + pictureInPictureParams
464                 + " displayCutoutSafeInsets=" + displayCutoutInsets
465                 + " topActivityInfo=" + topActivityInfo
466                 + " launchCookies=" + launchCookies
467                 + " positionInParent=" + positionInParent
468                 + " parentTaskId=" + parentTaskId
469                 + " isFocused=" + isFocused
470                 + " isVisible=" + isVisible
471                 + " topActivityInSizeCompat=" + topActivityInSizeCompat
472                 + " locusId= " + mTopActivityLocusId
473                 + "}";
474     }
475 }
476