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