blob: cdc099b8e2eaf0c6c014bf6538c88abb29bde173 [file] [log] [blame]
Aurimas Liutikas93554f22022-04-19 16:51:35 -07001/*
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
17package android.view;
18
19import static android.graphics.GraphicsProtos.dumpPointProto;
20import static android.view.RemoteAnimationTargetProto.CLIP_RECT;
21import static android.view.RemoteAnimationTargetProto.CONTENT_INSETS;
22import static android.view.RemoteAnimationTargetProto.IS_TRANSLUCENT;
23import static android.view.RemoteAnimationTargetProto.LEASH;
24import static android.view.RemoteAnimationTargetProto.LOCAL_BOUNDS;
25import static android.view.RemoteAnimationTargetProto.MODE;
26import static android.view.RemoteAnimationTargetProto.POSITION;
27import static android.view.RemoteAnimationTargetProto.PREFIX_ORDER_INDEX;
28import static android.view.RemoteAnimationTargetProto.SCREEN_SPACE_BOUNDS;
29import static android.view.RemoteAnimationTargetProto.SOURCE_CONTAINER_BOUNDS;
30import static android.view.RemoteAnimationTargetProto.START_BOUNDS;
31import static android.view.RemoteAnimationTargetProto.START_LEASH;
32import static android.view.RemoteAnimationTargetProto.TASK_ID;
33import static android.view.RemoteAnimationTargetProto.WINDOW_CONFIGURATION;
34import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
35
36import android.annotation.IntDef;
37import android.app.ActivityManager;
38import android.app.TaskInfo;
39import android.app.WindowConfiguration;
40import android.compat.annotation.UnsupportedAppUsage;
41import android.graphics.Point;
42import android.graphics.Rect;
43import android.os.Build;
44import android.os.Parcel;
45import android.os.Parcelable;
46import android.util.proto.ProtoOutputStream;
47
48import java.io.PrintWriter;
49import java.lang.annotation.Retention;
50import java.lang.annotation.RetentionPolicy;
51
52/**
53 * Describes an activity to be animated as part of a remote animation.
54 *
55 * @hide
56 */
57public 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
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
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
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
262 public int describeContents() {
263 return 0;
264 }
265
266 @Override
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
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
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
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}