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