• 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 import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
21 
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.TestApi;
25 import android.compat.annotation.UnsupportedAppUsage;
26 import android.content.ComponentName;
27 import android.content.Intent;
28 import android.content.LocusId;
29 import android.content.pm.ActivityInfo;
30 import android.content.res.Configuration;
31 import android.graphics.Point;
32 import android.graphics.Rect;
33 import android.os.Build;
34 import android.os.IBinder;
35 import android.os.Parcel;
36 import android.view.DisplayCutout;
37 import android.window.WindowContainerToken;
38 
39 import java.util.ArrayList;
40 import java.util.Objects;
41 
42 /**
43  * Stores information about a particular Task.
44  */
45 public class TaskInfo {
46     private static final String TAG = "TaskInfo";
47 
48     /**
49      * The value to use when the property has not a specific value.
50      * @hide
51      */
52     public static final int PROPERTY_VALUE_UNSET = -1;
53 
54     /**
55      * The id of the user the task was running as if this is a leaf task. The id of the current
56      * running user of the system otherwise.
57      * @hide
58      */
59     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
60     public int userId;
61 
62     /**
63      * The identifier for this task.
64      */
65     public int taskId;
66 
67     /**
68      * Whether or not this task has any running activities.
69      */
70     public boolean isRunning;
71 
72     /**
73      * The base intent of the task (generally the intent that launched the task). This intent can
74      * be used to relaunch the task (if it is no longer running) or brought to the front if it is.
75      */
76     @NonNull
77     public Intent baseIntent;
78 
79     /**
80      * The component of the first activity in the task, can be considered the "application" of this
81      * task.
82      */
83     @Nullable
84     public ComponentName baseActivity;
85 
86     /**
87      * The component of the top activity in the task, currently showing to the user.
88      */
89     @Nullable
90     public ComponentName topActivity;
91 
92     /**
93      * The component of the target activity if this task was started from an activity alias.
94      * Otherwise, this is null.
95      */
96     @Nullable
97     public ComponentName origActivity;
98 
99     /**
100      * The component of the activity that started this task (may be the component of the activity
101      * alias).
102      * @hide
103      */
104     @Nullable
105     public ComponentName realActivity;
106 
107     /**
108      * The number of activities in this task (including running).
109      */
110     public int numActivities;
111 
112     /**
113      * The last time this task was active since boot (including time spent in sleep).
114      * @hide
115      */
116     @UnsupportedAppUsage
117     public long lastActiveTime;
118 
119     /**
120      * The id of the display this task is associated with.
121      * @hide
122      */
123     public int displayId;
124 
125     /**
126      * The feature id of {@link com.android.server.wm.TaskDisplayArea} this task is associated with.
127      * @hide
128      */
129     public int displayAreaFeatureId = FEATURE_UNDEFINED;
130 
131     /**
132      * The recent activity values for the highest activity in the stack to have set the values.
133      * {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}.
134      */
135     @Nullable
136     public ActivityManager.TaskDescription taskDescription;
137 
138     /**
139      * The locusId of the task.
140      * @hide
141      */
142     @Nullable
143     public LocusId mTopActivityLocusId;
144 
145     /**
146      * Whether this task supports multi windowing modes based on the device settings and the
147      * root activity resizability and configuration.
148      * @hide
149      */
150     public boolean supportsMultiWindow;
151 
152     /**
153      * The resize mode of the task. See {@link ActivityInfo#resizeMode}.
154      * @hide
155      */
156     @UnsupportedAppUsage
157     public int resizeMode;
158 
159     /**
160      * The current configuration of the task.
161      * @hide
162      */
163     @NonNull
164     @UnsupportedAppUsage
165     public final Configuration configuration = new Configuration();
166 
167     /**
168      * Used as an opaque identifier for this task.
169      * @hide
170      */
171     @NonNull
172     public WindowContainerToken token;
173 
174     /**
175      * The PictureInPictureParams for the Task, if set.
176      * @hide
177      */
178     @Nullable
179     public PictureInPictureParams pictureInPictureParams;
180 
181     /**
182      * @hide
183      */
184     public boolean shouldDockBigOverlays;
185 
186     /**
187      * The task id of the host Task of the launch-into-pip Activity, i.e., it points to the Task
188      * the launch-into-pip Activity is originated from.
189      * @hide
190      */
191     public int launchIntoPipHostTaskId;
192 
193     /**
194      * The task id of the parent Task of the launch-into-pip Activity, i.e., if task have more than
195      * one activity it will create new task for this activity, this id is the origin task id and
196      * the pip activity will be reparent to origin task when it exit pip mode.
197      * @hide
198      */
199     public int lastParentTaskIdBeforePip;
200 
201     /**
202      * The {@link Rect} copied from {@link DisplayCutout#getSafeInsets()} if the cutout is not of
203      * (LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS),
204      * {@code null} otherwise.
205      * @hide
206      */
207     @Nullable
208     public Rect displayCutoutInsets;
209 
210     /**
211      * The activity type of the top activity in this task.
212      * @hide
213      */
214     public @WindowConfiguration.ActivityType int topActivityType;
215 
216     /**
217      * The {@link ActivityInfo} of the top activity in this task.
218      * @hide
219      */
220     @Nullable
221     public ActivityInfo topActivityInfo;
222 
223     /**
224      * Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity
225      * supports), this is what the system actually uses for resizability based on other policy and
226      * developer options.
227      * @hide
228      */
229     public boolean isResizeable;
230 
231     /**
232      * Minimal width of the task when it's resizeable.
233      * @hide
234      */
235     public int minWidth;
236 
237     /**
238      * Minimal height of the task when it's resizeable.
239      * @hide
240      */
241     public int minHeight;
242 
243     /**
244      * The default minimal size of the task used when a minWidth or minHeight is not specified.
245      * @hide
246      */
247     public int defaultMinSize;
248 
249     /**
250      * Relative position of the task's top left corner in the parent container.
251      * @hide
252      */
253     public Point positionInParent;
254 
255     /**
256      * The launch cookies associated with activities in this task if any.
257      * @see ActivityOptions#setLaunchCookie(IBinder)
258      * @hide
259      */
260     public ArrayList<IBinder> launchCookies = new ArrayList<>();
261 
262     /**
263      * The identifier of the parent task that is created by organizer, otherwise
264      * {@link ActivityTaskManager#INVALID_TASK_ID}.
265      * @hide
266      */
267     public int parentTaskId;
268 
269     /**
270      * Whether this task is focused.
271      * @hide
272      */
273     public boolean isFocused;
274 
275     /**
276      * Whether this task is visible.
277      * @hide
278      */
279     public boolean isVisible;
280 
281     /**
282      * Whether this task is request visible.
283      * @hide
284      */
285     public boolean isVisibleRequested;
286 
287     /**
288      * Whether this task is sleeping due to sleeping display.
289      * @hide
290      */
291     public boolean isSleeping;
292 
293     /**
294      * Whether the top activity fillsParent() is false
295      * @hide
296      */
297     public boolean isTopActivityTransparent;
298 
299     /**
300      * Encapsulate specific App Compat information.
301      * @hide
302      */
303     public AppCompatTaskInfo appCompatTaskInfo = AppCompatTaskInfo.create();
304 
TaskInfo()305     TaskInfo() {
306         // Do nothing
307     }
308 
TaskInfo(Parcel source)309     private TaskInfo(Parcel source) {
310         readFromParcel(source);
311     }
312 
313     /**
314      * Whether this task is visible.
315      */
isVisible()316     public boolean isVisible() {
317         return isVisible;
318     }
319 
320     /** @hide */
321     @NonNull
322     @TestApi
getToken()323     public WindowContainerToken getToken() {
324         return token;
325     }
326 
327     /** @hide */
328     @NonNull
329     @TestApi
getConfiguration()330     public Configuration getConfiguration() {
331         return configuration;
332     }
333 
334     /** @hide */
335     @Nullable
336     @TestApi
getPictureInPictureParams()337     public PictureInPictureParams getPictureInPictureParams() {
338         return pictureInPictureParams;
339     }
340 
341     /** @hide */
342     @TestApi
shouldDockBigOverlays()343     public boolean shouldDockBigOverlays() {
344         return shouldDockBigOverlays;
345     }
346 
347     /** @hide */
348     @WindowConfiguration.WindowingMode
getWindowingMode()349     public int getWindowingMode() {
350         return configuration.windowConfiguration.getWindowingMode();
351     }
352 
353     /** @hide */
isFreeform()354     public boolean isFreeform() {
355         return configuration.windowConfiguration.getWindowingMode()
356                 == WindowConfiguration.WINDOWING_MODE_FREEFORM;
357     }
358 
359     /** @hide */
360     @WindowConfiguration.ActivityType
getActivityType()361     public int getActivityType() {
362         return configuration.windowConfiguration.getActivityType();
363     }
364 
365     /** @hide */
addLaunchCookie(IBinder cookie)366     public void addLaunchCookie(IBinder cookie) {
367         if (cookie == null || launchCookies.contains(cookie)) return;
368         launchCookies.add(cookie);
369     }
370 
371     /**
372      * @return {@code true} if this task contains the launch cookie.
373      * @hide
374      */
375     @TestApi
containsLaunchCookie(@onNull IBinder cookie)376     public boolean containsLaunchCookie(@NonNull IBinder cookie) {
377         return launchCookies.contains(cookie);
378     }
379 
380     /**
381      * @return The parent task id of this task.
382      * @hide
383      */
384     @TestApi
getParentTaskId()385     public int getParentTaskId() {
386         return parentTaskId;
387     }
388 
389     /** @hide */
390     @TestApi
hasParentTask()391     public boolean hasParentTask() {
392         return parentTaskId != INVALID_TASK_ID;
393     }
394 
395     /**
396      * @return The id of the display this task is associated with.
397      * @hide
398      */
399     @TestApi
getDisplayId()400     public int getDisplayId() {
401         return displayId;
402     }
403 
404     /**
405      * Returns {@code true} if the parameters that are important for task organizers are equal
406      * between this {@link TaskInfo} and {@param that}.
407      * @hide
408      */
equalsForTaskOrganizer(@ullable TaskInfo that)409     public boolean equalsForTaskOrganizer(@Nullable TaskInfo that) {
410         if (that == null) {
411             return false;
412         }
413         return topActivityType == that.topActivityType
414                 && isResizeable == that.isResizeable
415                 && supportsMultiWindow == that.supportsMultiWindow
416                 && displayAreaFeatureId == that.displayAreaFeatureId
417                 && Objects.equals(positionInParent, that.positionInParent)
418                 && Objects.equals(pictureInPictureParams, that.pictureInPictureParams)
419                 && Objects.equals(shouldDockBigOverlays, that.shouldDockBigOverlays)
420                 && Objects.equals(displayCutoutInsets, that.displayCutoutInsets)
421                 && getWindowingMode() == that.getWindowingMode()
422                 && configuration.uiMode == that.configuration.uiMode
423                 && Objects.equals(taskDescription, that.taskDescription)
424                 && isFocused == that.isFocused
425                 && isVisible == that.isVisible
426                 && isVisibleRequested == that.isVisibleRequested
427                 && isSleeping == that.isSleeping
428                 && Objects.equals(mTopActivityLocusId, that.mTopActivityLocusId)
429                 && parentTaskId == that.parentTaskId
430                 && Objects.equals(topActivity, that.topActivity)
431                 && isTopActivityTransparent == that.isTopActivityTransparent
432                 && appCompatTaskInfo.equalsForTaskOrganizer(that.appCompatTaskInfo);
433     }
434 
435     /**
436      * @return {@code true} if parameters that are important for size compat have changed.
437      * @hide
438      */
equalsForCompatUi(@ullable TaskInfo that)439     public boolean equalsForCompatUi(@Nullable TaskInfo that) {
440         if (that == null) {
441             return false;
442         }
443         final boolean hasCompatUI = appCompatTaskInfo.hasCompatUI();
444         return displayId == that.displayId
445                 && taskId == that.taskId
446                 && isFocused == that.isFocused
447                 && isTopActivityTransparent == that.isTopActivityTransparent
448                 && appCompatTaskInfo.equalsForCompatUi(that.appCompatTaskInfo)
449                 // Bounds are important if top activity has compat controls.
450                 && (!hasCompatUI || configuration.windowConfiguration.getBounds()
451                     .equals(that.configuration.windowConfiguration.getBounds()))
452                 && (!hasCompatUI || configuration.getLayoutDirection()
453                     == that.configuration.getLayoutDirection())
454                 && (!hasCompatUI || configuration.uiMode == that.configuration.uiMode)
455                 && (!hasCompatUI || isVisible == that.isVisible);
456     }
457 
458     /**
459      * Reads the TaskInfo from a parcel.
460      */
readFromParcel(Parcel source)461     void readFromParcel(Parcel source) {
462         userId = source.readInt();
463         taskId = source.readInt();
464         displayId = source.readInt();
465         isRunning = source.readBoolean();
466         baseIntent = source.readTypedObject(Intent.CREATOR);
467         baseActivity = ComponentName.readFromParcel(source);
468         topActivity = ComponentName.readFromParcel(source);
469         origActivity = ComponentName.readFromParcel(source);
470         realActivity = ComponentName.readFromParcel(source);
471 
472         numActivities = source.readInt();
473         lastActiveTime = source.readLong();
474 
475         taskDescription = source.readTypedObject(ActivityManager.TaskDescription.CREATOR);
476         supportsMultiWindow = source.readBoolean();
477         resizeMode = source.readInt();
478         configuration.readFromParcel(source);
479         token = WindowContainerToken.CREATOR.createFromParcel(source);
480         topActivityType = source.readInt();
481         pictureInPictureParams = source.readTypedObject(PictureInPictureParams.CREATOR);
482         shouldDockBigOverlays = source.readBoolean();
483         launchIntoPipHostTaskId = source.readInt();
484         lastParentTaskIdBeforePip = source.readInt();
485         displayCutoutInsets = source.readTypedObject(Rect.CREATOR);
486         topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR);
487         isResizeable = source.readBoolean();
488         minWidth = source.readInt();
489         minHeight = source.readInt();
490         defaultMinSize = source.readInt();
491         source.readBinderList(launchCookies);
492         positionInParent = source.readTypedObject(Point.CREATOR);
493         parentTaskId = source.readInt();
494         isFocused = source.readBoolean();
495         isVisible = source.readBoolean();
496         isVisibleRequested = source.readBoolean();
497         isSleeping = source.readBoolean();
498         mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR);
499         displayAreaFeatureId = source.readInt();
500         isTopActivityTransparent = source.readBoolean();
501         appCompatTaskInfo = source.readTypedObject(AppCompatTaskInfo.CREATOR);
502     }
503 
504     /**
505      * Writes the TaskInfo to a parcel.
506      */
writeToParcel(Parcel dest, int flags)507     void writeToParcel(Parcel dest, int flags) {
508         dest.writeInt(userId);
509         dest.writeInt(taskId);
510         dest.writeInt(displayId);
511         dest.writeBoolean(isRunning);
512         dest.writeTypedObject(baseIntent, 0);
513 
514         ComponentName.writeToParcel(baseActivity, dest);
515         ComponentName.writeToParcel(topActivity, dest);
516         ComponentName.writeToParcel(origActivity, dest);
517         ComponentName.writeToParcel(realActivity, dest);
518 
519         dest.writeInt(numActivities);
520         dest.writeLong(lastActiveTime);
521 
522         dest.writeTypedObject(taskDescription, flags);
523         dest.writeBoolean(supportsMultiWindow);
524         dest.writeInt(resizeMode);
525         configuration.writeToParcel(dest, flags);
526         token.writeToParcel(dest, flags);
527         dest.writeInt(topActivityType);
528         dest.writeTypedObject(pictureInPictureParams, flags);
529         dest.writeBoolean(shouldDockBigOverlays);
530         dest.writeInt(launchIntoPipHostTaskId);
531         dest.writeInt(lastParentTaskIdBeforePip);
532         dest.writeTypedObject(displayCutoutInsets, flags);
533         dest.writeTypedObject(topActivityInfo, flags);
534         dest.writeBoolean(isResizeable);
535         dest.writeInt(minWidth);
536         dest.writeInt(minHeight);
537         dest.writeInt(defaultMinSize);
538         dest.writeBinderList(launchCookies);
539         dest.writeTypedObject(positionInParent, flags);
540         dest.writeInt(parentTaskId);
541         dest.writeBoolean(isFocused);
542         dest.writeBoolean(isVisible);
543         dest.writeBoolean(isVisibleRequested);
544         dest.writeBoolean(isSleeping);
545         dest.writeTypedObject(mTopActivityLocusId, flags);
546         dest.writeInt(displayAreaFeatureId);
547         dest.writeBoolean(isTopActivityTransparent);
548         dest.writeTypedObject(appCompatTaskInfo, flags);
549     }
550 
551     @Override
toString()552     public String toString() {
553         return "TaskInfo{userId=" + userId + " taskId=" + taskId
554                 + " displayId=" + displayId
555                 + " isRunning=" + isRunning
556                 + " baseIntent=" + baseIntent + " baseActivity=" + baseActivity
557                 + " topActivity=" + topActivity + " origActivity=" + origActivity
558                 + " realActivity=" + realActivity
559                 + " numActivities=" + numActivities
560                 + " lastActiveTime=" + lastActiveTime
561                 + " supportsMultiWindow=" + supportsMultiWindow
562                 + " resizeMode=" + resizeMode
563                 + " isResizeable=" + isResizeable
564                 + " minWidth=" + minWidth
565                 + " minHeight=" + minHeight
566                 + " defaultMinSize=" + defaultMinSize
567                 + " token=" + token
568                 + " topActivityType=" + topActivityType
569                 + " pictureInPictureParams=" + pictureInPictureParams
570                 + " shouldDockBigOverlays=" + shouldDockBigOverlays
571                 + " launchIntoPipHostTaskId=" + launchIntoPipHostTaskId
572                 + " lastParentTaskIdBeforePip=" + lastParentTaskIdBeforePip
573                 + " displayCutoutSafeInsets=" + displayCutoutInsets
574                 + " topActivityInfo=" + topActivityInfo
575                 + " launchCookies=" + launchCookies
576                 + " positionInParent=" + positionInParent
577                 + " parentTaskId=" + parentTaskId
578                 + " isFocused=" + isFocused
579                 + " isVisible=" + isVisible
580                 + " isVisibleRequested=" + isVisibleRequested
581                 + " isSleeping=" + isSleeping
582                 + " locusId=" + mTopActivityLocusId
583                 + " displayAreaFeatureId=" + displayAreaFeatureId
584                 + " isTopActivityTransparent=" + isTopActivityTransparent
585                 + " appCompatTaskInfo=" + appCompatTaskInfo
586                 + "}";
587     }
588 }
589