1 /* 2 * Copyright (C) 2020 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.window; 18 19 import static android.app.ActivityOptions.ANIM_CLIP_REVEAL; 20 import static android.app.ActivityOptions.ANIM_CUSTOM; 21 import static android.app.ActivityOptions.ANIM_FROM_STYLE; 22 import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS; 23 import static android.app.ActivityOptions.ANIM_SCALE_UP; 24 import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION; 25 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN; 26 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP; 27 import static android.app.WindowConfiguration.ROTATION_UNDEFINED; 28 import static android.view.Display.INVALID_DISPLAY; 29 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED; 30 import static android.view.WindowManager.TRANSIT_CHANGE; 31 import static android.view.WindowManager.TRANSIT_CLOSE; 32 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_APPEARING; 33 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; 34 import static android.view.WindowManager.TRANSIT_NONE; 35 import static android.view.WindowManager.TRANSIT_OPEN; 36 import static android.view.WindowManager.TRANSIT_TO_BACK; 37 import static android.view.WindowManager.TRANSIT_TO_FRONT; 38 import static android.view.WindowManager.TransitionFlags; 39 import static android.view.WindowManager.TransitionType; 40 import static android.view.WindowManager.transitTypeToString; 41 42 import android.annotation.ColorInt; 43 import android.annotation.IntDef; 44 import android.annotation.NonNull; 45 import android.annotation.Nullable; 46 import android.app.ActivityManager; 47 import android.graphics.Point; 48 import android.graphics.Rect; 49 import android.hardware.HardwareBuffer; 50 import android.os.Parcel; 51 import android.os.Parcelable; 52 import android.view.Surface; 53 import android.view.SurfaceControl; 54 import android.view.WindowManager; 55 56 import java.util.ArrayList; 57 import java.util.List; 58 59 /** 60 * Used to communicate information about what is changing during a transition to a TransitionPlayer. 61 * @hide 62 */ 63 public final class TransitionInfo implements Parcelable { 64 private static final String TAG = "TransitionInfo"; 65 66 /** 67 * Modes are only a sub-set of all the transit-types since they are per-container 68 * @hide 69 */ 70 @IntDef(prefix = { "TRANSIT_" }, value = { 71 TRANSIT_NONE, 72 TRANSIT_OPEN, 73 TRANSIT_CLOSE, 74 // Note: to_front/to_back really mean show/hide respectively at the container level. 75 TRANSIT_TO_FRONT, 76 TRANSIT_TO_BACK, 77 TRANSIT_CHANGE 78 }) 79 public @interface TransitionMode {} 80 81 /** No flags */ 82 public static final int FLAG_NONE = 0; 83 84 /** The container shows the wallpaper behind it. */ 85 public static final int FLAG_SHOW_WALLPAPER = 1; 86 87 /** The container IS the wallpaper. */ 88 public static final int FLAG_IS_WALLPAPER = 1 << 1; 89 90 /** The container is translucent. */ 91 public static final int FLAG_TRANSLUCENT = 1 << 2; 92 93 // TODO: remove when starting-window is moved to Task 94 /** The container is the recipient of a transferred starting-window */ 95 public static final int FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT = 1 << 3; 96 97 /** The container has voice session. */ 98 public static final int FLAG_IS_VOICE_INTERACTION = 1 << 4; 99 100 /** The container is the display. */ 101 public static final int FLAG_IS_DISPLAY = 1 << 5; 102 103 /** 104 * Only for IS_DISPLAY containers. Is set if the display has system alert windows. This is 105 * used to prevent seamless rotation. 106 * TODO(b/194540864): Once we can include all windows in transition, then replace this with 107 * something like FLAG_IS_SYSTEM_ALERT instead. Then we can do mixed rotations. 108 */ 109 public static final int FLAG_DISPLAY_HAS_ALERT_WINDOWS = 1 << 7; 110 111 /** The container is an input-method window. */ 112 public static final int FLAG_IS_INPUT_METHOD = 1 << 8; 113 114 /** The container is in a Task with embedded activity. */ 115 public static final int FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY = 1 << 9; 116 117 /** The container fills its parent Task before and after the transition. */ 118 public static final int FLAG_FILLS_TASK = 1 << 10; 119 120 /** The container is going to show IME on its task after the transition. */ 121 public static final int FLAG_WILL_IME_SHOWN = 1 << 11; 122 123 /** The container attaches owner profile thumbnail for cross profile animation. */ 124 public static final int FLAG_CROSS_PROFILE_OWNER_THUMBNAIL = 1 << 12; 125 126 /** The container attaches work profile thumbnail for cross profile animation. */ 127 public static final int FLAG_CROSS_PROFILE_WORK_THUMBNAIL = 1 << 13; 128 129 /** 130 * Whether the window is covered by an app starting window. This is different from 131 * {@link #FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT} which is only set on the Activity window 132 * that contains the starting window. 133 */ 134 public static final int FLAG_IS_BEHIND_STARTING_WINDOW = 1 << 14; 135 136 /** This change happened underneath something else. */ 137 public static final int FLAG_IS_OCCLUDED = 1 << 15; 138 139 /** The container is a system window, excluding wallpaper and input-method. */ 140 public static final int FLAG_IS_SYSTEM_WINDOW = 1 << 16; 141 142 /** The window was animated by back gesture. */ 143 public static final int FLAG_BACK_GESTURE_ANIMATED = 1 << 17; 144 145 /** The window should have no animation (by policy). */ 146 public static final int FLAG_NO_ANIMATION = 1 << 18; 147 148 /** The task is launching behind home. */ 149 public static final int FLAG_TASK_LAUNCHING_BEHIND = 1 << 19; 150 151 /** The task became the top-most task even if it didn't change visibility. */ 152 public static final int FLAG_MOVED_TO_TOP = 1 << 20; 153 154 /** 155 * This transition must be the only transition when it starts (ie. it must wait for all other 156 * transition animations to finish). 157 */ 158 public static final int FLAG_SYNC = 1 << 21; 159 160 /** The first unused bit. This can be used by remotes to attach custom flags to this change. */ 161 public static final int FLAG_FIRST_CUSTOM = 1 << 22; 162 163 /** The change belongs to a window that won't contain activities. */ 164 public static final int FLAGS_IS_NON_APP_WINDOW = 165 FLAG_IS_WALLPAPER | FLAG_IS_INPUT_METHOD | FLAG_IS_SYSTEM_WINDOW; 166 167 /** @hide */ 168 @IntDef(prefix = { "FLAG_" }, value = { 169 FLAG_NONE, 170 FLAG_SHOW_WALLPAPER, 171 FLAG_IS_WALLPAPER, 172 FLAG_TRANSLUCENT, 173 FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT, 174 FLAG_IS_VOICE_INTERACTION, 175 FLAG_IS_DISPLAY, 176 FLAG_DISPLAY_HAS_ALERT_WINDOWS, 177 FLAG_IS_INPUT_METHOD, 178 FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY, 179 FLAG_FILLS_TASK, 180 FLAG_WILL_IME_SHOWN, 181 FLAG_CROSS_PROFILE_OWNER_THUMBNAIL, 182 FLAG_CROSS_PROFILE_WORK_THUMBNAIL, 183 FLAG_IS_BEHIND_STARTING_WINDOW, 184 FLAG_IS_OCCLUDED, 185 FLAG_IS_SYSTEM_WINDOW, 186 FLAG_BACK_GESTURE_ANIMATED, 187 FLAG_NO_ANIMATION, 188 FLAG_TASK_LAUNCHING_BEHIND, 189 FLAG_MOVED_TO_TOP, 190 FLAG_SYNC, 191 FLAG_FIRST_CUSTOM 192 }) 193 public @interface ChangeFlags {} 194 195 private final @TransitionType int mType; 196 private @TransitionFlags int mFlags; 197 private int mTrack = 0; 198 private final ArrayList<Change> mChanges = new ArrayList<>(); 199 private final ArrayList<Root> mRoots = new ArrayList<>(); 200 201 private AnimationOptions mOptions; 202 203 /** This is only a BEST-EFFORT id used for log correlation. DO NOT USE for any real work! */ 204 private int mDebugId = -1; 205 206 /** @hide */ TransitionInfo(@ransitionType int type, @TransitionFlags int flags)207 public TransitionInfo(@TransitionType int type, @TransitionFlags int flags) { 208 mType = type; 209 mFlags = flags; 210 } 211 TransitionInfo(Parcel in)212 private TransitionInfo(Parcel in) { 213 mType = in.readInt(); 214 mFlags = in.readInt(); 215 in.readTypedList(mChanges, Change.CREATOR); 216 in.readTypedList(mRoots, Root.CREATOR); 217 mOptions = in.readTypedObject(AnimationOptions.CREATOR); 218 mDebugId = in.readInt(); 219 mTrack = in.readInt(); 220 } 221 222 @Override 223 /** @hide */ writeToParcel(@onNull Parcel dest, int flags)224 public void writeToParcel(@NonNull Parcel dest, int flags) { 225 dest.writeInt(mType); 226 dest.writeInt(mFlags); 227 dest.writeTypedList(mChanges); 228 dest.writeTypedList(mRoots, flags); 229 dest.writeTypedObject(mOptions, flags); 230 dest.writeInt(mDebugId); 231 dest.writeInt(mTrack); 232 } 233 234 @NonNull 235 public static final Creator<TransitionInfo> CREATOR = 236 new Creator<TransitionInfo>() { 237 @Override 238 public TransitionInfo createFromParcel(Parcel in) { 239 return new TransitionInfo(in); 240 } 241 242 @Override 243 public TransitionInfo[] newArray(int size) { 244 return new TransitionInfo[size]; 245 } 246 }; 247 248 @Override 249 /** @hide */ describeContents()250 public int describeContents() { 251 return 0; 252 } 253 254 /** @see #getRoot */ addRootLeash(int displayId, @NonNull SurfaceControl leash, int offsetLeft, int offsetTop)255 public void addRootLeash(int displayId, @NonNull SurfaceControl leash, 256 int offsetLeft, int offsetTop) { 257 mRoots.add(new Root(displayId, leash, offsetLeft, offsetTop)); 258 } 259 260 /** @see #getRoot */ addRoot(Root other)261 public void addRoot(Root other) { 262 mRoots.add(other); 263 } 264 setAnimationOptions(AnimationOptions options)265 public void setAnimationOptions(AnimationOptions options) { 266 mOptions = options; 267 } 268 getType()269 public @TransitionType int getType() { 270 return mType; 271 } 272 setFlags(int flags)273 public void setFlags(int flags) { 274 mFlags = flags; 275 } 276 getFlags()277 public int getFlags() { 278 return mFlags; 279 } 280 281 /** 282 * @return The number of animation roots. Most transitions should have 1, but there may be more 283 * in some cases (such as a transition spanning multiple displays). 284 */ getRootCount()285 public int getRootCount() { 286 return mRoots.size(); 287 } 288 289 /** 290 * @return the transition-root at a specific index. 291 */ 292 @NonNull getRoot(int idx)293 public Root getRoot(int idx) { 294 return mRoots.get(idx); 295 } 296 297 /** 298 * @return the index of the transition-root associated with `displayId` or -1 if not found. 299 */ findRootIndex(int displayId)300 public int findRootIndex(int displayId) { 301 for (int i = 0; i < mRoots.size(); ++i) { 302 if (mRoots.get(i).mDisplayId == displayId) { 303 return i; 304 } 305 } 306 return -1; 307 } 308 309 /** 310 * @return a surfacecontrol that can serve as a parent surfacecontrol for all the changing 311 * participants to animate within. This will generally be placed at the highest-z-order 312 * shared ancestor of all participants. While this is non-null, it's possible for the rootleash 313 * to be invalid if the transition is a no-op. 314 * 315 * @deprecated Use {@link #getRoot} instead. This call assumes there is only one root. 316 */ 317 @Deprecated 318 @NonNull getRootLeash()319 public SurfaceControl getRootLeash() { 320 if (mRoots.isEmpty()) { 321 throw new IllegalStateException("Trying to get a root leash from a no-op transition."); 322 } 323 if (mRoots.size() > 1) { 324 android.util.Log.e(TAG, "Assuming one animation root when there are more.", 325 new Throwable()); 326 } 327 return mRoots.get(0).mLeash; 328 } 329 getAnimationOptions()330 public AnimationOptions getAnimationOptions() { 331 return mOptions; 332 } 333 334 /** 335 * @return the list of {@link Change}s in this transition. The list is sorted top-to-bottom 336 * in Z (meaning index 0 is the top-most container). 337 */ 338 @NonNull getChanges()339 public List<Change> getChanges() { 340 return mChanges; 341 } 342 343 /** 344 * @return the Change that a window is undergoing or {@code null} if not directly 345 * represented. 346 */ 347 @Nullable getChange(@onNull WindowContainerToken token)348 public Change getChange(@NonNull WindowContainerToken token) { 349 for (int i = mChanges.size() - 1; i >= 0; --i) { 350 if (token.equals(mChanges.get(i).mContainer)) { 351 return mChanges.get(i); 352 } 353 } 354 return null; 355 } 356 357 /** 358 * Add a {@link Change} to this transition. 359 */ addChange(@onNull Change change)360 public void addChange(@NonNull Change change) { 361 mChanges.add(change); 362 } 363 364 /** 365 * Whether this transition contains any changes to the window hierarchy, 366 * including keyguard visibility. 367 */ hasChangesOrSideEffects()368 public boolean hasChangesOrSideEffects() { 369 return !mChanges.isEmpty() || isKeyguardGoingAway() 370 || (mFlags & TRANSIT_FLAG_KEYGUARD_APPEARING) != 0; 371 } 372 373 /** 374 * Whether this transition includes keyguard going away. 375 */ isKeyguardGoingAway()376 public boolean isKeyguardGoingAway() { 377 return (mFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY) != 0; 378 } 379 380 /** Gets which animation track this transition should run on. */ getTrack()381 public int getTrack() { 382 return mTrack; 383 } 384 385 /** Sets which animation track this transition should run on. */ setTrack(int track)386 public void setTrack(int track) { 387 mTrack = track; 388 } 389 390 /** 391 * Set an arbitrary "debug" id for this info. This id will not be used for any "real work", 392 * it is just for debugging and logging. 393 */ setDebugId(int id)394 public void setDebugId(int id) { 395 mDebugId = id; 396 } 397 398 /** Get the "debug" id of this info. Do NOT use this for real work, only use for debugging. */ getDebugId()399 public int getDebugId() { 400 return mDebugId; 401 } 402 403 @Override toString()404 public String toString() { 405 StringBuilder sb = new StringBuilder(); 406 sb.append("{id=").append(mDebugId).append(" t=").append(transitTypeToString(mType)) 407 .append(" f=0x").append(Integer.toHexString(mFlags)).append(" trk=").append(mTrack) 408 .append(" r=["); 409 for (int i = 0; i < mRoots.size(); ++i) { 410 if (i > 0) { 411 sb.append(','); 412 } 413 sb.append(mRoots.get(i).mDisplayId).append("@").append(mRoots.get(i).mOffset); 414 } 415 sb.append("] c=["); 416 for (int i = 0; i < mChanges.size(); ++i) { 417 if (i > 0) { 418 sb.append(','); 419 } 420 sb.append(mChanges.get(i)); 421 } 422 sb.append("]}"); 423 return sb.toString(); 424 } 425 426 /** Converts a transition mode/action to its string representation. */ 427 @NonNull modeToString(@ransitionMode int mode)428 public static String modeToString(@TransitionMode int mode) { 429 switch(mode) { 430 case TRANSIT_NONE: return "NONE"; 431 case TRANSIT_OPEN: return "OPEN"; 432 case TRANSIT_CLOSE: return "CLOSE"; 433 case TRANSIT_TO_FRONT: return "TO_FRONT"; 434 case TRANSIT_TO_BACK: return "TO_BACK"; 435 case TRANSIT_CHANGE: return "CHANGE"; 436 default: return "<unknown:" + mode + ">"; 437 } 438 } 439 440 /** Converts change flags into a string representation. */ 441 @NonNull flagsToString(@hangeFlags int flags)442 public static String flagsToString(@ChangeFlags int flags) { 443 if (flags == 0) return "NONE"; 444 final StringBuilder sb = new StringBuilder(); 445 if ((flags & FLAG_SHOW_WALLPAPER) != 0) { 446 sb.append("SHOW_WALLPAPER"); 447 } 448 if ((flags & FLAG_IS_WALLPAPER) != 0) { 449 sb.append("IS_WALLPAPER"); 450 } 451 if ((flags & FLAG_IS_INPUT_METHOD) != 0) { 452 sb.append("IS_INPUT_METHOD"); 453 } 454 if ((flags & FLAG_TRANSLUCENT) != 0) { 455 sb.append(sb.length() == 0 ? "" : "|").append("TRANSLUCENT"); 456 } 457 if ((flags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0) { 458 sb.append(sb.length() == 0 ? "" : "|").append("STARTING_WINDOW_TRANSFER"); 459 } 460 if ((flags & FLAG_IS_VOICE_INTERACTION) != 0) { 461 sb.append(sb.length() == 0 ? "" : "|").append("IS_VOICE_INTERACTION"); 462 } 463 if ((flags & FLAG_IS_DISPLAY) != 0) { 464 sb.append(sb.length() == 0 ? "" : "|").append("IS_DISPLAY"); 465 } 466 if ((flags & FLAG_DISPLAY_HAS_ALERT_WINDOWS) != 0) { 467 sb.append(sb.length() == 0 ? "" : "|").append("DISPLAY_HAS_ALERT_WINDOWS"); 468 } 469 if ((flags & FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY) != 0) { 470 sb.append(sb.length() == 0 ? "" : "|").append("IN_TASK_WITH_EMBEDDED_ACTIVITY"); 471 } 472 if ((flags & FLAG_FILLS_TASK) != 0) { 473 sb.append(sb.length() == 0 ? "" : "|").append("FILLS_TASK"); 474 } 475 if ((flags & FLAG_IS_BEHIND_STARTING_WINDOW) != 0) { 476 sb.append(sb.length() == 0 ? "" : "|").append("IS_BEHIND_STARTING_WINDOW"); 477 } 478 if ((flags & FLAG_IS_OCCLUDED) != 0) { 479 sb.append(sb.length() == 0 ? "" : "|").append("IS_OCCLUDED"); 480 } 481 if ((flags & FLAG_IS_SYSTEM_WINDOW) != 0) { 482 sb.append(sb.length() == 0 ? "" : "|").append("FLAG_IS_SYSTEM_WINDOW"); 483 } 484 if ((flags & FLAG_BACK_GESTURE_ANIMATED) != 0) { 485 sb.append(sb.length() == 0 ? "" : "|").append("FLAG_BACK_GESTURE_ANIMATED"); 486 } 487 if ((flags & FLAG_NO_ANIMATION) != 0) { 488 sb.append(sb.length() == 0 ? "" : "|").append("NO_ANIMATION"); 489 } 490 if ((flags & FLAG_TASK_LAUNCHING_BEHIND) != 0) { 491 sb.append((sb.length() == 0 ? "" : "|") + "TASK_LAUNCHING_BEHIND"); 492 } 493 if ((flags & FLAG_SYNC) != 0) { 494 sb.append((sb.length() == 0 ? "" : "|") + "SYNC"); 495 } 496 if ((flags & FLAG_FIRST_CUSTOM) != 0) { 497 sb.append(sb.length() == 0 ? "" : "|").append("FIRST_CUSTOM"); 498 } 499 if ((flags & FLAG_MOVED_TO_TOP) != 0) { 500 sb.append(sb.length() == 0 ? "" : "|").append("MOVE_TO_TOP"); 501 } 502 return sb.toString(); 503 } 504 505 /** 506 * Indication that `change` is independent of parents (ie. it has a different type of 507 * transition vs. "going along for the ride") 508 */ isIndependent(@onNull TransitionInfo.Change change, @NonNull TransitionInfo info)509 public static boolean isIndependent(@NonNull TransitionInfo.Change change, 510 @NonNull TransitionInfo info) { 511 // If the change has no parent (it is root), then it is independent 512 if (change.getParent() == null) return true; 513 514 // non-visibility changes will just be folded into the parent change, so they aren't 515 // independent either. 516 if (change.getMode() == TRANSIT_CHANGE) return false; 517 518 TransitionInfo.Change parentChg = info.getChange(change.getParent()); 519 while (parentChg != null) { 520 // If the parent is a visibility change, it will include the results of all child 521 // changes into itself, so none of its children can be independent. 522 if (parentChg.getMode() != TRANSIT_CHANGE) return false; 523 524 // If there are no more parents left, then all the parents, so far, have not been 525 // visibility changes which means this change is independent. 526 if (parentChg.getParent() == null) return true; 527 528 parentChg = info.getChange(parentChg.getParent()); 529 } 530 return false; 531 } 532 533 /** 534 * Releases temporary-for-animation surfaces referenced by this to potentially free up memory. 535 * This includes root-leash and snapshots. 536 */ releaseAnimSurfaces()537 public void releaseAnimSurfaces() { 538 for (int i = mChanges.size() - 1; i >= 0; --i) { 539 final Change c = mChanges.get(i); 540 if (c.mSnapshot != null) { 541 c.mSnapshot.release(); 542 c.mSnapshot = null; 543 } 544 } 545 for (int i = 0; i < mRoots.size(); ++i) { 546 mRoots.get(i).mLeash.release(); 547 } 548 } 549 550 /** 551 * Releases ALL the surfaces referenced by this to potentially free up memory. Do NOT use this 552 * if the surface-controls get stored and used elsewhere in the process. To just release 553 * temporary-for-animation surfaces, use {@link #releaseAnimSurfaces}. 554 */ releaseAllSurfaces()555 public void releaseAllSurfaces() { 556 releaseAnimSurfaces(); 557 for (int i = mChanges.size() - 1; i >= 0; --i) { 558 mChanges.get(i).getLeash().release(); 559 } 560 } 561 562 /** 563 * Updates the callsites of all the surfaces in this transition, which aids in the debugging of 564 * lingering surfaces. 565 */ setUnreleasedWarningCallSiteForAllSurfaces(String callsite)566 public void setUnreleasedWarningCallSiteForAllSurfaces(String callsite) { 567 for (int i = mChanges.size() - 1; i >= 0; --i) { 568 mChanges.get(i).getLeash().setUnreleasedWarningCallSite(callsite); 569 } 570 } 571 572 /** 573 * Makes a copy of this as if it were parcel'd and unparcel'd. This implies that surfacecontrol 574 * refcounts are incremented which allows the "remote" receiver to release them without breaking 575 * the caller's references. Use this only if you need to "send" this to a local function which 576 * assumes it is being called from a remote caller. 577 */ localRemoteCopy()578 public TransitionInfo localRemoteCopy() { 579 final TransitionInfo out = new TransitionInfo(mType, mFlags); 580 out.mTrack = mTrack; 581 out.mDebugId = mDebugId; 582 for (int i = 0; i < mChanges.size(); ++i) { 583 out.mChanges.add(mChanges.get(i).localRemoteCopy()); 584 } 585 for (int i = 0; i < mRoots.size(); ++i) { 586 out.mRoots.add(mRoots.get(i).localRemoteCopy()); 587 } 588 // Doesn't have any native stuff, so no need for actual copy 589 out.mOptions = mOptions; 590 return out; 591 } 592 593 /** Represents the change a WindowContainer undergoes during a transition */ 594 public static final class Change implements Parcelable { 595 private final WindowContainerToken mContainer; 596 private WindowContainerToken mParent; 597 private WindowContainerToken mLastParent; 598 private final SurfaceControl mLeash; 599 private @TransitionMode int mMode = TRANSIT_NONE; 600 private @ChangeFlags int mFlags = FLAG_NONE; 601 private final Rect mStartAbsBounds = new Rect(); 602 private final Rect mEndAbsBounds = new Rect(); 603 private final Point mEndRelOffset = new Point(); 604 private ActivityManager.RunningTaskInfo mTaskInfo = null; 605 private boolean mAllowEnterPip; 606 private int mStartDisplayId = INVALID_DISPLAY; 607 private int mEndDisplayId = INVALID_DISPLAY; 608 private @Surface.Rotation int mStartRotation = ROTATION_UNDEFINED; 609 private @Surface.Rotation int mEndRotation = ROTATION_UNDEFINED; 610 /** 611 * The end rotation of the top activity after fixed rotation is finished. If the top 612 * activity is not in fixed rotation, it will be {@link ROTATION_UNDEFINED}. 613 */ 614 private @Surface.Rotation int mEndFixedRotation = ROTATION_UNDEFINED; 615 private int mRotationAnimation = ROTATION_ANIMATION_UNSPECIFIED; 616 private @ColorInt int mBackgroundColor; 617 private SurfaceControl mSnapshot = null; 618 private float mSnapshotLuma; 619 Change(@ullable WindowContainerToken container, @NonNull SurfaceControl leash)620 public Change(@Nullable WindowContainerToken container, @NonNull SurfaceControl leash) { 621 mContainer = container; 622 mLeash = leash; 623 } 624 Change(Parcel in)625 private Change(Parcel in) { 626 mContainer = in.readTypedObject(WindowContainerToken.CREATOR); 627 mParent = in.readTypedObject(WindowContainerToken.CREATOR); 628 mLastParent = in.readTypedObject(WindowContainerToken.CREATOR); 629 mLeash = new SurfaceControl(); 630 mLeash.readFromParcel(in); 631 mMode = in.readInt(); 632 mFlags = in.readInt(); 633 mStartAbsBounds.readFromParcel(in); 634 mEndAbsBounds.readFromParcel(in); 635 mEndRelOffset.readFromParcel(in); 636 mTaskInfo = in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR); 637 mAllowEnterPip = in.readBoolean(); 638 mStartDisplayId = in.readInt(); 639 mEndDisplayId = in.readInt(); 640 mStartRotation = in.readInt(); 641 mEndRotation = in.readInt(); 642 mEndFixedRotation = in.readInt(); 643 mRotationAnimation = in.readInt(); 644 mBackgroundColor = in.readInt(); 645 mSnapshot = in.readTypedObject(SurfaceControl.CREATOR); 646 mSnapshotLuma = in.readFloat(); 647 } 648 localRemoteCopy()649 private Change localRemoteCopy() { 650 final Change out = new Change(mContainer, new SurfaceControl(mLeash, "localRemote")); 651 out.mParent = mParent; 652 out.mLastParent = mLastParent; 653 out.mMode = mMode; 654 out.mFlags = mFlags; 655 out.mStartAbsBounds.set(mStartAbsBounds); 656 out.mEndAbsBounds.set(mEndAbsBounds); 657 out.mEndRelOffset.set(mEndRelOffset); 658 out.mTaskInfo = mTaskInfo; 659 out.mAllowEnterPip = mAllowEnterPip; 660 out.mStartDisplayId = mStartDisplayId; 661 out.mEndDisplayId = mEndDisplayId; 662 out.mStartRotation = mStartRotation; 663 out.mEndRotation = mEndRotation; 664 out.mEndFixedRotation = mEndFixedRotation; 665 out.mRotationAnimation = mRotationAnimation; 666 out.mBackgroundColor = mBackgroundColor; 667 out.mSnapshot = mSnapshot != null ? new SurfaceControl(mSnapshot, "localRemote") : null; 668 out.mSnapshotLuma = mSnapshotLuma; 669 return out; 670 } 671 672 /** Sets the parent of this change's container. The parent must be a participant or null. */ setParent(@ullable WindowContainerToken parent)673 public void setParent(@Nullable WindowContainerToken parent) { 674 mParent = parent; 675 } 676 677 /** 678 * Sets the parent of this change's container before the transition if this change's 679 * container is reparented in the transition. 680 */ setLastParent(@ullable WindowContainerToken lastParent)681 public void setLastParent(@Nullable WindowContainerToken lastParent) { 682 mLastParent = lastParent; 683 } 684 685 /** Sets the transition mode for this change */ setMode(@ransitionMode int mode)686 public void setMode(@TransitionMode int mode) { 687 mMode = mode; 688 } 689 690 /** Sets the flags for this change */ setFlags(@hangeFlags int flags)691 public void setFlags(@ChangeFlags int flags) { 692 mFlags = flags; 693 } 694 695 /** Sets the bounds this container occupied before the change in screen space */ setStartAbsBounds(@ullable Rect rect)696 public void setStartAbsBounds(@Nullable Rect rect) { 697 mStartAbsBounds.set(rect); 698 } 699 700 /** Sets the bounds this container will occupy after the change in screen space */ setEndAbsBounds(@ullable Rect rect)701 public void setEndAbsBounds(@Nullable Rect rect) { 702 mEndAbsBounds.set(rect); 703 } 704 705 /** Sets the offset of this container from its parent surface */ setEndRelOffset(int left, int top)706 public void setEndRelOffset(int left, int top) { 707 mEndRelOffset.set(left, top); 708 } 709 710 /** 711 * Sets the taskinfo of this container if this is a task. WARNING: this takes the 712 * reference, so don't modify it afterwards. 713 */ setTaskInfo(@ullable ActivityManager.RunningTaskInfo taskInfo)714 public void setTaskInfo(@Nullable ActivityManager.RunningTaskInfo taskInfo) { 715 mTaskInfo = taskInfo; 716 } 717 718 /** Sets the allowEnterPip flag which represents AppOpsManager check on PiP permission */ setAllowEnterPip(boolean allowEnterPip)719 public void setAllowEnterPip(boolean allowEnterPip) { 720 mAllowEnterPip = allowEnterPip; 721 } 722 723 /** Sets the start and end rotation of this container. */ setDisplayId(int start, int end)724 public void setDisplayId(int start, int end) { 725 mStartDisplayId = start; 726 mEndDisplayId = end; 727 } 728 729 /** Sets the start and end rotation of this container. */ setRotation(@urface.Rotation int start, @Surface.Rotation int end)730 public void setRotation(@Surface.Rotation int start, @Surface.Rotation int end) { 731 mStartRotation = start; 732 mEndRotation = end; 733 } 734 735 /** Sets end rotation that top activity will be launched to after fixed rotation. */ setEndFixedRotation(@urface.Rotation int endFixedRotation)736 public void setEndFixedRotation(@Surface.Rotation int endFixedRotation) { 737 mEndFixedRotation = endFixedRotation; 738 } 739 740 /** 741 * Sets the app-requested animation type for rotation. Will be one of the 742 * ROTATION_ANIMATION_ values in {@link android.view.WindowManager.LayoutParams}; 743 */ setRotationAnimation(int anim)744 public void setRotationAnimation(int anim) { 745 mRotationAnimation = anim; 746 } 747 748 /** Sets the background color of this change's container. */ setBackgroundColor(@olorInt int backgroundColor)749 public void setBackgroundColor(@ColorInt int backgroundColor) { 750 mBackgroundColor = backgroundColor; 751 } 752 753 /** Sets a snapshot surface for the "start" state of the container. */ setSnapshot(@ullable SurfaceControl snapshot, float luma)754 public void setSnapshot(@Nullable SurfaceControl snapshot, float luma) { 755 mSnapshot = snapshot; 756 mSnapshotLuma = luma; 757 } 758 759 /** @return the container that is changing. May be null if non-remotable (eg. activity) */ 760 @Nullable getContainer()761 public WindowContainerToken getContainer() { 762 return mContainer; 763 } 764 765 /** 766 * @return the parent of the changing container. This is the parent within the participants, 767 * not necessarily the actual parent. 768 */ 769 @Nullable getParent()770 public WindowContainerToken getParent() { 771 return mParent; 772 } 773 774 /** 775 * @return the parent of the changing container before the transition if it is reparented 776 * in the transition. The parent window may not be collected in the transition as a 777 * participant, and it may have been detached from the display. {@code null} if the changing 778 * container has not been reparented in the transition, or if the parent is not organizable. 779 */ 780 @Nullable getLastParent()781 public WindowContainerToken getLastParent() { 782 return mLastParent; 783 } 784 785 /** @return which action this change represents. */ getMode()786 public @TransitionMode int getMode() { 787 return mMode; 788 } 789 790 /** @return the flags for this change. */ getFlags()791 public @ChangeFlags int getFlags() { 792 return mFlags; 793 } 794 795 /** Whether this change contains any of the given change flags. */ hasFlags(@hangeFlags int flags)796 public boolean hasFlags(@ChangeFlags int flags) { 797 return (mFlags & flags) != 0; 798 } 799 800 /** Whether this change contains all of the given change flags. */ hasAllFlags(@hangeFlags int flags)801 public boolean hasAllFlags(@ChangeFlags int flags) { 802 return (mFlags & flags) == flags; 803 } 804 805 /** 806 * @return the bounds of the container before the change. It may be empty if the container 807 * is coming into existence. 808 */ 809 @NonNull getStartAbsBounds()810 public Rect getStartAbsBounds() { 811 return mStartAbsBounds; 812 } 813 814 /** 815 * @return the bounds of the container after the change. It may be empty if the container 816 * is disappearing. 817 */ 818 @NonNull getEndAbsBounds()819 public Rect getEndAbsBounds() { 820 return mEndAbsBounds; 821 } 822 823 /** 824 * @return the offset of the container's surface from its parent surface after the change. 825 */ 826 @NonNull getEndRelOffset()827 public Point getEndRelOffset() { 828 return mEndRelOffset; 829 } 830 831 /** @return the leash or surface to animate for this container */ 832 @NonNull getLeash()833 public SurfaceControl getLeash() { 834 return mLeash; 835 } 836 837 /** @return the task info or null if this isn't a task */ 838 @Nullable getTaskInfo()839 public ActivityManager.RunningTaskInfo getTaskInfo() { 840 return mTaskInfo; 841 } 842 getAllowEnterPip()843 public boolean getAllowEnterPip() { 844 return mAllowEnterPip; 845 } 846 getStartDisplayId()847 public int getStartDisplayId() { 848 return mStartDisplayId; 849 } 850 getEndDisplayId()851 public int getEndDisplayId() { 852 return mEndDisplayId; 853 } 854 855 @Surface.Rotation getStartRotation()856 public int getStartRotation() { 857 return mStartRotation; 858 } 859 860 @Surface.Rotation getEndRotation()861 public int getEndRotation() { 862 return mEndRotation; 863 } 864 865 @Surface.Rotation getEndFixedRotation()866 public int getEndFixedRotation() { 867 return mEndFixedRotation; 868 } 869 870 /** @return the rotation animation. */ getRotationAnimation()871 public int getRotationAnimation() { 872 return mRotationAnimation; 873 } 874 875 /** @return get the background color of this change's container. */ 876 @ColorInt getBackgroundColor()877 public int getBackgroundColor() { 878 return mBackgroundColor; 879 } 880 881 /** @return a snapshot surface (if applicable). */ 882 @Nullable getSnapshot()883 public SurfaceControl getSnapshot() { 884 return mSnapshot; 885 } 886 887 /** @return the luma calculated for the snapshot surface (if applicable). */ getSnapshotLuma()888 public float getSnapshotLuma() { 889 return mSnapshotLuma; 890 } 891 892 /** @hide */ 893 @Override writeToParcel(@onNull Parcel dest, int flags)894 public void writeToParcel(@NonNull Parcel dest, int flags) { 895 dest.writeTypedObject(mContainer, flags); 896 dest.writeTypedObject(mParent, flags); 897 dest.writeTypedObject(mLastParent, flags); 898 mLeash.writeToParcel(dest, flags); 899 dest.writeInt(mMode); 900 dest.writeInt(mFlags); 901 mStartAbsBounds.writeToParcel(dest, flags); 902 mEndAbsBounds.writeToParcel(dest, flags); 903 mEndRelOffset.writeToParcel(dest, flags); 904 dest.writeTypedObject(mTaskInfo, flags); 905 dest.writeBoolean(mAllowEnterPip); 906 dest.writeInt(mStartDisplayId); 907 dest.writeInt(mEndDisplayId); 908 dest.writeInt(mStartRotation); 909 dest.writeInt(mEndRotation); 910 dest.writeInt(mEndFixedRotation); 911 dest.writeInt(mRotationAnimation); 912 dest.writeInt(mBackgroundColor); 913 dest.writeTypedObject(mSnapshot, flags); 914 dest.writeFloat(mSnapshotLuma); 915 } 916 917 @NonNull 918 public static final Creator<Change> CREATOR = 919 new Creator<Change>() { 920 @Override 921 public Change createFromParcel(Parcel in) { 922 return new Change(in); 923 } 924 925 @Override 926 public Change[] newArray(int size) { 927 return new Change[size]; 928 } 929 }; 930 931 /** @hide */ 932 @Override describeContents()933 public int describeContents() { 934 return 0; 935 } 936 937 @Override toString()938 public String toString() { 939 final StringBuilder sb = new StringBuilder(); 940 sb.append('{'); sb.append(mContainer); 941 sb.append(" m="); sb.append(modeToString(mMode)); 942 sb.append(" f="); sb.append(flagsToString(mFlags)); 943 if (mParent != null) { 944 sb.append(" p="); sb.append(mParent); 945 } 946 if (mLeash != null) { 947 sb.append(" leash="); sb.append(mLeash); 948 } 949 sb.append(" sb="); sb.append(mStartAbsBounds); 950 sb.append(" eb="); sb.append(mEndAbsBounds); 951 if (mEndRelOffset.x != 0 || mEndRelOffset.y != 0) { 952 sb.append(" eo="); sb.append(mEndRelOffset); 953 } 954 sb.append(" d="); 955 if (mStartDisplayId != mEndDisplayId) { 956 sb.append(mStartDisplayId).append("->"); 957 } 958 sb.append(mEndDisplayId); 959 if (mStartRotation != mEndRotation) { 960 sb.append(" r="); sb.append(mStartRotation); 961 sb.append("->"); sb.append(mEndRotation); 962 sb.append(':'); sb.append(mRotationAnimation); 963 } 964 if (mEndFixedRotation != ROTATION_UNDEFINED) { 965 sb.append(" endFixedRotation="); sb.append(mEndFixedRotation); 966 } 967 if (mSnapshot != null) { 968 sb.append(" snapshot="); sb.append(mSnapshot); 969 } 970 if (mLastParent != null) { 971 sb.append(" lastParent="); sb.append(mLastParent); 972 } 973 sb.append('}'); 974 return sb.toString(); 975 } 976 } 977 978 /** Represents animation options during a transition */ 979 public static final class AnimationOptions implements Parcelable { 980 981 private int mType; 982 private int mEnterResId; 983 private int mExitResId; 984 private boolean mOverrideTaskTransition; 985 private String mPackageName; 986 private final Rect mTransitionBounds = new Rect(); 987 private HardwareBuffer mThumbnail; 988 private int mAnimations; 989 private @ColorInt int mBackgroundColor; 990 // Customize activity transition animation 991 private CustomActivityTransition mCustomActivityOpenTransition; 992 private CustomActivityTransition mCustomActivityCloseTransition; 993 AnimationOptions(int type)994 private AnimationOptions(int type) { 995 mType = type; 996 } 997 AnimationOptions(Parcel in)998 public AnimationOptions(Parcel in) { 999 mType = in.readInt(); 1000 mEnterResId = in.readInt(); 1001 mExitResId = in.readInt(); 1002 mBackgroundColor = in.readInt(); 1003 mOverrideTaskTransition = in.readBoolean(); 1004 mPackageName = in.readString(); 1005 mTransitionBounds.readFromParcel(in); 1006 mThumbnail = in.readTypedObject(HardwareBuffer.CREATOR); 1007 mAnimations = in.readInt(); 1008 mCustomActivityOpenTransition = in.readTypedObject(CustomActivityTransition.CREATOR); 1009 mCustomActivityCloseTransition = in.readTypedObject(CustomActivityTransition.CREATOR); 1010 } 1011 1012 /** Make basic customized animation for a package */ makeCommonAnimOptions(String packageName)1013 public static AnimationOptions makeCommonAnimOptions(String packageName) { 1014 AnimationOptions options = new AnimationOptions(ANIM_FROM_STYLE); 1015 options.mPackageName = packageName; 1016 return options; 1017 } 1018 makeAnimOptionsFromLayoutParameters( WindowManager.LayoutParams lp)1019 public static AnimationOptions makeAnimOptionsFromLayoutParameters( 1020 WindowManager.LayoutParams lp) { 1021 AnimationOptions options = new AnimationOptions(ANIM_FROM_STYLE); 1022 options.mPackageName = lp.packageName; 1023 options.mAnimations = lp.windowAnimations; 1024 return options; 1025 } 1026 1027 /** Add customized window animations */ addOptionsFromLayoutParameters(WindowManager.LayoutParams lp)1028 public void addOptionsFromLayoutParameters(WindowManager.LayoutParams lp) { 1029 mAnimations = lp.windowAnimations; 1030 } 1031 1032 /** Add customized activity animation attributes */ addCustomActivityTransition(boolean isOpen, int enterResId, int exitResId, int backgroundColor)1033 public void addCustomActivityTransition(boolean isOpen, 1034 int enterResId, int exitResId, int backgroundColor) { 1035 CustomActivityTransition customTransition = isOpen 1036 ? mCustomActivityOpenTransition : mCustomActivityCloseTransition; 1037 if (customTransition == null) { 1038 customTransition = new CustomActivityTransition(); 1039 if (isOpen) { 1040 mCustomActivityOpenTransition = customTransition; 1041 } else { 1042 mCustomActivityCloseTransition = customTransition; 1043 } 1044 } 1045 customTransition.addCustomActivityTransition(enterResId, exitResId, backgroundColor); 1046 } 1047 makeCustomAnimOptions(String packageName, int enterResId, int exitResId, @ColorInt int backgroundColor, boolean overrideTaskTransition)1048 public static AnimationOptions makeCustomAnimOptions(String packageName, int enterResId, 1049 int exitResId, @ColorInt int backgroundColor, boolean overrideTaskTransition) { 1050 AnimationOptions options = new AnimationOptions(ANIM_CUSTOM); 1051 options.mPackageName = packageName; 1052 options.mEnterResId = enterResId; 1053 options.mExitResId = exitResId; 1054 options.mBackgroundColor = backgroundColor; 1055 options.mOverrideTaskTransition = overrideTaskTransition; 1056 return options; 1057 } 1058 makeClipRevealAnimOptions(int startX, int startY, int width, int height)1059 public static AnimationOptions makeClipRevealAnimOptions(int startX, int startY, int width, 1060 int height) { 1061 AnimationOptions options = new AnimationOptions(ANIM_CLIP_REVEAL); 1062 options.mTransitionBounds.set(startX, startY, startX + width, startY + height); 1063 return options; 1064 } 1065 makeScaleUpAnimOptions(int startX, int startY, int width, int height)1066 public static AnimationOptions makeScaleUpAnimOptions(int startX, int startY, int width, 1067 int height) { 1068 AnimationOptions options = new AnimationOptions(ANIM_SCALE_UP); 1069 options.mTransitionBounds.set(startX, startY, startX + width, startY + height); 1070 return options; 1071 } 1072 makeThumbnailAnimOptions(HardwareBuffer srcThumb, int startX, int startY, boolean scaleUp)1073 public static AnimationOptions makeThumbnailAnimOptions(HardwareBuffer srcThumb, 1074 int startX, int startY, boolean scaleUp) { 1075 AnimationOptions options = new AnimationOptions( 1076 scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN); 1077 options.mTransitionBounds.set(startX, startY, startX, startY); 1078 options.mThumbnail = srcThumb; 1079 return options; 1080 } 1081 makeCrossProfileAnimOptions()1082 public static AnimationOptions makeCrossProfileAnimOptions() { 1083 AnimationOptions options = new AnimationOptions(ANIM_OPEN_CROSS_PROFILE_APPS); 1084 return options; 1085 } 1086 makeSceneTransitionAnimOptions()1087 public static AnimationOptions makeSceneTransitionAnimOptions() { 1088 AnimationOptions options = new AnimationOptions(ANIM_SCENE_TRANSITION); 1089 return options; 1090 } 1091 getType()1092 public int getType() { 1093 return mType; 1094 } 1095 getEnterResId()1096 public int getEnterResId() { 1097 return mEnterResId; 1098 } 1099 getExitResId()1100 public int getExitResId() { 1101 return mExitResId; 1102 } 1103 getBackgroundColor()1104 public @ColorInt int getBackgroundColor() { 1105 return mBackgroundColor; 1106 } 1107 getOverrideTaskTransition()1108 public boolean getOverrideTaskTransition() { 1109 return mOverrideTaskTransition; 1110 } 1111 getPackageName()1112 public String getPackageName() { 1113 return mPackageName; 1114 } 1115 getTransitionBounds()1116 public Rect getTransitionBounds() { 1117 return mTransitionBounds; 1118 } 1119 getThumbnail()1120 public HardwareBuffer getThumbnail() { 1121 return mThumbnail; 1122 } 1123 getAnimations()1124 public int getAnimations() { 1125 return mAnimations; 1126 } 1127 1128 /** Return customized activity transition if existed. */ getCustomActivityTransition(boolean open)1129 public CustomActivityTransition getCustomActivityTransition(boolean open) { 1130 return open ? mCustomActivityOpenTransition : mCustomActivityCloseTransition; 1131 } 1132 1133 @Override writeToParcel(Parcel dest, int flags)1134 public void writeToParcel(Parcel dest, int flags) { 1135 dest.writeInt(mType); 1136 dest.writeInt(mEnterResId); 1137 dest.writeInt(mExitResId); 1138 dest.writeInt(mBackgroundColor); 1139 dest.writeBoolean(mOverrideTaskTransition); 1140 dest.writeString(mPackageName); 1141 mTransitionBounds.writeToParcel(dest, flags); 1142 dest.writeTypedObject(mThumbnail, flags); 1143 dest.writeInt(mAnimations); 1144 dest.writeTypedObject(mCustomActivityOpenTransition, flags); 1145 dest.writeTypedObject(mCustomActivityCloseTransition, flags); 1146 } 1147 1148 @NonNull 1149 public static final Creator<AnimationOptions> CREATOR = 1150 new Creator<AnimationOptions>() { 1151 @Override 1152 public AnimationOptions createFromParcel(Parcel in) { 1153 return new AnimationOptions(in); 1154 } 1155 1156 @Override 1157 public AnimationOptions[] newArray(int size) { 1158 return new AnimationOptions[size]; 1159 } 1160 }; 1161 1162 /** @hide */ 1163 @Override describeContents()1164 public int describeContents() { 1165 return 0; 1166 } 1167 1168 @NonNull typeToString(int mode)1169 private static String typeToString(int mode) { 1170 switch(mode) { 1171 case ANIM_CUSTOM: return "ANIM_CUSTOM"; 1172 case ANIM_CLIP_REVEAL: return "ANIM_CLIP_REVEAL"; 1173 case ANIM_SCALE_UP: return "ANIM_SCALE_UP"; 1174 case ANIM_THUMBNAIL_SCALE_UP: return "ANIM_THUMBNAIL_SCALE_UP"; 1175 case ANIM_THUMBNAIL_SCALE_DOWN: return "ANIM_THUMBNAIL_SCALE_DOWN"; 1176 case ANIM_OPEN_CROSS_PROFILE_APPS: return "ANIM_OPEN_CROSS_PROFILE_APPS"; 1177 default: return "<unknown:" + mode + ">"; 1178 } 1179 } 1180 1181 @Override toString()1182 public String toString() { 1183 return "{ AnimationOptions type= " + typeToString(mType) + " package=" + mPackageName 1184 + " override=" + mOverrideTaskTransition + " b=" + mTransitionBounds + "}"; 1185 } 1186 1187 /** Customized activity transition. */ 1188 public static class CustomActivityTransition implements Parcelable { 1189 private int mCustomEnterResId; 1190 private int mCustomExitResId; 1191 private int mCustomBackgroundColor; 1192 1193 /** Returns customize activity animation enter resource id */ getCustomEnterResId()1194 public int getCustomEnterResId() { 1195 return mCustomEnterResId; 1196 } 1197 1198 /** Returns customize activity animation exit resource id */ getCustomExitResId()1199 public int getCustomExitResId() { 1200 return mCustomExitResId; 1201 } 1202 1203 /** Returns customize activity animation background color */ getCustomBackgroundColor()1204 public int getCustomBackgroundColor() { 1205 return mCustomBackgroundColor; 1206 } CustomActivityTransition()1207 CustomActivityTransition() {} 1208 CustomActivityTransition(Parcel in)1209 CustomActivityTransition(Parcel in) { 1210 mCustomEnterResId = in.readInt(); 1211 mCustomExitResId = in.readInt(); 1212 mCustomBackgroundColor = in.readInt(); 1213 } 1214 1215 /** Add customized activity animation attributes */ addCustomActivityTransition( int enterResId, int exitResId, int backgroundColor)1216 public void addCustomActivityTransition( 1217 int enterResId, int exitResId, int backgroundColor) { 1218 mCustomEnterResId = enterResId; 1219 mCustomExitResId = exitResId; 1220 mCustomBackgroundColor = backgroundColor; 1221 } 1222 1223 @Override describeContents()1224 public int describeContents() { 1225 return 0; 1226 } 1227 1228 @Override writeToParcel(Parcel dest, int flags)1229 public void writeToParcel(Parcel dest, int flags) { 1230 dest.writeInt(mCustomEnterResId); 1231 dest.writeInt(mCustomExitResId); 1232 dest.writeInt(mCustomBackgroundColor); 1233 } 1234 1235 @NonNull 1236 public static final Creator<CustomActivityTransition> CREATOR = 1237 new Creator<CustomActivityTransition>() { 1238 @Override 1239 public CustomActivityTransition createFromParcel(Parcel in) { 1240 return new CustomActivityTransition(in); 1241 } 1242 1243 @Override 1244 public CustomActivityTransition[] newArray(int size) { 1245 return new CustomActivityTransition[size]; 1246 } 1247 }; 1248 } 1249 } 1250 1251 /** 1252 * An animation root in a transition. There is one of these for each display that contains 1253 * participants. It will be placed, in z-order, right above the top-most participant and at the 1254 * same position in the hierarchy. As a result, if all participants are animating within a 1255 * part of the screen, the root-leash will only be in that part of the screen. In these cases, 1256 * it's relative position (from the screen) is stored in {@link Root#getOffset}. 1257 */ 1258 public static final class Root implements Parcelable { 1259 private final int mDisplayId; 1260 private final SurfaceControl mLeash; 1261 private final Point mOffset = new Point(); 1262 Root(int displayId, @NonNull SurfaceControl leash, int offsetLeft, int offsetTop)1263 public Root(int displayId, @NonNull SurfaceControl leash, int offsetLeft, int offsetTop) { 1264 mDisplayId = displayId; 1265 mLeash = leash; 1266 mOffset.set(offsetLeft, offsetTop); 1267 } 1268 Root(Parcel in)1269 private Root(Parcel in) { 1270 mDisplayId = in.readInt(); 1271 mLeash = new SurfaceControl(); 1272 mLeash.readFromParcel(in); 1273 mLeash.setUnreleasedWarningCallSite("TransitionInfo.Root"); 1274 mOffset.readFromParcel(in); 1275 } 1276 localRemoteCopy()1277 private Root localRemoteCopy() { 1278 return new Root(mDisplayId, new SurfaceControl(mLeash, "localRemote"), 1279 mOffset.x, mOffset.y); 1280 } 1281 1282 /** @return the id of the display this root is on. */ getDisplayId()1283 public int getDisplayId() { 1284 return mDisplayId; 1285 } 1286 1287 /** @return the root's leash. Surfaces should be parented to this while animating. */ 1288 @NonNull getLeash()1289 public SurfaceControl getLeash() { 1290 return mLeash; 1291 } 1292 1293 /** @return the offset (relative to its screen) of the root leash. */ 1294 @NonNull getOffset()1295 public Point getOffset() { 1296 return mOffset; 1297 } 1298 1299 /** @hide */ 1300 @Override writeToParcel(@onNull Parcel dest, int flags)1301 public void writeToParcel(@NonNull Parcel dest, int flags) { 1302 dest.writeInt(mDisplayId); 1303 mLeash.writeToParcel(dest, flags); 1304 mOffset.writeToParcel(dest, flags); 1305 } 1306 1307 @NonNull 1308 public static final Creator<Root> CREATOR = 1309 new Creator<Root>() { 1310 @Override 1311 public Root createFromParcel(Parcel in) { 1312 return new Root(in); 1313 } 1314 1315 @Override 1316 public Root[] newArray(int size) { 1317 return new Root[size]; 1318 } 1319 }; 1320 1321 /** @hide */ 1322 @Override describeContents()1323 public int describeContents() { 1324 return 0; 1325 } 1326 1327 @Override toString()1328 public String toString() { 1329 return mDisplayId + "@" + mOffset + ":" + mLeash; 1330 } 1331 } 1332 } 1333