• 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.IntDef;
37 import android.app.ActivityManager;
38 import android.app.TaskInfo;
39 import android.app.WindowConfiguration;
40 import android.compat.annotation.UnsupportedAppUsage;
41 import android.graphics.Point;
42 import android.graphics.Rect;
43 import android.os.Build;
44 import android.os.Parcel;
45 import android.os.Parcelable;
46 import android.util.proto.ProtoOutputStream;
47 
48 import java.io.PrintWriter;
49 import java.lang.annotation.Retention;
50 import java.lang.annotation.RetentionPolicy;
51 
52 /**
53  * Describes an activity to be animated as part of a remote animation.
54  *
55  * @hide
56  */
57 public class RemoteAnimationTarget implements Parcelable {
58 
59     /**
60      * The app is in the set of opening apps of this transition.
61      */
62     public static final int MODE_OPENING = 0;
63 
64     /**
65      * The app is in the set of closing apps of this transition.
66      */
67     public static final int MODE_CLOSING = 1;
68 
69     /**
70      * The app is in the set of resizing apps (eg. mode change) of this transition.
71      */
72     public static final int MODE_CHANGING = 2;
73 
74     @IntDef(prefix = { "MODE_" }, value = {
75             MODE_OPENING,
76             MODE_CLOSING,
77             MODE_CHANGING
78     })
79     @Retention(RetentionPolicy.SOURCE)
80     public @interface Mode {}
81 
82     /**
83      * The {@link Mode} to describe whether this app is opening or closing.
84      */
85     @UnsupportedAppUsage
86     public final @Mode int mode;
87 
88     /**
89      * The id of the task this app belongs to.
90      */
91     @UnsupportedAppUsage
92     public final int taskId;
93 
94     /**
95      * The {@link SurfaceControl} object to actually control the transform of the app.
96      */
97     @UnsupportedAppUsage
98     public final SurfaceControl leash;
99 
100     /**
101      * The {@link SurfaceControl} for the starting state of a target if this transition is
102      * MODE_CHANGING, {@code null)} otherwise. This is relative to the app window.
103      */
104     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
105     public final SurfaceControl startLeash;
106 
107     /**
108      * Whether the app is translucent and may reveal apps behind.
109      */
110     @UnsupportedAppUsage
111     public final boolean isTranslucent;
112 
113     /**
114      * The clip rect window manager applies when clipping the app's main surface in screen space
115      * coordinates. This is just a hint to the animation runner: If running a clip-rect animation,
116      * anything that extends beyond these bounds will not have any effect. This implies that any
117      * clip-rect animation should likely stop at these bounds.
118      */
119     @UnsupportedAppUsage
120     public final Rect clipRect;
121 
122     /**
123      * The insets of the main app window.
124      */
125     @UnsupportedAppUsage
126     public final Rect contentInsets;
127 
128     /**
129      * The index of the element in the tree in prefix order. This should be used for z-layering
130      * to preserve original z-layer order in the hierarchy tree assuming no "boosting" needs to
131      * happen.
132      */
133     @UnsupportedAppUsage
134     public final int prefixOrderIndex;
135 
136     /**
137      * The source position of the app, in screen spaces coordinates. If the position of the leash
138      * is modified from the controlling app, any animation transform needs to be offset by this
139      * amount.
140      * @deprecated Use {@link #localBounds} instead.
141      */
142     @Deprecated
143     @UnsupportedAppUsage
144     public final Point position;
145 
146     /**
147      * Bounds of the target relative to its parent.
148      * When the app target animating on its parent, we need to use the local coordinates relative to
149      * its parent with {@code localBounds.left} & {@code localBounds.top} rather than using
150      * {@code position} in screen coordinates.
151      */
152     public final Rect localBounds;
153 
154     /**
155      * The bounds of the source container the app lives in, in screen space coordinates. If the crop
156      * of the leash is modified from the controlling app, it needs to take the source container
157      * bounds into account when calculating the crop.
158      * @deprecated Renamed to {@link #screenSpaceBounds}
159      */
160     @Deprecated
161     @UnsupportedAppUsage
162     public final Rect sourceContainerBounds;
163 
164     /**
165      * Bounds of the target relative to the screen. If the crop of the leash is modified from the
166      * controlling app, it needs to take the screen space bounds into account when calculating the
167      * crop.
168      */
169     public final Rect screenSpaceBounds;
170 
171     /**
172      * The starting bounds of the source container in screen space coordinates. This is {@code null}
173      * if the animation target isn't MODE_CHANGING. Since this is the starting bounds, it's size
174      * should be equivalent to the size of the starting thumbnail. Note that sourceContainerBounds
175      * is the end bounds of a change transition.
176      */
177     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
178     public final Rect startBounds;
179 
180     /**
181      * The window configuration for the target.
182      */
183     @UnsupportedAppUsage
184     public final WindowConfiguration windowConfiguration;
185 
186     /**
187      * Whether the task is not presented in Recents UI.
188      */
189     @UnsupportedAppUsage
190     public boolean isNotInRecents;
191 
192     /**
193      * {@link TaskInfo} to allow the controller to identify information about the task.
194      *
195      * TODO: add this to proto dump
196      */
197     public ActivityManager.RunningTaskInfo taskInfo;
198 
199     /**
200      * The {@link android.view.WindowManager.LayoutParams.WindowType} of this window. It's only used
201      * for non-app window.
202      */
203     public final @WindowManager.LayoutParams.WindowType int windowType;
204 
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, Rect startBounds, ActivityManager.RunningTaskInfo taskInfo)205     public RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent,
206             Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
207             Rect localBounds, Rect screenSpaceBounds,
208             WindowConfiguration windowConfig, boolean isNotInRecents,
209             SurfaceControl startLeash, Rect startBounds, ActivityManager.RunningTaskInfo taskInfo) {
210         this(taskId, mode, leash, isTranslucent, clipRect, contentInsets, prefixOrderIndex,
211                 position, localBounds, screenSpaceBounds, windowConfig, isNotInRecents, startLeash,
212                 startBounds, taskInfo, INVALID_WINDOW_TYPE);
213     }
214 
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, Rect startBounds, ActivityManager.RunningTaskInfo taskInfo, @WindowManager.LayoutParams.WindowType int windowType)215     public RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent,
216             Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
217             Rect localBounds, Rect screenSpaceBounds,
218             WindowConfiguration windowConfig, boolean isNotInRecents,
219             SurfaceControl startLeash, Rect startBounds,
220             ActivityManager.RunningTaskInfo taskInfo,
221             @WindowManager.LayoutParams.WindowType int windowType) {
222         this.mode = mode;
223         this.taskId = taskId;
224         this.leash = leash;
225         this.isTranslucent = isTranslucent;
226         this.clipRect = new Rect(clipRect);
227         this.contentInsets = new Rect(contentInsets);
228         this.prefixOrderIndex = prefixOrderIndex;
229         this.position = new Point(position);
230         this.localBounds = new Rect(localBounds);
231         this.sourceContainerBounds = new Rect(screenSpaceBounds);
232         this.screenSpaceBounds = new Rect(screenSpaceBounds);
233         this.windowConfiguration = windowConfig;
234         this.isNotInRecents = isNotInRecents;
235         this.startLeash = startLeash;
236         this.startBounds = startBounds == null ? null : new Rect(startBounds);
237         this.taskInfo = taskInfo;
238         this.windowType = windowType;
239     }
240 
RemoteAnimationTarget(Parcel in)241     public RemoteAnimationTarget(Parcel in) {
242         taskId = in.readInt();
243         mode = in.readInt();
244         leash = in.readTypedObject(SurfaceControl.CREATOR);
245         isTranslucent = in.readBoolean();
246         clipRect = in.readTypedObject(Rect.CREATOR);
247         contentInsets = in.readTypedObject(Rect.CREATOR);
248         prefixOrderIndex = in.readInt();
249         position = in.readTypedObject(Point.CREATOR);
250         localBounds = in.readTypedObject(Rect.CREATOR);
251         sourceContainerBounds = in.readTypedObject(Rect.CREATOR);
252         screenSpaceBounds = in.readTypedObject(Rect.CREATOR);
253         windowConfiguration = in.readTypedObject(WindowConfiguration.CREATOR);
254         isNotInRecents = in.readBoolean();
255         startLeash = in.readTypedObject(SurfaceControl.CREATOR);
256         startBounds = in.readTypedObject(Rect.CREATOR);
257         taskInfo = in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
258         windowType = in.readInt();
259     }
260 
261     @Override
describeContents()262     public int describeContents() {
263         return 0;
264     }
265 
266     @Override
writeToParcel(Parcel dest, int flags)267     public void writeToParcel(Parcel dest, int flags) {
268         dest.writeInt(taskId);
269         dest.writeInt(mode);
270         dest.writeTypedObject(leash, 0 /* flags */);
271         dest.writeBoolean(isTranslucent);
272         dest.writeTypedObject(clipRect, 0 /* flags */);
273         dest.writeTypedObject(contentInsets, 0 /* flags */);
274         dest.writeInt(prefixOrderIndex);
275         dest.writeTypedObject(position, 0 /* flags */);
276         dest.writeTypedObject(localBounds, 0 /* flags */);
277         dest.writeTypedObject(sourceContainerBounds, 0 /* flags */);
278         dest.writeTypedObject(screenSpaceBounds, 0 /* flags */);
279         dest.writeTypedObject(windowConfiguration, 0 /* flags */);
280         dest.writeBoolean(isNotInRecents);
281         dest.writeTypedObject(startLeash, 0 /* flags */);
282         dest.writeTypedObject(startBounds, 0 /* flags */);
283         dest.writeTypedObject(taskInfo, 0 /* flags */);
284         dest.writeInt(windowType);
285     }
286 
dump(PrintWriter pw, String prefix)287     public void dump(PrintWriter pw, String prefix) {
288         pw.print(prefix); pw.print("mode="); pw.print(mode);
289         pw.print(" taskId="); pw.print(taskId);
290         pw.print(" isTranslucent="); pw.print(isTranslucent);
291         pw.print(" clipRect="); clipRect.printShortString(pw);
292         pw.print(" contentInsets="); contentInsets.printShortString(pw);
293         pw.print(" prefixOrderIndex="); pw.print(prefixOrderIndex);
294         pw.print(" position="); printPoint(position, pw);
295         pw.print(" sourceContainerBounds="); sourceContainerBounds.printShortString(pw);
296         pw.print(" screenSpaceBounds="); screenSpaceBounds.printShortString(pw);
297         pw.print(" localBounds="); localBounds.printShortString(pw);
298         pw.println();
299         pw.print(prefix); pw.print("windowConfiguration="); pw.println(windowConfiguration);
300         pw.print(prefix); pw.print("leash="); pw.println(leash);
301         pw.print(prefix); pw.print("taskInfo="); pw.println(taskInfo);
302         pw.print(prefix); pw.print("windowType="); pw.print(windowType);
303     }
304 
dumpDebug(ProtoOutputStream proto, long fieldId)305     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
306         final long token = proto.start(fieldId);
307         proto.write(TASK_ID, taskId);
308         proto.write(MODE, mode);
309         leash.dumpDebug(proto, LEASH);
310         proto.write(IS_TRANSLUCENT, isTranslucent);
311         clipRect.dumpDebug(proto, CLIP_RECT);
312         contentInsets.dumpDebug(proto, CONTENT_INSETS);
313         proto.write(PREFIX_ORDER_INDEX, prefixOrderIndex);
314         dumpPointProto(position, proto, POSITION);
315         sourceContainerBounds.dumpDebug(proto, SOURCE_CONTAINER_BOUNDS);
316         screenSpaceBounds.dumpDebug(proto, SCREEN_SPACE_BOUNDS);
317         localBounds.dumpDebug(proto, LOCAL_BOUNDS);
318         windowConfiguration.dumpDebug(proto, WINDOW_CONFIGURATION);
319         if (startLeash != null) {
320             startLeash.dumpDebug(proto, START_LEASH);
321         }
322         if (startBounds != null) {
323             startBounds.dumpDebug(proto, START_BOUNDS);
324         }
325         proto.end(token);
326     }
327 
printPoint(Point p, PrintWriter pw)328     private static void printPoint(Point p, PrintWriter pw) {
329         pw.print("["); pw.print(p.x); pw.print(","); pw.print(p.y); pw.print("]");
330     }
331 
332     public static final @android.annotation.NonNull Creator<RemoteAnimationTarget> CREATOR
333             = new Creator<RemoteAnimationTarget>() {
334         public RemoteAnimationTarget createFromParcel(Parcel in) {
335             return new RemoteAnimationTarget(in);
336         }
337 
338         public RemoteAnimationTarget[] newArray(int size) {
339             return new RemoteAnimationTarget[size];
340         }
341     };
342 }
343