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
17package android.view;
18
19import static android.app.RemoteAnimationTargetProto.CLIP_RECT;
20import static android.app.RemoteAnimationTargetProto.CONTENT_INSETS;
21import static android.app.RemoteAnimationTargetProto.IS_TRANSLUCENT;
22import static android.app.RemoteAnimationTargetProto.LEASH;
23import static android.app.RemoteAnimationTargetProto.MODE;
24import static android.app.RemoteAnimationTargetProto.POSITION;
25import static android.app.RemoteAnimationTargetProto.PREFIX_ORDER_INDEX;
26import static android.app.RemoteAnimationTargetProto.SOURCE_CONTAINER_BOUNDS;
27import static android.app.RemoteAnimationTargetProto.TASK_ID;
28import static android.app.RemoteAnimationTargetProto.WINDOW_CONFIGURATION;
29
30import android.annotation.IntDef;
31import android.app.WindowConfiguration;
32import android.graphics.Point;
33import android.graphics.Rect;
34import android.os.Parcel;
35import android.os.Parcelable;
36import android.util.proto.ProtoOutputStream;
37
38import java.io.PrintWriter;
39import java.lang.annotation.Retention;
40import java.lang.annotation.RetentionPolicy;
41
42/**
43 * Describes an activity to be animated as part of a remote animation.
44 *
45 * @hide
46 */
47public class RemoteAnimationTarget implements Parcelable {
48
49    /**
50     * The app is in the set of opening apps of this transition.
51     */
52    public static final int MODE_OPENING = 0;
53
54    /**
55     * The app is in the set of closing apps of this transition.
56     */
57    public static final int MODE_CLOSING = 1;
58
59    @IntDef(prefix = { "MODE_" }, value = {
60            MODE_OPENING,
61            MODE_CLOSING
62    })
63    @Retention(RetentionPolicy.SOURCE)
64    public @interface Mode {}
65
66    /**
67     * The {@link Mode} to describe whether this app is opening or closing.
68     */
69    public final @Mode int mode;
70
71    /**
72     * The id of the task this app belongs to.
73     */
74    public final int taskId;
75
76    /**
77     * The {@link SurfaceControl} object to actually control the transform of the app.
78     */
79    public final SurfaceControl leash;
80
81    /**
82     * Whether the app is translucent and may reveal apps behind.
83     */
84    public final boolean isTranslucent;
85
86    /**
87     * The clip rect window manager applies when clipping the app's main surface in screen space
88     * coordinates. This is just a hint to the animation runner: If running a clip-rect animation,
89     * anything that extends beyond these bounds will not have any effect. This implies that any
90     * clip-rect animation should likely stop at these bounds.
91     */
92    public final Rect clipRect;
93
94    /**
95     * The insets of the main app window.
96     */
97    public final Rect contentInsets;
98
99    /**
100     * The index of the element in the tree in prefix order. This should be used for z-layering
101     * to preserve original z-layer order in the hierarchy tree assuming no "boosting" needs to
102     * happen.
103     */
104    public final int prefixOrderIndex;
105
106    /**
107     * The source position of the app, in screen spaces coordinates. If the position of the leash
108     * is modified from the controlling app, any animation transform needs to be offset by this
109     * amount.
110     */
111    public final Point position;
112
113    /**
114     * The bounds of the source container the app lives in, in screen space coordinates. If the crop
115     * of the leash is modified from the controlling app, it needs to take the source container
116     * bounds into account when calculating the crop.
117     */
118    public final Rect sourceContainerBounds;
119
120    /**
121     * The window configuration for the target.
122     */
123    public final WindowConfiguration windowConfiguration;
124
125    /**
126     * Whether the task is not presented in Recents UI.
127     */
128    public boolean isNotInRecents;
129
130    public RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent,
131            Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
132            Rect sourceContainerBounds, WindowConfiguration windowConfig, boolean isNotInRecents) {
133        this.mode = mode;
134        this.taskId = taskId;
135        this.leash = leash;
136        this.isTranslucent = isTranslucent;
137        this.clipRect = new Rect(clipRect);
138        this.contentInsets = new Rect(contentInsets);
139        this.prefixOrderIndex = prefixOrderIndex;
140        this.position = new Point(position);
141        this.sourceContainerBounds = new Rect(sourceContainerBounds);
142        this.windowConfiguration = windowConfig;
143        this.isNotInRecents = isNotInRecents;
144    }
145
146    public RemoteAnimationTarget(Parcel in) {
147        taskId = in.readInt();
148        mode = in.readInt();
149        leash = in.readParcelable(null);
150        isTranslucent = in.readBoolean();
151        clipRect = in.readParcelable(null);
152        contentInsets = in.readParcelable(null);
153        prefixOrderIndex = in.readInt();
154        position = in.readParcelable(null);
155        sourceContainerBounds = in.readParcelable(null);
156        windowConfiguration = in.readParcelable(null);
157        isNotInRecents = in.readBoolean();
158    }
159
160    @Override
161    public int describeContents() {
162        return 0;
163    }
164
165    @Override
166    public void writeToParcel(Parcel dest, int flags) {
167        dest.writeInt(taskId);
168        dest.writeInt(mode);
169        dest.writeParcelable(leash, 0 /* flags */);
170        dest.writeBoolean(isTranslucent);
171        dest.writeParcelable(clipRect, 0 /* flags */);
172        dest.writeParcelable(contentInsets, 0 /* flags */);
173        dest.writeInt(prefixOrderIndex);
174        dest.writeParcelable(position, 0 /* flags */);
175        dest.writeParcelable(sourceContainerBounds, 0 /* flags */);
176        dest.writeParcelable(windowConfiguration, 0 /* flags */);
177        dest.writeBoolean(isNotInRecents);
178    }
179
180    public void dump(PrintWriter pw, String prefix) {
181        pw.print(prefix); pw.print("mode="); pw.print(mode);
182        pw.print(" taskId="); pw.print(taskId);
183        pw.print(" isTranslucent="); pw.print(isTranslucent);
184        pw.print(" clipRect="); clipRect.printShortString(pw);
185        pw.print(" contentInsets="); contentInsets.printShortString(pw);
186        pw.print(" prefixOrderIndex="); pw.print(prefixOrderIndex);
187        pw.print(" position="); position.printShortString(pw);
188        pw.print(" sourceContainerBounds="); sourceContainerBounds.printShortString(pw);
189        pw.println();
190        pw.print(prefix); pw.print("windowConfiguration="); pw.println(windowConfiguration);
191        pw.print(prefix); pw.print("leash="); pw.println(leash);
192    }
193
194    public void writeToProto(ProtoOutputStream proto, long fieldId) {
195        final long token = proto.start(fieldId);
196        proto.write(TASK_ID, taskId);
197        proto.write(MODE, mode);
198        leash.writeToProto(proto, LEASH);
199        proto.write(IS_TRANSLUCENT, isTranslucent);
200        clipRect.writeToProto(proto, CLIP_RECT);
201        contentInsets.writeToProto(proto, CONTENT_INSETS);
202        proto.write(PREFIX_ORDER_INDEX, prefixOrderIndex);
203        position.writeToProto(proto, POSITION);
204        sourceContainerBounds.writeToProto(proto, SOURCE_CONTAINER_BOUNDS);
205        windowConfiguration.writeToProto(proto, WINDOW_CONFIGURATION);
206        proto.end(token);
207    }
208
209    public static final Creator<RemoteAnimationTarget> CREATOR
210            = new Creator<RemoteAnimationTarget>() {
211        public RemoteAnimationTarget createFromParcel(Parcel in) {
212            return new RemoteAnimationTarget(in);
213        }
214
215        public RemoteAnimationTarget[] newArray(int size) {
216            return new RemoteAnimationTarget[size];
217        }
218    };
219}
220