1 /* 2 * Copyright (C) 2011 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 com.android.server.wm; 18 19 import static android.view.WindowManager.LayoutParams; 20 import static android.view.WindowManager.TRANSIT_CHANGE; 21 import static android.view.WindowManager.TRANSIT_CLOSE; 22 import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED; 23 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; 24 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION; 25 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT; 26 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; 27 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; 28 import static android.view.WindowManager.TRANSIT_FLAG_OPEN_BEHIND; 29 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; 30 import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE; 31 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; 32 import static android.view.WindowManager.TRANSIT_NONE; 33 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE; 34 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN; 35 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_RELAUNCH; 36 import static android.view.WindowManager.TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE; 37 import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_CLOSE; 38 import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN; 39 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; 40 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; 41 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE; 42 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM; 43 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE; 44 import static android.view.WindowManager.TRANSIT_OLD_NONE; 45 import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE; 46 import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE; 47 import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE; 48 import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE; 49 import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN; 50 import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN; 51 import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN_BEHIND; 52 import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_BACK; 53 import static android.view.WindowManager.TRANSIT_OLD_TASK_TO_FRONT; 54 import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE; 55 import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN; 56 import static android.view.WindowManager.TRANSIT_OLD_UNSET; 57 import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_CLOSE; 58 import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_CLOSE; 59 import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_OPEN; 60 import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_OPEN; 61 import static android.view.WindowManager.TRANSIT_OPEN; 62 import static android.view.WindowManager.TRANSIT_RELAUNCH; 63 import static android.view.WindowManager.TRANSIT_TO_BACK; 64 import static android.view.WindowManager.TRANSIT_TO_FRONT; 65 66 import static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation; 67 import static com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation; 68 import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation; 69 import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation; 70 import static com.android.internal.R.styleable.WindowAnimation_dreamActivityCloseExitAnimation; 71 import static com.android.internal.R.styleable.WindowAnimation_dreamActivityOpenEnterAnimation; 72 import static com.android.internal.R.styleable.WindowAnimation_dreamActivityOpenExitAnimation; 73 import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindSourceAnimation; 74 import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindTargetAnimation; 75 import static com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation; 76 import static com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation; 77 import static com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation; 78 import static com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation; 79 import static com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation; 80 import static com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation; 81 import static com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation; 82 import static com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation; 83 import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation; 84 import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation; 85 import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation; 86 import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation; 87 import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation; 88 import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation; 89 import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation; 90 import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation; 91 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ANIM; 92 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; 93 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM; 94 import static com.android.server.wm.AppTransitionProto.APP_TRANSITION_STATE; 95 import static com.android.server.wm.AppTransitionProto.LAST_USED_APP_TRANSITION; 96 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 97 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 98 import static com.android.server.wm.WindowManagerInternal.AppTransitionListener; 99 import static com.android.server.wm.WindowManagerInternal.KeyguardExitAnimationStartListener; 100 import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_AFTER_ANIM; 101 import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_NONE; 102 103 import android.annotation.ColorInt; 104 import android.annotation.NonNull; 105 import android.annotation.Nullable; 106 import android.content.ComponentName; 107 import android.content.Context; 108 import android.content.res.Configuration; 109 import android.content.res.TypedArray; 110 import android.graphics.Rect; 111 import android.graphics.drawable.Drawable; 112 import android.hardware.HardwareBuffer; 113 import android.os.Binder; 114 import android.os.Debug; 115 import android.os.Handler; 116 import android.os.IBinder; 117 import android.os.IRemoteCallback; 118 import android.os.RemoteException; 119 import android.os.SystemClock; 120 import android.os.SystemProperties; 121 import android.os.UserHandle; 122 import android.util.Pair; 123 import android.util.Slog; 124 import android.util.SparseArray; 125 import android.util.proto.ProtoOutputStream; 126 import android.view.AppTransitionAnimationSpec; 127 import android.view.IAppTransitionAnimationSpecsFuture; 128 import android.view.RemoteAnimationAdapter; 129 import android.view.WindowManager.TransitionFlags; 130 import android.view.WindowManager.TransitionOldType; 131 import android.view.WindowManager.TransitionType; 132 import android.view.animation.AlphaAnimation; 133 import android.view.animation.Animation; 134 import android.view.animation.AnimationSet; 135 import android.view.animation.ScaleAnimation; 136 import android.view.animation.TranslateAnimation; 137 138 import com.android.internal.annotations.VisibleForTesting; 139 import com.android.internal.policy.TransitionAnimation; 140 import com.android.internal.protolog.ProtoLogImpl; 141 import com.android.internal.protolog.common.ProtoLog; 142 import com.android.internal.util.DumpUtils.Dump; 143 import com.android.internal.util.function.pooled.PooledLambda; 144 import com.android.internal.util.function.pooled.PooledPredicate; 145 146 import java.io.PrintWriter; 147 import java.util.ArrayList; 148 import java.util.concurrent.ExecutorService; 149 import java.util.concurrent.Executors; 150 151 // State management of app transitions. When we are preparing for a 152 // transition, mNextAppTransition will be the kind of transition to 153 // perform or TRANSIT_NONE if we are not waiting. If we are waiting, 154 // mOpeningApps and mClosingApps are the lists of tokens that will be 155 // made visible or hidden at the next transition. 156 public class AppTransition implements Dump { 157 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppTransition" : TAG_WM; 158 159 static final int DEFAULT_APP_TRANSITION_DURATION = 336; 160 161 /** 162 * Maximum duration for the clip reveal animation. This is used when there is a lot of movement 163 * involved, to make it more understandable. 164 */ 165 private static final long APP_TRANSITION_TIMEOUT_MS = 5000; 166 static final int MAX_APP_TRANSITION_DURATION = 3 * 1000; // 3 secs. 167 168 private final Context mContext; 169 private final WindowManagerService mService; 170 private final DisplayContent mDisplayContent; 171 172 @VisibleForTesting 173 final TransitionAnimation mTransitionAnimation; 174 175 private @TransitionFlags int mNextAppTransitionFlags = 0; 176 private final ArrayList<Integer> mNextAppTransitionRequests = new ArrayList<>(); 177 private @TransitionOldType int mLastUsedAppTransition = TRANSIT_OLD_UNSET; 178 private String mLastOpeningApp; 179 private String mLastClosingApp; 180 private String mLastChangingApp; 181 182 private static final int NEXT_TRANSIT_TYPE_NONE = 0; 183 private static final int NEXT_TRANSIT_TYPE_CUSTOM = 1; 184 private static final int NEXT_TRANSIT_TYPE_SCALE_UP = 2; 185 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP = 3; 186 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN = 4; 187 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP = 5; 188 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN = 6; 189 private static final int NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE = 7; 190 private static final int NEXT_TRANSIT_TYPE_CLIP_REVEAL = 8; 191 192 /** 193 * Refers to the transition to activity started by using {@link 194 * android.content.pm.crossprofile.CrossProfileApps#startMainActivity(ComponentName, UserHandle) 195 * }. 196 */ 197 private static final int NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS = 9; 198 private static final int NEXT_TRANSIT_TYPE_REMOTE = 10; 199 200 private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE; 201 private boolean mNextAppTransitionOverrideRequested; 202 203 private String mNextAppTransitionPackage; 204 // Used for thumbnail transitions. True if we're scaling up, false if scaling down 205 private boolean mNextAppTransitionScaleUp; 206 private IRemoteCallback mNextAppTransitionCallback; 207 private IRemoteCallback mNextAppTransitionFutureCallback; 208 private IRemoteCallback mAnimationFinishedCallback; 209 private int mNextAppTransitionEnter; 210 private int mNextAppTransitionExit; 211 private @ColorInt int mNextAppTransitionBackgroundColor; 212 private int mNextAppTransitionInPlace; 213 private boolean mNextAppTransitionIsSync; 214 215 // Keyed by WindowContainer hashCode. 216 private final SparseArray<AppTransitionAnimationSpec> mNextAppTransitionAnimationsSpecs 217 = new SparseArray<>(); 218 private IAppTransitionAnimationSpecsFuture mNextAppTransitionAnimationsSpecsFuture; 219 private boolean mNextAppTransitionAnimationsSpecsPending; 220 private AppTransitionAnimationSpec mDefaultNextAppTransitionAnimationSpec; 221 222 private final Rect mTmpRect = new Rect(); 223 224 private final static int APP_STATE_IDLE = 0; 225 private final static int APP_STATE_READY = 1; 226 private final static int APP_STATE_RUNNING = 2; 227 private final static int APP_STATE_TIMEOUT = 3; 228 private int mAppTransitionState = APP_STATE_IDLE; 229 230 private final ArrayList<AppTransitionListener> mListeners = new ArrayList<>(); 231 private KeyguardExitAnimationStartListener mKeyguardExitAnimationStartListener; 232 private final ExecutorService mDefaultExecutor = Executors.newSingleThreadExecutor(); 233 234 private final boolean mGridLayoutRecentsEnabled; 235 236 private final int mDefaultWindowAnimationStyleResId; 237 private boolean mOverrideTaskTransition; 238 239 private RemoteAnimationController mRemoteAnimationController; 240 241 final Handler mHandler; 242 final Runnable mHandleAppTransitionTimeoutRunnable = () -> handleAppTransitionTimeout(); 243 AppTransition(Context context, WindowManagerService service, DisplayContent displayContent)244 AppTransition(Context context, WindowManagerService service, DisplayContent displayContent) { 245 mContext = context; 246 mService = service; 247 mHandler = new Handler(service.mH.getLooper()); 248 mDisplayContent = displayContent; 249 mTransitionAnimation = new TransitionAnimation( 250 context, ProtoLogImpl.isEnabled(WM_DEBUG_ANIM), TAG); 251 252 mGridLayoutRecentsEnabled = SystemProperties.getBoolean("ro.recents.grid", false); 253 254 final TypedArray windowStyle = mContext.getTheme().obtainStyledAttributes( 255 com.android.internal.R.styleable.Window); 256 mDefaultWindowAnimationStyleResId = windowStyle.getResourceId( 257 com.android.internal.R.styleable.Window_windowAnimationStyle, 0); 258 windowStyle.recycle(); 259 } 260 isTransitionSet()261 boolean isTransitionSet() { 262 return !mNextAppTransitionRequests.isEmpty(); 263 } 264 isUnoccluding()265 boolean isUnoccluding() { 266 return mNextAppTransitionRequests.contains(TRANSIT_KEYGUARD_UNOCCLUDE); 267 } 268 transferFrom(AppTransition other)269 boolean transferFrom(AppTransition other) { 270 mNextAppTransitionRequests.addAll(other.mNextAppTransitionRequests); 271 return prepare(); 272 } 273 setLastAppTransition(@ransitionOldType int transit, ActivityRecord openingApp, ActivityRecord closingApp, ActivityRecord changingApp)274 void setLastAppTransition(@TransitionOldType int transit, ActivityRecord openingApp, 275 ActivityRecord closingApp, ActivityRecord changingApp) { 276 mLastUsedAppTransition = transit; 277 mLastOpeningApp = "" + openingApp; 278 mLastClosingApp = "" + closingApp; 279 mLastChangingApp = "" + changingApp; 280 } 281 isReady()282 boolean isReady() { 283 return mAppTransitionState == APP_STATE_READY 284 || mAppTransitionState == APP_STATE_TIMEOUT; 285 } 286 setReady()287 void setReady() { 288 setAppTransitionState(APP_STATE_READY); 289 fetchAppTransitionSpecsFromFuture(); 290 } 291 abort()292 void abort() { 293 if (mRemoteAnimationController != null) { 294 mRemoteAnimationController.cancelAnimation("aborted"); 295 } 296 clear(); 297 } 298 isRunning()299 boolean isRunning() { 300 return mAppTransitionState == APP_STATE_RUNNING; 301 } 302 setIdle()303 void setIdle() { 304 setAppTransitionState(APP_STATE_IDLE); 305 } 306 isIdle()307 boolean isIdle() { 308 return mAppTransitionState == APP_STATE_IDLE; 309 } 310 isTimeout()311 boolean isTimeout() { 312 return mAppTransitionState == APP_STATE_TIMEOUT; 313 } 314 setTimeout()315 void setTimeout() { 316 setAppTransitionState(APP_STATE_TIMEOUT); 317 } 318 319 /** 320 * Gets the animation overridden by app via {@link #overridePendingAppTransition}. 321 */ 322 @Nullable getNextAppRequestedAnimation(boolean enter)323 Animation getNextAppRequestedAnimation(boolean enter) { 324 final Animation a = mTransitionAnimation.loadAppTransitionAnimation( 325 mNextAppTransitionPackage, 326 enter ? mNextAppTransitionEnter : mNextAppTransitionExit); 327 if (mNextAppTransitionBackgroundColor != 0 && a != null) { 328 a.setBackdropColor(mNextAppTransitionBackgroundColor); 329 } 330 return a; 331 } 332 333 /** 334 * Gets the animation background color overridden by app via 335 * {@link #overridePendingAppTransition}. 336 */ getNextAppTransitionBackgroundColor()337 @ColorInt int getNextAppTransitionBackgroundColor() { 338 return mNextAppTransitionBackgroundColor; 339 } 340 341 @VisibleForTesting isNextAppTransitionOverrideRequested()342 boolean isNextAppTransitionOverrideRequested() { 343 return mNextAppTransitionOverrideRequested; 344 } 345 getAppTransitionThumbnailHeader(WindowContainer container)346 HardwareBuffer getAppTransitionThumbnailHeader(WindowContainer container) { 347 AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get( 348 container.hashCode()); 349 if (spec == null) { 350 spec = mDefaultNextAppTransitionAnimationSpec; 351 } 352 return spec != null ? spec.buffer : null; 353 } 354 355 /** Returns whether the next thumbnail transition is aspect scaled up. */ isNextThumbnailTransitionAspectScaled()356 boolean isNextThumbnailTransitionAspectScaled() { 357 return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP || 358 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN; 359 } 360 361 /** Returns whether the next thumbnail transition is scaling up. */ isNextThumbnailTransitionScaleUp()362 boolean isNextThumbnailTransitionScaleUp() { 363 return mNextAppTransitionScaleUp; 364 } 365 isNextAppTransitionThumbnailUp()366 boolean isNextAppTransitionThumbnailUp() { 367 return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP || 368 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP; 369 } 370 isNextAppTransitionThumbnailDown()371 boolean isNextAppTransitionThumbnailDown() { 372 return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN || 373 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN; 374 } 375 isNextAppTransitionOpenCrossProfileApps()376 boolean isNextAppTransitionOpenCrossProfileApps() { 377 return mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS; 378 } 379 380 /** 381 * @return true if and only if we are currently fetching app transition specs from the future 382 * passed into {@link #overridePendingAppTransitionMultiThumbFuture} 383 */ isFetchingAppTransitionsSpecs()384 boolean isFetchingAppTransitionsSpecs() { 385 return mNextAppTransitionAnimationsSpecsPending; 386 } 387 prepare()388 private boolean prepare() { 389 if (!isRunning()) { 390 setAppTransitionState(APP_STATE_IDLE); 391 notifyAppTransitionPendingLocked(); 392 return true; 393 } 394 return false; 395 } 396 397 /** 398 * @return bit-map of WindowManagerPolicy#FINISH_LAYOUT_REDO_* to indicate whether another 399 * layout pass needs to be done 400 */ goodToGo(@ransitionOldType int transit, ActivityRecord topOpeningApp)401 int goodToGo(@TransitionOldType int transit, ActivityRecord topOpeningApp) { 402 mNextAppTransitionFlags = 0; 403 mNextAppTransitionRequests.clear(); 404 setAppTransitionState(APP_STATE_RUNNING); 405 final WindowContainer wc = 406 topOpeningApp != null ? topOpeningApp.getAnimatingContainer() : null; 407 final AnimationAdapter topOpeningAnim = wc != null ? wc.getAnimation() : null; 408 409 int redoLayout = notifyAppTransitionStartingLocked( 410 AppTransition.isKeyguardGoingAwayTransitOld(transit), 411 AppTransition.isKeyguardOccludeTransitOld(transit), 412 topOpeningAnim != null ? topOpeningAnim.getDurationHint() : 0, 413 topOpeningAnim != null 414 ? topOpeningAnim.getStatusBarTransitionsStartTime() 415 : SystemClock.uptimeMillis(), 416 AnimationAdapter.STATUS_BAR_TRANSITION_DURATION); 417 418 if (mRemoteAnimationController != null) { 419 mRemoteAnimationController.goodToGo(transit); 420 } else if ((isTaskOpenTransitOld(transit) || transit == TRANSIT_OLD_WALLPAPER_CLOSE) 421 && topOpeningAnim != null) { 422 if (mDisplayContent.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition() 423 && mService.getRecentsAnimationController() == null) { 424 final NavBarFadeAnimationController controller = 425 new NavBarFadeAnimationController(mDisplayContent); 426 // For remote animation case, the nav bar fades out and in is controlled by the 427 // remote side. For non-remote animation case, we play the fade out/in animation 428 // here. We play the nav bar fade-out animation when the app transition animation 429 // starts and play the fade-in animation sequentially once the fade-out is finished. 430 controller.fadeOutAndInSequentially(topOpeningAnim.getDurationHint(), 431 null /* fadeOutParent */, topOpeningApp.getSurfaceControl()); 432 } 433 } 434 return redoLayout; 435 } 436 clear()437 void clear() { 438 clear(true /* clearAppOverride */); 439 } 440 clear(boolean clearAppOverride)441 private void clear(boolean clearAppOverride) { 442 mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE; 443 mNextAppTransitionOverrideRequested = false; 444 mNextAppTransitionAnimationsSpecs.clear(); 445 mRemoteAnimationController = null; 446 mNextAppTransitionAnimationsSpecsFuture = null; 447 mDefaultNextAppTransitionAnimationSpec = null; 448 mAnimationFinishedCallback = null; 449 mOverrideTaskTransition = false; 450 mNextAppTransitionIsSync = false; 451 if (clearAppOverride) { 452 mNextAppTransitionPackage = null; 453 mNextAppTransitionEnter = 0; 454 mNextAppTransitionExit = 0; 455 mNextAppTransitionBackgroundColor = 0; 456 } 457 } 458 freeze()459 void freeze() { 460 final boolean keyguardGoingAway = mNextAppTransitionRequests.contains( 461 TRANSIT_KEYGUARD_GOING_AWAY); 462 463 // The RemoteAnimationControl didn't register AppTransitionListener and 464 // only initialized the finish and timeout callback when goodToGo(). 465 // So cancel the remote animation here to prevent the animation can't do 466 // finish after transition state cleared. 467 if (mRemoteAnimationController != null) { 468 mRemoteAnimationController.cancelAnimation("freeze"); 469 } 470 mNextAppTransitionRequests.clear(); 471 clear(); 472 setReady(); 473 notifyAppTransitionCancelledLocked(keyguardGoingAway); 474 } 475 setAppTransitionState(int state)476 private void setAppTransitionState(int state) { 477 mAppTransitionState = state; 478 updateBooster(); 479 } 480 481 /** 482 * Updates whether we currently boost wm locked sections and the animation thread. We want to 483 * boost the priorities to a more important value whenever an app transition is going to happen 484 * soon or an app transition is running. 485 */ updateBooster()486 void updateBooster() { 487 WindowManagerService.sThreadPriorityBooster.setAppTransitionRunning(needsBoosting()); 488 } 489 needsBoosting()490 private boolean needsBoosting() { 491 final boolean recentsAnimRunning = mService.getRecentsAnimationController() != null; 492 return !mNextAppTransitionRequests.isEmpty() 493 || mAppTransitionState == APP_STATE_READY 494 || mAppTransitionState == APP_STATE_RUNNING 495 || recentsAnimRunning; 496 } 497 registerListenerLocked(AppTransitionListener listener)498 void registerListenerLocked(AppTransitionListener listener) { 499 mListeners.add(listener); 500 } 501 unregisterListener(AppTransitionListener listener)502 void unregisterListener(AppTransitionListener listener) { 503 mListeners.remove(listener); 504 } 505 registerKeygaurdExitAnimationStartListener( KeyguardExitAnimationStartListener listener)506 void registerKeygaurdExitAnimationStartListener( 507 KeyguardExitAnimationStartListener listener) { 508 mKeyguardExitAnimationStartListener = listener; 509 } 510 notifyAppTransitionFinishedLocked(IBinder token)511 public void notifyAppTransitionFinishedLocked(IBinder token) { 512 for (int i = 0; i < mListeners.size(); i++) { 513 mListeners.get(i).onAppTransitionFinishedLocked(token); 514 } 515 } 516 notifyAppTransitionPendingLocked()517 private void notifyAppTransitionPendingLocked() { 518 for (int i = 0; i < mListeners.size(); i++) { 519 mListeners.get(i).onAppTransitionPendingLocked(); 520 } 521 } 522 notifyAppTransitionCancelledLocked(boolean keyguardGoingAway)523 private void notifyAppTransitionCancelledLocked(boolean keyguardGoingAway) { 524 for (int i = 0; i < mListeners.size(); i++) { 525 mListeners.get(i).onAppTransitionCancelledLocked(keyguardGoingAway); 526 } 527 } 528 notifyAppTransitionTimeoutLocked()529 private void notifyAppTransitionTimeoutLocked() { 530 for (int i = 0; i < mListeners.size(); i++) { 531 mListeners.get(i).onAppTransitionTimeoutLocked(); 532 } 533 } 534 notifyAppTransitionStartingLocked(boolean keyguardGoingAway, boolean keyguardOcclude, long duration, long statusBarAnimationStartTime, long statusBarAnimationDuration)535 private int notifyAppTransitionStartingLocked(boolean keyguardGoingAway, 536 boolean keyguardOcclude, long duration, long statusBarAnimationStartTime, 537 long statusBarAnimationDuration) { 538 int redoLayout = 0; 539 for (int i = 0; i < mListeners.size(); i++) { 540 redoLayout |= mListeners.get(i).onAppTransitionStartingLocked(keyguardGoingAway, 541 keyguardOcclude, duration, statusBarAnimationStartTime, 542 statusBarAnimationDuration); 543 } 544 return redoLayout; 545 } 546 547 @VisibleForTesting getDefaultWindowAnimationStyleResId()548 int getDefaultWindowAnimationStyleResId() { 549 return mDefaultWindowAnimationStyleResId; 550 } 551 552 /** Returns window animation style ID from {@link LayoutParams} or from system in some cases */ 553 @VisibleForTesting getAnimationStyleResId(@onNull LayoutParams lp)554 int getAnimationStyleResId(@NonNull LayoutParams lp) { 555 return mTransitionAnimation.getAnimationStyleResId(lp); 556 } 557 558 @VisibleForTesting 559 @Nullable loadAnimationSafely(Context context, int resId)560 Animation loadAnimationSafely(Context context, int resId) { 561 return TransitionAnimation.loadAnimationSafely(context, resId, TAG); 562 } 563 mapOpenCloseTransitTypes(int transit, boolean enter)564 private static int mapOpenCloseTransitTypes(int transit, boolean enter) { 565 int animAttr = 0; 566 switch (transit) { 567 case TRANSIT_OLD_ACTIVITY_OPEN: 568 case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN: 569 animAttr = enter 570 ? WindowAnimation_activityOpenEnterAnimation 571 : WindowAnimation_activityOpenExitAnimation; 572 break; 573 case TRANSIT_OLD_ACTIVITY_CLOSE: 574 case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE: 575 animAttr = enter 576 ? WindowAnimation_activityCloseEnterAnimation 577 : WindowAnimation_activityCloseExitAnimation; 578 break; 579 case TRANSIT_OLD_TASK_OPEN: 580 animAttr = enter 581 ? WindowAnimation_taskOpenEnterAnimation 582 : WindowAnimation_taskOpenExitAnimation; 583 break; 584 case TRANSIT_OLD_TASK_CLOSE: 585 animAttr = enter 586 ? WindowAnimation_taskCloseEnterAnimation 587 : WindowAnimation_taskCloseExitAnimation; 588 break; 589 case TRANSIT_OLD_TASK_TO_FRONT: 590 animAttr = enter 591 ? WindowAnimation_taskToFrontEnterAnimation 592 : WindowAnimation_taskToFrontExitAnimation; 593 break; 594 case TRANSIT_OLD_TASK_TO_BACK: 595 animAttr = enter 596 ? WindowAnimation_taskToBackEnterAnimation 597 : WindowAnimation_taskToBackExitAnimation; 598 break; 599 case TRANSIT_OLD_WALLPAPER_OPEN: 600 animAttr = enter 601 ? WindowAnimation_wallpaperOpenEnterAnimation 602 : WindowAnimation_wallpaperOpenExitAnimation; 603 break; 604 case TRANSIT_OLD_WALLPAPER_CLOSE: 605 animAttr = enter 606 ? WindowAnimation_wallpaperCloseEnterAnimation 607 : WindowAnimation_wallpaperCloseExitAnimation; 608 break; 609 case TRANSIT_OLD_WALLPAPER_INTRA_OPEN: 610 animAttr = enter 611 ? WindowAnimation_wallpaperIntraOpenEnterAnimation 612 : WindowAnimation_wallpaperIntraOpenExitAnimation; 613 break; 614 case TRANSIT_OLD_WALLPAPER_INTRA_CLOSE: 615 animAttr = enter 616 ? WindowAnimation_wallpaperIntraCloseEnterAnimation 617 : WindowAnimation_wallpaperIntraCloseExitAnimation; 618 break; 619 case TRANSIT_OLD_TASK_OPEN_BEHIND: 620 animAttr = enter 621 ? WindowAnimation_launchTaskBehindSourceAnimation 622 : WindowAnimation_launchTaskBehindTargetAnimation; 623 break; 624 // TODO(b/189386466): Use activity transition as the fallback. Investigate if we 625 // need new TaskFragment transition. 626 case TRANSIT_OLD_TASK_FRAGMENT_OPEN: 627 animAttr = enter 628 ? WindowAnimation_activityOpenEnterAnimation 629 : WindowAnimation_activityOpenExitAnimation; 630 break; 631 // TODO(b/189386466): Use activity transition as the fallback. Investigate if we 632 // need new TaskFragment transition. 633 case TRANSIT_OLD_TASK_FRAGMENT_CLOSE: 634 animAttr = enter 635 ? WindowAnimation_activityCloseEnterAnimation 636 : WindowAnimation_activityCloseExitAnimation; 637 break; 638 case TRANSIT_OLD_DREAM_ACTIVITY_OPEN: 639 animAttr = enter 640 ? WindowAnimation_dreamActivityOpenEnterAnimation 641 : WindowAnimation_dreamActivityOpenExitAnimation; 642 break; 643 case TRANSIT_OLD_DREAM_ACTIVITY_CLOSE: 644 animAttr = enter 645 ? 0 646 : WindowAnimation_dreamActivityCloseExitAnimation; 647 break; 648 } 649 650 return animAttr; 651 } 652 653 @Nullable loadAnimationAttr(LayoutParams lp, int animAttr, int transit)654 Animation loadAnimationAttr(LayoutParams lp, int animAttr, int transit) { 655 return mTransitionAnimation.loadAnimationAttr(lp, animAttr, transit); 656 } 657 getDefaultNextAppTransitionStartRect(Rect rect)658 private void getDefaultNextAppTransitionStartRect(Rect rect) { 659 if (mDefaultNextAppTransitionAnimationSpec == null || 660 mDefaultNextAppTransitionAnimationSpec.rect == null) { 661 Slog.e(TAG, "Starting rect for app requested, but none available", new Throwable()); 662 rect.setEmpty(); 663 } else { 664 rect.set(mDefaultNextAppTransitionAnimationSpec.rect); 665 } 666 } 667 putDefaultNextAppTransitionCoordinates(int left, int top, int width, int height, HardwareBuffer buffer)668 private void putDefaultNextAppTransitionCoordinates(int left, int top, int width, int height, 669 HardwareBuffer buffer) { 670 mDefaultNextAppTransitionAnimationSpec = new AppTransitionAnimationSpec(-1 /* taskId */, 671 buffer, new Rect(left, top, left + width, top + height)); 672 } 673 674 /** 675 * Creates an overlay with a background color and a thumbnail for the cross profile apps 676 * animation. 677 */ createCrossProfileAppsThumbnail( Drawable thumbnailDrawable, Rect frame)678 HardwareBuffer createCrossProfileAppsThumbnail( 679 Drawable thumbnailDrawable, Rect frame) { 680 return mTransitionAnimation.createCrossProfileAppsThumbnail(thumbnailDrawable, frame); 681 } 682 createCrossProfileAppsThumbnailAnimationLocked(Rect appRect)683 Animation createCrossProfileAppsThumbnailAnimationLocked(Rect appRect) { 684 return mTransitionAnimation.createCrossProfileAppsThumbnailAnimationLocked(appRect); 685 } 686 687 /** 688 * This animation runs for the thumbnail that gets cross faded with the enter/exit activity 689 * when a thumbnail is specified with the pending animation override. 690 */ createThumbnailAspectScaleAnimationLocked(Rect appRect, @Nullable Rect contentInsets, HardwareBuffer thumbnailHeader, WindowContainer container, int orientation)691 Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, @Nullable Rect contentInsets, 692 HardwareBuffer thumbnailHeader, WindowContainer container, int orientation) { 693 AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get( 694 container.hashCode()); 695 return mTransitionAnimation.createThumbnailAspectScaleAnimationLocked(appRect, 696 contentInsets, thumbnailHeader, orientation, spec != null ? spec.rect : null, 697 mDefaultNextAppTransitionAnimationSpec != null 698 ? mDefaultNextAppTransitionAnimationSpec.rect : null, 699 mNextAppTransitionScaleUp); 700 } 701 createAspectScaledThumbnailFreeformAnimationLocked(Rect sourceFrame, Rect destFrame, @Nullable Rect surfaceInsets, boolean enter)702 private AnimationSet createAspectScaledThumbnailFreeformAnimationLocked(Rect sourceFrame, 703 Rect destFrame, @Nullable Rect surfaceInsets, boolean enter) { 704 final float sourceWidth = sourceFrame.width(); 705 final float sourceHeight = sourceFrame.height(); 706 final float destWidth = destFrame.width(); 707 final float destHeight = destFrame.height(); 708 final float scaleH = enter ? sourceWidth / destWidth : destWidth / sourceWidth; 709 final float scaleV = enter ? sourceHeight / destHeight : destHeight / sourceHeight; 710 AnimationSet set = new AnimationSet(true); 711 final int surfaceInsetsH = surfaceInsets == null 712 ? 0 : surfaceInsets.left + surfaceInsets.right; 713 final int surfaceInsetsV = surfaceInsets == null 714 ? 0 : surfaceInsets.top + surfaceInsets.bottom; 715 // We want the scaling to happen from the center of the surface. In order to achieve that, 716 // we need to account for surface insets that will be used to enlarge the surface. 717 final float scaleHCenter = ((enter ? destWidth : sourceWidth) + surfaceInsetsH) / 2; 718 final float scaleVCenter = ((enter ? destHeight : sourceHeight) + surfaceInsetsV) / 2; 719 final ScaleAnimation scale = enter ? 720 new ScaleAnimation(scaleH, 1, scaleV, 1, scaleHCenter, scaleVCenter) 721 : new ScaleAnimation(1, scaleH, 1, scaleV, scaleHCenter, scaleVCenter); 722 final int sourceHCenter = sourceFrame.left + sourceFrame.width() / 2; 723 final int sourceVCenter = sourceFrame.top + sourceFrame.height() / 2; 724 final int destHCenter = destFrame.left + destFrame.width() / 2; 725 final int destVCenter = destFrame.top + destFrame.height() / 2; 726 final int fromX = enter ? sourceHCenter - destHCenter : destHCenter - sourceHCenter; 727 final int fromY = enter ? sourceVCenter - destVCenter : destVCenter - sourceVCenter; 728 final TranslateAnimation translation = enter ? new TranslateAnimation(fromX, 0, fromY, 0) 729 : new TranslateAnimation(0, fromX, 0, fromY); 730 set.addAnimation(scale); 731 set.addAnimation(translation); 732 setAppTransitionFinishedCallbackIfNeeded(set); 733 return set; 734 } 735 736 /** 737 * @return true if and only if the first frame of the transition can be skipped, i.e. the first 738 * frame of the transition doesn't change the visuals on screen, so we can start 739 * directly with the second one 740 */ canSkipFirstFrame()741 boolean canSkipFirstFrame() { 742 return mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM 743 && !mNextAppTransitionOverrideRequested 744 && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE 745 && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL 746 && !mNextAppTransitionRequests.contains(TRANSIT_KEYGUARD_GOING_AWAY); 747 } 748 getRemoteAnimationController()749 RemoteAnimationController getRemoteAnimationController() { 750 return mRemoteAnimationController; 751 } 752 753 /** 754 * 755 * @param frame These are the bounds of the window when it finishes the animation. This is where 756 * the animation must usually finish in entrance animation, as the next frame will 757 * display the window at these coordinates. In case of exit animation, this is 758 * where the animation must start, as the frame before the animation is displaying 759 * the window at these bounds. 760 * @param insets Knowing where the window will be positioned is not enough. Some parts of the 761 * window might be obscured, usually by the system windows (status bar and 762 * navigation bar) and we use content insets to convey that information. This 763 * usually affects the animation aspects vertically, as the system decoration is 764 * at the top and the bottom. For example when we animate from full screen to 765 * recents, we want to exclude the covered parts, because they won't match the 766 * thumbnail after the last frame is executed. 767 * @param surfaceInsets In rare situation the surface is larger than the content and we need to 768 * know about this to make the animation frames match. We currently use 769 * this for freeform windows, which have larger surfaces to display 770 * shadows. When we animate them from recents, we want to match the content 771 * to the recents thumbnail and hence need to account for the surface being 772 * bigger. 773 */ 774 @Nullable loadAnimation(LayoutParams lp, int transit, boolean enter, int uiMode, int orientation, Rect frame, Rect displayFrame, Rect insets, @Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean isVoiceInteraction, boolean freeform, WindowContainer container)775 Animation loadAnimation(LayoutParams lp, int transit, boolean enter, int uiMode, 776 int orientation, Rect frame, Rect displayFrame, Rect insets, 777 @Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean isVoiceInteraction, 778 boolean freeform, WindowContainer container) { 779 780 final boolean canCustomizeAppTransition = container.canCustomizeAppTransition(); 781 782 if (mNextAppTransitionOverrideRequested) { 783 if (canCustomizeAppTransition || mOverrideTaskTransition) { 784 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM; 785 } else { 786 ProtoLog.e(WM_DEBUG_APP_TRANSITIONS_ANIM, "applyAnimation: " 787 + " override requested, but it is prohibited by policy."); 788 } 789 } 790 791 Animation a; 792 if (isKeyguardGoingAwayTransitOld(transit) && enter) { 793 a = mTransitionAnimation.loadKeyguardExitAnimation(mNextAppTransitionFlags, 794 transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER); 795 } else if (transit == TRANSIT_OLD_KEYGUARD_OCCLUDE 796 || transit == TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM) { 797 a = null; 798 } else if (transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE && !enter) { 799 a = mTransitionAnimation.loadKeyguardUnoccludeAnimation(); 800 } else if (transit == TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE) { 801 a = null; 802 } else if (isVoiceInteraction && (transit == TRANSIT_OLD_ACTIVITY_OPEN 803 || transit == TRANSIT_OLD_TASK_OPEN 804 || transit == TRANSIT_OLD_TASK_TO_FRONT)) { 805 a = mTransitionAnimation.loadVoiceActivityOpenAnimation(enter); 806 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 807 "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", a, 808 appTransitionOldToString(transit), enter, Debug.getCallers(3)); 809 } else if (isVoiceInteraction && (transit == TRANSIT_OLD_ACTIVITY_CLOSE 810 || transit == TRANSIT_OLD_TASK_CLOSE 811 || transit == TRANSIT_OLD_TASK_TO_BACK)) { 812 a = mTransitionAnimation.loadVoiceActivityExitAnimation(enter); 813 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 814 "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", a, 815 appTransitionOldToString(transit), enter, Debug.getCallers(3)); 816 } else if (transit == TRANSIT_OLD_ACTIVITY_RELAUNCH) { 817 a = mTransitionAnimation.createRelaunchAnimation(frame, insets, 818 mDefaultNextAppTransitionAnimationSpec != null 819 ? mDefaultNextAppTransitionAnimationSpec.rect : null); 820 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 821 "applyAnimation: anim=%s transit=%s Callers=%s", a, 822 appTransitionOldToString(transit), Debug.getCallers(3)); 823 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) { 824 a = getNextAppRequestedAnimation(enter); 825 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 826 "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s " 827 + "isEntrance=%b Callers=%s", 828 a, appTransitionOldToString(transit), enter, Debug.getCallers(3)); 829 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) { 830 a = mTransitionAnimation.loadAppTransitionAnimation( 831 mNextAppTransitionPackage, mNextAppTransitionInPlace); 832 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 833 "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM_IN_PLACE " 834 + "transit=%s Callers=%s", 835 a, appTransitionOldToString(transit), Debug.getCallers(3)); 836 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) { 837 a = mTransitionAnimation.createClipRevealAnimationLockedCompat( 838 transit, enter, frame, displayFrame, 839 mDefaultNextAppTransitionAnimationSpec != null 840 ? mDefaultNextAppTransitionAnimationSpec.rect : null); 841 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 842 "applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL " 843 + "transit=%s Callers=%s", 844 a, appTransitionOldToString(transit), Debug.getCallers(3)); 845 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) { 846 a = mTransitionAnimation.createScaleUpAnimationLockedCompat(transit, enter, frame, 847 mDefaultNextAppTransitionAnimationSpec != null 848 ? mDefaultNextAppTransitionAnimationSpec.rect : null); 849 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 850 "applyAnimation: anim=%s nextAppTransition=ANIM_SCALE_UP transit=%s " 851 + "isEntrance=%s Callers=%s", 852 a, appTransitionOldToString(transit), enter, Debug.getCallers(3)); 853 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP || 854 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) { 855 mNextAppTransitionScaleUp = 856 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP); 857 final HardwareBuffer thumbnailHeader = getAppTransitionThumbnailHeader(container); 858 a = mTransitionAnimation.createThumbnailEnterExitAnimationLockedCompat(enter, 859 mNextAppTransitionScaleUp, frame, transit, thumbnailHeader, 860 mDefaultNextAppTransitionAnimationSpec != null 861 ? mDefaultNextAppTransitionAnimationSpec.rect : null); 862 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 863 "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b " 864 + "Callers=%s", 865 a, mNextAppTransitionScaleUp 866 ? "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN", 867 appTransitionOldToString(transit), enter, Debug.getCallers(3)); 868 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP || 869 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN) { 870 mNextAppTransitionScaleUp = 871 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP); 872 AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get( 873 container.hashCode()); 874 a = mTransitionAnimation.createAspectScaledThumbnailEnterExitAnimationLocked(enter, 875 mNextAppTransitionScaleUp, orientation, transit, frame, insets, surfaceInsets, 876 stableInsets, freeform, spec != null ? spec.rect : null, 877 mDefaultNextAppTransitionAnimationSpec != null 878 ? mDefaultNextAppTransitionAnimationSpec.rect : null); 879 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 880 "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b " 881 + "Callers=%s", 882 a, mNextAppTransitionScaleUp 883 ? "ANIM_THUMBNAIL_ASPECT_SCALE_UP" 884 : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN", 885 appTransitionOldToString(transit), enter, Debug.getCallers(3)); 886 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS && enter) { 887 a = mTransitionAnimation.loadCrossProfileAppEnterAnimation(); 888 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 889 "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: " 890 + "anim=%s transit=%s isEntrance=true Callers=%s", 891 a, appTransitionOldToString(transit), Debug.getCallers(3)); 892 } else if (isChangeTransitOld(transit)) { 893 // In the absence of a specific adapter, we just want to keep everything stationary. 894 a = new AlphaAnimation(1.f, 1.f); 895 a.setDuration(WindowChangeAnimationSpec.ANIMATION_DURATION); 896 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 897 "applyAnimation: anim=%s transit=%s isEntrance=%b Callers=%s", 898 a, appTransitionOldToString(transit), enter, Debug.getCallers(3)); 899 } else { 900 int animAttr = mapOpenCloseTransitTypes(transit, enter); 901 a = animAttr == 0 ? null : (canCustomizeAppTransition 902 ? loadAnimationAttr(lp, animAttr, transit) 903 : mTransitionAnimation.loadDefaultAnimationAttr(animAttr, transit)); 904 905 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, 906 "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b " 907 + " canCustomizeAppTransition=%b Callers=%s", 908 a, animAttr, appTransitionOldToString(transit), enter, 909 canCustomizeAppTransition, Debug.getCallers(3)); 910 } 911 setAppTransitionFinishedCallbackIfNeeded(a); 912 913 return a; 914 } 915 getAppRootTaskClipMode()916 int getAppRootTaskClipMode() { 917 return mNextAppTransitionRequests.contains(TRANSIT_RELAUNCH) 918 || mNextAppTransitionRequests.contains(TRANSIT_KEYGUARD_GOING_AWAY) 919 || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL 920 ? ROOT_TASK_CLIP_NONE 921 : ROOT_TASK_CLIP_AFTER_ANIM; 922 } 923 924 @TransitionFlags getTransitFlags()925 public int getTransitFlags() { 926 return mNextAppTransitionFlags; 927 } 928 postAnimationCallback()929 void postAnimationCallback() { 930 if (mNextAppTransitionCallback != null) { 931 mHandler.sendMessage(PooledLambda.obtainMessage(AppTransition::doAnimationCallback, 932 mNextAppTransitionCallback)); 933 mNextAppTransitionCallback = null; 934 } 935 } 936 overridePendingAppTransition(String packageName, int enterAnim, int exitAnim, @ColorInt int backgroundColor, IRemoteCallback startedCallback, IRemoteCallback endedCallback, boolean overrideTaskTransaction)937 void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim, 938 @ColorInt int backgroundColor, IRemoteCallback startedCallback, 939 IRemoteCallback endedCallback, boolean overrideTaskTransaction) { 940 if (canOverridePendingAppTransition()) { 941 clear(); 942 mNextAppTransitionOverrideRequested = true; 943 mNextAppTransitionPackage = packageName; 944 mNextAppTransitionEnter = enterAnim; 945 mNextAppTransitionExit = exitAnim; 946 mNextAppTransitionBackgroundColor = backgroundColor; 947 postAnimationCallback(); 948 mNextAppTransitionCallback = startedCallback; 949 mAnimationFinishedCallback = endedCallback; 950 mOverrideTaskTransition = overrideTaskTransaction; 951 } 952 } 953 overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth, int startHeight)954 void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth, 955 int startHeight) { 956 if (canOverridePendingAppTransition()) { 957 clear(); 958 mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP; 959 putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight, null); 960 postAnimationCallback(); 961 } 962 } 963 overridePendingAppTransitionClipReveal(int startX, int startY, int startWidth, int startHeight)964 void overridePendingAppTransitionClipReveal(int startX, int startY, 965 int startWidth, int startHeight) { 966 if (canOverridePendingAppTransition()) { 967 clear(); 968 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL; 969 putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight, null); 970 postAnimationCallback(); 971 } 972 } 973 overridePendingAppTransitionThumb(HardwareBuffer srcThumb, int startX, int startY, IRemoteCallback startedCallback, boolean scaleUp)974 void overridePendingAppTransitionThumb(HardwareBuffer srcThumb, int startX, int startY, 975 IRemoteCallback startedCallback, boolean scaleUp) { 976 if (canOverridePendingAppTransition()) { 977 clear(); 978 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP 979 : NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN; 980 mNextAppTransitionScaleUp = scaleUp; 981 putDefaultNextAppTransitionCoordinates(startX, startY, 0, 0, srcThumb); 982 postAnimationCallback(); 983 mNextAppTransitionCallback = startedCallback; 984 } 985 } 986 overridePendingAppTransitionAspectScaledThumb(HardwareBuffer srcThumb, int startX, int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback, boolean scaleUp)987 void overridePendingAppTransitionAspectScaledThumb(HardwareBuffer srcThumb, int startX, 988 int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback, 989 boolean scaleUp) { 990 if (canOverridePendingAppTransition()) { 991 clear(); 992 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP 993 : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN; 994 mNextAppTransitionScaleUp = scaleUp; 995 putDefaultNextAppTransitionCoordinates(startX, startY, targetWidth, targetHeight, 996 srcThumb); 997 postAnimationCallback(); 998 mNextAppTransitionCallback = startedCallback; 999 } 1000 } 1001 overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs, IRemoteCallback onAnimationStartedCallback, IRemoteCallback onAnimationFinishedCallback, boolean scaleUp)1002 void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs, 1003 IRemoteCallback onAnimationStartedCallback, IRemoteCallback onAnimationFinishedCallback, 1004 boolean scaleUp) { 1005 if (canOverridePendingAppTransition()) { 1006 clear(); 1007 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP 1008 : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN; 1009 mNextAppTransitionScaleUp = scaleUp; 1010 if (specs != null) { 1011 for (int i = 0; i < specs.length; i++) { 1012 AppTransitionAnimationSpec spec = specs[i]; 1013 if (spec != null) { 1014 final PooledPredicate p = PooledLambda.obtainPredicate( 1015 Task::isTaskId, PooledLambda.__(Task.class), spec.taskId); 1016 final WindowContainer container = mDisplayContent.getTask(p); 1017 p.recycle(); 1018 if (container == null) { 1019 continue; 1020 } 1021 mNextAppTransitionAnimationsSpecs.put(container.hashCode(), spec); 1022 if (i == 0) { 1023 // In full screen mode, the transition code depends on the default spec 1024 // to be set. 1025 Rect rect = spec.rect; 1026 putDefaultNextAppTransitionCoordinates(rect.left, rect.top, 1027 rect.width(), rect.height(), spec.buffer); 1028 } 1029 } 1030 } 1031 } 1032 postAnimationCallback(); 1033 mNextAppTransitionCallback = onAnimationStartedCallback; 1034 mAnimationFinishedCallback = onAnimationFinishedCallback; 1035 } 1036 } 1037 overridePendingAppTransitionMultiThumbFuture( IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback, boolean scaleUp)1038 void overridePendingAppTransitionMultiThumbFuture( 1039 IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback, 1040 boolean scaleUp) { 1041 if (canOverridePendingAppTransition()) { 1042 clear(); 1043 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP 1044 : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN; 1045 mNextAppTransitionAnimationsSpecsFuture = specsFuture; 1046 mNextAppTransitionScaleUp = scaleUp; 1047 mNextAppTransitionFutureCallback = callback; 1048 if (isReady()) { 1049 fetchAppTransitionSpecsFromFuture(); 1050 } 1051 } 1052 } 1053 overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter)1054 void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter) { 1055 overridePendingAppTransitionRemote(remoteAnimationAdapter, false /* sync */, 1056 false /* isActivityEmbedding*/); 1057 } 1058 overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter, boolean sync, boolean isActivityEmbedding)1059 void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter, 1060 boolean sync, boolean isActivityEmbedding) { 1061 ProtoLog.i(WM_DEBUG_APP_TRANSITIONS, "Override pending remote transitionSet=%b adapter=%s", 1062 isTransitionSet(), remoteAnimationAdapter); 1063 if (isTransitionSet() && !mNextAppTransitionIsSync) { 1064 // ActivityEmbedding animation will run by the app process for which we want to respect 1065 // the app override for whether or not to show background color. 1066 clear(!isActivityEmbedding /* clearAppOverride */); 1067 mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE; 1068 mRemoteAnimationController = new RemoteAnimationController(mService, mDisplayContent, 1069 remoteAnimationAdapter, mHandler, isActivityEmbedding); 1070 mNextAppTransitionIsSync = sync; 1071 } 1072 } 1073 overrideInPlaceAppTransition(String packageName, int anim)1074 void overrideInPlaceAppTransition(String packageName, int anim) { 1075 if (canOverridePendingAppTransition()) { 1076 clear(); 1077 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE; 1078 mNextAppTransitionPackage = packageName; 1079 mNextAppTransitionInPlace = anim; 1080 } 1081 } 1082 1083 /** 1084 * @see {@link #NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS} 1085 */ overridePendingAppTransitionStartCrossProfileApps()1086 void overridePendingAppTransitionStartCrossProfileApps() { 1087 if (canOverridePendingAppTransition()) { 1088 clear(); 1089 mNextAppTransitionType = NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS; 1090 postAnimationCallback(); 1091 } 1092 } 1093 canOverridePendingAppTransition()1094 private boolean canOverridePendingAppTransition() { 1095 // Remote animations always take precedence 1096 return isTransitionSet() && mNextAppTransitionType != NEXT_TRANSIT_TYPE_REMOTE; 1097 } 1098 1099 /** 1100 * If a future is set for the app transition specs, fetch it in another thread. 1101 */ fetchAppTransitionSpecsFromFuture()1102 private void fetchAppTransitionSpecsFromFuture() { 1103 if (mNextAppTransitionAnimationsSpecsFuture != null) { 1104 mNextAppTransitionAnimationsSpecsPending = true; 1105 final IAppTransitionAnimationSpecsFuture future 1106 = mNextAppTransitionAnimationsSpecsFuture; 1107 mNextAppTransitionAnimationsSpecsFuture = null; 1108 mDefaultExecutor.execute(() -> { 1109 AppTransitionAnimationSpec[] specs = null; 1110 try { 1111 Binder.allowBlocking(future.asBinder()); 1112 specs = future.get(); 1113 } catch (RemoteException e) { 1114 Slog.w(TAG, "Failed to fetch app transition specs: " + e); 1115 } 1116 synchronized (mService.mGlobalLock) { 1117 mNextAppTransitionAnimationsSpecsPending = false; 1118 overridePendingAppTransitionMultiThumb(specs, 1119 mNextAppTransitionFutureCallback, null /* finishedCallback */, 1120 mNextAppTransitionScaleUp); 1121 mNextAppTransitionFutureCallback = null; 1122 mService.requestTraversal(); 1123 } 1124 }); 1125 } 1126 } 1127 1128 @Override toString()1129 public String toString() { 1130 StringBuilder sb = new StringBuilder(); 1131 sb.append("mNextAppTransitionRequests=["); 1132 1133 boolean separator = false; 1134 for (Integer transit : mNextAppTransitionRequests) { 1135 if (separator) { 1136 sb.append(", "); 1137 } 1138 sb.append(appTransitionToString(transit)); 1139 separator = true; 1140 } 1141 sb.append("]"); 1142 sb.append(", mNextAppTransitionFlags=" 1143 + appTransitionFlagsToString(mNextAppTransitionFlags)); 1144 return sb.toString(); 1145 } 1146 1147 /** 1148 * Returns the human readable name of a old window transition. 1149 * 1150 * @param transition The old window transition. 1151 * @return The transition symbolic name. 1152 */ appTransitionOldToString(@ransitionOldType int transition)1153 public static String appTransitionOldToString(@TransitionOldType int transition) { 1154 switch (transition) { 1155 case TRANSIT_OLD_UNSET: { 1156 return "TRANSIT_OLD_UNSET"; 1157 } 1158 case TRANSIT_OLD_NONE: { 1159 return "TRANSIT_OLD_NONE"; 1160 } 1161 case TRANSIT_OLD_ACTIVITY_OPEN: { 1162 return "TRANSIT_OLD_ACTIVITY_OPEN"; 1163 } 1164 case TRANSIT_OLD_ACTIVITY_CLOSE: { 1165 return "TRANSIT_OLD_ACTIVITY_CLOSE"; 1166 } 1167 case TRANSIT_OLD_TASK_OPEN: { 1168 return "TRANSIT_OLD_TASK_OPEN"; 1169 } 1170 case TRANSIT_OLD_TASK_CLOSE: { 1171 return "TRANSIT_OLD_TASK_CLOSE"; 1172 } 1173 case TRANSIT_OLD_TASK_TO_FRONT: { 1174 return "TRANSIT_OLD_TASK_TO_FRONT"; 1175 } 1176 case TRANSIT_OLD_TASK_TO_BACK: { 1177 return "TRANSIT_OLD_TASK_TO_BACK"; 1178 } 1179 case TRANSIT_OLD_WALLPAPER_CLOSE: { 1180 return "TRANSIT_OLD_WALLPAPER_CLOSE"; 1181 } 1182 case TRANSIT_OLD_WALLPAPER_OPEN: { 1183 return "TRANSIT_OLD_WALLPAPER_OPEN"; 1184 } 1185 case TRANSIT_OLD_WALLPAPER_INTRA_OPEN: { 1186 return "TRANSIT_OLD_WALLPAPER_INTRA_OPEN"; 1187 } 1188 case TRANSIT_OLD_WALLPAPER_INTRA_CLOSE: { 1189 return "TRANSIT_OLD_WALLPAPER_INTRA_CLOSE"; 1190 } 1191 case TRANSIT_OLD_TASK_OPEN_BEHIND: { 1192 return "TRANSIT_OLD_TASK_OPEN_BEHIND"; 1193 } 1194 case TRANSIT_OLD_ACTIVITY_RELAUNCH: { 1195 return "TRANSIT_OLD_ACTIVITY_RELAUNCH"; 1196 } 1197 case TRANSIT_OLD_KEYGUARD_GOING_AWAY: { 1198 return "TRANSIT_OLD_KEYGUARD_GOING_AWAY"; 1199 } 1200 case TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER: { 1201 return "TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER"; 1202 } 1203 case TRANSIT_OLD_KEYGUARD_OCCLUDE: { 1204 return "TRANSIT_OLD_KEYGUARD_OCCLUDE"; 1205 } 1206 case TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM: { 1207 return "TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM"; 1208 } 1209 case TRANSIT_OLD_KEYGUARD_UNOCCLUDE: { 1210 return "TRANSIT_OLD_KEYGUARD_UNOCCLUDE"; 1211 } 1212 case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN: { 1213 return "TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN"; 1214 } 1215 case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE: { 1216 return "TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE"; 1217 } 1218 case TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE: { 1219 return "TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE"; 1220 } 1221 case TRANSIT_OLD_TASK_FRAGMENT_OPEN: { 1222 return "TRANSIT_OLD_TASK_FRAGMENT_OPEN"; 1223 } 1224 case TRANSIT_OLD_TASK_FRAGMENT_CLOSE: { 1225 return "TRANSIT_OLD_TASK_FRAGMENT_CLOSE"; 1226 } 1227 case TRANSIT_OLD_TASK_FRAGMENT_CHANGE: { 1228 return "TRANSIT_OLD_TASK_FRAGMENT_CHANGE"; 1229 } 1230 case TRANSIT_OLD_DREAM_ACTIVITY_OPEN: { 1231 return "TRANSIT_OLD_DREAM_ACTIVITY_OPEN"; 1232 } 1233 case TRANSIT_OLD_DREAM_ACTIVITY_CLOSE: { 1234 return "TRANSIT_OLD_DREAM_ACTIVITY_CLOSE"; 1235 } 1236 default: { 1237 return "<UNKNOWN: " + transition + ">"; 1238 } 1239 } 1240 } 1241 1242 /** 1243 * Returns the human readable name of a window transition. 1244 * 1245 * @param transition The window transition. 1246 * @return The transition symbolic name. 1247 */ appTransitionToString(@ransitionType int transition)1248 public static String appTransitionToString(@TransitionType int transition) { 1249 switch (transition) { 1250 case TRANSIT_NONE: { 1251 return "TRANSIT_NONE"; 1252 } 1253 case TRANSIT_OPEN: { 1254 return "TRANSIT_OPEN"; 1255 } 1256 case TRANSIT_CLOSE: { 1257 return "TRANSIT_CLOSE"; 1258 } 1259 case TRANSIT_TO_FRONT: { 1260 return "TRANSIT_TO_FRONT"; 1261 } 1262 case TRANSIT_TO_BACK: { 1263 return "TRANSIT_TO_BACK"; 1264 } 1265 case TRANSIT_RELAUNCH: { 1266 return "TRANSIT_RELAUNCH"; 1267 } 1268 case TRANSIT_CHANGE: { 1269 return "TRANSIT_CHANGE"; 1270 } 1271 case TRANSIT_KEYGUARD_GOING_AWAY: { 1272 return "TRANSIT_KEYGUARD_GOING_AWAY"; 1273 } 1274 case TRANSIT_KEYGUARD_OCCLUDE: { 1275 return "TRANSIT_KEYGUARD_OCCLUDE"; 1276 } 1277 case TRANSIT_KEYGUARD_UNOCCLUDE: { 1278 return "TRANSIT_KEYGUARD_UNOCCLUDE"; 1279 } 1280 default: { 1281 return "<UNKNOWN: " + transition + ">"; 1282 } 1283 } 1284 } 1285 appStateToString()1286 private String appStateToString() { 1287 switch (mAppTransitionState) { 1288 case APP_STATE_IDLE: 1289 return "APP_STATE_IDLE"; 1290 case APP_STATE_READY: 1291 return "APP_STATE_READY"; 1292 case APP_STATE_RUNNING: 1293 return "APP_STATE_RUNNING"; 1294 case APP_STATE_TIMEOUT: 1295 return "APP_STATE_TIMEOUT"; 1296 default: 1297 return "unknown state=" + mAppTransitionState; 1298 } 1299 } 1300 transitTypeToString()1301 private String transitTypeToString() { 1302 switch (mNextAppTransitionType) { 1303 case NEXT_TRANSIT_TYPE_NONE: 1304 return "NEXT_TRANSIT_TYPE_NONE"; 1305 case NEXT_TRANSIT_TYPE_CUSTOM: 1306 return "NEXT_TRANSIT_TYPE_CUSTOM"; 1307 case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE: 1308 return "NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE"; 1309 case NEXT_TRANSIT_TYPE_SCALE_UP: 1310 return "NEXT_TRANSIT_TYPE_SCALE_UP"; 1311 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP: 1312 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP"; 1313 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN: 1314 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN"; 1315 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP: 1316 return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP"; 1317 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN: 1318 return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN"; 1319 case NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: 1320 return "NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS"; 1321 default: 1322 return "unknown type=" + mNextAppTransitionType; 1323 } 1324 } 1325 1326 private static final ArrayList<Pair<Integer, String>> sFlagToString; 1327 1328 static { 1329 sFlagToString = new ArrayList<>(); sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE, "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE"))1330 sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE, 1331 "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE")); sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION, "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION"))1332 sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION, 1333 "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION")); sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER, "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER"))1334 sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER, 1335 "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER")); sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION, "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION"))1336 sFlagToString.add(new Pair<>(TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION, 1337 "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION")); sFlagToString.add(new Pair<>( TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT, "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_WITH_IN_WINDOW_ANIMATIONS"))1338 sFlagToString.add(new Pair<>( 1339 TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT, 1340 "TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_WITH_IN_WINDOW_ANIMATIONS")); sFlagToString.add(new Pair<>(TRANSIT_FLAG_APP_CRASHED, "TRANSIT_FLAG_APP_CRASHED"))1341 sFlagToString.add(new Pair<>(TRANSIT_FLAG_APP_CRASHED, 1342 "TRANSIT_FLAG_APP_CRASHED")); sFlagToString.add(new Pair<>(TRANSIT_FLAG_OPEN_BEHIND, "TRANSIT_FLAG_OPEN_BEHIND"))1343 sFlagToString.add(new Pair<>(TRANSIT_FLAG_OPEN_BEHIND, 1344 "TRANSIT_FLAG_OPEN_BEHIND")); 1345 } 1346 1347 /** 1348 * Returns the human readable names of transit flags. 1349 * 1350 * @param flags a bitmask combination of transit flags. 1351 * @return The combination of symbolic names. 1352 */ appTransitionFlagsToString(int flags)1353 public static String appTransitionFlagsToString(int flags) { 1354 String sep = ""; 1355 StringBuilder sb = new StringBuilder(); 1356 for (Pair<Integer, String> pair : sFlagToString) { 1357 if ((flags & pair.first) != 0) { 1358 sb.append(sep); 1359 sb.append(pair.second); 1360 sep = " | "; 1361 } 1362 } 1363 return sb.toString(); 1364 } 1365 dumpDebug(ProtoOutputStream proto, long fieldId)1366 void dumpDebug(ProtoOutputStream proto, long fieldId) { 1367 final long token = proto.start(fieldId); 1368 proto.write(APP_TRANSITION_STATE, mAppTransitionState); 1369 proto.write(LAST_USED_APP_TRANSITION, mLastUsedAppTransition); 1370 proto.end(token); 1371 } 1372 1373 @Override dump(PrintWriter pw, String prefix)1374 public void dump(PrintWriter pw, String prefix) { 1375 pw.print(prefix); pw.println(this); 1376 pw.print(prefix); pw.print("mAppTransitionState="); pw.println(appStateToString()); 1377 if (mNextAppTransitionType != NEXT_TRANSIT_TYPE_NONE) { 1378 pw.print(prefix); pw.print("mNextAppTransitionType="); 1379 pw.println(transitTypeToString()); 1380 } 1381 if (mNextAppTransitionOverrideRequested 1382 || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) { 1383 pw.print(prefix); pw.print("mNextAppTransitionPackage="); 1384 pw.println(mNextAppTransitionPackage); 1385 pw.print(prefix); pw.print("mNextAppTransitionEnter=0x"); 1386 pw.print(Integer.toHexString(mNextAppTransitionEnter)); 1387 pw.print(" mNextAppTransitionExit=0x"); 1388 pw.println(Integer.toHexString(mNextAppTransitionExit)); 1389 pw.print(" mNextAppTransitionBackgroundColor=0x"); 1390 pw.println(Integer.toHexString(mNextAppTransitionBackgroundColor)); 1391 } 1392 switch (mNextAppTransitionType) { 1393 case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE: 1394 pw.print(prefix); pw.print("mNextAppTransitionPackage="); 1395 pw.println(mNextAppTransitionPackage); 1396 pw.print(prefix); pw.print("mNextAppTransitionInPlace=0x"); 1397 pw.print(Integer.toHexString(mNextAppTransitionInPlace)); 1398 break; 1399 case NEXT_TRANSIT_TYPE_SCALE_UP: { 1400 getDefaultNextAppTransitionStartRect(mTmpRect); 1401 pw.print(prefix); pw.print("mNextAppTransitionStartX="); 1402 pw.print(mTmpRect.left); 1403 pw.print(" mNextAppTransitionStartY="); 1404 pw.println(mTmpRect.top); 1405 pw.print(prefix); pw.print("mNextAppTransitionStartWidth="); 1406 pw.print(mTmpRect.width()); 1407 pw.print(" mNextAppTransitionStartHeight="); 1408 pw.println(mTmpRect.height()); 1409 break; 1410 } 1411 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP: 1412 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN: 1413 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP: 1414 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN: { 1415 pw.print(prefix); pw.print("mDefaultNextAppTransitionAnimationSpec="); 1416 pw.println(mDefaultNextAppTransitionAnimationSpec); 1417 pw.print(prefix); pw.print("mNextAppTransitionAnimationsSpecs="); 1418 pw.println(mNextAppTransitionAnimationsSpecs); 1419 pw.print(prefix); pw.print("mNextAppTransitionScaleUp="); 1420 pw.println(mNextAppTransitionScaleUp); 1421 break; 1422 } 1423 } 1424 if (mNextAppTransitionCallback != null) { 1425 pw.print(prefix); pw.print("mNextAppTransitionCallback="); 1426 pw.println(mNextAppTransitionCallback); 1427 } 1428 if (mLastUsedAppTransition != TRANSIT_OLD_NONE) { 1429 pw.print(prefix); pw.print("mLastUsedAppTransition="); 1430 pw.println(appTransitionOldToString(mLastUsedAppTransition)); 1431 pw.print(prefix); pw.print("mLastOpeningApp="); 1432 pw.println(mLastOpeningApp); 1433 pw.print(prefix); pw.print("mLastClosingApp="); 1434 pw.println(mLastClosingApp); 1435 pw.print(prefix); pw.print("mLastChangingApp="); 1436 pw.println(mLastChangingApp); 1437 } 1438 } 1439 prepareAppTransition(@ransitionType int transit, @TransitionFlags int flags)1440 boolean prepareAppTransition(@TransitionType int transit, @TransitionFlags int flags) { 1441 if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) { 1442 return false; 1443 } 1444 mNextAppTransitionRequests.add(transit); 1445 mNextAppTransitionFlags |= flags; 1446 updateBooster(); 1447 removeAppTransitionTimeoutCallbacks(); 1448 mHandler.postDelayed(mHandleAppTransitionTimeoutRunnable, 1449 APP_TRANSITION_TIMEOUT_MS); 1450 return prepare(); 1451 } 1452 1453 /** 1454 * @return true if {@param transit} is representing a transition in which Keyguard is going 1455 * away, false otherwise 1456 */ isKeyguardGoingAwayTransitOld(int transit)1457 public static boolean isKeyguardGoingAwayTransitOld(int transit) { 1458 return transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY 1459 || transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; 1460 } 1461 isKeyguardOccludeTransitOld(@ransitionOldType int transit)1462 static boolean isKeyguardOccludeTransitOld(@TransitionOldType int transit) { 1463 return transit == TRANSIT_OLD_KEYGUARD_OCCLUDE 1464 || transit == TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM 1465 || transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE; 1466 } 1467 isKeyguardTransitOld(@ransitionOldType int transit)1468 static boolean isKeyguardTransitOld(@TransitionOldType int transit) { 1469 return isKeyguardGoingAwayTransitOld(transit) || isKeyguardOccludeTransitOld(transit); 1470 } 1471 isTaskTransitOld(@ransitionOldType int transit)1472 static boolean isTaskTransitOld(@TransitionOldType int transit) { 1473 return isTaskOpenTransitOld(transit) 1474 || isTaskCloseTransitOld(transit); 1475 } 1476 isTaskCloseTransitOld(@ransitionOldType int transit)1477 static boolean isTaskCloseTransitOld(@TransitionOldType int transit) { 1478 return transit == TRANSIT_OLD_TASK_CLOSE 1479 || transit == TRANSIT_OLD_TASK_TO_BACK; 1480 } 1481 isTaskOpenTransitOld(@ransitionOldType int transit)1482 private static boolean isTaskOpenTransitOld(@TransitionOldType int transit) { 1483 return transit == TRANSIT_OLD_TASK_OPEN 1484 || transit == TRANSIT_OLD_TASK_OPEN_BEHIND 1485 || transit == TRANSIT_OLD_TASK_TO_FRONT; 1486 } 1487 isActivityTransitOld(@ransitionOldType int transit)1488 static boolean isActivityTransitOld(@TransitionOldType int transit) { 1489 return transit == TRANSIT_OLD_ACTIVITY_OPEN 1490 || transit == TRANSIT_OLD_ACTIVITY_CLOSE 1491 || transit == TRANSIT_OLD_ACTIVITY_RELAUNCH; 1492 } 1493 isTaskFragmentTransitOld(@ransitionOldType int transit)1494 static boolean isTaskFragmentTransitOld(@TransitionOldType int transit) { 1495 return transit == TRANSIT_OLD_TASK_FRAGMENT_OPEN 1496 || transit == TRANSIT_OLD_TASK_FRAGMENT_CLOSE 1497 || transit == TRANSIT_OLD_TASK_FRAGMENT_CHANGE; 1498 } 1499 isChangeTransitOld(@ransitionOldType int transit)1500 static boolean isChangeTransitOld(@TransitionOldType int transit) { 1501 return transit == TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE 1502 || transit == TRANSIT_OLD_TASK_FRAGMENT_CHANGE; 1503 } 1504 isClosingTransitOld(@ransitionOldType int transit)1505 static boolean isClosingTransitOld(@TransitionOldType int transit) { 1506 return transit == TRANSIT_OLD_ACTIVITY_CLOSE 1507 || transit == TRANSIT_OLD_TASK_CLOSE 1508 || transit == TRANSIT_OLD_WALLPAPER_CLOSE 1509 || transit == TRANSIT_OLD_WALLPAPER_INTRA_CLOSE 1510 || transit == TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE 1511 || transit == TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE; 1512 } 1513 isNormalTransit(@ransitionType int transit)1514 static boolean isNormalTransit(@TransitionType int transit) { 1515 return transit == TRANSIT_OPEN 1516 || transit == TRANSIT_CLOSE 1517 || transit == TRANSIT_TO_FRONT 1518 || transit == TRANSIT_TO_BACK; 1519 } 1520 isKeyguardTransit(@ransitionType int transit)1521 static boolean isKeyguardTransit(@TransitionType int transit) { 1522 return transit == TRANSIT_KEYGUARD_GOING_AWAY 1523 || transit == TRANSIT_KEYGUARD_OCCLUDE 1524 || transit == TRANSIT_KEYGUARD_UNOCCLUDE; 1525 } 1526 getKeyguardTransition()1527 @TransitionType int getKeyguardTransition() { 1528 if (mNextAppTransitionRequests.indexOf(TRANSIT_KEYGUARD_GOING_AWAY) != -1) { 1529 return TRANSIT_KEYGUARD_GOING_AWAY; 1530 } 1531 final int unoccludeIndex = mNextAppTransitionRequests.indexOf(TRANSIT_KEYGUARD_UNOCCLUDE); 1532 final int occludeIndex = mNextAppTransitionRequests.indexOf(TRANSIT_KEYGUARD_OCCLUDE); 1533 // No keyguard related transition requests. 1534 if (unoccludeIndex == -1 && occludeIndex == -1) { 1535 return TRANSIT_NONE; 1536 } 1537 // In case we unocclude Keyguard and occlude it again, meaning that we never actually 1538 // unoccclude/occlude Keyguard, but just run a normal transition. 1539 if (unoccludeIndex != -1 && unoccludeIndex < occludeIndex) { 1540 return TRANSIT_NONE; 1541 } 1542 return unoccludeIndex != -1 ? TRANSIT_KEYGUARD_UNOCCLUDE : TRANSIT_KEYGUARD_OCCLUDE; 1543 } 1544 getFirstAppTransition()1545 @TransitionType int getFirstAppTransition() { 1546 for (int i = 0; i < mNextAppTransitionRequests.size(); ++i) { 1547 final @TransitionType int transit = mNextAppTransitionRequests.get(i); 1548 if (transit != TRANSIT_NONE && !isKeyguardTransit(transit)) { 1549 return transit; 1550 } 1551 } 1552 return TRANSIT_NONE; 1553 } 1554 containsTransitRequest(@ransitionType int transit)1555 boolean containsTransitRequest(@TransitionType int transit) { 1556 return mNextAppTransitionRequests.contains(transit); 1557 } 1558 1559 /** 1560 * @return whether the transition should show the thumbnail being scaled down. 1561 */ shouldScaleDownThumbnailTransition(int uiMode, int orientation)1562 private boolean shouldScaleDownThumbnailTransition(int uiMode, int orientation) { 1563 return mGridLayoutRecentsEnabled 1564 || orientation == Configuration.ORIENTATION_PORTRAIT; 1565 } 1566 handleAppTransitionTimeout()1567 private void handleAppTransitionTimeout() { 1568 synchronized (mService.mGlobalLock) { 1569 final DisplayContent dc = mDisplayContent; 1570 if (dc == null) { 1571 return; 1572 } 1573 notifyAppTransitionTimeoutLocked(); 1574 if (isTransitionSet() || !dc.mOpeningApps.isEmpty() || !dc.mClosingApps.isEmpty() 1575 || !dc.mChangingContainers.isEmpty()) { 1576 ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, 1577 "*** APP TRANSITION TIMEOUT. displayId=%d isTransitionSet()=%b " 1578 + "mOpeningApps.size()=%d mClosingApps.size()=%d " 1579 + "mChangingApps.size()=%d", 1580 dc.getDisplayId(), dc.mAppTransition.isTransitionSet(), 1581 dc.mOpeningApps.size(), dc.mClosingApps.size(), 1582 dc.mChangingContainers.size()); 1583 1584 setTimeout(); 1585 mService.mWindowPlacerLocked.performSurfacePlacement(); 1586 } 1587 } 1588 } 1589 doAnimationCallback(@onNull IRemoteCallback callback)1590 private static void doAnimationCallback(@NonNull IRemoteCallback callback) { 1591 try { 1592 ((IRemoteCallback) callback).sendResult(null); 1593 } catch (RemoteException e) { 1594 } 1595 } 1596 setAppTransitionFinishedCallbackIfNeeded(Animation anim)1597 private void setAppTransitionFinishedCallbackIfNeeded(Animation anim) { 1598 final IRemoteCallback callback = mAnimationFinishedCallback; 1599 if (callback != null && anim != null) { 1600 anim.setAnimationListener(new Animation.AnimationListener() { 1601 @Override 1602 public void onAnimationStart(Animation animation) { } 1603 1604 @Override 1605 public void onAnimationEnd(Animation animation) { 1606 mHandler.sendMessage(PooledLambda.obtainMessage( 1607 AppTransition::doAnimationCallback, callback)); 1608 } 1609 1610 @Override 1611 public void onAnimationRepeat(Animation animation) { } 1612 }); 1613 } 1614 } 1615 removeAppTransitionTimeoutCallbacks()1616 void removeAppTransitionTimeoutCallbacks() { 1617 mHandler.removeCallbacks(mHandleAppTransitionTimeoutRunnable); 1618 } 1619 } 1620