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