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