• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.window;
18 
19 import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
20 import static android.app.ActivityOptions.ANIM_CUSTOM;
21 import static android.app.ActivityOptions.ANIM_FROM_STYLE;
22 import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
23 import static android.app.ActivityOptions.ANIM_SCALE_UP;
24 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
25 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
26 import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
27 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
28 import static android.view.WindowManager.TRANSIT_CHANGE;
29 import static android.view.WindowManager.TRANSIT_CLOSE;
30 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
31 import static android.view.WindowManager.TRANSIT_NONE;
32 import static android.view.WindowManager.TRANSIT_OPEN;
33 import static android.view.WindowManager.TRANSIT_TO_BACK;
34 import static android.view.WindowManager.TRANSIT_TO_FRONT;
35 import static android.view.WindowManager.TransitionFlags;
36 import static android.view.WindowManager.TransitionType;
37 import static android.view.WindowManager.transitTypeToString;
38 
39 import android.annotation.ColorInt;
40 import android.annotation.IntDef;
41 import android.annotation.NonNull;
42 import android.annotation.Nullable;
43 import android.app.ActivityManager;
44 import android.graphics.Point;
45 import android.graphics.Rect;
46 import android.hardware.HardwareBuffer;
47 import android.os.Parcel;
48 import android.os.Parcelable;
49 import android.view.Surface;
50 import android.view.SurfaceControl;
51 import android.view.WindowManager;
52 
53 import java.util.ArrayList;
54 import java.util.List;
55 
56 /**
57  * Used to communicate information about what is changing during a transition to a TransitionPlayer.
58  * @hide
59  */
60 public final class TransitionInfo implements Parcelable {
61 
62     /**
63      * Modes are only a sub-set of all the transit-types since they are per-container
64      * @hide
65      */
66     @IntDef(prefix = { "TRANSIT_" }, value = {
67             TRANSIT_NONE,
68             TRANSIT_OPEN,
69             TRANSIT_CLOSE,
70             // Note: to_front/to_back really mean show/hide respectively at the container level.
71             TRANSIT_TO_FRONT,
72             TRANSIT_TO_BACK,
73             TRANSIT_CHANGE
74     })
75     public @interface TransitionMode {}
76 
77     /** No flags */
78     public static final int FLAG_NONE = 0;
79 
80     /** The container shows the wallpaper behind it. */
81     public static final int FLAG_SHOW_WALLPAPER = 1;
82 
83     /** The container IS the wallpaper. */
84     public static final int FLAG_IS_WALLPAPER = 1 << 1;
85 
86     /** The container is translucent. */
87     public static final int FLAG_TRANSLUCENT = 1 << 2;
88 
89     // TODO: remove when starting-window is moved to Task
90     /** The container is the recipient of a transferred starting-window */
91     public static final int FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT = 1 << 3;
92 
93     /** The container has voice session. */
94     public static final int FLAG_IS_VOICE_INTERACTION = 1 << 4;
95 
96     /** The container is the display. */
97     public static final int FLAG_IS_DISPLAY = 1 << 5;
98 
99     /** The container can show on top of lock screen. */
100     public static final int FLAG_OCCLUDES_KEYGUARD = 1 << 6;
101 
102     /**
103      * Only for IS_DISPLAY containers. Is set if the display has system alert windows. This is
104      * used to prevent seamless rotation.
105      * TODO(b/194540864): Once we can include all windows in transition, then replace this with
106      *         something like FLAG_IS_SYSTEM_ALERT instead. Then we can do mixed rotations.
107      */
108     public static final int FLAG_DISPLAY_HAS_ALERT_WINDOWS = 1 << 7;
109 
110     /** The container is an input-method window. */
111     public static final int FLAG_IS_INPUT_METHOD = 1 << 8;
112 
113     /** The container is in a Task with embedded activity. */
114     public static final int FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY = 1 << 9;
115 
116     /** The container fills its parent Task before and after the transition. */
117     public static final int FLAG_FILLS_TASK = 1 << 10;
118 
119     /** The container is going to show IME on its task after the transition. */
120     public static final int FLAG_WILL_IME_SHOWN = 1 << 11;
121 
122     /** The container attaches owner profile thumbnail for cross profile animation. */
123     public static final int FLAG_CROSS_PROFILE_OWNER_THUMBNAIL = 1 << 12;
124 
125     /** The container attaches work profile thumbnail for cross profile animation. */
126     public static final int FLAG_CROSS_PROFILE_WORK_THUMBNAIL = 1 << 13;
127 
128     /**
129      * Whether the window is covered by an app starting window. This is different from
130      * {@link #FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT} which is only set on the Activity window
131      * that contains the starting window.
132      */
133     public static final int FLAG_IS_BEHIND_STARTING_WINDOW = 1 << 14;
134 
135     /** This change happened underneath something else. */
136     public static final int FLAG_IS_OCCLUDED = 1 << 15;
137 
138     /** The container is a system window, excluding wallpaper and input-method. */
139     public static final int FLAG_IS_SYSTEM_WINDOW = 1 << 16;
140 
141     /** The first unused bit. This can be used by remotes to attach custom flags to this change. */
142     public static final int FLAG_FIRST_CUSTOM = 1 << 17;
143 
144     /** The change belongs to a window that won't contain activities. */
145     public static final int FLAGS_IS_NON_APP_WINDOW =
146             FLAG_IS_WALLPAPER | FLAG_IS_INPUT_METHOD | FLAG_IS_SYSTEM_WINDOW;
147 
148     /** @hide */
149     @IntDef(prefix = { "FLAG_" }, value = {
150             FLAG_NONE,
151             FLAG_SHOW_WALLPAPER,
152             FLAG_IS_WALLPAPER,
153             FLAG_TRANSLUCENT,
154             FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT,
155             FLAG_IS_VOICE_INTERACTION,
156             FLAG_IS_DISPLAY,
157             FLAG_OCCLUDES_KEYGUARD,
158             FLAG_DISPLAY_HAS_ALERT_WINDOWS,
159             FLAG_IS_INPUT_METHOD,
160             FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY,
161             FLAG_FILLS_TASK,
162             FLAG_WILL_IME_SHOWN,
163             FLAG_CROSS_PROFILE_OWNER_THUMBNAIL,
164             FLAG_CROSS_PROFILE_WORK_THUMBNAIL,
165             FLAG_IS_BEHIND_STARTING_WINDOW,
166             FLAG_IS_OCCLUDED,
167             FLAG_IS_SYSTEM_WINDOW,
168             FLAG_FIRST_CUSTOM
169     })
170     public @interface ChangeFlags {}
171 
172     private final @TransitionType int mType;
173     private final @TransitionFlags int mFlags;
174     private final ArrayList<Change> mChanges = new ArrayList<>();
175 
176     private SurfaceControl mRootLeash;
177     private final Point mRootOffset = new Point();
178 
179     private AnimationOptions mOptions;
180 
181     /** @hide */
TransitionInfo(@ransitionType int type, @TransitionFlags int flags)182     public TransitionInfo(@TransitionType int type, @TransitionFlags int flags) {
183         mType = type;
184         mFlags = flags;
185     }
186 
TransitionInfo(Parcel in)187     private TransitionInfo(Parcel in) {
188         mType = in.readInt();
189         mFlags = in.readInt();
190         in.readTypedList(mChanges, Change.CREATOR);
191         mRootLeash = new SurfaceControl();
192         mRootLeash.readFromParcel(in);
193         mRootOffset.readFromParcel(in);
194         mOptions = in.readTypedObject(AnimationOptions.CREATOR);
195     }
196 
197     @Override
198     /** @hide */
writeToParcel(@onNull Parcel dest, int flags)199     public void writeToParcel(@NonNull Parcel dest, int flags) {
200         dest.writeInt(mType);
201         dest.writeInt(mFlags);
202         dest.writeTypedList(mChanges);
203         mRootLeash.writeToParcel(dest, flags);
204         mRootOffset.writeToParcel(dest, flags);
205         dest.writeTypedObject(mOptions, flags);
206     }
207 
208     @NonNull
209     public static final Creator<TransitionInfo> CREATOR =
210             new Creator<TransitionInfo>() {
211                 @Override
212                 public TransitionInfo createFromParcel(Parcel in) {
213                     return new TransitionInfo(in);
214                 }
215 
216                 @Override
217                 public TransitionInfo[] newArray(int size) {
218                     return new TransitionInfo[size];
219                 }
220             };
221 
222     @Override
223     /** @hide */
describeContents()224     public int describeContents() {
225         return 0;
226     }
227 
228     /** @see #getRootLeash() */
setRootLeash(@onNull SurfaceControl leash, int offsetLeft, int offsetTop)229     public void setRootLeash(@NonNull SurfaceControl leash, int offsetLeft, int offsetTop) {
230         mRootLeash = leash;
231         mRootOffset.set(offsetLeft, offsetTop);
232     }
233 
setAnimationOptions(AnimationOptions options)234     public void setAnimationOptions(AnimationOptions options) {
235         mOptions = options;
236     }
237 
getType()238     public @TransitionType int getType() {
239         return mType;
240     }
241 
getFlags()242     public int getFlags() {
243         return mFlags;
244     }
245 
246     /**
247      * @return a surfacecontrol that can serve as a parent surfacecontrol for all the changing
248      * participants to animate within. This will generally be placed at the highest-z-order
249      * shared ancestor of all participants. While this is non-null, it's possible for the rootleash
250      * to be invalid if the transition is a no-op.
251      */
252     @NonNull
getRootLeash()253     public SurfaceControl getRootLeash() {
254         if (mRootLeash == null) {
255             throw new IllegalStateException("Trying to get a leash which wasn't set");
256         }
257         return mRootLeash;
258     }
259 
260     /** @return the offset (relative to the screen) of the root leash. */
261     @NonNull
getRootOffset()262     public Point getRootOffset() {
263         return mRootOffset;
264     }
265 
getAnimationOptions()266     public AnimationOptions getAnimationOptions() {
267         return mOptions;
268     }
269 
270     /**
271      * @return the list of {@link Change}s in this transition. The list is sorted top-to-bottom
272      *         in Z (meaning index 0 is the top-most container).
273      */
274     @NonNull
getChanges()275     public List<Change> getChanges() {
276         return mChanges;
277     }
278 
279     /**
280      * @return the Change that a window is undergoing or {@code null} if not directly
281      * represented.
282      */
283     @Nullable
getChange(@onNull WindowContainerToken token)284     public Change getChange(@NonNull WindowContainerToken token) {
285         for (int i = mChanges.size() - 1; i >= 0; --i) {
286             if (token.equals(mChanges.get(i).mContainer)) {
287                 return mChanges.get(i);
288             }
289         }
290         return null;
291     }
292 
293     /**
294      * Add a {@link Change} to this transition.
295      */
addChange(@onNull Change change)296     public void addChange(@NonNull Change change) {
297         mChanges.add(change);
298     }
299 
300     /**
301      * Whether this transition includes keyguard going away.
302      */
isKeyguardGoingAway()303     public boolean isKeyguardGoingAway() {
304         return (mFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0;
305     }
306 
307     @Override
toString()308     public String toString() {
309         StringBuilder sb = new StringBuilder();
310         sb.append("{t=" + transitTypeToString(mType) + " f=0x" + Integer.toHexString(mFlags)
311                 + " ro=" + mRootOffset + " c=[");
312         for (int i = 0; i < mChanges.size(); ++i) {
313             if (i > 0) {
314                 sb.append(',');
315             }
316             sb.append(mChanges.get(i));
317         }
318         sb.append("]}");
319         return sb.toString();
320     }
321 
322     /** Converts a transition mode/action to its string representation. */
323     @NonNull
modeToString(@ransitionMode int mode)324     public static String modeToString(@TransitionMode int mode) {
325         switch(mode) {
326             case TRANSIT_NONE: return "NONE";
327             case TRANSIT_OPEN: return "OPEN";
328             case TRANSIT_CLOSE: return "CLOSE";
329             case TRANSIT_TO_FRONT: return "SHOW";
330             case TRANSIT_TO_BACK: return "HIDE";
331             case TRANSIT_CHANGE: return "CHANGE";
332             default: return "<unknown:" + mode + ">";
333         }
334     }
335 
336     /** Converts change flags into a string representation. */
337     @NonNull
flagsToString(@hangeFlags int flags)338     public static String flagsToString(@ChangeFlags int flags) {
339         if (flags == 0) return "NONE";
340         final StringBuilder sb = new StringBuilder();
341         if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
342             sb.append("SHOW_WALLPAPER");
343         }
344         if ((flags & FLAG_IS_WALLPAPER) != 0) {
345             sb.append("IS_WALLPAPER");
346         }
347         if ((flags & FLAG_IS_INPUT_METHOD) != 0) {
348             sb.append("IS_INPUT_METHOD");
349         }
350         if ((flags & FLAG_TRANSLUCENT) != 0) {
351             sb.append(sb.length() == 0 ? "" : "|").append("TRANSLUCENT");
352         }
353         if ((flags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0) {
354             sb.append(sb.length() == 0 ? "" : "|").append("STARTING_WINDOW_TRANSFER");
355         }
356         if ((flags & FLAG_IS_VOICE_INTERACTION) != 0) {
357             sb.append(sb.length() == 0 ? "" : "|").append("IS_VOICE_INTERACTION");
358         }
359         if ((flags & FLAG_IS_DISPLAY) != 0) {
360             sb.append(sb.length() == 0 ? "" : "|").append("IS_DISPLAY");
361         }
362         if ((flags & FLAG_OCCLUDES_KEYGUARD) != 0) {
363             sb.append(sb.length() == 0 ? "" : "|").append("OCCLUDES_KEYGUARD");
364         }
365         if ((flags & FLAG_DISPLAY_HAS_ALERT_WINDOWS) != 0) {
366             sb.append(sb.length() == 0 ? "" : "|").append("DISPLAY_HAS_ALERT_WINDOWS");
367         }
368         if ((flags & FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY) != 0) {
369             sb.append(sb.length() == 0 ? "" : "|").append("IN_TASK_WITH_EMBEDDED_ACTIVITY");
370         }
371         if ((flags & FLAG_FILLS_TASK) != 0) {
372             sb.append(sb.length() == 0 ? "" : "|").append("FILLS_TASK");
373         }
374         if ((flags & FLAG_IS_BEHIND_STARTING_WINDOW) != 0) {
375             sb.append(sb.length() == 0 ? "" : "|").append("IS_BEHIND_STARTING_WINDOW");
376         }
377         if ((flags & FLAG_IS_OCCLUDED) != 0) {
378             sb.append(sb.length() == 0 ? "" : "|").append("IS_OCCLUDED");
379         }
380         if ((flags & FLAG_IS_SYSTEM_WINDOW) != 0) {
381             sb.append(sb.length() == 0 ? "" : "|").append("FLAG_IS_SYSTEM_WINDOW");
382         }
383         if ((flags & FLAG_FIRST_CUSTOM) != 0) {
384             sb.append(sb.length() == 0 ? "" : "|").append("FIRST_CUSTOM");
385         }
386         return sb.toString();
387     }
388 
389     /**
390      * Indication that `change` is independent of parents (ie. it has a different type of
391      * transition vs. "going along for the ride")
392      */
isIndependent(@onNull TransitionInfo.Change change, @NonNull TransitionInfo info)393     public static boolean isIndependent(@NonNull TransitionInfo.Change change,
394             @NonNull TransitionInfo info) {
395         // If the change has no parent (it is root), then it is independent
396         if (change.getParent() == null) return true;
397 
398         // non-visibility changes will just be folded into the parent change, so they aren't
399         // independent either.
400         if (change.getMode() == TRANSIT_CHANGE) return false;
401 
402         TransitionInfo.Change parentChg = info.getChange(change.getParent());
403         while (parentChg != null) {
404             // If the parent is a visibility change, it will include the results of all child
405             // changes into itself, so none of its children can be independent.
406             if (parentChg.getMode() != TRANSIT_CHANGE) return false;
407 
408             // If there are no more parents left, then all the parents, so far, have not been
409             // visibility changes which means this change is independent.
410             if (parentChg.getParent() == null) return true;
411 
412             parentChg = info.getChange(parentChg.getParent());
413         }
414         return false;
415     }
416 
417     /**
418      * Releases temporary-for-animation surfaces referenced by this to potentially free up memory.
419      * This includes root-leash and snapshots.
420      */
releaseAnimSurfaces()421     public void releaseAnimSurfaces() {
422         for (int i = mChanges.size() - 1; i >= 0; --i) {
423             final Change c = mChanges.get(i);
424             if (c.mSnapshot != null) {
425                 c.mSnapshot.release();
426                 c.mSnapshot = null;
427             }
428         }
429         if (mRootLeash != null) {
430             mRootLeash.release();
431         }
432     }
433 
434     /**
435      * Releases ALL the surfaces referenced by this to potentially free up memory. Do NOT use this
436      * if the surface-controls get stored and used elsewhere in the process. To just release
437      * temporary-for-animation surfaces, use {@link #releaseAnimSurfaces}.
438      */
releaseAllSurfaces()439     public void releaseAllSurfaces() {
440         releaseAnimSurfaces();
441         for (int i = mChanges.size() - 1; i >= 0; --i) {
442             mChanges.get(i).getLeash().release();
443         }
444     }
445 
446     /**
447      * Makes a copy of this as if it were parcel'd and unparcel'd. This implies that surfacecontrol
448      * refcounts are incremented which allows the "remote" receiver to release them without breaking
449      * the caller's references. Use this only if you need to "send" this to a local function which
450      * assumes it is being called from a remote caller.
451      */
localRemoteCopy()452     public TransitionInfo localRemoteCopy() {
453         final TransitionInfo out = new TransitionInfo(mType, mFlags);
454         for (int i = 0; i < mChanges.size(); ++i) {
455             out.mChanges.add(mChanges.get(i).localRemoteCopy());
456         }
457         out.mRootLeash = mRootLeash != null ? new SurfaceControl(mRootLeash, "localRemote") : null;
458         // Doesn't have any native stuff, so no need for actual copy
459         out.mOptions = mOptions;
460         out.mRootOffset.set(mRootOffset);
461         return out;
462     }
463 
464     /** Represents the change a WindowContainer undergoes during a transition */
465     public static final class Change implements Parcelable {
466         private final WindowContainerToken mContainer;
467         private WindowContainerToken mParent;
468         private WindowContainerToken mLastParent;
469         private final SurfaceControl mLeash;
470         private @TransitionMode int mMode = TRANSIT_NONE;
471         private @ChangeFlags int mFlags = FLAG_NONE;
472         private final Rect mStartAbsBounds = new Rect();
473         private final Rect mEndAbsBounds = new Rect();
474         private final Point mEndRelOffset = new Point();
475         private ActivityManager.RunningTaskInfo mTaskInfo = null;
476         private boolean mAllowEnterPip;
477         private @Surface.Rotation int mStartRotation = ROTATION_UNDEFINED;
478         private @Surface.Rotation int mEndRotation = ROTATION_UNDEFINED;
479         /**
480          * The end rotation of the top activity after fixed rotation is finished. If the top
481          * activity is not in fixed rotation, it will be {@link ROTATION_UNDEFINED}.
482          */
483         private @Surface.Rotation int mEndFixedRotation = ROTATION_UNDEFINED;
484         private int mRotationAnimation = ROTATION_ANIMATION_UNSPECIFIED;
485         private @ColorInt int mBackgroundColor;
486         private SurfaceControl mSnapshot = null;
487         private float mSnapshotLuma;
488 
Change(@ullable WindowContainerToken container, @NonNull SurfaceControl leash)489         public Change(@Nullable WindowContainerToken container, @NonNull SurfaceControl leash) {
490             mContainer = container;
491             mLeash = leash;
492         }
493 
Change(Parcel in)494         private Change(Parcel in) {
495             mContainer = in.readTypedObject(WindowContainerToken.CREATOR);
496             mParent = in.readTypedObject(WindowContainerToken.CREATOR);
497             mLastParent = in.readTypedObject(WindowContainerToken.CREATOR);
498             mLeash = new SurfaceControl();
499             mLeash.readFromParcel(in);
500             mMode = in.readInt();
501             mFlags = in.readInt();
502             mStartAbsBounds.readFromParcel(in);
503             mEndAbsBounds.readFromParcel(in);
504             mEndRelOffset.readFromParcel(in);
505             mTaskInfo = in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
506             mAllowEnterPip = in.readBoolean();
507             mStartRotation = in.readInt();
508             mEndRotation = in.readInt();
509             mEndFixedRotation = in.readInt();
510             mRotationAnimation = in.readInt();
511             mBackgroundColor = in.readInt();
512             mSnapshot = in.readTypedObject(SurfaceControl.CREATOR);
513             mSnapshotLuma = in.readFloat();
514         }
515 
localRemoteCopy()516         private Change localRemoteCopy() {
517             final Change out = new Change(mContainer, new SurfaceControl(mLeash, "localRemote"));
518             out.mParent = mParent;
519             out.mLastParent = mLastParent;
520             out.mMode = mMode;
521             out.mFlags = mFlags;
522             out.mStartAbsBounds.set(mStartAbsBounds);
523             out.mEndAbsBounds.set(mEndAbsBounds);
524             out.mEndRelOffset.set(mEndRelOffset);
525             out.mTaskInfo = mTaskInfo;
526             out.mAllowEnterPip = mAllowEnterPip;
527             out.mStartRotation = mStartRotation;
528             out.mEndRotation = mEndRotation;
529             out.mEndFixedRotation = mEndFixedRotation;
530             out.mRotationAnimation = mRotationAnimation;
531             out.mBackgroundColor = mBackgroundColor;
532             out.mSnapshot = mSnapshot != null ? new SurfaceControl(mSnapshot, "localRemote") : null;
533             out.mSnapshotLuma = mSnapshotLuma;
534             return out;
535         }
536 
537         /** Sets the parent of this change's container. The parent must be a participant or null. */
setParent(@ullable WindowContainerToken parent)538         public void setParent(@Nullable WindowContainerToken parent) {
539             mParent = parent;
540         }
541 
542         /**
543          * Sets the parent of this change's container before the transition if this change's
544          * container is reparented in the transition.
545          */
setLastParent(@ullable WindowContainerToken lastParent)546         public void setLastParent(@Nullable WindowContainerToken lastParent) {
547             mLastParent = lastParent;
548         }
549 
550         /** Sets the transition mode for this change */
setMode(@ransitionMode int mode)551         public void setMode(@TransitionMode int mode) {
552             mMode = mode;
553         }
554 
555         /** Sets the flags for this change */
setFlags(@hangeFlags int flags)556         public void setFlags(@ChangeFlags int flags) {
557             mFlags = flags;
558         }
559 
560         /** Sets the bounds this container occupied before the change in screen space */
setStartAbsBounds(@ullable Rect rect)561         public void setStartAbsBounds(@Nullable Rect rect) {
562             mStartAbsBounds.set(rect);
563         }
564 
565         /** Sets the bounds this container will occupy after the change in screen space */
setEndAbsBounds(@ullable Rect rect)566         public void setEndAbsBounds(@Nullable Rect rect) {
567             mEndAbsBounds.set(rect);
568         }
569 
570         /** Sets the offset of this container from its parent surface */
setEndRelOffset(int left, int top)571         public void setEndRelOffset(int left, int top) {
572             mEndRelOffset.set(left, top);
573         }
574 
575         /**
576          * Sets the taskinfo of this container if this is a task. WARNING: this takes the
577          * reference, so don't modify it afterwards.
578          */
setTaskInfo(@ullable ActivityManager.RunningTaskInfo taskInfo)579         public void setTaskInfo(@Nullable ActivityManager.RunningTaskInfo taskInfo) {
580             mTaskInfo = taskInfo;
581         }
582 
583         /** Sets the allowEnterPip flag which represents AppOpsManager check on PiP permission */
setAllowEnterPip(boolean allowEnterPip)584         public void setAllowEnterPip(boolean allowEnterPip) {
585             mAllowEnterPip = allowEnterPip;
586         }
587 
588         /** Sets the start and end rotation of this container. */
setRotation(@urface.Rotation int start, @Surface.Rotation int end)589         public void setRotation(@Surface.Rotation int start, @Surface.Rotation int end) {
590             mStartRotation = start;
591             mEndRotation = end;
592         }
593 
594         /** Sets end rotation that top activity will be launched to after fixed rotation. */
setEndFixedRotation(@urface.Rotation int endFixedRotation)595         public void setEndFixedRotation(@Surface.Rotation int endFixedRotation) {
596             mEndFixedRotation = endFixedRotation;
597         }
598 
599         /**
600          * Sets the app-requested animation type for rotation. Will be one of the
601          * ROTATION_ANIMATION_ values in {@link android.view.WindowManager.LayoutParams};
602          */
setRotationAnimation(int anim)603         public void setRotationAnimation(int anim) {
604             mRotationAnimation = anim;
605         }
606 
607         /** Sets the background color of this change's container. */
setBackgroundColor(@olorInt int backgroundColor)608         public void setBackgroundColor(@ColorInt int backgroundColor) {
609             mBackgroundColor = backgroundColor;
610         }
611 
612         /** Sets a snapshot surface for the "start" state of the container. */
setSnapshot(@ullable SurfaceControl snapshot, float luma)613         public void setSnapshot(@Nullable SurfaceControl snapshot, float luma) {
614             mSnapshot = snapshot;
615             mSnapshotLuma = luma;
616         }
617 
618         /** @return the container that is changing. May be null if non-remotable (eg. activity) */
619         @Nullable
getContainer()620         public WindowContainerToken getContainer() {
621             return mContainer;
622         }
623 
624         /**
625          * @return the parent of the changing container. This is the parent within the participants,
626          * not necessarily the actual parent.
627          */
628         @Nullable
getParent()629         public WindowContainerToken getParent() {
630             return mParent;
631         }
632 
633         /**
634          * @return the parent of the changing container before the transition if it is reparented
635          * in the transition. The parent window may not be collected in the transition as a
636          * participant, and it may have been detached from the display. {@code null} if the changing
637          * container has not been reparented in the transition, or if the parent is not organizable.
638          */
639         @Nullable
getLastParent()640         public WindowContainerToken getLastParent() {
641             return mLastParent;
642         }
643 
644         /** @return which action this change represents. */
getMode()645         public @TransitionMode int getMode() {
646             return mMode;
647         }
648 
649         /** @return the flags for this change. */
getFlags()650         public @ChangeFlags int getFlags() {
651             return mFlags;
652         }
653 
654         /** Whether this change contains any of the given change flags. */
hasFlags(@hangeFlags int flags)655         public boolean hasFlags(@ChangeFlags int flags) {
656             return (mFlags & flags) != 0;
657         }
658 
659         /** Whether this change contains all of the given change flags. */
hasAllFlags(@hangeFlags int flags)660         public boolean hasAllFlags(@ChangeFlags int flags) {
661             return (mFlags & flags) == flags;
662         }
663 
664         /**
665          * @return the bounds of the container before the change. It may be empty if the container
666          * is coming into existence.
667          */
668         @NonNull
getStartAbsBounds()669         public Rect getStartAbsBounds() {
670             return mStartAbsBounds;
671         }
672 
673         /**
674          * @return the bounds of the container after the change. It may be empty if the container
675          * is disappearing.
676          */
677         @NonNull
getEndAbsBounds()678         public Rect getEndAbsBounds() {
679             return mEndAbsBounds;
680         }
681 
682         /**
683          * @return the offset of the container's surface from its parent surface after the change.
684          */
685         @NonNull
getEndRelOffset()686         public Point getEndRelOffset() {
687             return mEndRelOffset;
688         }
689 
690         /** @return the leash or surface to animate for this container */
691         @NonNull
getLeash()692         public SurfaceControl getLeash() {
693             return mLeash;
694         }
695 
696         /** @return the task info or null if this isn't a task */
697         @Nullable
getTaskInfo()698         public ActivityManager.RunningTaskInfo getTaskInfo() {
699             return mTaskInfo;
700         }
701 
getAllowEnterPip()702         public boolean getAllowEnterPip() {
703             return mAllowEnterPip;
704         }
705 
706         @Surface.Rotation
getStartRotation()707         public int getStartRotation() {
708             return mStartRotation;
709         }
710 
711         @Surface.Rotation
getEndRotation()712         public int getEndRotation() {
713             return mEndRotation;
714         }
715 
716         @Surface.Rotation
getEndFixedRotation()717         public int getEndFixedRotation() {
718             return mEndFixedRotation;
719         }
720 
721         /** @return the rotation animation. */
getRotationAnimation()722         public int getRotationAnimation() {
723             return mRotationAnimation;
724         }
725 
726         /** @return get the background color of this change's container. */
727         @ColorInt
getBackgroundColor()728         public int getBackgroundColor() {
729             return mBackgroundColor;
730         }
731 
732         /** @return a snapshot surface (if applicable). */
733         @Nullable
getSnapshot()734         public SurfaceControl getSnapshot() {
735             return mSnapshot;
736         }
737 
738         /** @return the luma calculated for the snapshot surface (if applicable). */
getSnapshotLuma()739         public float getSnapshotLuma() {
740             return mSnapshotLuma;
741         }
742 
743         /** @hide */
744         @Override
writeToParcel(@onNull Parcel dest, int flags)745         public void writeToParcel(@NonNull Parcel dest, int flags) {
746             dest.writeTypedObject(mContainer, flags);
747             dest.writeTypedObject(mParent, flags);
748             dest.writeTypedObject(mLastParent, flags);
749             mLeash.writeToParcel(dest, flags);
750             dest.writeInt(mMode);
751             dest.writeInt(mFlags);
752             mStartAbsBounds.writeToParcel(dest, flags);
753             mEndAbsBounds.writeToParcel(dest, flags);
754             mEndRelOffset.writeToParcel(dest, flags);
755             dest.writeTypedObject(mTaskInfo, flags);
756             dest.writeBoolean(mAllowEnterPip);
757             dest.writeInt(mStartRotation);
758             dest.writeInt(mEndRotation);
759             dest.writeInt(mEndFixedRotation);
760             dest.writeInt(mRotationAnimation);
761             dest.writeInt(mBackgroundColor);
762             dest.writeTypedObject(mSnapshot, flags);
763             dest.writeFloat(mSnapshotLuma);
764         }
765 
766         @NonNull
767         public static final Creator<Change> CREATOR =
768                 new Creator<Change>() {
769                     @Override
770                     public Change createFromParcel(Parcel in) {
771                         return new Change(in);
772                     }
773 
774                     @Override
775                     public Change[] newArray(int size) {
776                         return new Change[size];
777                     }
778                 };
779 
780         /** @hide */
781         @Override
describeContents()782         public int describeContents() {
783             return 0;
784         }
785 
786         @Override
toString()787         public String toString() {
788             final StringBuilder sb = new StringBuilder();
789             sb.append('{'); sb.append(mContainer);
790             sb.append(" m="); sb.append(modeToString(mMode));
791             sb.append(" f="); sb.append(flagsToString(mFlags));
792             if (mParent != null) {
793                 sb.append(" p="); sb.append(mParent);
794             }
795             if (mLeash != null) {
796                 sb.append(" leash="); sb.append(mLeash);
797             }
798             sb.append(" sb="); sb.append(mStartAbsBounds);
799             sb.append(" eb="); sb.append(mEndAbsBounds);
800             if (mEndRelOffset.x != 0 || mEndRelOffset.y != 0) {
801                 sb.append(" eo="); sb.append(mEndRelOffset);
802             }
803             if (mStartRotation != mEndRotation) {
804                 sb.append(" r="); sb.append(mStartRotation);
805                 sb.append("->"); sb.append(mEndRotation);
806                 sb.append(':'); sb.append(mRotationAnimation);
807             }
808             if (mEndFixedRotation != ROTATION_UNDEFINED) {
809                 sb.append(" endFixedRotation="); sb.append(mEndFixedRotation);
810             }
811             if (mSnapshot != null) {
812                 sb.append(" snapshot="); sb.append(mSnapshot);
813             }
814             if (mLastParent != null) {
815                 sb.append(" lastParent="); sb.append(mLastParent);
816             }
817             sb.append('}');
818             return sb.toString();
819         }
820     }
821 
822     /** Represents animation options during a transition */
823     public static final class AnimationOptions implements Parcelable {
824 
825         private int mType;
826         private int mEnterResId;
827         private int mExitResId;
828         private boolean mOverrideTaskTransition;
829         private String mPackageName;
830         private final Rect mTransitionBounds = new Rect();
831         private HardwareBuffer mThumbnail;
832         private int mAnimations;
833         private @ColorInt int mBackgroundColor;
834 
AnimationOptions(int type)835         private AnimationOptions(int type) {
836             mType = type;
837         }
838 
AnimationOptions(Parcel in)839         public AnimationOptions(Parcel in) {
840             mType = in.readInt();
841             mEnterResId = in.readInt();
842             mExitResId = in.readInt();
843             mBackgroundColor = in.readInt();
844             mOverrideTaskTransition = in.readBoolean();
845             mPackageName = in.readString();
846             mTransitionBounds.readFromParcel(in);
847             mThumbnail = in.readTypedObject(HardwareBuffer.CREATOR);
848             mAnimations = in.readInt();
849         }
850 
makeAnimOptionsFromLayoutParameters( WindowManager.LayoutParams lp)851         public static AnimationOptions makeAnimOptionsFromLayoutParameters(
852                 WindowManager.LayoutParams lp) {
853             AnimationOptions options = new AnimationOptions(ANIM_FROM_STYLE);
854             options.mPackageName = lp.packageName;
855             options.mAnimations = lp.windowAnimations;
856             return options;
857         }
858 
makeCustomAnimOptions(String packageName, int enterResId, int exitResId, @ColorInt int backgroundColor, boolean overrideTaskTransition)859         public static AnimationOptions makeCustomAnimOptions(String packageName, int enterResId,
860                 int exitResId, @ColorInt int backgroundColor, boolean overrideTaskTransition) {
861             AnimationOptions options = new AnimationOptions(ANIM_CUSTOM);
862             options.mPackageName = packageName;
863             options.mEnterResId = enterResId;
864             options.mExitResId = exitResId;
865             options.mBackgroundColor = backgroundColor;
866             options.mOverrideTaskTransition = overrideTaskTransition;
867             return options;
868         }
869 
makeClipRevealAnimOptions(int startX, int startY, int width, int height)870         public static AnimationOptions makeClipRevealAnimOptions(int startX, int startY, int width,
871                 int height) {
872             AnimationOptions options = new AnimationOptions(ANIM_CLIP_REVEAL);
873             options.mTransitionBounds.set(startX, startY, startX + width, startY + height);
874             return options;
875         }
876 
makeScaleUpAnimOptions(int startX, int startY, int width, int height)877         public static AnimationOptions makeScaleUpAnimOptions(int startX, int startY, int width,
878                 int height) {
879             AnimationOptions options = new AnimationOptions(ANIM_SCALE_UP);
880             options.mTransitionBounds.set(startX, startY, startX + width, startY + height);
881             return options;
882         }
883 
makeThumbnailAnimOptions(HardwareBuffer srcThumb, int startX, int startY, boolean scaleUp)884         public static AnimationOptions makeThumbnailAnimOptions(HardwareBuffer srcThumb,
885                 int startX, int startY, boolean scaleUp) {
886             AnimationOptions options = new AnimationOptions(
887                     scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN);
888             options.mTransitionBounds.set(startX, startY, startX, startY);
889             options.mThumbnail = srcThumb;
890             return options;
891         }
892 
makeCrossProfileAnimOptions()893         public static AnimationOptions makeCrossProfileAnimOptions() {
894             AnimationOptions options = new AnimationOptions(ANIM_OPEN_CROSS_PROFILE_APPS);
895             return options;
896         }
897 
getType()898         public int getType() {
899             return mType;
900         }
901 
getEnterResId()902         public int getEnterResId() {
903             return mEnterResId;
904         }
905 
getExitResId()906         public int getExitResId() {
907             return mExitResId;
908         }
909 
getBackgroundColor()910         public @ColorInt int getBackgroundColor() {
911             return mBackgroundColor;
912         }
913 
getOverrideTaskTransition()914         public boolean getOverrideTaskTransition() {
915             return mOverrideTaskTransition;
916         }
917 
getPackageName()918         public String getPackageName() {
919             return mPackageName;
920         }
921 
getTransitionBounds()922         public Rect getTransitionBounds() {
923             return mTransitionBounds;
924         }
925 
getThumbnail()926         public HardwareBuffer getThumbnail() {
927             return mThumbnail;
928         }
929 
getAnimations()930         public int getAnimations() {
931             return mAnimations;
932         }
933 
934         @Override
writeToParcel(Parcel dest, int flags)935         public void writeToParcel(Parcel dest, int flags) {
936             dest.writeInt(mType);
937             dest.writeInt(mEnterResId);
938             dest.writeInt(mExitResId);
939             dest.writeInt(mBackgroundColor);
940             dest.writeBoolean(mOverrideTaskTransition);
941             dest.writeString(mPackageName);
942             mTransitionBounds.writeToParcel(dest, flags);
943             dest.writeTypedObject(mThumbnail, flags);
944             dest.writeInt(mAnimations);
945         }
946 
947         @NonNull
948         public static final Creator<AnimationOptions> CREATOR =
949                 new Creator<AnimationOptions>() {
950                     @Override
951                     public AnimationOptions createFromParcel(Parcel in) {
952                         return new AnimationOptions(in);
953                     }
954 
955                     @Override
956                     public AnimationOptions[] newArray(int size) {
957                         return new AnimationOptions[size];
958                     }
959                 };
960 
961         /** @hide */
962         @Override
describeContents()963         public int describeContents() {
964             return 0;
965         }
966 
967         @NonNull
typeToString(int mode)968         private static String typeToString(int mode) {
969             switch(mode) {
970                 case ANIM_CUSTOM: return "ANIM_CUSTOM";
971                 case ANIM_CLIP_REVEAL: return "ANIM_CLIP_REVEAL";
972                 case ANIM_SCALE_UP: return "ANIM_SCALE_UP";
973                 case ANIM_THUMBNAIL_SCALE_UP: return "ANIM_THUMBNAIL_SCALE_UP";
974                 case ANIM_THUMBNAIL_SCALE_DOWN: return "ANIM_THUMBNAIL_SCALE_DOWN";
975                 case ANIM_OPEN_CROSS_PROFILE_APPS: return "ANIM_OPEN_CROSS_PROFILE_APPS";
976                 default: return "<unknown:" + mode + ">";
977             }
978         }
979 
980         @Override
toString()981         public String toString() {
982             return "{ AnimationOptions type= " + typeToString(mType) + " package=" + mPackageName
983                     + " override=" + mOverrideTaskTransition + " b=" + mTransitionBounds + "}";
984         }
985     }
986 }
987