1164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner/*
2164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner * Copyright (C) 2011 The Android Open Source Project
3164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner *
4164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner * Licensed under the Apache License, Version 2.0 (the "License");
5164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner * you may not use this file except in compliance with the License.
6164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner * You may obtain a copy of the License at
7164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner *
8164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner *      http://www.apache.org/licenses/LICENSE-2.0
9164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner *
10164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner * Unless required by applicable law or agreed to in writing, software
11164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner * distributed under the License is distributed on an "AS IS" BASIS,
12164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner * See the License for the specific language governing permissions and
14164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner * limitations under the License.
15164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner */
16164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
17164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerpackage com.android.server.wm;
18164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
19f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.LayoutParams;
20f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
21f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
22f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_ACTIVITY_RELAUNCH;
23935772129d244122e23308b812765d4591a3c04fAdrian Roosimport static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
24f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
25f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
26f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
27f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
28f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
29f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
30f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
31f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_NONE;
32f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_TASK_CLOSE;
33cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggiimport static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
34f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_TASK_OPEN;
35f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND;
36f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_TASK_TO_BACK;
37f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
3898a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggiimport static android.view.WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE;
3998a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggiimport static android.view.WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN;
40f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_UNSET;
41f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_WALLPAPER_CLOSE;
42f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_WALLPAPER_INTRA_CLOSE;
43f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_WALLPAPER_INTRA_OPEN;
44f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN;
4583546a83edd5073d43de6fc1dd8400291ec0f7c0Tony Mak
46828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation;
47828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
48828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
49828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
50828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindSourceAnimation;
51828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindTargetAnimation;
52828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation;
53828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
54828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation;
55828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
56828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation;
57828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
58828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation;
59828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
60828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation;
61828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
62828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation;
63828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
64828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation;
65828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
66828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
67828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynskiimport static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
68198dcbf5231761b7b644d9d7fbceb23e1f0f9aecFilip Gruszczynskiimport static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
69198dcbf5231761b7b644d9d7fbceb23e1f0f9aecFilip Gruszczynskiimport static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
700bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynskiimport static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
710bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynskiimport static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
72e99bc0501a288735d337f2ff64f8fa47f766a59bAdrian Roosimport static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
73089c35e9311386844332dbe2ca09076f845a604cTony Makimport static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
74bf1d985cc66da3b3b32cc87925757c9e7b34afedMatthew Ngimport static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
756a7c90a12b5e5250e0350d35ca6547b26630653fJorim Jaggiimport static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
766c6e9cab42bccb44ebb4b30e7eab7394c0dbb759Yi Jinimport static com.android.server.wm.AppTransitionProto.APP_TRANSITION_STATE;
776c6e9cab42bccb44ebb4b30e7eab7394c0dbb759Yi Jinimport static com.android.server.wm.AppTransitionProto.LAST_USED_APP_TRANSITION;
78828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynski
7964b8d562115e632ff65a17fab8923a931b0a5000Tony Makimport android.annotation.DrawableRes;
8071b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynskiimport android.annotation.Nullable;
8143db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ngimport android.app.ActivityManager;
82089c35e9311386844332dbe2ca09076f845a604cTony Makimport android.content.ComponentName;
83164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport android.content.Context;
84217009356efa2b854ab3981dff8d315a0d679c73Winsonimport android.content.res.Configuration;
8564c57a8c9649a1c264f667710538f65d1a8ea0b4Todd Kennedyimport android.content.res.ResourceId;
86519ad488a5157143e883e437b1e259472280c746John Reckimport android.graphics.Bitmap;
87519ad488a5157143e883e437b1e259472280c746John Reckimport android.graphics.Canvas;
8864b8d562115e632ff65a17fab8923a931b0a5000Tony Makimport android.graphics.Color;
89aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chungimport android.graphics.GraphicBuffer;
90787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggiimport android.graphics.Path;
91519ad488a5157143e883e437b1e259472280c746John Reckimport android.graphics.Picture;
92399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chungimport android.graphics.Rect;
9364b8d562115e632ff65a17fab8923a931b0a5000Tony Makimport android.graphics.drawable.Drawable;
94ed410b692820783e5677fd174693588ddc528414Jorim Jaggiimport android.os.Binder;
95164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport android.os.Debug;
9677ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggiimport android.os.IBinder;
97164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport android.os.IRemoteCallback;
982f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggiimport android.os.RemoteException;
99f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggiimport android.os.SystemClock;
100d737680ba29e493e62659a3997710cb5392d2657Manu Cornetimport android.os.SystemProperties;
101089c35e9311386844332dbe2ca09076f845a604cTony Makimport android.os.UserHandle;
10242625d1bc7ef99c4d4435e8cdebfe3eee57b8d97Jorim Jaggiimport android.util.ArraySet;
103164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport android.util.Slog;
104170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynskiimport android.util.SparseArray;
105af03df6a7a93c832e0bc77b88607ef9161f0791bSteven Timotiusimport android.util.proto.ProtoOutputStream;
106170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynskiimport android.view.AppTransitionAnimationSpec;
1072f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggiimport android.view.IAppTransitionAnimationSpecsFuture;
10833a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggiimport android.view.RemoteAnimationAdapter;
109f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport android.view.WindowManager.TransitionFlags;
110f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggiimport android.view.WindowManager.TransitionType;
111164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport android.view.animation.AlphaAnimation;
112164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport android.view.animation.Animation;
113164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport android.view.animation.AnimationSet;
114164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport android.view.animation.AnimationUtils;
115399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chungimport android.view.animation.ClipRectAnimation;
116164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport android.view.animation.Interpolator;
1171d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggiimport android.view.animation.PathInterpolator;
118164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport android.view.animation.ScaleAnimation;
119399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chungimport android.view.animation.TranslateAnimation;
1201d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi
12198a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggiimport com.android.internal.R;
122164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport com.android.internal.util.DumpUtils.Dump;
123164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport com.android.server.AttributeCache;
124164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport com.android.server.wm.WindowManagerService.H;
1258fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggiimport com.android.server.wm.animation.ClipRectLRAnimation;
1268fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggiimport com.android.server.wm.animation.ClipRectTBAnimation;
127787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggiimport com.android.server.wm.animation.CurvedTranslateAnimation;
128164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
129164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerimport java.io.PrintWriter;
13077ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggiimport java.util.ArrayList;
1312f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggiimport java.util.concurrent.ExecutorService;
1322f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggiimport java.util.concurrent.Executors;
133164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
134164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner// State management of app transitions.  When we are preparing for a
135164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner// transition, mNextAppTransition will be the kind of transition to
136164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner// perform or TRANSIT_NONE if we are not waiting.  If we are waiting,
137164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner// mOpeningApps and mClosingApps are the lists of tokens that will be
138164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner// made visible or hidden at the next transition.
139164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautnerpublic class AppTransition implements Dump {
1400bd180d8880b3d1b9677f154c034a2af840b4796Filip Gruszczynski    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppTransition" : TAG_WM;
1411d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi    private static final int CLIP_REVEAL_TRANSLATION_Y_DP = 8;
1429a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner
143a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    /** Fraction of animation at which the recents thumbnail stays completely transparent */
1441d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi    private static final float RECENTS_THUMBNAIL_FADEIN_FRACTION = 0.5f;
145321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner    /** Fraction of animation at which the recents thumbnail becomes completely transparent */
1461d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi    private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.5f;
1479a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner
14884fa3351a21b37d02fafd634a8de65cf6cd04c4dFilip Gruszczynski    static final int DEFAULT_APP_TRANSITION_DURATION = 336;
1498fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi
1508fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    /** Interpolator to be used for animations that respond directly to a touch */
1518fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    static final Interpolator TOUCH_RESPONSE_INTERPOLATOR =
1528fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            new PathInterpolator(0.3f, 0f, 0.1f, 1f);
1538fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi
154c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi    private static final Interpolator THUMBNAIL_DOCK_INTERPOLATOR =
155c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi            new PathInterpolator(0.85f, 0f, 1f, 1f);
156c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi
1578fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    /**
1588fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     * Maximum duration for the clip reveal animation. This is used when there is a lot of movement
1598fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     * involved, to make it more understandable.
1608fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     */
1618fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    private static final int MAX_CLIP_REVEAL_TRANSITION_DURATION = 420;
1621d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi    private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336;
16324966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski    private static final long APP_TRANSITION_TIMEOUT_MS = 5000;
164321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner
1659a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private final Context mContext;
1661a4dfe593aafda057ac9cb3086b84588d88cd09fFilip Gruszczynski    private final WindowManagerService mService;
167164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
168f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggi    private @TransitionType int mNextAppTransition = TRANSIT_UNSET;
169f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggi    private @TransitionFlags int mNextAppTransitionFlags = 0;
17060091a978f21994e59388d90b90cc1dbe0537628Chong Zhang    private int mLastUsedAppTransition = TRANSIT_UNSET;
17160091a978f21994e59388d90b90cc1dbe0537628Chong Zhang    private String mLastOpeningApp;
17260091a978f21994e59388d90b90cc1dbe0537628Chong Zhang    private String mLastClosingApp;
173164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
1749a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private static final int NEXT_TRANSIT_TYPE_NONE = 0;
1759a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private static final int NEXT_TRANSIT_TYPE_CUSTOM = 1;
1769a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private static final int NEXT_TRANSIT_TYPE_SCALE_UP = 2;
1779a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP = 3;
1789a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN = 4;
179a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP = 5;
180a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN = 6;
181044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung    private static final int NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE = 7;
18210e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase    private static final int NEXT_TRANSIT_TYPE_CLIP_REVEAL = 8;
183089c35e9311386844332dbe2ca09076f845a604cTony Mak
184089c35e9311386844332dbe2ca09076f845a604cTony Mak    /**
185089c35e9311386844332dbe2ca09076f845a604cTony Mak     * Refers to the transition to activity started by using {@link
186089c35e9311386844332dbe2ca09076f845a604cTony Mak     * android.content.pm.crossprofile.CrossProfileApps#startMainActivity(ComponentName, UserHandle)
187089c35e9311386844332dbe2ca09076f845a604cTony Mak     * }.
188089c35e9311386844332dbe2ca09076f845a604cTony Mak     */
189089c35e9311386844332dbe2ca09076f845a604cTony Mak    private static final int NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS = 9;
19033a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi    private static final int NEXT_TRANSIT_TYPE_REMOTE = 10;
19133a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi
1929a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
1939a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner
194399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    // These are the possible states for the enter/exit activities during a thumbnail transition
195399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
196399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_UP = 1;
197399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN = 2;
198399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;
199399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
2009a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private String mNextAppTransitionPackage;
201164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    // Used for thumbnail transitions. True if we're scaling up, false if scaling down
2029a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private boolean mNextAppTransitionScaleUp;
2039a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private IRemoteCallback mNextAppTransitionCallback;
2047cc7b08a40c1eb5b231cafc8c663312a7f8f19e1Jorim Jaggi    private IRemoteCallback mNextAppTransitionFutureCallback;
2051a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski    private IRemoteCallback mAnimationFinishedCallback;
2069a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private int mNextAppTransitionEnter;
2079a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private int mNextAppTransitionExit;
208044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung    private int mNextAppTransitionInPlace;
209170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski
210170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski    // Keyed by task id.
211170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski    private final SparseArray<AppTransitionAnimationSpec> mNextAppTransitionAnimationsSpecs
212170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            = new SparseArray<>();
2132f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    private IAppTransitionAnimationSpecsFuture mNextAppTransitionAnimationsSpecsFuture;
2142f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    private boolean mNextAppTransitionAnimationsSpecsPending;
215170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski    private AppTransitionAnimationSpec mDefaultNextAppTransitionAnimationSpec;
216170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski
217a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    private Rect mNextAppTransitionInsets = new Rect();
2189a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner
2192820c4523cd37b4a9c5d33e558d39b798830e7e5Winson Chung    private Rect mTmpFromClipRect = new Rect();
2202820c4523cd37b4a9c5d33e558d39b798830e7e5Winson Chung    private Rect mTmpToClipRect = new Rect();
2212820c4523cd37b4a9c5d33e558d39b798830e7e5Winson Chung
222d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski    private final Rect mTmpRect = new Rect();
223170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski
2249a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private final static int APP_STATE_IDLE = 0;
2259a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private final static int APP_STATE_READY = 1;
2269a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private final static int APP_STATE_RUNNING = 2;
2279a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private final static int APP_STATE_TIMEOUT = 3;
2289a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private int mAppTransitionState = APP_STATE_IDLE;
2299a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner
2309a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private final int mConfigShortAnimTime;
231321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner    private final Interpolator mDecelerateInterpolator;
232a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    private final Interpolator mThumbnailFadeInInterpolator;
233a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    private final Interpolator mThumbnailFadeOutInterpolator;
23410e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase    private final Interpolator mLinearOutSlowInInterpolator;
2351d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi    private final Interpolator mFastOutLinearInInterpolator;
236787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi    private final Interpolator mFastOutSlowInInterpolator;
2371d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi    private final Interpolator mClipHorizontalInterpolator = new PathInterpolator(0, 0, 0.4f, 1f);
2381d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi
2391d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi    private final int mClipRevealTranslationY;
240164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
2414befbecfcc286652209126b9a64883b35544157dAmith Yamasani    private int mCurrentUserId = 0;
2428fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    private long mLastClipRevealTransitionDuration = DEFAULT_APP_TRANSITION_DURATION;
2434befbecfcc286652209126b9a64883b35544157dAmith Yamasani
24477ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi    private final ArrayList<AppTransitionListener> mListeners = new ArrayList<>();
2452f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    private final ExecutorService mDefaultExecutor = Executors.newSingleThreadExecutor();
24677ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi
247f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi    private int mLastClipRevealMaxTranslation;
248f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi    private boolean mLastHadClipReveal;
249f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi
250d737680ba29e493e62659a3997710cb5392d2657Manu Cornet    private final boolean mGridLayoutRecentsEnabled;
25143db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng    private final boolean mLowRamRecentsEnabled;
252d737680ba29e493e62659a3997710cb5392d2657Manu Cornet
25333a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi    private RemoteAnimationController mRemoteAnimationController;
25433a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi
2551a4dfe593aafda057ac9cb3086b84588d88cd09fFilip Gruszczynski    AppTransition(Context context, WindowManagerService service) {
256164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        mContext = context;
2571a4dfe593aafda057ac9cb3086b84588d88cd09fFilip Gruszczynski        mService = service;
25810e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
25910e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                com.android.internal.R.interpolator.linear_out_slow_in);
2601d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi        mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
2611d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi                com.android.internal.R.interpolator.fast_out_linear_in);
262787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
263787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi                com.android.internal.R.interpolator.fast_out_slow_in);
264164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        mConfigShortAnimTime = context.getResources().getInteger(
265164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                com.android.internal.R.integer.config_shortAnimTime);
266321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
267321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner                com.android.internal.R.interpolator.decelerate_cubic);
268a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        mThumbnailFadeInInterpolator = new Interpolator() {
269a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            @Override
270a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            public float getInterpolation(float input) {
271a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                // Linear response for first fraction, then complete after that.
272a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                if (input < RECENTS_THUMBNAIL_FADEIN_FRACTION) {
273a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                    return 0f;
274a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                }
2751d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi                float t = (input - RECENTS_THUMBNAIL_FADEIN_FRACTION) /
276a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                        (1f - RECENTS_THUMBNAIL_FADEIN_FRACTION);
2771d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi                return mFastOutLinearInInterpolator.getInterpolation(t);
278a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            }
279a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        };
280a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        mThumbnailFadeOutInterpolator = new Interpolator() {
281321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            @Override
282321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            public float getInterpolation(float input) {
283321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner                // Linear response for first fraction, then complete after that.
284321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner                if (input < RECENTS_THUMBNAIL_FADEOUT_FRACTION) {
2851d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi                    float t = input / RECENTS_THUMBNAIL_FADEOUT_FRACTION;
2861d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi                    return mLinearOutSlowInInterpolator.getInterpolation(t);
287321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner                }
288a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                return 1f;
289321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            }
290321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        };
2911d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi        mClipRevealTranslationY = (int) (CLIP_REVEAL_TRANSLATION_Y_DP
2921d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi                * mContext.getResources().getDisplayMetrics().density);
293d737680ba29e493e62659a3997710cb5392d2657Manu Cornet        mGridLayoutRecentsEnabled = SystemProperties.getBoolean("ro.recents.grid", false);
29443db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng        mLowRamRecentsEnabled = ActivityManager.isLowRamDeviceStatic();
295164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
296164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
297164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    boolean isTransitionSet() {
298164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        return mNextAppTransition != TRANSIT_UNSET;
299164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
300164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
301f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggi    boolean isTransitionEqual(@TransitionType int transit) {
302164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        return mNextAppTransition == transit;
303164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
304164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
305f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggi    @TransitionType int getAppTransition() {
306321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        return mNextAppTransition;
307164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner     }
308164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
309fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    private void setAppTransition(int transit, int flags) {
310164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        mNextAppTransition = transit;
311fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        mNextAppTransitionFlags |= flags;
31260091a978f21994e59388d90b90cc1dbe0537628Chong Zhang        setLastAppTransition(TRANSIT_UNSET, null, null);
313245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi        updateBooster();
31460091a978f21994e59388d90b90cc1dbe0537628Chong Zhang    }
31560091a978f21994e59388d90b90cc1dbe0537628Chong Zhang
31660091a978f21994e59388d90b90cc1dbe0537628Chong Zhang    void setLastAppTransition(int transit, AppWindowToken openingApp, AppWindowToken closingApp) {
31760091a978f21994e59388d90b90cc1dbe0537628Chong Zhang        mLastUsedAppTransition = transit;
31860091a978f21994e59388d90b90cc1dbe0537628Chong Zhang        mLastOpeningApp = "" + openingApp;
31960091a978f21994e59388d90b90cc1dbe0537628Chong Zhang        mLastClosingApp = "" + closingApp;
320164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
321164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
322164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    boolean isReady() {
3239a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        return mAppTransitionState == APP_STATE_READY
3249a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                || mAppTransitionState == APP_STATE_TIMEOUT;
325164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
326164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
327ae44659f30ddaba67581fbdf9c9255ac982d45abCraig Mautner    void setReady() {
328245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi        setAppTransitionState(APP_STATE_READY);
3292f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi        fetchAppTransitionSpecsFromFuture();
330164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
331164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
332164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    boolean isRunning() {
3339a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        return mAppTransitionState == APP_STATE_RUNNING;
334164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
335164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
3369a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    void setIdle() {
337245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi        setAppTransitionState(APP_STATE_IDLE);
338164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
339164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
340164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    boolean isTimeout() {
3419a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        return mAppTransitionState == APP_STATE_TIMEOUT;
342164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
343164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
3449a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    void setTimeout() {
345245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi        setAppTransitionState(APP_STATE_TIMEOUT);
346164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
347164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
348aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chung    GraphicBuffer getAppTransitionThumbnailHeader(int taskId) {
349170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
3507248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski        if (spec == null) {
3517248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski            spec = mDefaultNextAppTransitionAnimationSpec;
3527248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski        }
353aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chung        return spec != null ? spec.buffer : null;
354164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
355164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
356a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    /** Returns whether the next thumbnail transition is aspect scaled up. */
357a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    boolean isNextThumbnailTransitionAspectScaled() {
358a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
359a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
360a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    }
361a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
362a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    /** Returns whether the next thumbnail transition is scaling up. */
363a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    boolean isNextThumbnailTransitionScaleUp() {
364a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        return mNextAppTransitionScaleUp;
365a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    }
366a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
3674cbc315305379b0892cc4fb347d7050f3058f81eFilip Gruszczynski    boolean isNextAppTransitionThumbnailUp() {
3684cbc315305379b0892cc4fb347d7050f3058f81eFilip Gruszczynski        return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
3694cbc315305379b0892cc4fb347d7050f3058f81eFilip Gruszczynski                mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP;
3704cbc315305379b0892cc4fb347d7050f3058f81eFilip Gruszczynski    }
3714cbc315305379b0892cc4fb347d7050f3058f81eFilip Gruszczynski
3724cbc315305379b0892cc4fb347d7050f3058f81eFilip Gruszczynski    boolean isNextAppTransitionThumbnailDown() {
3734cbc315305379b0892cc4fb347d7050f3058f81eFilip Gruszczynski        return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN ||
3744cbc315305379b0892cc4fb347d7050f3058f81eFilip Gruszczynski                mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
3754cbc315305379b0892cc4fb347d7050f3058f81eFilip Gruszczynski    }
3764cbc315305379b0892cc4fb347d7050f3058f81eFilip Gruszczynski
37764b8d562115e632ff65a17fab8923a931b0a5000Tony Mak
37864b8d562115e632ff65a17fab8923a931b0a5000Tony Mak    boolean isNextAppTransitionOpenCrossProfileApps() {
37964b8d562115e632ff65a17fab8923a931b0a5000Tony Mak        return mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS;
38064b8d562115e632ff65a17fab8923a931b0a5000Tony Mak    }
38164b8d562115e632ff65a17fab8923a931b0a5000Tony Mak
3822f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    /**
3832f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi     * @return true if and only if we are currently fetching app transition specs from the future
3842f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi     *         passed into {@link #overridePendingAppTransitionMultiThumbFuture}
3852f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi     */
3862f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    boolean isFetchingAppTransitionsSpecs() {
3872f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi        return mNextAppTransitionAnimationsSpecsPending;
3882f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    }
3892f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi
39024966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski    private boolean prepare() {
3919a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        if (!isRunning()) {
392245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi            setAppTransitionState(APP_STATE_IDLE);
39377ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi            notifyAppTransitionPendingLocked();
394f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi            mLastHadClipReveal = false;
395f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi            mLastClipRevealMaxTranslation = 0;
396f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi            mLastClipRevealTransitionDuration = DEFAULT_APP_TRANSITION_DURATION;
3978ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale            return true;
3989a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        }
3998ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        return false;
400164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
401164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
402fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    /**
403fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi     * @return bit-map of WindowManagerPolicy#FINISH_LAYOUT_REDO_* to indicate whether another
404fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi     *         layout pass needs to be done
405fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi     */
406f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi    int goodToGo(int transit, AppWindowToken topOpeningApp,
407f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi            AppWindowToken topClosingApp, ArraySet<AppWindowToken> openingApps,
408fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            ArraySet<AppWindowToken> closingApps) {
4094b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner        mNextAppTransition = TRANSIT_UNSET;
410fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        mNextAppTransitionFlags = 0;
411245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi        setAppTransitionState(APP_STATE_RUNNING);
412f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi        final AnimationAdapter topOpeningAnim = topOpeningApp != null
413f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi                ? topOpeningApp.getAnimation()
414f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi                : null;
415fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        int redoLayout = notifyAppTransitionStartingLocked(transit,
416f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi                topOpeningApp != null ? topOpeningApp.token : null,
417f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi                topClosingApp != null ? topClosingApp.token : null,
418f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi                topOpeningAnim != null ? topOpeningAnim.getDurationHint() : 0,
419f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi                topOpeningAnim != null
420f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi                        ? topOpeningAnim.getStatusBarTransitionsStartTime()
421f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi                        : SystemClock.uptimeMillis(),
422f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi                AnimationAdapter.STATUS_BAR_TRANSITION_DURATION);
42342625d1bc7ef99c4d4435e8cdebfe3eee57b8d97Jorim Jaggi        mService.getDefaultDisplayContentLocked().getDockedDividerController()
424fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                .notifyAppTransitionStarting(openingApps, transit);
425363ab98fced07bf7647355367be9e6ef76751450Jorim Jaggi
42633a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        if (mRemoteAnimationController != null) {
42733a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi            mRemoteAnimationController.goodToGo();
42833a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        }
429fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        return redoLayout;
430363ab98fced07bf7647355367be9e6ef76751450Jorim Jaggi    }
431363ab98fced07bf7647355367be9e6ef76751450Jorim Jaggi
432164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    void clear() {
4339a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
434164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        mNextAppTransitionPackage = null;
435170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        mNextAppTransitionAnimationsSpecs.clear();
43633a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        mRemoteAnimationController = null;
43765193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi        mNextAppTransitionAnimationsSpecsFuture = null;
43865193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi        mDefaultNextAppTransitionAnimationSpec = null;
43965193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi        mAnimationFinishedCallback = null;
440164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
441164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
4429a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    void freeze() {
443fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        final int transit = mNextAppTransition;
444f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggi        setAppTransition(TRANSIT_UNSET, 0 /* flags */);
4459a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        clear();
4469a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        setReady();
447fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        notifyAppTransitionCancelledLocked(transit);
44877ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi    }
44977ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi
450245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi    private void setAppTransitionState(int state) {
451245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi        mAppTransitionState = state;
452245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi        updateBooster();
453245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi    }
454245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi
455245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi    /**
456245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi     * Updates whether we currently boost wm locked sections and the animation thread. We want to
457245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi     * boost the priorities to a more important value whenever an app transition is going to happen
458245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi     * soon or an app transition is running.
459245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi     */
460c8cc2292a6e60ec2276ea0d562dfc5711a205b41Jorim Jaggi    void updateBooster() {
461c8cc2292a6e60ec2276ea0d562dfc5711a205b41Jorim Jaggi        WindowManagerService.sThreadPriorityBooster.setAppTransitionRunning(needsBoosting());
462c8cc2292a6e60ec2276ea0d562dfc5711a205b41Jorim Jaggi    }
463c8cc2292a6e60ec2276ea0d562dfc5711a205b41Jorim Jaggi
464c8cc2292a6e60ec2276ea0d562dfc5711a205b41Jorim Jaggi    private boolean needsBoosting() {
465c8cc2292a6e60ec2276ea0d562dfc5711a205b41Jorim Jaggi        final boolean recentsAnimRunning = mService.getRecentsAnimationController() != null;
466c8cc2292a6e60ec2276ea0d562dfc5711a205b41Jorim Jaggi        return mNextAppTransition != TRANSIT_UNSET
467c8cc2292a6e60ec2276ea0d562dfc5711a205b41Jorim Jaggi                || mAppTransitionState == APP_STATE_READY
468c8cc2292a6e60ec2276ea0d562dfc5711a205b41Jorim Jaggi                || mAppTransitionState == APP_STATE_RUNNING
469c8cc2292a6e60ec2276ea0d562dfc5711a205b41Jorim Jaggi                || recentsAnimRunning;
470245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi    }
471245281c056a5b880486671157b48d6c4e5815ce1Jorim Jaggi
47277ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi    void registerListenerLocked(AppTransitionListener listener) {
47377ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi        mListeners.add(listener);
47477ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi    }
47577ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi
476a48eadbeb6fa34f27d6db7de51d3c01972ea2ebfWale Ogunwale    public void notifyAppTransitionFinishedLocked(IBinder token) {
47777ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi        for (int i = 0; i < mListeners.size(); i++) {
47877ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi            mListeners.get(i).onAppTransitionFinishedLocked(token);
47977ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi        }
48077ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi    }
48177ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi
48277ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi    private void notifyAppTransitionPendingLocked() {
48377ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi        for (int i = 0; i < mListeners.size(); i++) {
48477ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi            mListeners.get(i).onAppTransitionPendingLocked();
48577ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi        }
48677ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi    }
48777ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi
488fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    private void notifyAppTransitionCancelledLocked(int transit) {
48977ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi        for (int i = 0; i < mListeners.size(); i++) {
490fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            mListeners.get(i).onAppTransitionCancelledLocked(transit);
49177ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi        }
49277ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi    }
49377ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi
494fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    private int notifyAppTransitionStartingLocked(int transit, IBinder openToken,
495f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi            IBinder closeToken, long duration, long statusBarAnimationStartTime,
496f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi            long statusBarAnimationDuration) {
497fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        int redoLayout = 0;
49877ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi        for (int i = 0; i < mListeners.size(); i++) {
499fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            redoLayout |= mListeners.get(i).onAppTransitionStartingLocked(transit, openToken,
500f5f9e12146a3857c28b8c0fc96c2fa68a2ae40deJorim Jaggi                    closeToken, duration, statusBarAnimationStartTime, statusBarAnimationDuration);
50177ba4803a510717032181e7cf0beca9d07f09733Jorim Jaggi        }
502fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        return redoLayout;
5039a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    }
5049a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner
505f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggi    private AttributeCache.Entry getCachedAnimations(LayoutParams lp) {
506164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
507164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                + (lp != null ? lp.packageName : null)
508164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
509164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        if (lp != null && lp.windowAnimations != 0) {
510164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            // If this is a system resource, don't try to load it from the
511164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            // application resources.  It is nice to avoid loading application
512164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            // resources if we can.
513164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            String packageName = lp.packageName != null ? lp.packageName : "android";
514164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            int resId = lp.windowAnimations;
515164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            if ((resId&0xFF000000) == 0x01000000) {
516164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                packageName = "android";
517164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            }
518164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
519164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    + packageName);
520164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            return AttributeCache.instance().get(packageName, resId,
5214befbecfcc286652209126b9a64883b35544157dAmith Yamasani                    com.android.internal.R.styleable.WindowAnimation, mCurrentUserId);
522164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
523164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        return null;
524164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
525164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
526164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
527164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
528164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                + packageName + " resId=0x" + Integer.toHexString(resId));
529164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        if (packageName != null) {
530164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            if ((resId&0xFF000000) == 0x01000000) {
531164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                packageName = "android";
532164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            }
533164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
534164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    + packageName);
535164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            return AttributeCache.instance().get(packageName, resId,
5364befbecfcc286652209126b9a64883b35544157dAmith Yamasani                    com.android.internal.R.styleable.WindowAnimation, mCurrentUserId);
537164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
538164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        return null;
539164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
540164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
5410a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi    Animation loadAnimationAttr(LayoutParams lp, int animAttr, int transit) {
54264c57a8c9649a1c264f667710538f65d1a8ea0b4Todd Kennedy        int resId = ResourceId.ID_NULL;
543164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        Context context = mContext;
5445f95b0000ae540b1166e8443e8fa6e0e41f984d7Jorim Jaggi        if (animAttr >= 0) {
545164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            AttributeCache.Entry ent = getCachedAnimations(lp);
546164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            if (ent != null) {
547164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                context = ent.context;
54864c57a8c9649a1c264f667710538f65d1a8ea0b4Todd Kennedy                resId = ent.array.getResourceId(animAttr, 0);
549164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            }
550164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
55164c57a8c9649a1c264f667710538f65d1a8ea0b4Todd Kennedy        resId = updateToTranslucentAnimIfNeeded(resId, transit);
55264c57a8c9649a1c264f667710538f65d1a8ea0b4Todd Kennedy        if (ResourceId.isValid(resId)) {
55364c57a8c9649a1c264f667710538f65d1a8ea0b4Todd Kennedy            return AnimationUtils.loadAnimation(context, resId);
554164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
555164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        return null;
556164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
557164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
558f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggi    Animation loadAnimationRes(LayoutParams lp, int resId) {
559e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        Context context = mContext;
56064c57a8c9649a1c264f667710538f65d1a8ea0b4Todd Kennedy        if (ResourceId.isValid(resId)) {
561e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            AttributeCache.Entry ent = getCachedAnimations(lp);
562e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            if (ent != null) {
563e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                context = ent.context;
564e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            }
565e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            return AnimationUtils.loadAnimation(context, resId);
566e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        }
567e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        return null;
568e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn    }
569e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn
570e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn    private Animation loadAnimationRes(String packageName, int resId) {
57164c57a8c9649a1c264f667710538f65d1a8ea0b4Todd Kennedy        if (ResourceId.isValid(resId)) {
572164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
573164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            if (ent != null) {
57464c57a8c9649a1c264f667710538f65d1a8ea0b4Todd Kennedy                return AnimationUtils.loadAnimation(ent.context, resId);
575164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            }
576164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
577164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        return null;
578164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
579164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
5800a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi    private int updateToTranslucentAnimIfNeeded(int anim, int transit) {
5810a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi        if (transit == TRANSIT_TRANSLUCENT_ACTIVITY_OPEN && anim == R.anim.activity_open_enter) {
5820a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi            return R.anim.activity_translucent_open_enter;
5830a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi        }
5840a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi        if (transit == TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE && anim == R.anim.activity_close_exit) {
5850a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi            return R.anim.activity_translucent_close_exit;
5860a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi        }
5870a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi        return anim;
5880a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi    }
5890a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi
590164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    /**
591164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner     * Compute the pivot point for an animation that is scaling from a small
592164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner     * rect on screen to a larger rect.  The pivot point varies depending on
593164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner     * the distance between the inner and outer edges on both sides.  This
594164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner     * function computes the pivot point for one dimension.
595164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner     * @param startPos  Offset from left/top edge of outer rectangle to
596164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner     * left/top edge of inner rectangle.
597164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner     * @param finalScale The scaling factor between the size of the outer
598164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner     * and inner rectangles.
599164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner     */
600164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    private static float computePivot(int startPos, float finalScale) {
601c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi
602c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi        /*
603c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi        Theorem of intercepting lines:
604c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi
605c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          +      +   +-----------------------------------------------+
606c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |      |   |                                               |
607c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |      |   |                                               |
608c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |      |   |                                               |
609c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |      |   |                                               |
610c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi        x |    y |   |                                               |
611c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |      |   |                                               |
612c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |      |   |                                               |
613c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |      |   |                                               |
614c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |      |   |                                               |
615c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |      +   |             +--------------------+            |
616c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
617c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
618c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
619c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
620c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
621c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
622c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
623c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
624c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
625c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
626c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
627c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
628c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
629c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
630c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
631c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
632c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             |                    |            |
633c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |             +--------------------+            |
634c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |                                               |
635c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |                                               |
636c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |                                               |
637c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |                                               |
638c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |                                               |
639c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |                                               |
640c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          |                                               |
641c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |          +-----------------------------------------------+
642c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |
643c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |
644c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |
645c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |
646c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |
647c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |
648c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |
649c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |
650c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          |
651c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi          +                                 ++
652c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi                                         p  ++
653c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi
654c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi        scale = (x - y) / x
655c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi        <=> x = -y / (scale - 1)
656c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi        */
657164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        final float denom = finalScale-1;
658164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        if (Math.abs(denom) < .0001f) {
659164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            return startPos;
660164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
661164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        return -startPos / denom;
662164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
663164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
664541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski    private Animation createScaleUpAnimationLocked(int transit, boolean enter,
665541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski            Rect containingFrame) {
666541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski        Animation a;
667d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        getDefaultNextAppTransitionStartRect(mTmpRect);
668541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski        final int appWidth = containingFrame.width();
669541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski        final int appHeight = containingFrame.height();
670164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        if (enter) {
671164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            // Entering app zooms out from the center of the initial rect.
672d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            float scaleW = mTmpRect.width() / (float) appWidth;
673d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            float scaleH = mTmpRect.height() / (float) appHeight;
674164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
675d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                    computePivot(mTmpRect.left, scaleW),
6764c3fecd31fb611d8391898b19570147eab71b3eeWinson                    computePivot(mTmpRect.top, scaleH));
677321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            scale.setInterpolator(mDecelerateInterpolator);
678321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner
679164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            Animation alpha = new AlphaAnimation(0, 1);
680a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            alpha.setInterpolator(mThumbnailFadeOutInterpolator);
681321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner
682321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            AnimationSet set = new AnimationSet(false);
683164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            set.addAnimation(scale);
684164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            set.addAnimation(alpha);
685164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            set.setDetachWallpaper(true);
686164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            a = set;
6874b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner        } else  if (transit == TRANSIT_WALLPAPER_INTRA_OPEN ||
6884b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                    transit == TRANSIT_WALLPAPER_INTRA_CLOSE) {
689321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            // If we are on top of the wallpaper, we need an animation that
690321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            // correctly handles the wallpaper staying static behind all of
691321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            // the animated elements.  To do this, will just have the existing
692321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            // element fade out.
693321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            a = new AlphaAnimation(1, 0);
694321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            a.setDetachWallpaper(true);
695164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        } else {
696321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            // For normal animations, the exiting element just holds in place.
697321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            a = new AlphaAnimation(1, 1);
698164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
699164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
700164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        // Pick the desired duration.  If this is an inter-activity transition,
701164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        // it  is the standard duration for that.  Otherwise we use the longer
702164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        // task transition duration.
703321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        final long duration;
704164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        switch (transit) {
7054b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_ACTIVITY_OPEN:
7064b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_ACTIVITY_CLOSE:
707164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                duration = mConfigShortAnimTime;
708164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                break;
709164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            default:
710321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner                duration = DEFAULT_APP_TRANSITION_DURATION;
711164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                break;
712164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
713321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        a.setDuration(duration);
714321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        a.setFillAfter(true);
715321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        a.setInterpolator(mDecelerateInterpolator);
716321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        a.initialize(appWidth, appHeight, appWidth, appHeight);
717321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        return a;
718321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner    }
719321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner
720170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski    private void getDefaultNextAppTransitionStartRect(Rect rect) {
721170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        if (mDefaultNextAppTransitionAnimationSpec == null ||
722170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski                mDefaultNextAppTransitionAnimationSpec.rect == null) {
7232550f3f787a850dc2cd0f45aa78ba70fb5c8ec3eJorim Jaggi            Slog.e(TAG, "Starting rect for app requested, but none available", new Throwable());
724170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            rect.setEmpty();
725170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        } else {
726170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            rect.set(mDefaultNextAppTransitionAnimationSpec.rect);
727170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        }
728170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski    }
729170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski
730170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski    void getNextAppTransitionStartRect(int taskId, Rect rect) {
731170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
7327248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski        if (spec == null) {
7337248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski            spec = mDefaultNextAppTransitionAnimationSpec;
7347248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski        }
735170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        if (spec == null || spec.rect == null) {
7362550f3f787a850dc2cd0f45aa78ba70fb5c8ec3eJorim Jaggi            Slog.e(TAG, "Starting rect for task: " + taskId + " requested, but not available",
737170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski                    new Throwable());
738170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            rect.setEmpty();
739170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        } else {
740170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            rect.set(spec.rect);
741170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        }
742170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski    }
743170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski
7447248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski    private void putDefaultNextAppTransitionCoordinates(int left, int top, int width, int height,
745aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chung            GraphicBuffer buffer) {
746170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        mDefaultNextAppTransitionAnimationSpec = new AppTransitionAnimationSpec(-1 /* taskId */,
747aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chung                buffer, new Rect(left, top, left + width, top + height));
748170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski    }
749170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski
750f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi    /**
751f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi     * @return the duration of the last clip reveal animation
752f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi     */
7538fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    long getLastClipRevealTransitionDuration() {
7548fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi        return mLastClipRevealTransitionDuration;
7558fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    }
7568fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi
7578fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    /**
758f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi     * @return the maximum distance the app surface is traveling of the last clip reveal animation
759f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi     */
760f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi    int getLastClipRevealMaxTranslation() {
761f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi        return mLastClipRevealMaxTranslation;
762f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi    }
763f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi
764f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi    /**
765f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi     * @return true if in the last app transition had a clip reveal animation, false otherwise
766f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi     */
767f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi    boolean hadClipRevealAnimation() {
768f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi        return mLastHadClipReveal;
769f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi    }
770f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi
771f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi    /**
7728fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     * Calculates the duration for the clip reveal animation. If the clip is "cut off", meaning that
7738fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     * the start rect is outside of the target rect, and there is a lot of movement going on.
7748fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     *
7758fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     * @param cutOff whether the start rect was not fully contained by the end rect
7768fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     * @param translationX the total translation the surface moves in x direction
7778fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     * @param translationY the total translation the surfaces moves in y direction
7788fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     * @param displayFrame our display frame
7798fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     *
7808fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     * @return the duration of the clip reveal animation, in milliseconds
7818fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi     */
7828fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    private long calculateClipRevealTransitionDuration(boolean cutOff, float translationX,
7838fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            float translationY, Rect displayFrame) {
7848fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi        if (!cutOff) {
7858fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            return DEFAULT_APP_TRANSITION_DURATION;
7868fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi        }
7878fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi        final float fraction = Math.max(Math.abs(translationX) / displayFrame.width(),
7888fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                Math.abs(translationY) / displayFrame.height());
7898fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi        return (long) (DEFAULT_APP_TRANSITION_DURATION + fraction *
7908fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                (MAX_CLIP_REVEAL_TRANSITION_DURATION - DEFAULT_APP_TRANSITION_DURATION));
7918fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    }
7928fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi
7938fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi    private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame,
7948fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            Rect displayFrame) {
79510e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase        final Animation anim;
79610e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase        if (enter) {
79780b1f64280829e7d483302c23518e9d937e7340aCraig Mautner            final int appWidth = appFrame.width();
79880b1f64280829e7d483302c23518e9d937e7340aCraig Mautner            final int appHeight = appFrame.height();
7998fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi
800d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            // mTmpRect will contain an area around the launcher icon that was pressed. We will
801828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynski            // clip reveal from that area in the final area of the app.
802d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            getDefaultNextAppTransitionStartRect(mTmpRect);
80380b1f64280829e7d483302c23518e9d937e7340aCraig Mautner
8041d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi            float t = 0f;
8051d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi            if (appHeight > 0) {
8068fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                t = (float) mTmpRect.top / displayFrame.height();
8071d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi            }
8088fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            int translationY = mClipRevealTranslationY + (int)(displayFrame.height() / 7f * t);
8098fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            int translationX = 0;
8108fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            int translationYCorrection = translationY;
811d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            int centerX = mTmpRect.centerX();
812d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            int centerY = mTmpRect.centerY();
813d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            int halfWidth = mTmpRect.width() / 2;
814d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            int halfHeight = mTmpRect.height() / 2;
8158fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            int clipStartX = centerX - halfWidth - appFrame.left;
8168fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            int clipStartY = centerY - halfHeight - appFrame.top;
8178fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            boolean cutOff = false;
8188fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi
8198fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            // If the starting rectangle is fully or partially outside of the target rectangle, we
8208fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            // need to start the clipping at the edge and then achieve the rest with translation
8218fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            // and extending the clip rect from that edge.
8228fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            if (appFrame.top > centerY - halfHeight) {
8238fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                translationY = (centerY - halfHeight) - appFrame.top;
8248fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                translationYCorrection = 0;
8258fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                clipStartY = 0;
8268fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                cutOff = true;
8278fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            }
8288fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            if (appFrame.left > centerX - halfWidth) {
8298fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                translationX = (centerX - halfWidth) - appFrame.left;
8308fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                clipStartX = 0;
8318fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                cutOff = true;
8328fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            }
8338fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            if (appFrame.right < centerX + halfWidth) {
8348fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                translationX = (centerX + halfWidth) - appFrame.right;
8358fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                clipStartX = appWidth - mTmpRect.width();
8368fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                cutOff = true;
8378fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            }
8388fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            final long duration = calculateClipRevealTransitionDuration(cutOff, translationX,
8398fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                    translationY, displayFrame);
8401d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi
8411d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi            // Clip third of the from size of launch icon, expand to full width/height
84210e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            Animation clipAnimLR = new ClipRectLRAnimation(
8438fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                    clipStartX, clipStartX + mTmpRect.width(), 0, appWidth);
8441d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi            clipAnimLR.setInterpolator(mClipHorizontalInterpolator);
8458fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            clipAnimLR.setDuration((long) (duration / 2.5f));
8468fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi
8478fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            TranslateAnimation translate = new TranslateAnimation(translationX, 0, translationY, 0);
8488fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            translate.setInterpolator(cutOff ? TOUCH_RESPONSE_INTERPOLATOR
8498fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                    : mLinearOutSlowInInterpolator);
8508fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            translate.setDuration(duration);
8518fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi
8528fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            Animation clipAnimTB = new ClipRectTBAnimation(
8538fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                    clipStartY, clipStartY + mTmpRect.height(),
8548fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                    0, appHeight,
8558fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                    translationYCorrection, 0,
8568fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi                    mLinearOutSlowInInterpolator);
8578fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            clipAnimTB.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
8588fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            clipAnimTB.setDuration(duration);
85910e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase
86010e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            // Quick fade-in from icon to app window
8618fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            final long alphaDuration = duration / 4;
8621d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi            AlphaAnimation alpha = new AlphaAnimation(0.5f, 1);
86310e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            alpha.setDuration(alphaDuration);
8641d763a6d60c09e59b1aeba6a2cb009511323c08cJorim Jaggi            alpha.setInterpolator(mLinearOutSlowInInterpolator);
86510e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase
86610e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            AnimationSet set = new AnimationSet(false);
86710e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            set.addAnimation(clipAnimLR);
86810e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            set.addAnimation(clipAnimTB);
869828613605cff46930ba6e634a1547442f3908e6dFilip Gruszczynski            set.addAnimation(translate);
87010e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            set.addAnimation(alpha);
8719e2cf5be18b4a127a7e700c6bbc11d8c1d72f551Filip Gruszczynski            set.setZAdjustment(Animation.ZORDER_TOP);
87210e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            set.initialize(appWidth, appHeight, appWidth, appHeight);
87310e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            anim = set;
874f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi            mLastHadClipReveal = true;
8758fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            mLastClipRevealTransitionDuration = duration;
876f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi
877f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi            // If the start rect was full inside the target rect (cutOff == false), we don't need
878f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi            // to store the translation, because it's only used if cutOff == true.
879f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi            mLastClipRevealMaxTranslation = cutOff
880f97ed9271fef192f5411206e781eb3519c144aceJorim Jaggi                    ? Math.max(Math.abs(translationY), Math.abs(translationX)) : 0;
88110e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase        } else {
88210e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            final long duration;
88310e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            switch (transit) {
88410e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                case TRANSIT_ACTIVITY_OPEN:
88510e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                case TRANSIT_ACTIVITY_CLOSE:
88610e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                    duration = mConfigShortAnimTime;
88710e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                    break;
88810e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                default:
88910e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                    duration = DEFAULT_APP_TRANSITION_DURATION;
89010e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                    break;
89110e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            }
89210e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            if (transit == TRANSIT_WALLPAPER_INTRA_OPEN ||
89310e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                    transit == TRANSIT_WALLPAPER_INTRA_CLOSE) {
89410e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                // If we are on top of the wallpaper, we need an animation that
89510e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                // correctly handles the wallpaper staying static behind all of
89610e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                // the animated elements.  To do this, will just have the existing
89710e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                // element fade out.
89810e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                anim = new AlphaAnimation(1, 0);
89910e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                anim.setDetachWallpaper(true);
90010e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            } else {
90110e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                // For normal animations, the exiting element just holds in place.
90210e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                anim = new AlphaAnimation(1, 1);
90310e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            }
90410e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            anim.setInterpolator(mDecelerateInterpolator);
90510e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            anim.setDuration(duration);
90610e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            anim.setFillAfter(true);
90710e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase        }
90810e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase        return anim;
90910e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase    }
91010e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase
911399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    /**
912399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     * Prepares the specified animation with a standard duration, interpolator, etc.
913399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     */
9145393dff555641f5666573952498e27c90fd3edcaWinson Chung    Animation prepareThumbnailAnimationWithDuration(Animation a, int appWidth, int appHeight,
915787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            long duration, Interpolator interpolator) {
916a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        if (duration > 0) {
917a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            a.setDuration(duration);
918a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        }
9195393dff555641f5666573952498e27c90fd3edcaWinson Chung        a.setFillAfter(true);
920c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi        if (interpolator != null) {
921c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi            a.setInterpolator(interpolator);
922c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi        }
9235393dff555641f5666573952498e27c90fd3edcaWinson Chung        a.initialize(appWidth, appHeight, appWidth, appHeight);
9245393dff555641f5666573952498e27c90fd3edcaWinson Chung        return a;
9255393dff555641f5666573952498e27c90fd3edcaWinson Chung    }
9265393dff555641f5666573952498e27c90fd3edcaWinson Chung
9275393dff555641f5666573952498e27c90fd3edcaWinson Chung    /**
9285393dff555641f5666573952498e27c90fd3edcaWinson Chung     * Prepares the specified animation with a standard duration, interpolator, etc.
9295393dff555641f5666573952498e27c90fd3edcaWinson Chung     */
930399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    Animation prepareThumbnailAnimation(Animation a, int appWidth, int appHeight, int transit) {
931399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        // Pick the desired duration.  If this is an inter-activity transition,
932399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        // it  is the standard duration for that.  Otherwise we use the longer
933399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        // task transition duration.
9345393dff555641f5666573952498e27c90fd3edcaWinson Chung        final int duration;
935399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        switch (transit) {
936399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            case TRANSIT_ACTIVITY_OPEN:
937399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            case TRANSIT_ACTIVITY_CLOSE:
938399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                duration = mConfigShortAnimTime;
939399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                break;
940399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            default:
941399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                duration = DEFAULT_APP_TRANSITION_DURATION;
942399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                break;
943399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        }
9445393dff555641f5666573952498e27c90fd3edcaWinson Chung        return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
9455393dff555641f5666573952498e27c90fd3edcaWinson Chung                mDecelerateInterpolator);
946399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    }
947399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
948399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    /**
949399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     * Return the current thumbnail transition state.
950399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     */
951399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    int getThumbnailTransitionState(boolean enter) {
952399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        if (enter) {
953399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            if (mNextAppTransitionScaleUp) {
954399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                return THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
955399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            } else {
956399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                return THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN;
957399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            }
958399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        } else {
959399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            if (mNextAppTransitionScaleUp) {
960399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                return THUMBNAIL_TRANSITION_EXIT_SCALE_UP;
961399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            } else {
962399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                return THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN;
963399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            }
964399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        }
965399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    }
966399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
967399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    /**
96864b8d562115e632ff65a17fab8923a931b0a5000Tony Mak     * Creates an overlay with a background color and a thumbnail for the cross profile apps
96964b8d562115e632ff65a17fab8923a931b0a5000Tony Mak     * animation.
97064b8d562115e632ff65a17fab8923a931b0a5000Tony Mak     */
97164b8d562115e632ff65a17fab8923a931b0a5000Tony Mak    GraphicBuffer createCrossProfileAppsThumbnail(
97264b8d562115e632ff65a17fab8923a931b0a5000Tony Mak            @DrawableRes int thumbnailDrawableRes, Rect frame) {
97364b8d562115e632ff65a17fab8923a931b0a5000Tony Mak        final int width = frame.width();
97464b8d562115e632ff65a17fab8923a931b0a5000Tony Mak        final int height = frame.height();
97564b8d562115e632ff65a17fab8923a931b0a5000Tony Mak
976519ad488a5157143e883e437b1e259472280c746John Reck        final Picture picture = new Picture();
977519ad488a5157143e883e437b1e259472280c746John Reck        final Canvas canvas = picture.beginRecording(width, height);
97864b8d562115e632ff65a17fab8923a931b0a5000Tony Mak        canvas.drawColor(Color.argb(0.6f, 0, 0, 0));
97964b8d562115e632ff65a17fab8923a931b0a5000Tony Mak        final int thumbnailSize = mService.mContext.getResources().getDimensionPixelSize(
98064b8d562115e632ff65a17fab8923a931b0a5000Tony Mak                com.android.internal.R.dimen.cross_profile_apps_thumbnail_size);
98164b8d562115e632ff65a17fab8923a931b0a5000Tony Mak        final Drawable drawable = mService.mContext.getDrawable(thumbnailDrawableRes);
98264b8d562115e632ff65a17fab8923a931b0a5000Tony Mak        drawable.setBounds(
98364b8d562115e632ff65a17fab8923a931b0a5000Tony Mak                (width - thumbnailSize) / 2,
98464b8d562115e632ff65a17fab8923a931b0a5000Tony Mak                (height - thumbnailSize) / 2,
98564b8d562115e632ff65a17fab8923a931b0a5000Tony Mak                (width + thumbnailSize) / 2,
98664b8d562115e632ff65a17fab8923a931b0a5000Tony Mak                (height + thumbnailSize) / 2);
987da4af2379576f824bb6b439041222147cc17979bTony Mak        drawable.setTint(mContext.getColor(android.R.color.white));
98864b8d562115e632ff65a17fab8923a931b0a5000Tony Mak        drawable.draw(canvas);
989519ad488a5157143e883e437b1e259472280c746John Reck        picture.endRecording();
99064b8d562115e632ff65a17fab8923a931b0a5000Tony Mak
991519ad488a5157143e883e437b1e259472280c746John Reck        return Bitmap.createBitmap(picture).createGraphicBufferHandle();
99264b8d562115e632ff65a17fab8923a931b0a5000Tony Mak    }
99364b8d562115e632ff65a17fab8923a931b0a5000Tony Mak
99464b8d562115e632ff65a17fab8923a931b0a5000Tony Mak    Animation createCrossProfileAppsThumbnailAnimationLocked(Rect appRect) {
99564b8d562115e632ff65a17fab8923a931b0a5000Tony Mak        final Animation animation = loadAnimationRes(
99664b8d562115e632ff65a17fab8923a931b0a5000Tony Mak                "android", com.android.internal.R.anim.cross_profile_apps_thumbnail_enter);
99764b8d562115e632ff65a17fab8923a931b0a5000Tony Mak        return prepareThumbnailAnimationWithDuration(animation, appRect.width(),
99864b8d562115e632ff65a17fab8923a931b0a5000Tony Mak                appRect.height(), 0, null);
99964b8d562115e632ff65a17fab8923a931b0a5000Tony Mak    }
100064b8d562115e632ff65a17fab8923a931b0a5000Tony Mak
100164b8d562115e632ff65a17fab8923a931b0a5000Tony Mak    /**
1002399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
1003170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski     * when a thumbnail is specified with the pending animation override.
1004399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     */
1005de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi    Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, @Nullable Rect contentInsets,
1006aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chung            GraphicBuffer thumbnailHeader, final int taskId, int uiMode, int orientation) {
1007321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        Animation a;
1008170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        final int thumbWidthI = thumbnailHeader.getWidth();
1009321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
1010170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        final int thumbHeightI = thumbnailHeader.getHeight();
1011dfb25d3fd513ccbe9a403e7b9a21c44d8382c703Filip Gruszczynski        final int appWidth = appRect.width();
1012321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner
1013dfb25d3fd513ccbe9a403e7b9a21c44d8382c703Filip Gruszczynski        float scaleW = appWidth / thumbWidth;
1014d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        getNextAppTransitionStartRect(taskId, mTmpRect);
10150907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi        final float fromX;
101657b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet        float fromY;
10170907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi        final float toX;
101857b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet        float toY;
10190907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi        final float pivotX;
10200907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi        final float pivotY;
1021d737680ba29e493e62659a3997710cb5392d2657Manu Cornet        if (shouldScaleDownThumbnailTransition(uiMode, orientation)) {
10220907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            fromX = mTmpRect.left;
10230907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            fromY = mTmpRect.top;
10240907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi
10250907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            // For the curved translate animation to work, the pivot points needs to be at the
10260907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            // same absolute position as the one from the real surface.
10270907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            toX = mTmpRect.width() / 2 * (scaleW - 1f) + appRect.left;
10280907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            toY = appRect.height() / 2 * (1 - 1 / scaleW) + appRect.top;
10290907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            pivotX = mTmpRect.width() / 2;
10300907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            pivotY = appRect.height() / 2 / scaleW;
103157b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet            if (mGridLayoutRecentsEnabled) {
103257b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet                // In the grid layout, the header is displayed above the thumbnail instead of
103357b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet                // overlapping it.
103457b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet                fromY -= thumbHeightI;
103557b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet                toY -= thumbHeightI * scaleW;
103657b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet            }
10370907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi        } else {
10380907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            pivotX = 0;
10390907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            pivotY = 0;
10400907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            fromX = mTmpRect.left;
10410907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            fromY = mTmpRect.top;
10420907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            toX = appRect.left;
10430907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi            toY = appRect.top;
10440907200095ec73e71c6520580a9b82126058ddf2Jorim Jaggi        }
1045787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        final long duration = getAspectScaleDuration();
1046787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        final Interpolator interpolator = getAspectScaleInterpolator();
1047399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        if (mNextAppTransitionScaleUp) {
1048a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            // Animation up from the thumbnail to the full screen
10498448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi            Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW, pivotX, pivotY);
1050787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            scale.setInterpolator(interpolator);
1051787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            scale.setDuration(duration);
1052c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi            Animation alpha = new AlphaAnimation(1f, 0f);
1053c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi            alpha.setInterpolator(mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS
1054c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                    ? THUMBNAIL_DOCK_INTERPOLATOR : mThumbnailFadeOutInterpolator);
1055c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi            alpha.setDuration(mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS
1056c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                    ? duration / 2
1057c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                    : duration);
1058787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            Animation translate = createCurvedMotion(fromX, toX, fromY, toY);
1059787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            translate.setInterpolator(interpolator);
1060787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            translate.setDuration(duration);
1061399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
1062de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi            mTmpFromClipRect.set(0, 0, thumbWidthI, thumbHeightI);
1063de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi            mTmpToClipRect.set(appRect);
1064de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi
1065de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi            // Containing frame is in screen space, but we need the clip rect in the
1066de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi            // app space.
1067de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi            mTmpToClipRect.offsetTo(0, 0);
1068c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi            mTmpToClipRect.right = (int) (mTmpToClipRect.right / scaleW);
1069c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi            mTmpToClipRect.bottom = (int) (mTmpToClipRect.bottom / scaleW);
1070de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi
1071de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi            if (contentInsets != null) {
10728448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                mTmpToClipRect.inset((int) (-contentInsets.left * scaleW),
10738448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        (int) (-contentInsets.top * scaleW),
10748448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        (int) (-contentInsets.right * scaleW),
10758448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        (int) (-contentInsets.bottom * scaleW));
1076de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi            }
1077de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi
1078de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi            Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
1079787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            clipAnim.setInterpolator(interpolator);
1080787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            clipAnim.setDuration(duration);
1081de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi
1082399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            // This AnimationSet uses the Interpolators assigned above.
1083399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            AnimationSet set = new AnimationSet(false);
1084399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            set.addAnimation(scale);
108557b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet            if (!mGridLayoutRecentsEnabled) {
108657b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet                // In the grid layout, the header should be shown for the whole animation.
108757b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet                set.addAnimation(alpha);
108857b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet            }
1089a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            set.addAnimation(translate);
1090de63d441d7daf0503bcc6d5fd3f4f7efe06e23d3Jorim Jaggi            set.addAnimation(clipAnim);
1091399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            a = set;
1092399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        } else {
1093a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            // Animation down from the full screen to the thumbnail
10948448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi            Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f, pivotX, pivotY);
1095787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            scale.setInterpolator(interpolator);
1096787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            scale.setDuration(duration);
1097a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            Animation alpha = new AlphaAnimation(0f, 1f);
1098a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            alpha.setInterpolator(mThumbnailFadeInInterpolator);
1099787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            alpha.setDuration(duration);
1100787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            Animation translate = createCurvedMotion(toX, fromX, toY, fromY);
1101787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            translate.setInterpolator(interpolator);
1102787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            translate.setDuration(duration);
1103399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
1104a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            // This AnimationSet uses the Interpolators assigned above.
1105a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            AnimationSet set = new AnimationSet(false);
1106a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            set.addAnimation(scale);
110757b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet            if (!mGridLayoutRecentsEnabled) {
110857b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet                // In the grid layout, the header should be shown for the whole animation.
110957b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet                set.addAnimation(alpha);
111057b6149f8bd287650992e3e4d4adae4369fd4f88Manu Cornet            }
1111a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            set.addAnimation(translate);
1112a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            a = set;
1113a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
1114a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        }
1115dfb25d3fd513ccbe9a403e7b9a21c44d8382c703Filip Gruszczynski        return prepareThumbnailAnimationWithDuration(a, appWidth, appRect.height(), 0,
1116c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                null);
1117399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    }
1118399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
1119787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi    private Animation createCurvedMotion(float fromX, float toX, float fromY, float toY) {
1120787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi
1121787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        // Almost no x-change - use linear animation
1122c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi        if (Math.abs(toX - fromX) < 1f || mNextAppTransition != TRANSIT_DOCK_TASK_FROM_RECENTS) {
1123787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            return new TranslateAnimation(fromX, toX, fromY, toY);
1124787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        } else {
1125787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            final Path path = createCurvedPath(fromX, toX, fromY, toY);
1126787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            return new CurvedTranslateAnimation(path);
1127787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        }
1128787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi    }
1129787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi
1130787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi    private Path createCurvedPath(float fromX, float toX, float fromY, float toY) {
1131787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        final Path path = new Path();
1132787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        path.moveTo(fromX, fromY);
11331f458fb6a1fbb8ec693d10f195b99310bcfd34d0Jorim Jaggi
11341f458fb6a1fbb8ec693d10f195b99310bcfd34d0Jorim Jaggi        if (fromY > toY) {
11351f458fb6a1fbb8ec693d10f195b99310bcfd34d0Jorim Jaggi            // If the object needs to go up, move it in horizontal direction first, then vertical.
11361f458fb6a1fbb8ec693d10f195b99310bcfd34d0Jorim Jaggi            path.cubicTo(fromX, fromY, toX, 0.9f * fromY + 0.1f * toY, toX, toY);
11371f458fb6a1fbb8ec693d10f195b99310bcfd34d0Jorim Jaggi        } else {
11381f458fb6a1fbb8ec693d10f195b99310bcfd34d0Jorim Jaggi            // If the object needs to go down, move it in vertical direction first, then horizontal.
11391f458fb6a1fbb8ec693d10f195b99310bcfd34d0Jorim Jaggi            path.cubicTo(fromX, fromY, fromX, 0.1f * fromY + 0.9f * toY, toX, toY);
11401f458fb6a1fbb8ec693d10f195b99310bcfd34d0Jorim Jaggi        }
1141787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        return path;
1142787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi    }
1143787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi
1144787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi    private long getAspectScaleDuration() {
1145787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        if (mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS) {
1146c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi            return (long) (THUMBNAIL_APP_TRANSITION_DURATION * 1.35f);
1147787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        } else {
1148787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            return THUMBNAIL_APP_TRANSITION_DURATION;
1149787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        }
1150787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi    }
1151787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi
1152787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi    private Interpolator getAspectScaleInterpolator() {
1153787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        if (mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS) {
1154787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            return mFastOutSlowInInterpolator;
1155787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        } else {
1156787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi            return TOUCH_RESPONSE_INTERPOLATOR;
1157787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        }
1158787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi    }
1159787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi
1160399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    /**
1161399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     * This alternate animation is created when we are doing a thumbnail transition, for the
1162399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     * activity that is leaving, and the activity that is entering.
1163399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     */
1164a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState,
1165b20247636b0e0a75edcd327a047b9ea7a9d21b77Winson            int uiMode, int orientation, int transit, Rect containingFrame, Rect contentInsets,
116643db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng            @Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean freeform,
116743db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng            int taskId) {
1168399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        Animation a;
1169541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski        final int appWidth = containingFrame.width();
1170541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski        final int appHeight = containingFrame.height();
1171d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        getDefaultNextAppTransitionStartRect(mTmpRect);
1172d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final int thumbWidthI = mTmpRect.width();
1173399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
1174d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final int thumbHeightI = mTmpRect.height();
1175399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
1176cbb625bc6d22ad806560dd192d3945cdd5021cfbWinson        final int thumbStartX = mTmpRect.left - containingFrame.left - contentInsets.left;
1177217009356efa2b854ab3981dff8d315a0d679c73Winson        final int thumbStartY = mTmpRect.top - containingFrame.top;
1178399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
1179399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        switch (thumbTransitState) {
11808448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi            case THUMBNAIL_TRANSITION_ENTER_SCALE_UP:
11818448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi            case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
11828448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                final boolean scaleUp = thumbTransitState == THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
11838448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                if (freeform && scaleUp) {
1184d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                    a = createAspectScaledThumbnailEnterFreeformAnimationLocked(
1185170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski                            containingFrame, surfaceInsets, taskId);
11868448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                } else if (freeform) {
11878448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                    a = createAspectScaledThumbnailExitFreeformAnimationLocked(
11888448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                            containingFrame, surfaceInsets, taskId);
11892820c4523cd37b4a9c5d33e558d39b798830e7e5Winson Chung                } else {
1190217009356efa2b854ab3981dff8d315a0d679c73Winson                    AnimationSet set = new AnimationSet(true);
1191217009356efa2b854ab3981dff8d315a0d679c73Winson
1192217009356efa2b854ab3981dff8d315a0d679c73Winson                    // In portrait, we scale to fit the width
1193efd3d1b41f5c9ced2b6eed4ab6f95a267bcde9f2Filip Gruszczynski                    mTmpFromClipRect.set(containingFrame);
1194efd3d1b41f5c9ced2b6eed4ab6f95a267bcde9f2Filip Gruszczynski                    mTmpToClipRect.set(containingFrame);
1195c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi
1196c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi                    // Containing frame is in screen space, but we need the clip rect in the
1197c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi                    // app space.
1198c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi                    mTmpFromClipRect.offsetTo(0, 0);
1199c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi                    mTmpToClipRect.offsetTo(0, 0);
1200c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi
1201c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi                    // Exclude insets region from the source clip.
1202c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi                    mTmpFromClipRect.inset(contentInsets);
1203217009356efa2b854ab3981dff8d315a0d679c73Winson                    mNextAppTransitionInsets.set(contentInsets);
1204c6c89a82144f59475242c75d67529fed943ae30bJorim Jaggi
1205d737680ba29e493e62659a3997710cb5392d2657Manu Cornet                    if (shouldScaleDownThumbnailTransition(uiMode, orientation)) {
1206c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                        // We scale the width and clip to the top/left square
1207c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                        float scale = thumbWidth /
1208c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                                (appWidth - contentInsets.left - contentInsets.right);
1209b68b765cbf61cc2aa79940475a11662dd97f3b80Manu Cornet                        if (!mGridLayoutRecentsEnabled) {
1210b68b765cbf61cc2aa79940475a11662dd97f3b80Manu Cornet                            int unscaledThumbHeight = (int) (thumbHeight / scale);
1211b68b765cbf61cc2aa79940475a11662dd97f3b80Manu Cornet                            mTmpFromClipRect.bottom = mTmpFromClipRect.top + unscaledThumbHeight;
1212b68b765cbf61cc2aa79940475a11662dd97f3b80Manu Cornet                        }
1213c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi
1214c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                        mNextAppTransitionInsets.set(contentInsets);
1215c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi
12168448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        Animation scaleAnim = new ScaleAnimation(
12178448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                                scaleUp ? scale : 1, scaleUp ? 1 : scale,
12188448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                                scaleUp ? scale : 1, scaleUp ? 1 : scale,
1219c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                                containingFrame.width() / 2f,
1220c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                                containingFrame.height() / 2f + contentInsets.top);
12218448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        final float targetX = (mTmpRect.left - containingFrame.left);
1222c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                        final float x = containingFrame.width() / 2f
1223c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                                - containingFrame.width() / 2f * scale;
12248448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        final float targetY = (mTmpRect.top - containingFrame.top);
122543db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng                        float y = containingFrame.height() / 2f
1226c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                                - containingFrame.height() / 2f * scale;
122743db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng
122843db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng                        // During transition may require clipping offset from any top stable insets
122943db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng                        // such as the statusbar height when statusbar is hidden
123043db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng                        if (mLowRamRecentsEnabled && contentInsets.top == 0 && scaleUp) {
123143db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng                            mTmpFromClipRect.top += stableInsets.top;
123243db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng                            y += stableInsets.top;
123343db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng                        }
12348448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        final float startX = targetX - x;
12358448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        final float startY = targetY - y;
12368448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        Animation clipAnim = scaleUp
12378448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                                ? new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect)
12388448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                                : new ClipRectAnimation(mTmpToClipRect, mTmpFromClipRect);
12398448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        Animation translateAnim = scaleUp
1240c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                                ? createCurvedMotion(startX, 0, startY - contentInsets.top, 0)
1241c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                                : createCurvedMotion(0, startX, 0, startY - contentInsets.top);
1242c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi
1243217009356efa2b854ab3981dff8d315a0d679c73Winson                        set.addAnimation(clipAnim);
1244217009356efa2b854ab3981dff8d315a0d679c73Winson                        set.addAnimation(scaleAnim);
1245217009356efa2b854ab3981dff8d315a0d679c73Winson                        set.addAnimation(translateAnim);
1246217009356efa2b854ab3981dff8d315a0d679c73Winson
1247217009356efa2b854ab3981dff8d315a0d679c73Winson                    } else {
1248217009356efa2b854ab3981dff8d315a0d679c73Winson                        // In landscape, we don't scale at all and only crop
1249217009356efa2b854ab3981dff8d315a0d679c73Winson                        mTmpFromClipRect.bottom = mTmpFromClipRect.top + thumbHeightI;
1250217009356efa2b854ab3981dff8d315a0d679c73Winson                        mTmpFromClipRect.right = mTmpFromClipRect.left + thumbWidthI;
1251217009356efa2b854ab3981dff8d315a0d679c73Winson
12528448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        Animation clipAnim = scaleUp
12538448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                                ? new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect)
12548448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                                : new ClipRectAnimation(mTmpToClipRect, mTmpFromClipRect);
12558448f339f9207aa1e554b1a1e537ce269462807aJorim Jaggi                        Animation translateAnim = scaleUp
1256787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi                                ? createCurvedMotion(thumbStartX, 0,
1257787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi                                thumbStartY - contentInsets.top, 0)
1258787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi                                : createCurvedMotion(0, thumbStartX, 0,
1259787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi                                        thumbStartY - contentInsets.top);
1260217009356efa2b854ab3981dff8d315a0d679c73Winson
1261217009356efa2b854ab3981dff8d315a0d679c73Winson                        set.addAnimation(clipAnim);
1262217009356efa2b854ab3981dff8d315a0d679c73Winson                        set.addAnimation(translateAnim);
1263217009356efa2b854ab3981dff8d315a0d679c73Winson                    }
126471b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski                    a = set;
1265217009356efa2b854ab3981dff8d315a0d679c73Winson                    a.setZAdjustment(Animation.ZORDER_TOP);
12662820c4523cd37b4a9c5d33e558d39b798830e7e5Winson Chung                }
1267399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                break;
1268164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            }
1269399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
1270a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                // Previous app window during the scale up
1271399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
1272a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                    // Fade out the source activity if we are animating to a wallpaper
1273399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                    // activity.
1274399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                    a = new AlphaAnimation(1, 0);
1275399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                } else {
1276399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                    a = new AlphaAnimation(1, 1);
1277399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                }
1278399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                break;
1279399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            }
1280399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
1281a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                // Target app window during the scale down
1282a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
1283a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                    // Fade in the destination activity if we are animating from a wallpaper
1284a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                    // activity.
1285a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                    a = new AlphaAnimation(0, 1);
1286a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                } else {
1287a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                    a = new AlphaAnimation(1, 1);
1288a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                }
1289399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                break;
1290399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            }
1291399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            default:
1292399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                throw new RuntimeException("Invalid thumbnail transition state");
1293399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        }
1294399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
1295787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi        return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight,
1296787e9dd6c81a2db27cd002ca6672be4279cabe88Jorim Jaggi                getAspectScaleDuration(), getAspectScaleInterpolator());
1297399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    }
1298399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
1299d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski    private Animation createAspectScaledThumbnailEnterFreeformAnimationLocked(Rect frame,
1300d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            @Nullable Rect surfaceInsets, int taskId) {
1301d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        getNextAppTransitionStartRect(taskId, mTmpRect);
1302d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        return createAspectScaledThumbnailFreeformAnimationLocked(mTmpRect, frame, surfaceInsets,
1303d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                true);
1304d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski    }
1305d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski
1306d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski    private Animation createAspectScaledThumbnailExitFreeformAnimationLocked(Rect frame,
1307d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            @Nullable Rect surfaceInsets, int taskId) {
1308d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        getNextAppTransitionStartRect(taskId, mTmpRect);
1309d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        return createAspectScaledThumbnailFreeformAnimationLocked(frame, mTmpRect, surfaceInsets,
1310d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                false);
1311d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski    }
1312d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski
1313d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski    private AnimationSet createAspectScaledThumbnailFreeformAnimationLocked(Rect sourceFrame,
1314d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski            Rect destFrame, @Nullable Rect surfaceInsets, boolean enter) {
1315d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final float sourceWidth = sourceFrame.width();
1316d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final float sourceHeight = sourceFrame.height();
1317d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final float destWidth = destFrame.width();
1318d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final float destHeight = destFrame.height();
1319d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final float scaleH = enter ? sourceWidth / destWidth : destWidth / sourceWidth;
1320d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final float scaleV = enter ? sourceHeight / destHeight : destHeight / sourceHeight;
132171b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski        AnimationSet set = new AnimationSet(true);
1322d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final int surfaceInsetsH = surfaceInsets == null
132371b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski                ? 0 : surfaceInsets.left + surfaceInsets.right;
1324d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final int surfaceInsetsV = surfaceInsets == null
132571b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski                ? 0 : surfaceInsets.top + surfaceInsets.bottom;
132671b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski        // We want the scaling to happen from the center of the surface. In order to achieve that,
132771b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski        // we need to account for surface insets that will be used to enlarge the surface.
1328d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final float scaleHCenter = ((enter ? destWidth : sourceWidth) + surfaceInsetsH) / 2;
1329d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final float scaleVCenter = ((enter ? destHeight : sourceHeight) + surfaceInsetsV) / 2;
1330d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final ScaleAnimation scale = enter ?
1331d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                new ScaleAnimation(scaleH, 1, scaleV, 1, scaleHCenter, scaleVCenter)
1332d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                : new ScaleAnimation(1, scaleH, 1, scaleV, scaleHCenter, scaleVCenter);
1333d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final int sourceHCenter = sourceFrame.left + sourceFrame.width() / 2;
1334d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final int sourceVCenter = sourceFrame.top + sourceFrame.height() / 2;
1335d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final int destHCenter = destFrame.left + destFrame.width() / 2;
1336d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final int destVCenter = destFrame.top + destFrame.height() / 2;
1337d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final int fromX = enter ? sourceHCenter - destHCenter : destHCenter - sourceHCenter;
1338d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final int fromY = enter ? sourceVCenter - destVCenter : destVCenter - sourceVCenter;
1339d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        final TranslateAnimation translation = enter ? new TranslateAnimation(fromX, 0, fromY, 0)
1340d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                : new TranslateAnimation(0, fromX, 0, fromY);
134171b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski        set.addAnimation(scale);
134271b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski        set.addAnimation(translation);
13431a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski
13441a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski        final IRemoteCallback callback = mAnimationFinishedCallback;
13451a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski        if (callback != null) {
13461a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski            set.setAnimationListener(new Animation.AnimationListener() {
13471a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski                @Override
13481a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski                public void onAnimationStart(Animation animation) { }
13491a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski
13501a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski                @Override
13511a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski                public void onAnimationEnd(Animation animation) {
13521a4dfe593aafda057ac9cb3086b84588d88cd09fFilip Gruszczynski                    mService.mH.obtainMessage(H.DO_ANIMATION_CALLBACK, callback).sendToTarget();
13531a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski                }
13541a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski
13551a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski                @Override
13561a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski                public void onAnimationRepeat(Animation animation) { }
13571a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski            });
13581a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski        }
135971b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski        return set;
136071b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski    }
136171b0d2dba06bbb17b92b830c4adb795ad0211922Filip Gruszczynski
1362399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung    /**
1363a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung     * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
1364170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski     * when a thumbnail is specified with the pending animation override.
1365a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung     */
1366170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski    Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit,
1367aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chung            GraphicBuffer thumbnailHeader) {
1368a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        Animation a;
1369d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        getDefaultNextAppTransitionStartRect(mTmpRect);
1370170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        final int thumbWidthI = thumbnailHeader.getWidth();
1371a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
1372170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        final int thumbHeightI = thumbnailHeader.getHeight();
1373a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
1374a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
1375a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        if (mNextAppTransitionScaleUp) {
1376a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            // Animation for the thumbnail zooming from its initial size to the full screen
1377a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            float scaleW = appWidth / thumbWidth;
1378a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            float scaleH = appHeight / thumbHeight;
1379a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
1380d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                    computePivot(mTmpRect.left, 1 / scaleW),
1381d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                    computePivot(mTmpRect.top, 1 / scaleH));
1382a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            scale.setInterpolator(mDecelerateInterpolator);
1383a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
1384a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            Animation alpha = new AlphaAnimation(1, 0);
1385a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            alpha.setInterpolator(mThumbnailFadeOutInterpolator);
1386a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
1387a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            // This AnimationSet uses the Interpolators assigned above.
1388a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            AnimationSet set = new AnimationSet(false);
1389a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            set.addAnimation(scale);
1390a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            set.addAnimation(alpha);
1391a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            a = set;
1392a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        } else {
1393a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            // Animation for the thumbnail zooming down from the full screen to its final size
1394a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            float scaleW = appWidth / thumbWidth;
1395a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            float scaleH = appHeight / thumbHeight;
1396a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            a = new ScaleAnimation(scaleW, 1, scaleH, 1,
1397d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                    computePivot(mTmpRect.left, 1 / scaleW),
1398d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                    computePivot(mTmpRect.top, 1 / scaleH));
1399a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        }
1400a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
1401a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
1402a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    }
1403a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
1404a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    /**
1405399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     * This animation is created when we are doing a thumbnail transition, for the activity that is
1406399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     * leaving, and the activity that is entering.
1407399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung     */
1408541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski    Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, Rect containingFrame,
1409541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski            int transit, int taskId) {
1410541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski        final int appWidth = containingFrame.width();
1411541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski        final int appHeight = containingFrame.height();
1412aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chung        final GraphicBuffer thumbnailHeader = getAppTransitionThumbnailHeader(taskId);
1413399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        Animation a;
1414d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski        getDefaultNextAppTransitionStartRect(mTmpRect);
1415170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        final int thumbWidthI = thumbnailHeader != null ? thumbnailHeader.getWidth() : appWidth;
1416399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
1417170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        final int thumbHeightI = thumbnailHeader != null ? thumbnailHeader.getHeight() : appHeight;
1418399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
1419399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
1420399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        switch (thumbTransitState) {
1421399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
1422399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                // Entering app scales up with the thumbnail
1423164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                float scaleW = thumbWidth / appWidth;
1424164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                float scaleH = thumbHeight / appHeight;
1425321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner                a = new ScaleAnimation(scaleW, 1, scaleH, 1,
1426d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                        computePivot(mTmpRect.left, scaleW),
1427d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                        computePivot(mTmpRect.top, scaleH));
1428399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                break;
1429164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            }
1430399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
1431399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                // Exiting app while the thumbnail is scaling up should fade or stay in place
14324b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
1433164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    // Fade out while bringing up selected activity. This keeps the
1434164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    // current activity from showing through a launching wallpaper
1435164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    // activity.
1436164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    a = new AlphaAnimation(1, 0);
1437164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                } else {
1438164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    // noop animation
1439164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    a = new AlphaAnimation(1, 1);
1440164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                }
1441399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                break;
1442399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            }
1443399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
1444399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                // Entering the other app, it should just be visible while we scale the thumbnail
1445399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                // down above it
1446399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                a = new AlphaAnimation(1, 1);
1447399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                break;
1448399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            }
1449399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
1450399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                // Exiting the current app, the app should scale down with the thumbnail
1451164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                float scaleW = thumbWidth / appWidth;
1452164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                float scaleH = thumbHeight / appHeight;
1453164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
1454d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                        computePivot(mTmpRect.left, scaleW),
1455d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                        computePivot(mTmpRect.top, scaleH));
1456321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner
1457164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                Animation alpha = new AlphaAnimation(1, 0);
1458321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner
1459321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner                AnimationSet set = new AnimationSet(true);
1460164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                set.addAnimation(scale);
1461164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                set.addAnimation(alpha);
1462164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                set.setZAdjustment(Animation.ZORDER_TOP);
1463164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                a = set;
1464321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner                break;
1465399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung            }
1466321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner            default:
1467399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung                throw new RuntimeException("Invalid thumbnail transition state");
1468321bdf52a1b277a687c8618bcd20c3cfc5a60b40Craig Mautner        }
1469399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung
1470399f62052a88e5e7628b7312637ae54fbbaa4becWinson Chung        return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
1471164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
1472164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
1473541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski    private Animation createRelaunchAnimation(Rect containingFrame, Rect contentInsets) {
147455a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski        getDefaultNextAppTransitionStartRect(mTmpFromClipRect);
147555a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski        final int left = mTmpFromClipRect.left;
147655a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski        final int top = mTmpFromClipRect.top;
147755a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski        mTmpFromClipRect.offset(-left, -top);
1478541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski        // TODO: Isn't that strange that we ignore exact position of the containingFrame?
1479541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski        mTmpToClipRect.set(0, 0, containingFrame.width(), containingFrame.height());
148055a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski        AnimationSet set = new AnimationSet(true);
148149b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski        float fromWidth = mTmpFromClipRect.width();
148249b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski        float toWidth = mTmpToClipRect.width();
148349b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski        float fromHeight = mTmpFromClipRect.height();
14842dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski        // While the window might span the whole display, the actual content will be cropped to the
14852dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski        // system decoration frame, for example when the window is docked. We need to take into
14862dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski        // account the visible height when constructing the animation.
14872dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski        float toHeight = mTmpToClipRect.height() - contentInsets.top - contentInsets.bottom;
14882dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski        int translateAdjustment = 0;
148949b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski        if (fromWidth <= toWidth && fromHeight <= toHeight) {
149049b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski            // The final window is larger in both dimensions than current window (e.g. we are
149149b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski            // maximizing), so we can simply unclip the new window and there will be no disappearing
149249b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski            // frame.
149349b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski            set.addAnimation(new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect));
149449b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski        } else {
149549b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski            // The disappearing window has one larger dimension. We need to apply scaling, so the
149649b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski            // first frame of the entry animation matches the old window.
149749b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski            set.addAnimation(new ScaleAnimation(fromWidth / toWidth, 1, fromHeight / toHeight, 1));
14982dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski            // We might not be going exactly full screen, but instead be aligned under the status
14992dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski            // bar using cropping. We still need to account for the cropped part, which will also
15002dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski            // be scaled.
15012dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski            translateAdjustment = (int) (contentInsets.top * fromHeight / toHeight);
150249b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski        }
150349b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski
15042dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski        // We animate the translation from the old position of the removed window, to the new
15052dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski        // position of the added window. The latter might not be full screen, for example docked for
15062dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski        // docked windows.
150749b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski        TranslateAnimation translate = new TranslateAnimation(left - containingFrame.left,
15082dfcf840aa5d99aceab969e99a76625a12aa9b56Filip Gruszczynski                0, top - containingFrame.top - translateAdjustment, 0);
150955a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski        set.addAnimation(translate);
151055a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski        set.setDuration(DEFAULT_APP_TRANSITION_DURATION);
1511e95b0aef6d259ff9322bd9a34e36e61737844eeeFilip Gruszczynski        set.setZAdjustment(Animation.ZORDER_TOP);
151255a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski        return set;
151355a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski    }
151455a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski
1515c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi    /**
1516c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi     * @return true if and only if the first frame of the transition can be skipped, i.e. the first
1517c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi     *         frame of the transition doesn't change the visuals on screen, so we can start
1518c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi     *         directly with the second one
1519c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi     */
1520c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi    boolean canSkipFirstFrame() {
1521c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi        return mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM
1522c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi                && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE
1523fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL
1524fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                && mNextAppTransition != TRANSIT_KEYGUARD_GOING_AWAY;
1525c554b77b7392b97e0f455d8276b739e16147d6dfJorim Jaggi    }
1526164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
152733a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi    RemoteAnimationController getRemoteAnimationController() {
152833a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        return mRemoteAnimationController;
152933a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi    }
153033a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi
1531541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski    /**
1532541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *
1533541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     * @param frame These are the bounds of the window when it finishes the animation. This is where
1534541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *              the animation must usually finish in entrance animation, as the next frame will
1535541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *              display the window at these coordinates. In case of exit animation, this is
1536541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *              where the animation must start, as the frame before the animation is displaying
1537541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *              the window at these bounds.
1538541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     * @param insets Knowing where the window will be positioned is not enough. Some parts of the
1539541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *               window might be obscured, usually by the system windows (status bar and
1540541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *               navigation bar) and we use content insets to convey that information. This
1541541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *               usually affects the animation aspects vertically, as the system decoration is
1542541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *               at the top and the bottom. For example when we animate from full screen to
1543541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *               recents, we want to exclude the covered parts, because they won't match the
1544541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *               thumbnail after the last frame is executed.
1545541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     * @param surfaceInsets In rare situation the surface is larger than the content and we need to
1546541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *                      know about this to make the animation frames match. We currently use
1547541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *                      this for freeform windows, which have larger surfaces to display
1548541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *                      shadows. When we animate them from recents, we want to match the content
1549541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *                      to the recents thumbnail and hence need to account for the surface being
1550541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     *                      bigger.
1551541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski     */
1552f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggi    Animation loadAnimation(LayoutParams lp, int transit, boolean enter, int uiMode,
15538fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            int orientation, Rect frame, Rect displayFrame, Rect insets,
155443db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng            @Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean isVoiceInteraction,
155543db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng            boolean freeform, int taskId) {
1556164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        Animation a;
1557fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        if (isKeyguardGoingAwayTransit(transit) && enter) {
1558fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            a = loadKeyguardExitAnimation(transit);
1559fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        } else if (transit == TRANSIT_KEYGUARD_OCCLUDE) {
1560fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            a = null;
1561fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        } else if (transit == TRANSIT_KEYGUARD_UNOCCLUDE && !enter) {
1562fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            a = loadAnimationRes(lp, com.android.internal.R.anim.wallpaper_open_exit);
1563935772129d244122e23308b812765d4591a3c04fAdrian Roos        } else if (transit == TRANSIT_CRASHING_ACTIVITY_CLOSE) {
1564935772129d244122e23308b812765d4591a3c04fAdrian Roos            a = null;
1565fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
1566e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                || transit == TRANSIT_TASK_OPEN
1567e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                || transit == TRANSIT_TASK_TO_FRONT)) {
1568e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            a = loadAnimationRes(lp, enter
1569e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                    ? com.android.internal.R.anim.voice_activity_open_enter
1570e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                    : com.android.internal.R.anim.voice_activity_open_exit);
1571e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1572e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                    "applyAnimation voice:"
15738ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    + " anim=" + a + " transit=" + appTransitionToString(transit)
15748ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
1575e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE
1576e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                || transit == TRANSIT_TASK_CLOSE
1577e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                || transit == TRANSIT_TASK_TO_BACK)) {
1578e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            a = loadAnimationRes(lp, enter
1579e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                    ? com.android.internal.R.anim.voice_activity_close_enter
1580e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                    : com.android.internal.R.anim.voice_activity_close_exit);
1581e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1582e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn                    "applyAnimation voice:"
15838ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    + " anim=" + a + " transit=" + appTransitionToString(transit)
15848ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
158555a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski        } else if (transit == TRANSIT_ACTIVITY_RELAUNCH) {
1586541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski            a = createRelaunchAnimation(frame, insets);
158749b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
158849b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski                    "applyAnimation:"
158949b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski                    + " anim=" + a + " nextAppTransition=" + mNextAppTransition
159049b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski                    + " transit=" + appTransitionToString(transit)
159149b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski                    + " Callers=" + Debug.getCallers(3));
1592e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
1593e30e02f5d9a9141c9ee70c712d4f9d52c88ea969Dianne Hackborn            a = loadAnimationRes(mNextAppTransitionPackage, enter ?
1594164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    mNextAppTransitionEnter : mNextAppTransitionExit);
1595164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1596164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    "applyAnimation:"
1597164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
15988ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
1599164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    + " Callers=" + Debug.getCallers(3));
1600044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
1601044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung            a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
1602044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1603044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung                    "applyAnimation:"
16048ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
16058ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    + " transit=" + appTransitionToString(transit)
16068ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    + " Callers=" + Debug.getCallers(3));
160710e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
16088fe7e0a88ecc4a995a3a86b2ef60143fb0ffa1b0Jorim Jaggi            a = createClipRevealAnimationLocked(transit, enter, frame, displayFrame);
160910e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
161010e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                    "applyAnimation:"
161110e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                            + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL"
161249b80afaf9e71d6b5d4cab26f1459d84d1070f19Filip Gruszczynski                            + " transit=" + appTransitionToString(transit)
161310e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                            + " Callers=" + Debug.getCallers(3));
16149a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
1615541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski            a = createScaleUpAnimationLocked(transit, enter, frame);
1616164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1617164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    "applyAnimation:"
1618164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
16198ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
1620164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    + " Callers=" + Debug.getCallers(3));
16219a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
16229a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
1623164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            mNextAppTransitionScaleUp =
16249a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                    (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
1625a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
1626541f92cb19438678abfa888f1821ec2df334844bFilip Gruszczynski                    frame, transit, taskId);
1627a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
1628a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                String animName = mNextAppTransitionScaleUp ?
1629a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                        "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
1630a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                Slog.v(TAG, "applyAnimation:"
1631a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                        + " anim=" + a + " nextAppTransition=" + animName
16328ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                        + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
1633a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                        + " Callers=" + Debug.getCallers(3));
1634a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            }
1635a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
1636a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN) {
1637a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            mNextAppTransitionScaleUp =
1638a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                    (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP);
1639a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            a = createAspectScaledThumbnailEnterExitAnimationLocked(
1640b20247636b0e0a75edcd327a047b9ea7a9d21b77Winson                    getThumbnailTransitionState(enter), uiMode, orientation, transit, frame,
164143db6d26d8cfc7004c0f71f7e8f8de59081f6ccdMatthew Ng                    insets, surfaceInsets, stableInsets, freeform, taskId);
1642164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
1643164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                String animName = mNextAppTransitionScaleUp ?
1644a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                        "ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN";
1645164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                Slog.v(TAG, "applyAnimation:"
1646164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                        + " anim=" + a + " nextAppTransition=" + animName
16478ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                        + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
1648164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                        + " Callers=" + Debug.getCallers(3));
1649164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            }
165083546a83edd5073d43de6fc1dd8400291ec0f7c0Tony Mak        } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS && enter) {
165198a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi            a = loadAnimationRes("android",
165298a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi                    com.android.internal.R.anim.task_open_enter_cross_profile_apps);
1653089c35e9311386844332dbe2ca09076f845a604cTony Mak            Slog.v(TAG,
1654089c35e9311386844332dbe2ca09076f845a604cTony Mak                    "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS:"
1655089c35e9311386844332dbe2ca09076f845a604cTony Mak                            + " anim=" + a + " transit=" + appTransitionToString(transit)
165698a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi                            + " isEntrance=true" + " Callers=" + Debug.getCallers(3));
1657164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        } else {
1658164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            int animAttr = 0;
1659164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            switch (transit) {
16604b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                case TRANSIT_ACTIVITY_OPEN:
16610a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi                case TRANSIT_TRANSLUCENT_ACTIVITY_OPEN:
1662164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    animAttr = enter
16639a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            ? WindowAnimation_activityOpenEnterAnimation
16649a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            : WindowAnimation_activityOpenExitAnimation;
1665164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    break;
16664b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                case TRANSIT_ACTIVITY_CLOSE:
16670a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi                case TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE:
1668164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    animAttr = enter
16699a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            ? WindowAnimation_activityCloseEnterAnimation
16709a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            : WindowAnimation_activityCloseExitAnimation;
1671164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    break;
1672192086eb8aff3fb873a7e03ade0b81652aacf25fJorim Jaggi                case TRANSIT_DOCK_TASK_FROM_RECENTS:
16734b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                case TRANSIT_TASK_OPEN:
1674164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    animAttr = enter
16759a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            ? WindowAnimation_taskOpenEnterAnimation
16769a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            : WindowAnimation_taskOpenExitAnimation;
1677164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    break;
16784b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                case TRANSIT_TASK_CLOSE:
1679164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    animAttr = enter
16809a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            ? WindowAnimation_taskCloseEnterAnimation
16819a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            : WindowAnimation_taskCloseExitAnimation;
1682164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    break;
16834b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                case TRANSIT_TASK_TO_FRONT:
1684164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    animAttr = enter
16859a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            ? WindowAnimation_taskToFrontEnterAnimation
16869a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            : WindowAnimation_taskToFrontExitAnimation;
1687164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    break;
16884b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                case TRANSIT_TASK_TO_BACK:
1689164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    animAttr = enter
16909a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            ? WindowAnimation_taskToBackEnterAnimation
16919a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            : WindowAnimation_taskToBackExitAnimation;
1692164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    break;
16934b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                case TRANSIT_WALLPAPER_OPEN:
1694164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    animAttr = enter
16959a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            ? WindowAnimation_wallpaperOpenEnterAnimation
16969a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            : WindowAnimation_wallpaperOpenExitAnimation;
1697164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    break;
16984b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                case TRANSIT_WALLPAPER_CLOSE:
1699164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    animAttr = enter
17009a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            ? WindowAnimation_wallpaperCloseEnterAnimation
17019a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            : WindowAnimation_wallpaperCloseExitAnimation;
1702164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    break;
17034b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                case TRANSIT_WALLPAPER_INTRA_OPEN:
1704164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    animAttr = enter
17059a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            ? WindowAnimation_wallpaperIntraOpenEnterAnimation
17069a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            : WindowAnimation_wallpaperIntraOpenExitAnimation;
1707164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    break;
17084b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                case TRANSIT_WALLPAPER_INTRA_CLOSE:
1709164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    animAttr = enter
17109a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            ? WindowAnimation_wallpaperIntraCloseEnterAnimation
17119a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                            : WindowAnimation_wallpaperIntraCloseExitAnimation;
1712164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    break;
1713bb742462781a73bb25516067c8fe6311c1c8a93eCraig Mautner                case TRANSIT_TASK_OPEN_BEHIND:
1714bb742462781a73bb25516067c8fe6311c1c8a93eCraig Mautner                    animAttr = enter
1715bb742462781a73bb25516067c8fe6311c1c8a93eCraig Mautner                            ? WindowAnimation_launchTaskBehindSourceAnimation
17163b2cd1d59fd894ac67a044c6c540fa69360a34a2Craig Mautner                            : WindowAnimation_launchTaskBehindTargetAnimation;
1717164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            }
17180a1523de3ec3b5662e4dc8148bcaa1b443809caaJorim Jaggi            a = animAttr != 0 ? loadAnimationAttr(lp, animAttr, transit) : null;
1719164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1720164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    "applyAnimation:"
1721164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    + " anim=" + a
1722164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    + " animAttr=0x" + Integer.toHexString(animAttr)
17238ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale                    + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
1724164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                    + " Callers=" + Debug.getCallers(3));
1725164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
1726164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        return a;
1727164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
1728164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
1729fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    private Animation loadKeyguardExitAnimation(int transit) {
1730fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        if ((mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) != 0) {
1731fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            return null;
1732fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        }
1733fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        final boolean toShade =
1734fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                (mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0;
1735fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        return mService.mPolicy.createHiddenByKeyguardExit(
1736fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER, toShade);
1737fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    }
1738fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi
17396a7c90a12b5e5250e0350d35ca6547b26630653fJorim Jaggi    int getAppStackClipMode() {
1740bf1d985cc66da3b3b32cc87925757c9e7b34afedMatthew Ng        // When dismiss keyguard animation occurs, clip before the animation to prevent docked
1741bf1d985cc66da3b3b32cc87925757c9e7b34afedMatthew Ng        // app from showing beyond the divider
1742bf1d985cc66da3b3b32cc87925757c9e7b34afedMatthew Ng        if (mNextAppTransition == TRANSIT_KEYGUARD_GOING_AWAY
1743bf1d985cc66da3b3b32cc87925757c9e7b34afedMatthew Ng                || mNextAppTransition == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER) {
1744bf1d985cc66da3b3b32cc87925757c9e7b34afedMatthew Ng            return STACK_CLIP_BEFORE_ANIM;
1745bf1d985cc66da3b3b32cc87925757c9e7b34afedMatthew Ng        }
17466a7c90a12b5e5250e0350d35ca6547b26630653fJorim Jaggi        return mNextAppTransition == TRANSIT_ACTIVITY_RELAUNCH
1747c69bd2246f4ec5000591fdc381f84cd90be85b7fJorim Jaggi                || mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS
17481f458fb6a1fbb8ec693d10f195b99310bcfd34d0Jorim Jaggi                || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL
17496a7c90a12b5e5250e0350d35ca6547b26630653fJorim Jaggi                ? STACK_CLIP_NONE
17506a7c90a12b5e5250e0350d35ca6547b26630653fJorim Jaggi                : STACK_CLIP_AFTER_ANIM;
17516a7c90a12b5e5250e0350d35ca6547b26630653fJorim Jaggi    }
17526a7c90a12b5e5250e0350d35ca6547b26630653fJorim Jaggi
1753fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    public int getTransitFlags() {
1754fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        return mNextAppTransitionFlags;
1755fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    }
1756fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi
1757164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    void postAnimationCallback() {
1758164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        if (mNextAppTransitionCallback != null) {
17591a4dfe593aafda057ac9cb3086b84588d88cd09fFilip Gruszczynski            mService.mH.sendMessage(mService.mH.obtainMessage(H.DO_ANIMATION_CALLBACK,
17601a4dfe593aafda057ac9cb3086b84588d88cd09fFilip Gruszczynski                    mNextAppTransitionCallback));
1761164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            mNextAppTransitionCallback = null;
1762164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
1763164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
1764164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
1765164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
1766d143142f3d26564feda324968b0469c0f600f0adFilip Gruszczynski            IRemoteCallback startedCallback) {
176733a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        if (canOverridePendingAppTransition()) {
176865193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi            clear();
17699a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
1770164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            mNextAppTransitionPackage = packageName;
1771164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            mNextAppTransitionEnter = enterAnim;
1772164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            mNextAppTransitionExit = exitAnim;
1773164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            postAnimationCallback();
1774164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            mNextAppTransitionCallback = startedCallback;
1775164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
1776164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
1777164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
1778164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
1779170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            int startHeight) {
178033a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        if (canOverridePendingAppTransition()) {
178165193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi            clear();
17829a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP;
17834c3fecd31fb611d8391898b19570147eab71b3eeWinson            putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight, null);
1784164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            postAnimationCallback();
1785164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
1786164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
1787164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
178810e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase    void overridePendingAppTransitionClipReveal(int startX, int startY,
178910e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase                                                int startWidth, int startHeight) {
179033a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        if (canOverridePendingAppTransition()) {
179165193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi            clear();
179210e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL;
17937248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski            putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight, null);
179410e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase            postAnimationCallback();
179510e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase        }
179610e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase    }
179710e23ab61b820fb3149b2f89003753d98ebd6a80Chet Haase
1798aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chung    void overridePendingAppTransitionThumb(GraphicBuffer srcThumb, int startX, int startY,
1799164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                                           IRemoteCallback startedCallback, boolean scaleUp) {
180033a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        if (canOverridePendingAppTransition()) {
180165193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi            clear();
18029a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP
18039a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                    : NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN;
1804164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            mNextAppTransitionScaleUp = scaleUp;
18057248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski            putDefaultNextAppTransitionCoordinates(startX, startY, 0, 0, srcThumb);
1806164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            postAnimationCallback();
1807164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner            mNextAppTransitionCallback = startedCallback;
1808164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
1809164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
1810164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
1811aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chung    void overridePendingAppTransitionAspectScaledThumb(GraphicBuffer srcThumb, int startX, int startY,
18122e7f3bdcc9ec0b3e95b565b943ecee2210f4b937Winson Chung            int targetWidth, int targetHeight, IRemoteCallback startedCallback, boolean scaleUp) {
181333a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        if (canOverridePendingAppTransition()) {
181465193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi            clear();
1815a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
1816a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                    : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
1817a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            mNextAppTransitionScaleUp = scaleUp;
18187248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski            putDefaultNextAppTransitionCoordinates(startX, startY, targetWidth, targetHeight,
18197248c568a01b4215380b0ca5d0e9583535ff2cf1Filip Gruszczynski                    srcThumb);
1820a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            postAnimationCallback();
1821a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            mNextAppTransitionCallback = startedCallback;
1822a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        }
1823a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    }
1824a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
182533a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi    void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
18261a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski            IRemoteCallback onAnimationStartedCallback, IRemoteCallback onAnimationFinishedCallback,
18271a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski            boolean scaleUp) {
182833a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        if (canOverridePendingAppTransition()) {
182965193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi            clear();
1830170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
1831170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski                    : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
1832170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            mNextAppTransitionScaleUp = scaleUp;
18334310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi            if (specs != null) {
18344310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi                for (int i = 0; i < specs.length; i++) {
18354310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi                    AppTransitionAnimationSpec spec = specs[i];
18364310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi                    if (spec != null) {
18374310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi                        mNextAppTransitionAnimationsSpecs.put(spec.taskId, spec);
18384310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi                        if (i == 0) {
18394310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi                            // In full screen mode, the transition code depends on the default spec
18404310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi                            // to be set.
18414310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi                            Rect rect = spec.rect;
18424310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi                            putDefaultNextAppTransitionCoordinates(rect.left, rect.top,
1843aa7fa0135366b80d9bfdb7dffb6795b365a40607Winson Chung                                    rect.width(), rect.height(), spec.buffer);
18444310241ace41aaf6aee81c6e098246e59ebbabadJorim Jaggi                        }
1845d143142f3d26564feda324968b0469c0f600f0adFilip Gruszczynski                    }
1846170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski                }
1847170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            }
1848170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            postAnimationCallback();
18491a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski            mNextAppTransitionCallback = onAnimationStartedCallback;
18501a5203dfd5264104db018b8a09d50075b1af9b2dFilip Gruszczynski            mAnimationFinishedCallback = onAnimationFinishedCallback;
1851170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski        }
1852170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski    }
1853170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski
18542f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    void overridePendingAppTransitionMultiThumbFuture(
18552f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi            IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback,
18562f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi            boolean scaleUp) {
185733a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        if (canOverridePendingAppTransition()) {
185865193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi            clear();
18592f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi            mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
18602f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi                    : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
18612f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi            mNextAppTransitionAnimationsSpecsFuture = specsFuture;
18622f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi            mNextAppTransitionScaleUp = scaleUp;
18637cc7b08a40c1eb5b231cafc8c663312a7f8f19e1Jorim Jaggi            mNextAppTransitionFutureCallback = callback;
18642f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi        }
18652f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    }
18662f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi
186733a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi    void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter) {
1868044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung        if (isTransitionSet()) {
186965193999dab0d35811b346fef7ddd87498b56508Jorim Jaggi            clear();
187033a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi            mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE;
187133a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi            mRemoteAnimationController = new RemoteAnimationController(mService,
187233a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi                    remoteAnimationAdapter, mService.mH);
187333a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        }
187433a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi    }
187533a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi
187633a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi    void overrideInPlaceAppTransition(String packageName, int anim) {
187733a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        if (canOverridePendingAppTransition()) {
187833a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi            clear();
1879044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung            mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE;
1880044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung            mNextAppTransitionPackage = packageName;
1881044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung            mNextAppTransitionInPlace = anim;
1882044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung        }
1883044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung    }
1884044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung
18852f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    /**
1886089c35e9311386844332dbe2ca09076f845a604cTony Mak     * @see {@link #NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS}
1887089c35e9311386844332dbe2ca09076f845a604cTony Mak     */
1888089c35e9311386844332dbe2ca09076f845a604cTony Mak    void overridePendingAppTransitionStartCrossProfileApps() {
188933a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        if (canOverridePendingAppTransition()) {
1890089c35e9311386844332dbe2ca09076f845a604cTony Mak            clear();
1891089c35e9311386844332dbe2ca09076f845a604cTony Mak            mNextAppTransitionType = NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS;
1892089c35e9311386844332dbe2ca09076f845a604cTony Mak            postAnimationCallback();
1893089c35e9311386844332dbe2ca09076f845a604cTony Mak        }
1894089c35e9311386844332dbe2ca09076f845a604cTony Mak    }
1895089c35e9311386844332dbe2ca09076f845a604cTony Mak
189633a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi    private boolean canOverridePendingAppTransition() {
189733a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        // Remote animations always take precedence
189833a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi        return isTransitionSet() &&  mNextAppTransitionType != NEXT_TRANSIT_TYPE_REMOTE;
189933a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi    }
190033a701a55c28dd20390acee1ba7881a500830d7dJorim Jaggi
1901089c35e9311386844332dbe2ca09076f845a604cTony Mak    /**
19022f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi     * If a future is set for the app transition specs, fetch it in another thread.
19032f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi     */
19042f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    private void fetchAppTransitionSpecsFromFuture() {
19052f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi        if (mNextAppTransitionAnimationsSpecsFuture != null) {
19062f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi            mNextAppTransitionAnimationsSpecsPending = true;
19072f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi            final IAppTransitionAnimationSpecsFuture future
19082f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi                    = mNextAppTransitionAnimationsSpecsFuture;
19092f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi            mNextAppTransitionAnimationsSpecsFuture = null;
1910ed410b692820783e5677fd174693588ddc528414Jorim Jaggi            mDefaultExecutor.execute(() -> {
1911ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                AppTransitionAnimationSpec[] specs = null;
1912ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                try {
1913ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                    Binder.allowBlocking(future.asBinder());
1914ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                    specs = future.get();
1915ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                } catch (RemoteException e) {
1916ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                    Slog.w(TAG, "Failed to fetch app transition specs: " + e);
1917ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                }
1918ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                synchronized (mService.mWindowMap) {
1919ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                    mNextAppTransitionAnimationsSpecsPending = false;
1920ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                    overridePendingAppTransitionMultiThumb(specs,
1921ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                            mNextAppTransitionFutureCallback, null /* finishedCallback */,
1922ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                            mNextAppTransitionScaleUp);
1923ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                    mNextAppTransitionFutureCallback = null;
19242f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi                }
1925ed410b692820783e5677fd174693588ddc528414Jorim Jaggi                mService.requestTraversal();
19262f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi            });
19272f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi        }
19282f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi    }
19292f7d292596bdba15e441046e3a2e047f37d6ea59Jorim Jaggi
1930164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    @Override
1931164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    public String toString() {
19328ebc82a63f7e4818bb615cf980b961757c8d6587Wale Ogunwale        return "mNextAppTransition=" + appTransitionToString(mNextAppTransition);
1933164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
1934164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner
19354b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner    /**
19364b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner     * Returns the human readable name of a window transition.
19374b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner     *
19384b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner     * @param transition The window transition.
19394b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner     * @return The transition symbolic name.
19404b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner     */
19414b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner    public static String appTransitionToString(int transition) {
19424b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner        switch (transition) {
19434b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_UNSET: {
19444b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_UNSET";
19454b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19464b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_NONE: {
19474b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_NONE";
19484b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19494b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_ACTIVITY_OPEN: {
19504b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_ACTIVITY_OPEN";
19514b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19524b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_ACTIVITY_CLOSE: {
19534b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_ACTIVITY_CLOSE";
19544b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19554b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_TASK_OPEN: {
19564b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_TASK_OPEN";
19574b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19584b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_TASK_CLOSE: {
19594b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_TASK_CLOSE";
19604b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19614b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_TASK_TO_FRONT: {
19624b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_TASK_TO_FRONT";
19634b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19644b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_TASK_TO_BACK: {
19654b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_TASK_TO_BACK";
19664b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19674b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_WALLPAPER_CLOSE: {
19684b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_WALLPAPER_CLOSE";
19694b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19704b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_WALLPAPER_OPEN: {
19714b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_WALLPAPER_OPEN";
19724b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19734b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_WALLPAPER_INTRA_OPEN: {
19744b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_WALLPAPER_INTRA_OPEN";
19754b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
19764b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            case TRANSIT_WALLPAPER_INTRA_CLOSE: {
19774b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner                return "TRANSIT_WALLPAPER_INTRA_CLOSE";
19784b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
1979bb742462781a73bb25516067c8fe6311c1c8a93eCraig Mautner            case TRANSIT_TASK_OPEN_BEHIND: {
1980bb742462781a73bb25516067c8fe6311c1c8a93eCraig Mautner                return "TRANSIT_TASK_OPEN_BEHIND";
1981bb742462781a73bb25516067c8fe6311c1c8a93eCraig Mautner            }
198255a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski            case TRANSIT_ACTIVITY_RELAUNCH: {
198355a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski                return "TRANSIT_ACTIVITY_RELAUNCH";
198455a309f8e2a972a2f0ef0cd86736d3c2f47a75f6Filip Gruszczynski            }
1985192086eb8aff3fb873a7e03ade0b81652aacf25fJorim Jaggi            case TRANSIT_DOCK_TASK_FROM_RECENTS: {
1986192086eb8aff3fb873a7e03ade0b81652aacf25fJorim Jaggi                return "TRANSIT_DOCK_TASK_FROM_RECENTS";
1987192086eb8aff3fb873a7e03ade0b81652aacf25fJorim Jaggi            }
1988fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            case TRANSIT_KEYGUARD_GOING_AWAY: {
1989fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                return "TRANSIT_KEYGUARD_GOING_AWAY";
1990fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            }
1991fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            case TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER: {
1992fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                return "TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER";
1993fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            }
1994fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            case TRANSIT_KEYGUARD_OCCLUDE: {
1995fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                return "TRANSIT_KEYGUARD_OCCLUDE";
1996fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            }
1997fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            case TRANSIT_KEYGUARD_UNOCCLUDE: {
1998fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                return "TRANSIT_KEYGUARD_UNOCCLUDE";
1999fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            }
200098a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi            case TRANSIT_TRANSLUCENT_ACTIVITY_OPEN: {
200198a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi                return "TRANSIT_TRANSLUCENT_ACTIVITY_OPEN";
200298a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi            }
200398a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi            case TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE: {
200498a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi                return "TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE";
200598a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi            }
20069c52ebbf96ba04e07bde962c93f203e81621599bJorim Jaggi            case TRANSIT_CRASHING_ACTIVITY_CLOSE: {
20079c52ebbf96ba04e07bde962c93f203e81621599bJorim Jaggi                return "TRANSIT_CRASHING_ACTIVITY_CLOSE";
20089c52ebbf96ba04e07bde962c93f203e81621599bJorim Jaggi            }
20094b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            default: {
20109c52ebbf96ba04e07bde962c93f203e81621599bJorim Jaggi                return "<UNKNOWN: " + transition + ">";
20114b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner            }
20124b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner        }
20134b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner    }
20144b71aa1f8a1a3b7189fd29241ea7c594ce01623cCraig Mautner
20159a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private String appStateToString() {
20169a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        switch (mAppTransitionState) {
20179a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case APP_STATE_IDLE:
20189a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "APP_STATE_IDLE";
20199a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case APP_STATE_READY:
20209a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "APP_STATE_READY";
20219a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case APP_STATE_RUNNING:
20229a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "APP_STATE_RUNNING";
20239a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case APP_STATE_TIMEOUT:
20249a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "APP_STATE_TIMEOUT";
20259a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            default:
20269a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "unknown state=" + mAppTransitionState;
20279a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        }
20289a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    }
20299a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner
20309a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    private String transitTypeToString() {
20319a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        switch (mNextAppTransitionType) {
20329a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case NEXT_TRANSIT_TYPE_NONE:
20339a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "NEXT_TRANSIT_TYPE_NONE";
20349a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case NEXT_TRANSIT_TYPE_CUSTOM:
20359a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "NEXT_TRANSIT_TYPE_CUSTOM";
2036044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung            case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
2037044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung                return "NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE";
20389a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case NEXT_TRANSIT_TYPE_SCALE_UP:
20399a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "NEXT_TRANSIT_TYPE_SCALE_UP";
20409a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
20419a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP";
20429a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
20439a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN";
2044a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
2045a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP";
2046a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
2047a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN";
204864b8d562115e632ff65a17fab8923a931b0a5000Tony Mak            case NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS:
204964b8d562115e632ff65a17fab8923a931b0a5000Tony Mak                return "NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS";
20509a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            default:
20519a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner                return "unknown type=" + mNextAppTransitionType;
20529a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        }
20539a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner    }
20549a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner
2055af03df6a7a93c832e0bc77b88607ef9161f0791bSteven Timotius    void writeToProto(ProtoOutputStream proto, long fieldId) {
2056af03df6a7a93c832e0bc77b88607ef9161f0791bSteven Timotius        final long token = proto.start(fieldId);
2057af03df6a7a93c832e0bc77b88607ef9161f0791bSteven Timotius        proto.write(APP_TRANSITION_STATE, mAppTransitionState);
2058af03df6a7a93c832e0bc77b88607ef9161f0791bSteven Timotius        proto.write(LAST_USED_APP_TRANSITION, mLastUsedAppTransition);
2059af03df6a7a93c832e0bc77b88607ef9161f0791bSteven Timotius        proto.end(token);
2060af03df6a7a93c832e0bc77b88607ef9161f0791bSteven Timotius    }
2061af03df6a7a93c832e0bc77b88607ef9161f0791bSteven Timotius
2062164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    @Override
2063ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn    public void dump(PrintWriter pw, String prefix) {
2064ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn        pw.print(prefix); pw.println(this);
2065ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn        pw.print(prefix); pw.print("mAppTransitionState="); pw.println(appStateToString());
20669a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner        if (mNextAppTransitionType != NEXT_TRANSIT_TYPE_NONE) {
2067ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn            pw.print(prefix); pw.print("mNextAppTransitionType=");
2068ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                    pw.println(transitTypeToString());
2069164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
2070164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        switch (mNextAppTransitionType) {
20719a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case NEXT_TRANSIT_TYPE_CUSTOM:
2072ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                pw.print(prefix); pw.print("mNextAppTransitionPackage=");
2073164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                        pw.println(mNextAppTransitionPackage);
2074ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                pw.print(prefix); pw.print("mNextAppTransitionEnter=0x");
2075164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                        pw.print(Integer.toHexString(mNextAppTransitionEnter));
2076164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                        pw.print(" mNextAppTransitionExit=0x");
2077164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                        pw.println(Integer.toHexString(mNextAppTransitionExit));
2078164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                break;
2079044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung            case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
2080ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                pw.print(prefix); pw.print("mNextAppTransitionPackage=");
2081044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung                        pw.println(mNextAppTransitionPackage);
2082ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                pw.print(prefix); pw.print("mNextAppTransitionInPlace=0x");
2083044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung                        pw.print(Integer.toHexString(mNextAppTransitionInPlace));
2084044d52934e57a337665f707aa4be1d423ee3fb29Winson Chung                break;
2085170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            case NEXT_TRANSIT_TYPE_SCALE_UP: {
2086d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                getDefaultNextAppTransitionStartRect(mTmpRect);
2087ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                pw.print(prefix); pw.print("mNextAppTransitionStartX=");
2088d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                        pw.print(mTmpRect.left);
2089164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                        pw.print(" mNextAppTransitionStartY=");
2090d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                        pw.println(mTmpRect.top);
2091ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
2092d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                        pw.print(mTmpRect.width());
2093164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                        pw.print(" mNextAppTransitionStartHeight=");
2094d64ef3ef33c50a03b4be3b2baaa93aab7319fca8Filip Gruszczynski                        pw.println(mTmpRect.height());
2095164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                break;
2096170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            }
20979a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
20989a29a5d6790cda3f9eedd8231570d9b4f76c06cdCraig Mautner            case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
2099a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung            case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
2100170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN: {
2101170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski                pw.print(prefix); pw.print("mDefaultNextAppTransitionAnimationSpec=");
2102170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski                        pw.println(mDefaultNextAppTransitionAnimationSpec);
2103170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski                pw.print(prefix); pw.print("mNextAppTransitionAnimationsSpecs=");
2104170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski                        pw.println(mNextAppTransitionAnimationsSpecs);
2105ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                pw.print(prefix); pw.print("mNextAppTransitionScaleUp=");
2106ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                        pw.println(mNextAppTransitionScaleUp);
2107164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner                break;
2108170192ab55812bd25124cf602042477c3ea042d1Filip Gruszczynski            }
2109164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
2110164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        if (mNextAppTransitionCallback != null) {
2111ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn            pw.print(prefix); pw.print("mNextAppTransitionCallback=");
2112ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                    pw.println(mNextAppTransitionCallback);
2113164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner        }
211460091a978f21994e59388d90b90cc1dbe0537628Chong Zhang        if (mLastUsedAppTransition != TRANSIT_NONE) {
211560091a978f21994e59388d90b90cc1dbe0537628Chong Zhang            pw.print(prefix); pw.print("mLastUsedAppTransition=");
211660091a978f21994e59388d90b90cc1dbe0537628Chong Zhang                    pw.println(appTransitionToString(mLastUsedAppTransition));
211760091a978f21994e59388d90b90cc1dbe0537628Chong Zhang            pw.print(prefix); pw.print("mLastOpeningApp=");
211860091a978f21994e59388d90b90cc1dbe0537628Chong Zhang                    pw.println(mLastOpeningApp);
211960091a978f21994e59388d90b90cc1dbe0537628Chong Zhang            pw.print(prefix); pw.print("mLastClosingApp=");
212060091a978f21994e59388d90b90cc1dbe0537628Chong Zhang                    pw.println(mLastClosingApp);
212160091a978f21994e59388d90b90cc1dbe0537628Chong Zhang        }
2122164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner    }
21234befbecfcc286652209126b9a64883b35544157dAmith Yamasani
21244befbecfcc286652209126b9a64883b35544157dAmith Yamasani    public void setCurrentUser(int newUserId) {
21254befbecfcc286652209126b9a64883b35544157dAmith Yamasani        mCurrentUserId = newUserId;
21264befbecfcc286652209126b9a64883b35544157dAmith Yamasani    }
212724966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski
212824966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski    /**
212924966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski     * @return true if transition is not running and should not be skipped, false if transition is
213024966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski     *         already running
213124966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski     */
2132f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggi    boolean prepareAppTransitionLocked(@TransitionType int transit, boolean alwaysKeepCurrent,
2133f84e2f60fec6f6d2ecfb3b90ddf075101f4b902fJorim Jaggi            @TransitionFlags int flags, boolean forceOverride) {
213424966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:"
213524966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski                + " transit=" + appTransitionToString(transit)
213624966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski                + " " + this
213724966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski                + " alwaysKeepCurrent=" + alwaysKeepCurrent
213824966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski                + " Callers=" + Debug.getCallers(3));
21399c52ebbf96ba04e07bde962c93f203e81621599bJorim Jaggi        final boolean allowSetCrashing = !isKeyguardTransit(mNextAppTransition)
21409c52ebbf96ba04e07bde962c93f203e81621599bJorim Jaggi                && transit == TRANSIT_CRASHING_ACTIVITY_CLOSE;
2141fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        if (forceOverride || isKeyguardTransit(transit) || !isTransitionSet()
21429c52ebbf96ba04e07bde962c93f203e81621599bJorim Jaggi                || mNextAppTransition == TRANSIT_NONE || allowSetCrashing) {
2143fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi            setAppTransition(transit, flags);
2144a69243a5475c3cecc410c3328f221bab220cab8aJorim Jaggi        }
2145a69243a5475c3cecc410c3328f221bab220cab8aJorim Jaggi        // We never want to change from a Keyguard transit to a non-Keyguard transit, as our logic
2146935772129d244122e23308b812765d4591a3c04fAdrian Roos        // relies on the fact that we always execute a Keyguard transition after preparing one. We
2147935772129d244122e23308b812765d4591a3c04fAdrian Roos        // also don't want to change away from a crashing transition.
21489c52ebbf96ba04e07bde962c93f203e81621599bJorim Jaggi        else if (!alwaysKeepCurrent && !isKeyguardTransit(mNextAppTransition)
21499c52ebbf96ba04e07bde962c93f203e81621599bJorim Jaggi                && mNextAppTransition != TRANSIT_CRASHING_ACTIVITY_CLOSE) {
215024966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski            if (transit == TRANSIT_TASK_OPEN && isTransitionEqual(TRANSIT_TASK_CLOSE)) {
215124966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski                // Opening a new task always supersedes a close for the anim.
2152fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                setAppTransition(transit, flags);
215324966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski            } else if (transit == TRANSIT_ACTIVITY_OPEN
215424966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski                    && isTransitionEqual(TRANSIT_ACTIVITY_CLOSE)) {
215524966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski                // Opening a new activity always supersedes a close for the anim.
2156fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                setAppTransition(transit, flags);
2157cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi            } else if (isTaskTransit(transit) && isActivityTransit(mNextAppTransition)) {
2158cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi                // Task animations always supersede activity animations, because if we have both, it
2159cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi                // usually means that activity transition were just trampoline activities.
2160cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi                setAppTransition(transit, flags);
216124966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski            }
216224966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski        }
216324966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski        boolean prepared = prepare();
216424966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski        if (isTransitionSet()) {
21651a4dfe593aafda057ac9cb3086b84588d88cd09fFilip Gruszczynski            mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
21661a4dfe593aafda057ac9cb3086b84588d88cd09fFilip Gruszczynski            mService.mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, APP_TRANSITION_TIMEOUT_MS);
216724966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski        }
216824966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski        return prepared;
216924966d4789c7a2054650ec1a5ed7450f0d691224Filip Gruszczynski    }
2170b20247636b0e0a75edcd327a047b9ea7a9d21b77Winson
2171b20247636b0e0a75edcd327a047b9ea7a9d21b77Winson    /**
2172fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi     * @return true if {@param transit} is representing a transition in which Keyguard is going
2173fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi     *         away, false otherwise
2174fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi     */
2175fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    public static boolean isKeyguardGoingAwayTransit(int transit) {
2176fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        return transit == TRANSIT_KEYGUARD_GOING_AWAY
2177fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                || transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
2178fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    }
2179fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi
2180fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    private static boolean isKeyguardTransit(int transit) {
2181fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi        return isKeyguardGoingAwayTransit(transit) || transit == TRANSIT_KEYGUARD_OCCLUDE
2182fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi                || transit == TRANSIT_KEYGUARD_UNOCCLUDE;
2183fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    }
2184fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi
218598a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi    static boolean isTaskTransit(int transit) {
218698a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi        return isTaskOpenTransit(transit)
2187cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi                || transit == TRANSIT_TASK_CLOSE
2188cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi                || transit == TRANSIT_TASK_TO_BACK
2189cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi                || transit == TRANSIT_TASK_IN_PLACE;
2190cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi    }
2191cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi
219298a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi    private static  boolean isTaskOpenTransit(int transit) {
219398a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi        return transit == TRANSIT_TASK_OPEN
219498a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi                || transit == TRANSIT_TASK_OPEN_BEHIND
219598a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi                || transit == TRANSIT_TASK_TO_FRONT;
219698a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi    }
219798a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi
219898a9d206be7e2c87b58d0d59c7a0ccc53eb22dd0Jorim Jaggi    static boolean isActivityTransit(int transit) {
2199cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi        return transit == TRANSIT_ACTIVITY_OPEN
2200cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi                || transit == TRANSIT_ACTIVITY_CLOSE
2201cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi                || transit == TRANSIT_ACTIVITY_RELAUNCH;
2202cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi    }
2203cecf424d3ad031f7353bc228e970211b443d91c5Jorim Jaggi
2204fe762344f4475a3a336bb46aef2d59c1fabf32abJorim Jaggi    /**
2205d737680ba29e493e62659a3997710cb5392d2657Manu Cornet     * @return whether the transition should show the thumbnail being scaled down.
2206d737680ba29e493e62659a3997710cb5392d2657Manu Cornet     */
2207d737680ba29e493e62659a3997710cb5392d2657Manu Cornet    private boolean shouldScaleDownThumbnailTransition(int uiMode, int orientation) {
22080e88d32b96526adc241ce7a0970e8177b4254810Sid Soundararajan        return mGridLayoutRecentsEnabled
2209d737680ba29e493e62659a3997710cb5392d2657Manu Cornet                || orientation == Configuration.ORIENTATION_PORTRAIT;
2210d737680ba29e493e62659a3997710cb5392d2657Manu Cornet    }
2211164d4bb4c3eeba1488d9b4994980d24c1f6ec961Craig Mautner}
2212