• 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.view;
18 
19 import static android.graphics.GraphicsProtos.dumpPointProto;
20 import static android.view.RemoteAnimationTargetProto.CLIP_RECT;
21 import static android.view.RemoteAnimationTargetProto.CONTENT_INSETS;
22 import static android.view.RemoteAnimationTargetProto.IS_TRANSLUCENT;
23 import static android.view.RemoteAnimationTargetProto.LEASH;
24 import static android.view.RemoteAnimationTargetProto.LOCAL_BOUNDS;
25 import static android.view.RemoteAnimationTargetProto.MODE;
26 import static android.view.RemoteAnimationTargetProto.POSITION;
27 import static android.view.RemoteAnimationTargetProto.PREFIX_ORDER_INDEX;
28 import static android.view.RemoteAnimationTargetProto.SCREEN_SPACE_BOUNDS;
29 import static android.view.RemoteAnimationTargetProto.SOURCE_CONTAINER_BOUNDS;
30 import static android.view.RemoteAnimationTargetProto.START_BOUNDS;
31 import static android.view.RemoteAnimationTargetProto.START_LEASH;
32 import static android.view.RemoteAnimationTargetProto.TASK_ID;
33 import static android.view.RemoteAnimationTargetProto.WINDOW_CONFIGURATION;
34 import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
35 
36 import android.annotation.ColorInt;
37 import android.annotation.IntDef;
38 import android.annotation.Nullable;
39 import android.app.ActivityManager;
40 import android.app.TaskInfo;
41 import android.app.WindowConfiguration;
42 import android.compat.annotation.UnsupportedAppUsage;
43 import android.graphics.Point;
44 import android.graphics.Rect;
45 import android.os.Build;
46 import android.os.Parcel;
47 import android.os.Parcelable;
48 import android.util.proto.ProtoOutputStream;
49 import android.window.TaskSnapshot;
50 
51 import java.io.PrintWriter;
52 import java.lang.annotation.Retention;
53 import java.lang.annotation.RetentionPolicy;
54 
55 /**
56  * Describes an activity to be animated as part of a remote animation.
57  *
58  * @hide
59  */
60 public class RemoteAnimationTarget implements Parcelable {
61 
62     /**
63      * The app is in the set of opening apps of this transition.
64      */
65     public static final int MODE_OPENING = 0;
66 
67     /**
68      * The app is in the set of closing apps of this transition.
69      */
70     public static final int MODE_CLOSING = 1;
71 
72     /**
73      * The app is in the set of resizing apps (eg. mode change) of this transition.
74      */
75     public static final int MODE_CHANGING = 2;
76 
77     @IntDef(prefix = { "MODE_" }, value = {
78             MODE_OPENING,
79             MODE_CLOSING,
80             MODE_CHANGING
81     })
82     @Retention(RetentionPolicy.SOURCE)
83     public @interface Mode {}
84 
85     /**
86      * The {@link Mode} to describe whether this app is opening or closing.
87      */
88     @UnsupportedAppUsage
89     public final @Mode int mode;
90 
91     /**
92      * The id of the task this app belongs to.
93      */
94     @UnsupportedAppUsage
95     public final int taskId;
96 
97     /**
98      * The {@link SurfaceControl} object to actually control the transform of the app.
99      */
100     @UnsupportedAppUsage
101     public final SurfaceControl leash;
102 
103     /**
104      * The {@link SurfaceControl} for the starting state of a target if this transition is
105      * MODE_CHANGING, {@code null)} otherwise. This is relative to the app window.
106      */
107     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
108     public final SurfaceControl startLeash;
109 
110     /**
111      * Whether the app is translucent and may reveal apps behind.
112      */
113     @UnsupportedAppUsage
114     public final boolean isTranslucent;
115 
116     /**
117      * The clip rect window manager applies when clipping the app's main surface in screen space
118      * coordinates. This is just a hint to the animation runner: If running a clip-rect animation,
119      * anything that extends beyond these bounds will not have any effect. This implies that any
120      * clip-rect animation should likely stop at these bounds.
121      */
122     @UnsupportedAppUsage
123     public final Rect clipRect;
124 
125     /**
126      * The insets of the main app window.
127      */
128     @UnsupportedAppUsage
129     public final Rect contentInsets;
130 
131     /**
132      * The index of the element in the tree in prefix order. This should be used for z-layering
133      * to preserve original z-layer order in the hierarchy tree assuming no "boosting" needs to
134      * happen.
135      * @deprecated WindowManager may set a z-order different from the prefix order, and has set the
136      *             correct layer for the animation leash already, so this should not be used for
137      *             layer any more.
138      */
139     @Deprecated
140     @UnsupportedAppUsage
141     public final int prefixOrderIndex;
142 
143     /**
144      * The source position of the app, in screen spaces coordinates. If the position of the leash
145      * is modified from the controlling app, any animation transform needs to be offset by this
146      * amount.
147      * @deprecated Use {@link #localBounds} instead.
148      */
149     @Deprecated
150     @UnsupportedAppUsage
151     public final Point position;
152 
153     /**
154      * Bounds of the target relative to its parent.
155      * When the app target animating on its parent, we need to use the local coordinates relative to
156      * its parent with {@code localBounds.left} & {@code localBounds.top} rather than using
157      * {@code position} in screen coordinates.
158      */
159     public final Rect localBounds;
160 
161     /**
162      * The bounds of the source container the app lives in, in screen space coordinates. If the crop
163      * of the leash is modified from the controlling app, it needs to take the source container
164      * bounds into account when calculating the crop.
165      * @deprecated Renamed to {@link #screenSpaceBounds}
166      */
167     @Deprecated
168     @UnsupportedAppUsage
169     public final Rect sourceContainerBounds;
170 
171     /**
172      * Bounds of the target relative to the screen. If the crop of the leash is modified from the
173      * controlling app, it needs to take the screen space bounds into account when calculating the
174      * crop.
175      */
176     public final Rect screenSpaceBounds;
177 
178     /**
179      * The starting bounds of the source container in screen space coordinates.
180      * For {@link #MODE_OPENING}, this will be equivalent to {@link #screenSpaceBounds}.
181      * For {@link #MODE_CLOSING}, this will be equivalent to {@link #screenSpaceBounds} unless the
182      * closing container is also resizing. For example, when ActivityEmbedding split pair becomes
183      * stacked, the container on the back will be resized to fullscreen, but will also be covered
184      * (closing) by the container in the front.
185      * For {@link #MODE_CHANGING}, since this is the starting bounds, its size should be equivalent
186      * to the bounds of the starting thumbnail.
187      *
188      * Note that {@link #screenSpaceBounds} is the end bounds of a transition.
189      */
190     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
191     public final Rect startBounds;
192 
193     /**
194      * The window configuration for the target.
195      */
196     @UnsupportedAppUsage
197     public final WindowConfiguration windowConfiguration;
198 
199     /**
200      * Whether the task is not presented in Recents UI.
201      */
202     @UnsupportedAppUsage
203     public boolean isNotInRecents;
204 
205     /**
206      * {@link TaskInfo} to allow the controller to identify information about the task.
207      *
208      * TODO: add this to proto dump
209      */
210     public ActivityManager.RunningTaskInfo taskInfo;
211 
212     /**
213      * {@code true} if picture-in-picture permission is granted in {@link android.app.AppOpsManager}
214      */
215     @UnsupportedAppUsage
216     public boolean allowEnterPip;
217 
218     /**
219      * The {@link android.view.WindowManager.LayoutParams.WindowType} of this window. It's only used
220      * for non-app window.
221      */
222     public final @WindowManager.LayoutParams.WindowType int windowType;
223 
224     /**
225      * {@code true} if its parent is also a {@link RemoteAnimationTarget} in the same transition.
226      *
227      * For example, when a TaskFragment is resizing while one of its children is open/close, both
228      * windows will be animation targets. This value will be {@code true} for the child, so that
229      * the handler can choose to handle it differently.
230      */
231     public boolean hasAnimatingParent;
232 
233     /**
234      * Whether an activity has enabled {@link android.R.styleable#Animation_showBackdrop} for
235      * transition.
236      */
237     public boolean showBackdrop;
238 
239     /**
240      * The background color of animation in case the task info is not available if the transition
241      * is activity level.
242      */
243     public @ColorInt int backgroundColor;
244 
245     /**
246      * Whether the activity is going to show IME on the target window after the app transition.
247      * @see TaskSnapshot#hasImeSurface() that used the task snapshot during animating task.
248      */
249     public boolean willShowImeOnTarget;
250 
251     public int rotationChange;
252 
RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent, Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position, Rect localBounds, Rect screenSpaceBounds, WindowConfiguration windowConfig, boolean isNotInRecents, SurfaceControl startLeash, @Nullable Rect startBounds, ActivityManager.RunningTaskInfo taskInfo, boolean allowEnterPip)253     public RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent,
254             Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
255             Rect localBounds, Rect screenSpaceBounds,
256             WindowConfiguration windowConfig, boolean isNotInRecents,
257             SurfaceControl startLeash, @Nullable Rect startBounds,
258             ActivityManager.RunningTaskInfo taskInfo,
259             boolean allowEnterPip) {
260         this(taskId, mode, leash, isTranslucent, clipRect, contentInsets, prefixOrderIndex,
261                 position, localBounds, screenSpaceBounds, windowConfig, isNotInRecents, startLeash,
262                 startBounds, taskInfo, allowEnterPip, INVALID_WINDOW_TYPE);
263     }
264 
RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent, Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position, Rect localBounds, Rect screenSpaceBounds, WindowConfiguration windowConfig, boolean isNotInRecents, SurfaceControl startLeash, @Nullable Rect startBounds, ActivityManager.RunningTaskInfo taskInfo, boolean allowEnterPip, @WindowManager.LayoutParams.WindowType int windowType)265     public RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent,
266             Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
267             Rect localBounds, Rect screenSpaceBounds,
268             WindowConfiguration windowConfig, boolean isNotInRecents,
269             SurfaceControl startLeash, @Nullable Rect startBounds,
270             ActivityManager.RunningTaskInfo taskInfo, boolean allowEnterPip,
271             @WindowManager.LayoutParams.WindowType int windowType) {
272         this.mode = mode;
273         this.taskId = taskId;
274         this.leash = leash;
275         this.isTranslucent = isTranslucent;
276         this.clipRect = new Rect(clipRect);
277         this.contentInsets = new Rect(contentInsets);
278         this.prefixOrderIndex = prefixOrderIndex;
279         this.position = position == null ? new Point() : new Point(position);
280         this.localBounds = new Rect(localBounds);
281         this.sourceContainerBounds = new Rect(screenSpaceBounds);
282         this.screenSpaceBounds = new Rect(screenSpaceBounds);
283         this.windowConfiguration = windowConfig;
284         this.isNotInRecents = isNotInRecents;
285         this.startLeash = startLeash;
286         this.taskInfo = taskInfo;
287         this.allowEnterPip = allowEnterPip;
288         this.windowType = windowType;
289         // Same as screenSpaceBounds if the window is not resizing.
290         this.startBounds = startBounds == null
291                 ? new Rect(screenSpaceBounds)
292                 : new Rect(startBounds);
293     }
294 
RemoteAnimationTarget(Parcel in)295     public RemoteAnimationTarget(Parcel in) {
296         taskId = in.readInt();
297         mode = in.readInt();
298         leash = in.readTypedObject(SurfaceControl.CREATOR);
299         isTranslucent = in.readBoolean();
300         clipRect = in.readTypedObject(Rect.CREATOR);
301         contentInsets = in.readTypedObject(Rect.CREATOR);
302         prefixOrderIndex = in.readInt();
303         position = in.readTypedObject(Point.CREATOR);
304         localBounds = in.readTypedObject(Rect.CREATOR);
305         sourceContainerBounds = in.readTypedObject(Rect.CREATOR);
306         screenSpaceBounds = in.readTypedObject(Rect.CREATOR);
307         windowConfiguration = in.readTypedObject(WindowConfiguration.CREATOR);
308         isNotInRecents = in.readBoolean();
309         startLeash = in.readTypedObject(SurfaceControl.CREATOR);
310         startBounds = in.readTypedObject(Rect.CREATOR);
311         taskInfo = in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
312         allowEnterPip = in.readBoolean();
313         windowType = in.readInt();
314         hasAnimatingParent = in.readBoolean();
315         backgroundColor = in.readInt();
316         showBackdrop = in.readBoolean();
317         willShowImeOnTarget = in.readBoolean();
318         rotationChange = in.readInt();
319     }
320 
setShowBackdrop(boolean shouldShowBackdrop)321     public void setShowBackdrop(boolean shouldShowBackdrop) {
322         showBackdrop = shouldShowBackdrop;
323     }
324 
setWillShowImeOnTarget(boolean showImeOnTarget)325     public void setWillShowImeOnTarget(boolean showImeOnTarget) {
326         willShowImeOnTarget = showImeOnTarget;
327     }
328 
willShowImeOnTarget()329     public boolean willShowImeOnTarget() {
330         return willShowImeOnTarget;
331     }
332 
setRotationChange(int rotationChange)333     public void setRotationChange(int rotationChange) {
334         this.rotationChange = rotationChange;
335     }
336 
getRotationChange()337     public int getRotationChange() {
338         return rotationChange;
339     }
340 
341     @Override
describeContents()342     public int describeContents() {
343         return 0;
344     }
345 
346     @Override
writeToParcel(Parcel dest, int flags)347     public void writeToParcel(Parcel dest, int flags) {
348         dest.writeInt(taskId);
349         dest.writeInt(mode);
350         dest.writeTypedObject(leash, 0 /* flags */);
351         dest.writeBoolean(isTranslucent);
352         dest.writeTypedObject(clipRect, 0 /* flags */);
353         dest.writeTypedObject(contentInsets, 0 /* flags */);
354         dest.writeInt(prefixOrderIndex);
355         dest.writeTypedObject(position, 0 /* flags */);
356         dest.writeTypedObject(localBounds, 0 /* flags */);
357         dest.writeTypedObject(sourceContainerBounds, 0 /* flags */);
358         dest.writeTypedObject(screenSpaceBounds, 0 /* flags */);
359         dest.writeTypedObject(windowConfiguration, 0 /* flags */);
360         dest.writeBoolean(isNotInRecents);
361         dest.writeTypedObject(startLeash, 0 /* flags */);
362         dest.writeTypedObject(startBounds, 0 /* flags */);
363         dest.writeTypedObject(taskInfo, 0 /* flags */);
364         dest.writeBoolean(allowEnterPip);
365         dest.writeInt(windowType);
366         dest.writeBoolean(hasAnimatingParent);
367         dest.writeInt(backgroundColor);
368         dest.writeBoolean(showBackdrop);
369         dest.writeBoolean(willShowImeOnTarget);
370         dest.writeInt(rotationChange);
371     }
372 
dump(PrintWriter pw, String prefix)373     public void dump(PrintWriter pw, String prefix) {
374         pw.print(prefix); pw.print("mode="); pw.print(mode);
375         pw.print(" taskId="); pw.print(taskId);
376         pw.print(" isTranslucent="); pw.print(isTranslucent);
377         pw.print(" clipRect="); clipRect.printShortString(pw);
378         pw.print(" contentInsets="); contentInsets.printShortString(pw);
379         pw.print(" prefixOrderIndex="); pw.print(prefixOrderIndex);
380         pw.print(" position="); printPoint(position, pw);
381         pw.print(" sourceContainerBounds="); sourceContainerBounds.printShortString(pw);
382         pw.print(" screenSpaceBounds="); screenSpaceBounds.printShortString(pw);
383         pw.print(" localBounds="); localBounds.printShortString(pw);
384         pw.println();
385         pw.print(prefix); pw.print("windowConfiguration="); pw.println(windowConfiguration);
386         pw.print(prefix); pw.print("leash="); pw.println(leash);
387         pw.print(prefix); pw.print("taskInfo="); pw.println(taskInfo);
388         pw.print(prefix); pw.print("allowEnterPip="); pw.println(allowEnterPip);
389         pw.print(prefix); pw.print("windowType="); pw.print(windowType);
390         pw.print(prefix); pw.print("hasAnimatingParent="); pw.print(hasAnimatingParent);
391         pw.print(prefix); pw.print("backgroundColor="); pw.print(backgroundColor);
392         pw.print(prefix); pw.print("showBackdrop="); pw.print(showBackdrop);
393         pw.print(prefix); pw.print("willShowImeOnTarget="); pw.print(willShowImeOnTarget);
394     }
395 
dumpDebug(ProtoOutputStream proto, long fieldId)396     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
397         final long token = proto.start(fieldId);
398         proto.write(TASK_ID, taskId);
399         proto.write(MODE, mode);
400         leash.dumpDebug(proto, LEASH);
401         proto.write(IS_TRANSLUCENT, isTranslucent);
402         clipRect.dumpDebug(proto, CLIP_RECT);
403         contentInsets.dumpDebug(proto, CONTENT_INSETS);
404         proto.write(PREFIX_ORDER_INDEX, prefixOrderIndex);
405         dumpPointProto(position, proto, POSITION);
406         sourceContainerBounds.dumpDebug(proto, SOURCE_CONTAINER_BOUNDS);
407         screenSpaceBounds.dumpDebug(proto, SCREEN_SPACE_BOUNDS);
408         localBounds.dumpDebug(proto, LOCAL_BOUNDS);
409         windowConfiguration.dumpDebug(proto, WINDOW_CONFIGURATION);
410         if (startLeash != null) {
411             startLeash.dumpDebug(proto, START_LEASH);
412         }
413         startBounds.dumpDebug(proto, START_BOUNDS);
414         proto.end(token);
415     }
416 
printPoint(Point p, PrintWriter pw)417     private static void printPoint(Point p, PrintWriter pw) {
418         pw.print("["); pw.print(p.x); pw.print(","); pw.print(p.y); pw.print("]");
419     }
420 
421     public static final @android.annotation.NonNull Creator<RemoteAnimationTarget> CREATOR
422             = new Creator<RemoteAnimationTarget>() {
423         public RemoteAnimationTarget createFromParcel(Parcel in) {
424             return new RemoteAnimationTarget(in);
425         }
426 
427         public RemoteAnimationTarget[] newArray(int size) {
428             return new RemoteAnimationTarget[size];
429         }
430     };
431 }
432