blob: a2307f9263ce60779829fa98bf27040b8d19f872 [file] [log] [blame]
Craig Mautner164d4bb2012-11-26 13:51:23 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wm;
18
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -070019import android.annotation.Nullable;
Craig Mautner164d4bb2012-11-26 13:51:23 -080020import android.content.Context;
Winson Chung2820c452014-04-15 15:34:44 -070021import android.content.res.Configuration;
Craig Mautner164d4bb2012-11-26 13:51:23 -080022import android.graphics.Bitmap;
Winson Chung399f6202014-03-19 10:47:20 -070023import android.graphics.Rect;
Craig Mautner164d4bb2012-11-26 13:51:23 -080024import android.os.Debug;
25import android.os.Handler;
Jorim Jaggi77ba4802015-02-18 13:57:50 +010026import android.os.IBinder;
Craig Mautner164d4bb2012-11-26 13:51:23 -080027import android.os.IRemoteCallback;
28import android.util.Slog;
29import android.view.WindowManager;
Craig Mautner164d4bb2012-11-26 13:51:23 -080030import android.view.animation.AlphaAnimation;
31import android.view.animation.Animation;
32import android.view.animation.AnimationSet;
33import android.view.animation.AnimationUtils;
Winson Chung399f6202014-03-19 10:47:20 -070034import android.view.animation.ClipRectAnimation;
Chet Haase10e23ab2015-02-11 15:08:38 -080035import android.view.animation.ClipRectLRAnimation;
36import android.view.animation.ClipRectTBAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -080037import android.view.animation.Interpolator;
Jorim Jaggi1d763a62015-06-02 17:07:39 -070038import android.view.animation.PathInterpolator;
Craig Mautner164d4bb2012-11-26 13:51:23 -080039import android.view.animation.ScaleAnimation;
Winson Chung399f6202014-03-19 10:47:20 -070040import android.view.animation.TranslateAnimation;
Chet Haase10e23ab2015-02-11 15:08:38 -080041import android.view.animation.TranslateYAnimation;
Jorim Jaggi1d763a62015-06-02 17:07:39 -070042
Craig Mautner164d4bb2012-11-26 13:51:23 -080043import com.android.internal.util.DumpUtils.Dump;
44import com.android.server.AttributeCache;
45import com.android.server.wm.WindowManagerService.H;
46
47import java.io.PrintWriter;
Jorim Jaggi77ba4802015-02-18 13:57:50 +010048import java.util.ArrayList;
Craig Mautner164d4bb2012-11-26 13:51:23 -080049
Jorim Jaggi77ba4802015-02-18 13:57:50 +010050import static android.view.WindowManagerInternal.AppTransitionListener;
Craig Mautner9a29a5d2012-12-27 19:03:40 -080051import static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation;
52import static com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
Jorim Jaggi1d763a62015-06-02 17:07:39 -070053import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
54import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -070055import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindSourceAnimation;
Jorim Jaggi1d763a62015-06-02 17:07:39 -070056import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindTargetAnimation;
Craig Mautner9a29a5d2012-12-27 19:03:40 -080057import static com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation;
58import static com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
Jorim Jaggi1d763a62015-06-02 17:07:39 -070059import static com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation;
60import static com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
Craig Mautner9a29a5d2012-12-27 19:03:40 -080061import static com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation;
62import static com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
Jorim Jaggi1d763a62015-06-02 17:07:39 -070063import static com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation;
64import static com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
Craig Mautner9a29a5d2012-12-27 19:03:40 -080065import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation;
66import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
Craig Mautner9a29a5d2012-12-27 19:03:40 -080067import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation;
68import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
Jorim Jaggi1d763a62015-06-02 17:07:39 -070069import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation;
70import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
71import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
72import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
Craig Mautner9a29a5d2012-12-27 19:03:40 -080073
Craig Mautner164d4bb2012-11-26 13:51:23 -080074// State management of app transitions. When we are preparing for a
75// transition, mNextAppTransition will be the kind of transition to
76// perform or TRANSIT_NONE if we are not waiting. If we are waiting,
77// mOpeningApps and mClosingApps are the lists of tokens that will be
78// made visible or hidden at the next transition.
79public class AppTransition implements Dump {
80 private static final String TAG = "AppTransition";
Craig Mautner321bdf52012-12-18 09:53:24 -080081 private static final boolean DEBUG_APP_TRANSITIONS =
82 WindowManagerService.DEBUG_APP_TRANSITIONS;
83 private static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
Jorim Jaggi1d763a62015-06-02 17:07:39 -070084 private static final int CLIP_REVEAL_TRANSLATION_Y_DP = 8;
Craig Mautner9a29a5d2012-12-27 19:03:40 -080085
Craig Mautner4b71aa12012-12-27 17:20:01 -080086 /** Not set up for a transition. */
87 public static final int TRANSIT_UNSET = -1;
88 /** No animation for transition. */
89 public static final int TRANSIT_NONE = 0;
90 /** A window in a new activity is being opened on top of an existing one in the same task. */
Craig Mautnerbb742462014-07-07 15:28:55 -070091 public static final int TRANSIT_ACTIVITY_OPEN = 6;
Craig Mautner4b71aa12012-12-27 17:20:01 -080092 /** The window in the top-most activity is being closed to reveal the
93 * previous activity in the same task. */
Craig Mautnerbb742462014-07-07 15:28:55 -070094 public static final int TRANSIT_ACTIVITY_CLOSE = 7;
Craig Mautner4b71aa12012-12-27 17:20:01 -080095 /** A window in a new task is being opened on top of an existing one
96 * in another activity's task. */
Craig Mautnerbb742462014-07-07 15:28:55 -070097 public static final int TRANSIT_TASK_OPEN = 8;
Craig Mautner4b71aa12012-12-27 17:20:01 -080098 /** A window in the top-most activity is being closed to reveal the
99 * previous activity in a different task. */
Craig Mautnerbb742462014-07-07 15:28:55 -0700100 public static final int TRANSIT_TASK_CLOSE = 9;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800101 /** A window in an existing task is being displayed on top of an existing one
102 * in another activity's task. */
Craig Mautnerbb742462014-07-07 15:28:55 -0700103 public static final int TRANSIT_TASK_TO_FRONT = 10;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800104 /** A window in an existing task is being put below all other tasks. */
Craig Mautnerbb742462014-07-07 15:28:55 -0700105 public static final int TRANSIT_TASK_TO_BACK = 11;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800106 /** A window in a new activity that doesn't have a wallpaper is being opened on top of one that
107 * does, effectively closing the wallpaper. */
Craig Mautnerbb742462014-07-07 15:28:55 -0700108 public static final int TRANSIT_WALLPAPER_CLOSE = 12;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800109 /** A window in a new activity that does have a wallpaper is being opened on one that didn't,
110 * effectively opening the wallpaper. */
Craig Mautnerbb742462014-07-07 15:28:55 -0700111 public static final int TRANSIT_WALLPAPER_OPEN = 13;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800112 /** A window in a new activity is being opened on top of an existing one, and both are on top
113 * of the wallpaper. */
Craig Mautnerbb742462014-07-07 15:28:55 -0700114 public static final int TRANSIT_WALLPAPER_INTRA_OPEN = 14;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800115 /** The window in the top-most activity is being closed to reveal the previous activity, and
116 * both are on top of the wallpaper. */
Craig Mautnerbb742462014-07-07 15:28:55 -0700117 public static final int TRANSIT_WALLPAPER_INTRA_CLOSE = 15;
118 /** A window in a new task is being opened behind an existing one in another activity's task.
119 * The new window will show briefly and then be gone. */
120 public static final int TRANSIT_TASK_OPEN_BEHIND = 16;
Winson Chung044d5292014-11-06 11:05:19 -0800121 /** A window in a task is being animated in-place. */
122 public static final int TRANSIT_TASK_IN_PLACE = 17;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800123
Winson Chunga4ccb862014-08-22 15:26:27 -0700124 /** Fraction of animation at which the recents thumbnail stays completely transparent */
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700125 private static final float RECENTS_THUMBNAIL_FADEIN_FRACTION = 0.5f;
Craig Mautner321bdf52012-12-18 09:53:24 -0800126 /** Fraction of animation at which the recents thumbnail becomes completely transparent */
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700127 private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.5f;
Craig Mautner321bdf52012-12-18 09:53:24 -0800128
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700129 private static final int DEFAULT_APP_TRANSITION_DURATION = 336;
130 private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336;
131 private static final int THUMBNAIL_APP_TRANSITION_ALPHA_DURATION = 336;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800132
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800133 private final Context mContext;
134 private final Handler mH;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800135
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800136 private int mNextAppTransition = TRANSIT_UNSET;
137
138 private static final int NEXT_TRANSIT_TYPE_NONE = 0;
139 private static final int NEXT_TRANSIT_TYPE_CUSTOM = 1;
140 private static final int NEXT_TRANSIT_TYPE_SCALE_UP = 2;
141 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP = 3;
142 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN = 4;
Winson Chunga4ccb862014-08-22 15:26:27 -0700143 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP = 5;
144 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN = 6;
Winson Chung044d5292014-11-06 11:05:19 -0800145 private static final int NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE = 7;
Chet Haase10e23ab2015-02-11 15:08:38 -0800146 private static final int NEXT_TRANSIT_TYPE_CLIP_REVEAL = 8;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800147 private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
148
Winson Chung399f6202014-03-19 10:47:20 -0700149 // These are the possible states for the enter/exit activities during a thumbnail transition
150 private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
151 private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_UP = 1;
152 private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN = 2;
153 private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;
154
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800155 private String mNextAppTransitionPackage;
156 private Bitmap mNextAppTransitionThumbnail;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800157 // Used for thumbnail transitions. True if we're scaling up, false if scaling down
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800158 private boolean mNextAppTransitionScaleUp;
159 private IRemoteCallback mNextAppTransitionCallback;
160 private int mNextAppTransitionEnter;
161 private int mNextAppTransitionExit;
Winson Chung044d5292014-11-06 11:05:19 -0800162 private int mNextAppTransitionInPlace;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800163 private int mNextAppTransitionStartX;
164 private int mNextAppTransitionStartY;
165 private int mNextAppTransitionStartWidth;
166 private int mNextAppTransitionStartHeight;
Winson Chunga4ccb862014-08-22 15:26:27 -0700167 private Rect mNextAppTransitionInsets = new Rect();
Craig Mautner164d4bb2012-11-26 13:51:23 -0800168
Winson Chung2820c452014-04-15 15:34:44 -0700169 private Rect mTmpFromClipRect = new Rect();
170 private Rect mTmpToClipRect = new Rect();
171
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800172 private final static int APP_STATE_IDLE = 0;
173 private final static int APP_STATE_READY = 1;
174 private final static int APP_STATE_RUNNING = 2;
175 private final static int APP_STATE_TIMEOUT = 3;
176 private int mAppTransitionState = APP_STATE_IDLE;
177
178 private final int mConfigShortAnimTime;
Craig Mautner321bdf52012-12-18 09:53:24 -0800179 private final Interpolator mDecelerateInterpolator;
Winson Chunga4ccb862014-08-22 15:26:27 -0700180 private final Interpolator mThumbnailFadeInInterpolator;
181 private final Interpolator mThumbnailFadeOutInterpolator;
Chet Haase10e23ab2015-02-11 15:08:38 -0800182 private final Interpolator mLinearOutSlowInInterpolator;
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700183 private final Interpolator mFastOutLinearInInterpolator;
184 private final Interpolator mClipHorizontalInterpolator = new PathInterpolator(0, 0, 0.4f, 1f);
185
186 /** Interpolator to be used for animations that respond directly to a touch */
187 private final Interpolator mTouchResponseInterpolator =
188 new PathInterpolator(0.3f, 0f, 0.1f, 1f);
189
190 private final int mClipRevealTranslationY;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800191
Amith Yamasani4befbec2013-07-10 16:18:01 -0700192 private int mCurrentUserId = 0;
193
Jorim Jaggi77ba4802015-02-18 13:57:50 +0100194 private final ArrayList<AppTransitionListener> mListeners = new ArrayList<>();
195
Craig Mautner164d4bb2012-11-26 13:51:23 -0800196 AppTransition(Context context, Handler h) {
197 mContext = context;
198 mH = h;
Chet Haase10e23ab2015-02-11 15:08:38 -0800199 mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
200 com.android.internal.R.interpolator.linear_out_slow_in);
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700201 mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
202 com.android.internal.R.interpolator.fast_out_linear_in);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800203 mConfigShortAnimTime = context.getResources().getInteger(
204 com.android.internal.R.integer.config_shortAnimTime);
Craig Mautner321bdf52012-12-18 09:53:24 -0800205 mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
206 com.android.internal.R.interpolator.decelerate_cubic);
Winson Chunga4ccb862014-08-22 15:26:27 -0700207 mThumbnailFadeInInterpolator = new Interpolator() {
208 @Override
209 public float getInterpolation(float input) {
210 // Linear response for first fraction, then complete after that.
211 if (input < RECENTS_THUMBNAIL_FADEIN_FRACTION) {
212 return 0f;
213 }
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700214 float t = (input - RECENTS_THUMBNAIL_FADEIN_FRACTION) /
Winson Chunga4ccb862014-08-22 15:26:27 -0700215 (1f - RECENTS_THUMBNAIL_FADEIN_FRACTION);
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700216 return mFastOutLinearInInterpolator.getInterpolation(t);
Winson Chunga4ccb862014-08-22 15:26:27 -0700217 }
218 };
219 mThumbnailFadeOutInterpolator = new Interpolator() {
Craig Mautner321bdf52012-12-18 09:53:24 -0800220 @Override
221 public float getInterpolation(float input) {
222 // Linear response for first fraction, then complete after that.
223 if (input < RECENTS_THUMBNAIL_FADEOUT_FRACTION) {
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700224 float t = input / RECENTS_THUMBNAIL_FADEOUT_FRACTION;
225 return mLinearOutSlowInInterpolator.getInterpolation(t);
Craig Mautner321bdf52012-12-18 09:53:24 -0800226 }
Winson Chunga4ccb862014-08-22 15:26:27 -0700227 return 1f;
Craig Mautner321bdf52012-12-18 09:53:24 -0800228 }
229 };
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700230 mClipRevealTranslationY = (int) (CLIP_REVEAL_TRANSLATION_Y_DP
231 * mContext.getResources().getDisplayMetrics().density);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800232 }
233
234 boolean isTransitionSet() {
235 return mNextAppTransition != TRANSIT_UNSET;
236 }
237
238 boolean isTransitionNone() {
239 return mNextAppTransition == TRANSIT_NONE;
240 }
241
242 boolean isTransitionEqual(int transit) {
243 return mNextAppTransition == transit;
244 }
245
246 int getAppTransition() {
Craig Mautner321bdf52012-12-18 09:53:24 -0800247 return mNextAppTransition;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800248 }
249
250 void setAppTransition(int transit) {
251 mNextAppTransition = transit;
252 }
253
254 boolean isReady() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800255 return mAppTransitionState == APP_STATE_READY
256 || mAppTransitionState == APP_STATE_TIMEOUT;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800257 }
258
Craig Mautnerae446592012-12-06 19:05:05 -0800259 void setReady() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800260 mAppTransitionState = APP_STATE_READY;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800261 }
262
263 boolean isRunning() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800264 return mAppTransitionState == APP_STATE_RUNNING;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800265 }
266
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800267 void setIdle() {
268 mAppTransitionState = APP_STATE_IDLE;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800269 }
270
271 boolean isTimeout() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800272 return mAppTransitionState == APP_STATE_TIMEOUT;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800273 }
274
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800275 void setTimeout() {
276 mAppTransitionState = APP_STATE_TIMEOUT;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800277 }
278
279 Bitmap getNextAppTransitionThumbnail() {
280 return mNextAppTransitionThumbnail;
281 }
282
Winson Chunga4ccb862014-08-22 15:26:27 -0700283 /** Returns whether the next thumbnail transition is aspect scaled up. */
284 boolean isNextThumbnailTransitionAspectScaled() {
285 return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
286 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
287 }
288
289 /** Returns whether the next thumbnail transition is scaling up. */
290 boolean isNextThumbnailTransitionScaleUp() {
291 return mNextAppTransitionScaleUp;
292 }
293
294 int getStartingX() {
295 return mNextAppTransitionStartX;
296 }
297
298 int getStartingY() {
299 return mNextAppTransitionStartY;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800300 }
301
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700302 boolean prepare() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800303 if (!isRunning()) {
304 mAppTransitionState = APP_STATE_IDLE;
Jorim Jaggi77ba4802015-02-18 13:57:50 +0100305 notifyAppTransitionPendingLocked();
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700306 return true;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800307 }
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700308 return false;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800309 }
310
Jorim Jaggi77ba4802015-02-18 13:57:50 +0100311 void goodToGo(AppWindowAnimator openingAppAnimator, AppWindowAnimator closingAppAnimator) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800312 mNextAppTransition = TRANSIT_UNSET;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800313 mAppTransitionState = APP_STATE_RUNNING;
Jorim Jaggi77ba4802015-02-18 13:57:50 +0100314 notifyAppTransitionStartingLocked(
315 openingAppAnimator != null ? openingAppAnimator.mAppToken.token : null,
316 closingAppAnimator != null ? closingAppAnimator.mAppToken.token : null,
317 openingAppAnimator != null ? openingAppAnimator.animation : null,
318 closingAppAnimator != null ? closingAppAnimator.animation : null);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800319 }
320
321 void clear() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800322 mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800323 mNextAppTransitionPackage = null;
324 mNextAppTransitionThumbnail = null;
325 }
326
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800327 void freeze() {
328 setAppTransition(AppTransition.TRANSIT_UNSET);
329 clear();
330 setReady();
Jorim Jaggi77ba4802015-02-18 13:57:50 +0100331 notifyAppTransitionCancelledLocked();
332 }
333
334 void registerListenerLocked(AppTransitionListener listener) {
335 mListeners.add(listener);
336 }
337
Wale Ogunwalea48eadb2015-05-14 17:43:12 -0700338 public void notifyAppTransitionFinishedLocked(IBinder token) {
Jorim Jaggi77ba4802015-02-18 13:57:50 +0100339 for (int i = 0; i < mListeners.size(); i++) {
340 mListeners.get(i).onAppTransitionFinishedLocked(token);
341 }
342 }
343
344 private void notifyAppTransitionPendingLocked() {
345 for (int i = 0; i < mListeners.size(); i++) {
346 mListeners.get(i).onAppTransitionPendingLocked();
347 }
348 }
349
350 private void notifyAppTransitionCancelledLocked() {
351 for (int i = 0; i < mListeners.size(); i++) {
352 mListeners.get(i).onAppTransitionCancelledLocked();
353 }
354 }
355
356 private void notifyAppTransitionStartingLocked(IBinder openToken,
357 IBinder closeToken, Animation openAnimation, Animation closeAnimation) {
358 for (int i = 0; i < mListeners.size(); i++) {
359 mListeners.get(i).onAppTransitionStartingLocked(openToken, closeToken, openAnimation,
360 closeAnimation);
361 }
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800362 }
363
Craig Mautner164d4bb2012-11-26 13:51:23 -0800364 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
365 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
366 + (lp != null ? lp.packageName : null)
367 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
368 if (lp != null && lp.windowAnimations != 0) {
369 // If this is a system resource, don't try to load it from the
370 // application resources. It is nice to avoid loading application
371 // resources if we can.
372 String packageName = lp.packageName != null ? lp.packageName : "android";
373 int resId = lp.windowAnimations;
374 if ((resId&0xFF000000) == 0x01000000) {
375 packageName = "android";
376 }
377 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
378 + packageName);
379 return AttributeCache.instance().get(packageName, resId,
Amith Yamasani4befbec2013-07-10 16:18:01 -0700380 com.android.internal.R.styleable.WindowAnimation, mCurrentUserId);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800381 }
382 return null;
383 }
384
385 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
386 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
387 + packageName + " resId=0x" + Integer.toHexString(resId));
388 if (packageName != null) {
389 if ((resId&0xFF000000) == 0x01000000) {
390 packageName = "android";
391 }
392 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
393 + packageName);
394 return AttributeCache.instance().get(packageName, resId,
Amith Yamasani4befbec2013-07-10 16:18:01 -0700395 com.android.internal.R.styleable.WindowAnimation, mCurrentUserId);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800396 }
397 return null;
398 }
399
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700400 Animation loadAnimationAttr(WindowManager.LayoutParams lp, int animAttr) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800401 int anim = 0;
402 Context context = mContext;
403 if (animAttr >= 0) {
404 AttributeCache.Entry ent = getCachedAnimations(lp);
405 if (ent != null) {
406 context = ent.context;
407 anim = ent.array.getResourceId(animAttr, 0);
408 }
409 }
410 if (anim != 0) {
411 return AnimationUtils.loadAnimation(context, anim);
412 }
413 return null;
414 }
415
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700416 Animation loadAnimationRes(WindowManager.LayoutParams lp, int resId) {
417 Context context = mContext;
418 if (resId >= 0) {
419 AttributeCache.Entry ent = getCachedAnimations(lp);
420 if (ent != null) {
421 context = ent.context;
422 }
423 return AnimationUtils.loadAnimation(context, resId);
424 }
425 return null;
426 }
427
428 private Animation loadAnimationRes(String packageName, int resId) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800429 int anim = 0;
430 Context context = mContext;
431 if (resId >= 0) {
432 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
433 if (ent != null) {
434 context = ent.context;
435 anim = resId;
436 }
437 }
438 if (anim != 0) {
439 return AnimationUtils.loadAnimation(context, anim);
440 }
441 return null;
442 }
443
Craig Mautner164d4bb2012-11-26 13:51:23 -0800444 /**
445 * Compute the pivot point for an animation that is scaling from a small
446 * rect on screen to a larger rect. The pivot point varies depending on
447 * the distance between the inner and outer edges on both sides. This
448 * function computes the pivot point for one dimension.
449 * @param startPos Offset from left/top edge of outer rectangle to
450 * left/top edge of inner rectangle.
451 * @param finalScale The scaling factor between the size of the outer
452 * and inner rectangles.
453 */
454 private static float computePivot(int startPos, float finalScale) {
455 final float denom = finalScale-1;
456 if (Math.abs(denom) < .0001f) {
457 return startPos;
458 }
459 return -startPos / denom;
460 }
461
462 private Animation createScaleUpAnimationLocked(int transit, boolean enter,
463 int appWidth, int appHeight) {
464 Animation a = null;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800465 if (enter) {
466 // Entering app zooms out from the center of the initial rect.
467 float scaleW = mNextAppTransitionStartWidth / (float) appWidth;
468 float scaleH = mNextAppTransitionStartHeight / (float) appHeight;
469 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
470 computePivot(mNextAppTransitionStartX, scaleW),
471 computePivot(mNextAppTransitionStartY, scaleH));
Craig Mautner321bdf52012-12-18 09:53:24 -0800472 scale.setInterpolator(mDecelerateInterpolator);
473
Craig Mautner164d4bb2012-11-26 13:51:23 -0800474 Animation alpha = new AlphaAnimation(0, 1);
Winson Chunga4ccb862014-08-22 15:26:27 -0700475 alpha.setInterpolator(mThumbnailFadeOutInterpolator);
Craig Mautner321bdf52012-12-18 09:53:24 -0800476
477 AnimationSet set = new AnimationSet(false);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800478 set.addAnimation(scale);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800479 set.addAnimation(alpha);
480 set.setDetachWallpaper(true);
481 a = set;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800482 } else if (transit == TRANSIT_WALLPAPER_INTRA_OPEN ||
483 transit == TRANSIT_WALLPAPER_INTRA_CLOSE) {
Craig Mautner321bdf52012-12-18 09:53:24 -0800484 // If we are on top of the wallpaper, we need an animation that
485 // correctly handles the wallpaper staying static behind all of
486 // the animated elements. To do this, will just have the existing
487 // element fade out.
488 a = new AlphaAnimation(1, 0);
489 a.setDetachWallpaper(true);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800490 } else {
Craig Mautner321bdf52012-12-18 09:53:24 -0800491 // For normal animations, the exiting element just holds in place.
492 a = new AlphaAnimation(1, 1);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800493 }
Craig Mautner321bdf52012-12-18 09:53:24 -0800494
495 // Pick the desired duration. If this is an inter-activity transition,
496 // it is the standard duration for that. Otherwise we use the longer
497 // task transition duration.
498 final long duration;
499 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800500 case TRANSIT_ACTIVITY_OPEN:
501 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner321bdf52012-12-18 09:53:24 -0800502 duration = mConfigShortAnimTime;
503 break;
504 default:
505 duration = DEFAULT_APP_TRANSITION_DURATION;
506 break;
507 }
508 a.setDuration(duration);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800509 a.setFillAfter(true);
Craig Mautner321bdf52012-12-18 09:53:24 -0800510 a.setInterpolator(mDecelerateInterpolator);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800511 a.initialize(appWidth, appHeight, appWidth, appHeight);
512 return a;
513 }
514
Craig Mautner80b1f642015-04-22 10:59:09 -0700515 private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame) {
Chet Haase10e23ab2015-02-11 15:08:38 -0800516 final Animation anim;
517 if (enter) {
518 // Reveal will expand and move faster in horizontal direction
519
Craig Mautner80b1f642015-04-22 10:59:09 -0700520 final int appWidth = appFrame.width();
521 final int appHeight = appFrame.height();
522
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700523 float t = 0f;
524 if (appHeight > 0) {
525 t = (float) mNextAppTransitionStartY / appHeight;
526 }
527 int translationY = mClipRevealTranslationY
528 + (int)(appHeight / 7f * t);
529
530 int centerX = mNextAppTransitionStartX + mNextAppTransitionStartWidth / 2;
531 int centerY = mNextAppTransitionStartY + mNextAppTransitionStartHeight / 2;
532
533 // Clip third of the from size of launch icon, expand to full width/height
Chet Haase10e23ab2015-02-11 15:08:38 -0800534 Animation clipAnimLR = new ClipRectLRAnimation(
Jorim Jaggib00dbd42015-07-01 12:54:58 -0700535 centerX - mNextAppTransitionStartWidth / 2,
536 centerX + mNextAppTransitionStartWidth / 2,
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700537 0, appWidth);
538 clipAnimLR.setInterpolator(mClipHorizontalInterpolator);
539 clipAnimLR.setDuration((long) (DEFAULT_APP_TRANSITION_DURATION / 2.5f));
Chet Haase10e23ab2015-02-11 15:08:38 -0800540 Animation clipAnimTB = new ClipRectTBAnimation(
Jorim Jaggib00dbd42015-07-01 12:54:58 -0700541 centerY - mNextAppTransitionStartHeight / 2 - translationY,
542 centerY + mNextAppTransitionStartHeight / 2 - translationY,
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700543 0, appHeight);
544 clipAnimTB.setInterpolator(mTouchResponseInterpolator);
Chet Haase10e23ab2015-02-11 15:08:38 -0800545 clipAnimTB.setDuration(DEFAULT_APP_TRANSITION_DURATION);
546
Chet Haase10e23ab2015-02-11 15:08:38 -0800547 TranslateYAnimation translateY = new TranslateYAnimation(
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700548 Animation.ABSOLUTE, translationY, Animation.ABSOLUTE, 0);
549 translateY.setInterpolator(mLinearOutSlowInInterpolator);
Chet Haase10e23ab2015-02-11 15:08:38 -0800550 translateY.setDuration(DEFAULT_APP_TRANSITION_DURATION);
551
552 // Quick fade-in from icon to app window
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700553 final int alphaDuration = DEFAULT_APP_TRANSITION_DURATION / 4;
554 AlphaAnimation alpha = new AlphaAnimation(0.5f, 1);
Chet Haase10e23ab2015-02-11 15:08:38 -0800555 alpha.setDuration(alphaDuration);
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700556 alpha.setInterpolator(mLinearOutSlowInInterpolator);
Chet Haase10e23ab2015-02-11 15:08:38 -0800557
558 AnimationSet set = new AnimationSet(false);
559 set.addAnimation(clipAnimLR);
560 set.addAnimation(clipAnimTB);
Chet Haase10e23ab2015-02-11 15:08:38 -0800561 set.addAnimation(translateY);
562 set.addAnimation(alpha);
Filip Gruszczynski9e2cf5b2015-07-31 12:20:40 -0700563 set.setZAdjustment(Animation.ZORDER_TOP);
Chet Haase10e23ab2015-02-11 15:08:38 -0800564 set.initialize(appWidth, appHeight, appWidth, appHeight);
565 anim = set;
566 } else {
567 final long duration;
568 switch (transit) {
569 case TRANSIT_ACTIVITY_OPEN:
570 case TRANSIT_ACTIVITY_CLOSE:
571 duration = mConfigShortAnimTime;
572 break;
573 default:
574 duration = DEFAULT_APP_TRANSITION_DURATION;
575 break;
576 }
577 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN ||
578 transit == TRANSIT_WALLPAPER_INTRA_CLOSE) {
579 // If we are on top of the wallpaper, we need an animation that
580 // correctly handles the wallpaper staying static behind all of
581 // the animated elements. To do this, will just have the existing
582 // element fade out.
583 anim = new AlphaAnimation(1, 0);
584 anim.setDetachWallpaper(true);
585 } else {
586 // For normal animations, the exiting element just holds in place.
587 anim = new AlphaAnimation(1, 1);
588 }
589 anim.setInterpolator(mDecelerateInterpolator);
590 anim.setDuration(duration);
591 anim.setFillAfter(true);
592 }
593 return anim;
594 }
595
Winson Chung399f6202014-03-19 10:47:20 -0700596 /**
597 * Prepares the specified animation with a standard duration, interpolator, etc.
598 */
Winson Chung5393dff2014-05-08 14:25:43 -0700599 Animation prepareThumbnailAnimationWithDuration(Animation a, int appWidth, int appHeight,
600 int duration, Interpolator interpolator) {
Winson Chunga4ccb862014-08-22 15:26:27 -0700601 if (duration > 0) {
602 a.setDuration(duration);
603 }
Winson Chung5393dff2014-05-08 14:25:43 -0700604 a.setFillAfter(true);
605 a.setInterpolator(interpolator);
606 a.initialize(appWidth, appHeight, appWidth, appHeight);
607 return a;
608 }
609
610 /**
611 * Prepares the specified animation with a standard duration, interpolator, etc.
612 */
Winson Chung399f6202014-03-19 10:47:20 -0700613 Animation prepareThumbnailAnimation(Animation a, int appWidth, int appHeight, int transit) {
Craig Mautner321bdf52012-12-18 09:53:24 -0800614 // Pick the desired duration. If this is an inter-activity transition,
615 // it is the standard duration for that. Otherwise we use the longer
616 // task transition duration.
Winson Chung5393dff2014-05-08 14:25:43 -0700617 final int duration;
Craig Mautner321bdf52012-12-18 09:53:24 -0800618 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800619 case TRANSIT_ACTIVITY_OPEN:
620 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner321bdf52012-12-18 09:53:24 -0800621 duration = mConfigShortAnimTime;
622 break;
623 default:
624 duration = DEFAULT_APP_TRANSITION_DURATION;
625 break;
626 }
Winson Chung5393dff2014-05-08 14:25:43 -0700627 return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
628 mDecelerateInterpolator);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800629 }
630
Winson Chung399f6202014-03-19 10:47:20 -0700631 /**
632 * Return the current thumbnail transition state.
633 */
634 int getThumbnailTransitionState(boolean enter) {
635 if (enter) {
636 if (mNextAppTransitionScaleUp) {
637 return THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
638 } else {
639 return THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN;
640 }
641 } else {
642 if (mNextAppTransitionScaleUp) {
643 return THUMBNAIL_TRANSITION_EXIT_SCALE_UP;
644 } else {
645 return THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN;
646 }
647 }
648 }
649
650 /**
651 * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
652 * when a thumbnail is specified with the activity options.
653 */
Winson Chunga4ccb862014-08-22 15:26:27 -0700654 Animation createThumbnailAspectScaleAnimationLocked(int appWidth, int appHeight,
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700655 int deviceWidth) {
Winson Chung399f6202014-03-19 10:47:20 -0700656 Animation a;
657 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
658 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
659 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
660 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
661
Winson Chunga4ccb862014-08-22 15:26:27 -0700662 float scaleW = deviceWidth / thumbWidth;
Winson Chunga4ccb862014-08-22 15:26:27 -0700663 float unscaledHeight = thumbHeight * scaleW;
664 float unscaledStartY = mNextAppTransitionStartY - (unscaledHeight - thumbHeight) / 2f;
Winson Chung399f6202014-03-19 10:47:20 -0700665 if (mNextAppTransitionScaleUp) {
Winson Chunga4ccb862014-08-22 15:26:27 -0700666 // Animation up from the thumbnail to the full screen
667 Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW,
668 mNextAppTransitionStartX + (thumbWidth / 2f),
669 mNextAppTransitionStartY + (thumbHeight / 2f));
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700670 scale.setInterpolator(mTouchResponseInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700671 scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Winson Chung399f6202014-03-19 10:47:20 -0700672 Animation alpha = new AlphaAnimation(1, 0);
Winson Chunga4ccb862014-08-22 15:26:27 -0700673 alpha.setInterpolator(mThumbnailFadeOutInterpolator);
674 alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
675 Animation translate = new TranslateAnimation(0, 0, 0, -unscaledStartY +
676 mNextAppTransitionInsets.top);
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700677 translate.setInterpolator(mTouchResponseInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700678 translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Winson Chung399f6202014-03-19 10:47:20 -0700679
680 // This AnimationSet uses the Interpolators assigned above.
681 AnimationSet set = new AnimationSet(false);
682 set.addAnimation(scale);
683 set.addAnimation(alpha);
Winson Chunga4ccb862014-08-22 15:26:27 -0700684 set.addAnimation(translate);
Winson Chung399f6202014-03-19 10:47:20 -0700685 a = set;
686 } else {
Winson Chunga4ccb862014-08-22 15:26:27 -0700687 // Animation down from the full screen to the thumbnail
688 Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f,
689 mNextAppTransitionStartX + (thumbWidth / 2f),
690 mNextAppTransitionStartY + (thumbHeight / 2f));
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700691 scale.setInterpolator(mTouchResponseInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700692 scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
693 Animation alpha = new AlphaAnimation(0f, 1f);
694 alpha.setInterpolator(mThumbnailFadeInInterpolator);
695 alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
696 Animation translate = new TranslateAnimation(0, 0, -unscaledStartY +
697 mNextAppTransitionInsets.top, 0);
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700698 translate.setInterpolator(mTouchResponseInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700699 translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Winson Chung399f6202014-03-19 10:47:20 -0700700
Winson Chunga4ccb862014-08-22 15:26:27 -0700701 // This AnimationSet uses the Interpolators assigned above.
702 AnimationSet set = new AnimationSet(false);
703 set.addAnimation(scale);
704 set.addAnimation(alpha);
705 set.addAnimation(translate);
706 a = set;
707
708 }
709 return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, 0,
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700710 mTouchResponseInterpolator);
Winson Chung399f6202014-03-19 10:47:20 -0700711 }
712
713 /**
714 * This alternate animation is created when we are doing a thumbnail transition, for the
715 * activity that is leaving, and the activity that is entering.
716 */
Winson Chunga4ccb862014-08-22 15:26:27 -0700717 Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState,
718 int appWidth, int appHeight, int orientation, int transit, Rect containingFrame,
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700719 Rect contentInsets, @Nullable Rect surfaceInsets, boolean resizedWindow) {
Winson Chung399f6202014-03-19 10:47:20 -0700720 Animation a;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200721 final int thumbWidthI = mNextAppTransitionStartWidth;
Winson Chung399f6202014-03-19 10:47:20 -0700722 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200723 final int thumbHeightI = mNextAppTransitionStartHeight;
Winson Chung399f6202014-03-19 10:47:20 -0700724 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
725
Winson Chung2820c452014-04-15 15:34:44 -0700726 // Used for the ENTER_SCALE_UP and EXIT_SCALE_DOWN transitions
727 float scale = 1f;
728 int scaledTopDecor = 0;
729
Winson Chung399f6202014-03-19 10:47:20 -0700730 switch (thumbTransitState) {
731 case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700732 if (resizedWindow) {
733 a = createAspectScaledThumbnailEnterNonFullscreenAnimationLocked(
734 containingFrame, surfaceInsets);
Winson Chung2820c452014-04-15 15:34:44 -0700735 } else {
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700736 // App window scaling up to become full screen
737 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
738 // In portrait, we scale the width and clip to the top/left square
739 scale = thumbWidth / appWidth;
740 scaledTopDecor = (int) (scale * contentInsets.top);
741 int unscaledThumbHeight = (int) (thumbHeight / scale);
742 mTmpFromClipRect.set(containingFrame);
743 mTmpFromClipRect.bottom = (mTmpFromClipRect.top + unscaledThumbHeight);
744 mTmpToClipRect.set(containingFrame);
745 } else {
746 // In landscape, we scale the height and clip to the top/left square
747 scale = thumbHeight / (appHeight - contentInsets.top);
748 scaledTopDecor = (int) (scale * contentInsets.top);
749 int unscaledThumbWidth = (int) (thumbWidth / scale);
750 mTmpFromClipRect.set(containingFrame);
751 mTmpFromClipRect.right = (mTmpFromClipRect.left + unscaledThumbWidth);
752 mTmpToClipRect.set(containingFrame);
753 }
754 // exclude top screen decor (status bar) region from the source clip.
755 mTmpFromClipRect.top = contentInsets.top;
756
757 mNextAppTransitionInsets.set(contentInsets);
758
759 Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1,
760 computePivot(mNextAppTransitionStartX, scale),
761 computePivot(mNextAppTransitionStartY, scale));
762 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
763 Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0);
764
765 AnimationSet set = new AnimationSet(true);
766 set.addAnimation(clipAnim);
767 set.addAnimation(scaleAnim);
768 set.addAnimation(translateAnim);
769 a = set;
Winson Chung2820c452014-04-15 15:34:44 -0700770 }
Winson Chung399f6202014-03-19 10:47:20 -0700771 break;
772 }
773 case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
Winson Chunga4ccb862014-08-22 15:26:27 -0700774 // Previous app window during the scale up
Winson Chung399f6202014-03-19 10:47:20 -0700775 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
Winson Chunga4ccb862014-08-22 15:26:27 -0700776 // Fade out the source activity if we are animating to a wallpaper
Winson Chung399f6202014-03-19 10:47:20 -0700777 // activity.
778 a = new AlphaAnimation(1, 0);
779 } else {
Winson Chung399f6202014-03-19 10:47:20 -0700780 a = new AlphaAnimation(1, 1);
781 }
782 break;
783 }
784 case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
Winson Chunga4ccb862014-08-22 15:26:27 -0700785 // Target app window during the scale down
786 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
787 // Fade in the destination activity if we are animating from a wallpaper
788 // activity.
789 a = new AlphaAnimation(0, 1);
790 } else {
791 a = new AlphaAnimation(1, 1);
792 }
Winson Chung399f6202014-03-19 10:47:20 -0700793 break;
794 }
795 case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
Winson Chunga4ccb862014-08-22 15:26:27 -0700796 // App window scaling down from full screen
Winson Chung2820c452014-04-15 15:34:44 -0700797 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
798 // In portrait, we scale the width and clip to the top/left square
799 scale = thumbWidth / appWidth;
800 scaledTopDecor = (int) (scale * contentInsets.top);
801 int unscaledThumbHeight = (int) (thumbHeight / scale);
802 mTmpFromClipRect.set(containingFrame);
803 mTmpToClipRect.set(containingFrame);
804 mTmpToClipRect.bottom = (mTmpToClipRect.top + unscaledThumbHeight);
805 } else {
806 // In landscape, we scale the height and clip to the top/left square
807 scale = thumbHeight / (appHeight - contentInsets.top);
808 scaledTopDecor = (int) (scale * contentInsets.top);
809 int unscaledThumbWidth = (int) (thumbWidth / scale);
810 mTmpFromClipRect.set(containingFrame);
811 mTmpToClipRect.set(containingFrame);
812 mTmpToClipRect.right = (mTmpToClipRect.left + unscaledThumbWidth);
813 }
Wale Ogunwale35a57f82015-07-01 15:07:36 -0700814 // exclude top screen decor (status bar) region from the destination clip.
815 mTmpToClipRect.top = contentInsets.top;
816
Winson Chunga4ccb862014-08-22 15:26:27 -0700817 mNextAppTransitionInsets.set(contentInsets);
Winson Chung399f6202014-03-19 10:47:20 -0700818
819 Animation scaleAnim = new ScaleAnimation(1, scale, 1, scale,
820 computePivot(mNextAppTransitionStartX, scale),
821 computePivot(mNextAppTransitionStartY, scale));
Winson Chung2820c452014-04-15 15:34:44 -0700822 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
Winson Chung399f6202014-03-19 10:47:20 -0700823 Animation translateAnim = new TranslateAnimation(0, 0, 0, -scaledTopDecor);
824
825 AnimationSet set = new AnimationSet(true);
Winson Chung399f6202014-03-19 10:47:20 -0700826 set.addAnimation(clipAnim);
827 set.addAnimation(scaleAnim);
828 set.addAnimation(translateAnim);
829
830 a = set;
831 a.setZAdjustment(Animation.ZORDER_TOP);
832 break;
833 }
834 default:
835 throw new RuntimeException("Invalid thumbnail transition state");
836 }
837
Winson Chungab79fce2014-11-04 16:15:22 -0800838 int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
839 THUMBNAIL_APP_TRANSITION_DURATION);
840 return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700841 mTouchResponseInterpolator);
Winson Chung399f6202014-03-19 10:47:20 -0700842 }
843
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700844 private Animation createAspectScaledThumbnailEnterNonFullscreenAnimationLocked(
845 Rect containingFrame, @Nullable Rect surfaceInsets) {
846 float width = containingFrame.width();
847 float height = containingFrame.height();
848 float scaleWidth = mNextAppTransitionStartWidth / width;
849 float scaleHeight = mNextAppTransitionStartHeight / height;
850 AnimationSet set = new AnimationSet(true);
851 int surfaceInsetsHorizontal = surfaceInsets == null
852 ? 0 : surfaceInsets.left + surfaceInsets.right;
853 int surfaceInsetsVertical = surfaceInsets == null
854 ? 0 : surfaceInsets.top + surfaceInsets.bottom;
855 // We want the scaling to happen from the center of the surface. In order to achieve that,
856 // we need to account for surface insets that will be used to enlarge the surface.
857 ScaleAnimation scale = new ScaleAnimation(scaleWidth, 1, scaleHeight, 1,
858 (width + surfaceInsetsHorizontal) / 2, (height + surfaceInsetsVertical) / 2);
859 int fromX = mNextAppTransitionStartX + mNextAppTransitionStartWidth / 2
860 - (containingFrame.left + containingFrame.width() / 2);
861 int fromY = mNextAppTransitionStartY + mNextAppTransitionStartHeight / 2
862 - (containingFrame.top + containingFrame.height() / 2);
863 TranslateAnimation translation = new TranslateAnimation(fromX, 0, fromY, 0);
864 set.addAnimation(scale);
865 set.addAnimation(translation);
866 return set;
867 }
868
Winson Chung399f6202014-03-19 10:47:20 -0700869 /**
Winson Chunga4ccb862014-08-22 15:26:27 -0700870 * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
871 * when a thumbnail is specified with the activity options.
872 */
873 Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit) {
874 Animation a;
875 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
876 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
877 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
878 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
879
880 if (mNextAppTransitionScaleUp) {
881 // Animation for the thumbnail zooming from its initial size to the full screen
882 float scaleW = appWidth / thumbWidth;
883 float scaleH = appHeight / thumbHeight;
884 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
885 computePivot(mNextAppTransitionStartX, 1 / scaleW),
886 computePivot(mNextAppTransitionStartY, 1 / scaleH));
887 scale.setInterpolator(mDecelerateInterpolator);
888
889 Animation alpha = new AlphaAnimation(1, 0);
890 alpha.setInterpolator(mThumbnailFadeOutInterpolator);
891
892 // This AnimationSet uses the Interpolators assigned above.
893 AnimationSet set = new AnimationSet(false);
894 set.addAnimation(scale);
895 set.addAnimation(alpha);
896 a = set;
897 } else {
898 // Animation for the thumbnail zooming down from the full screen to its final size
899 float scaleW = appWidth / thumbWidth;
900 float scaleH = appHeight / thumbHeight;
901 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
902 computePivot(mNextAppTransitionStartX, 1 / scaleW),
903 computePivot(mNextAppTransitionStartY, 1 / scaleH));
904 }
905
906 return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
907 }
908
909 /**
Winson Chung399f6202014-03-19 10:47:20 -0700910 * This animation is created when we are doing a thumbnail transition, for the activity that is
911 * leaving, and the activity that is entering.
912 */
913 Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700914 int appHeight, int transit) {
Winson Chung399f6202014-03-19 10:47:20 -0700915 Animation a;
916 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
917 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
918 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
919 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
920
921 switch (thumbTransitState) {
922 case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
923 // Entering app scales up with the thumbnail
924 float scaleW = thumbWidth / appWidth;
925 float scaleH = thumbHeight / appHeight;
926 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
927 computePivot(mNextAppTransitionStartX, scaleW),
928 computePivot(mNextAppTransitionStartY, scaleH));
929 break;
930 }
931 case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
932 // Exiting app while the thumbnail is scaling up should fade or stay in place
933 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
934 // Fade out while bringing up selected activity. This keeps the
935 // current activity from showing through a launching wallpaper
936 // activity.
937 a = new AlphaAnimation(1, 0);
938 } else {
939 // noop animation
940 a = new AlphaAnimation(1, 1);
941 }
942 break;
943 }
944 case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
945 // Entering the other app, it should just be visible while we scale the thumbnail
946 // down above it
947 a = new AlphaAnimation(1, 1);
948 break;
949 }
950 case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
951 // Exiting the current app, the app should scale down with the thumbnail
952 float scaleW = thumbWidth / appWidth;
953 float scaleH = thumbHeight / appHeight;
954 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
955 computePivot(mNextAppTransitionStartX, scaleW),
956 computePivot(mNextAppTransitionStartY, scaleH));
957
958 Animation alpha = new AlphaAnimation(1, 0);
959
960 AnimationSet set = new AnimationSet(true);
961 set.addAnimation(scale);
962 set.addAnimation(alpha);
963 set.setZAdjustment(Animation.ZORDER_TOP);
964 a = set;
965 break;
966 }
967 default:
968 throw new RuntimeException("Invalid thumbnail transition state");
969 }
970
971 return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
972 }
973
Jorim Jaggic554b772015-06-04 16:07:57 -0700974 /**
975 * @return true if and only if the first frame of the transition can be skipped, i.e. the first
976 * frame of the transition doesn't change the visuals on screen, so we can start
977 * directly with the second one
978 */
979 boolean canSkipFirstFrame() {
980 return mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM
981 && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE
982 && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL;
983 }
Craig Mautner164d4bb2012-11-26 13:51:23 -0800984
985 Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700986 int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets,
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700987 @Nullable Rect surfaceInsets, Rect appFrame, boolean isVoiceInteraction,
988 boolean resizedWindow) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800989 Animation a;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700990 if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
991 || transit == TRANSIT_TASK_OPEN
992 || transit == TRANSIT_TASK_TO_FRONT)) {
993 a = loadAnimationRes(lp, enter
994 ? com.android.internal.R.anim.voice_activity_open_enter
995 : com.android.internal.R.anim.voice_activity_open_exit);
996 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
997 "applyAnimation voice:"
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700998 + " anim=" + a + " transit=" + appTransitionToString(transit)
999 + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001000 } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE
1001 || transit == TRANSIT_TASK_CLOSE
1002 || transit == TRANSIT_TASK_TO_BACK)) {
1003 a = loadAnimationRes(lp, enter
1004 ? com.android.internal.R.anim.voice_activity_close_enter
1005 : com.android.internal.R.anim.voice_activity_close_exit);
1006 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1007 "applyAnimation voice:"
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001008 + " anim=" + a + " transit=" + appTransitionToString(transit)
1009 + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001010 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
1011 a = loadAnimationRes(mNextAppTransitionPackage, enter ?
Craig Mautner164d4bb2012-11-26 13:51:23 -08001012 mNextAppTransitionEnter : mNextAppTransitionExit);
1013 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1014 "applyAnimation:"
1015 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001016 + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
Craig Mautner164d4bb2012-11-26 13:51:23 -08001017 + " Callers=" + Debug.getCallers(3));
Winson Chung044d5292014-11-06 11:05:19 -08001018 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
1019 a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
1020 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1021 "applyAnimation:"
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001022 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
1023 + " transit=" + appTransitionToString(transit)
1024 + " Callers=" + Debug.getCallers(3));
Chet Haase10e23ab2015-02-11 15:08:38 -08001025 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
Craig Mautner80b1f642015-04-22 10:59:09 -07001026 a = createClipRevealAnimationLocked(transit, enter, appFrame);
Chet Haase10e23ab2015-02-11 15:08:38 -08001027 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1028 "applyAnimation:"
1029 + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL"
1030 + " Callers=" + Debug.getCallers(3));
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001031 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08001032 a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight);
1033 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1034 "applyAnimation:"
1035 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001036 + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
Craig Mautner164d4bb2012-11-26 13:51:23 -08001037 + " Callers=" + Debug.getCallers(3));
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001038 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
1039 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08001040 mNextAppTransitionScaleUp =
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001041 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
Winson Chunga4ccb862014-08-22 15:26:27 -07001042 a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
1043 appWidth, appHeight, transit);
1044 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
1045 String animName = mNextAppTransitionScaleUp ?
1046 "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
1047 Slog.v(TAG, "applyAnimation:"
1048 + " anim=" + a + " nextAppTransition=" + animName
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001049 + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
Winson Chunga4ccb862014-08-22 15:26:27 -07001050 + " Callers=" + Debug.getCallers(3));
1051 }
1052 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
1053 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN) {
1054 mNextAppTransitionScaleUp =
1055 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP);
1056 a = createAspectScaledThumbnailEnterExitAnimationLocked(
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -07001057 getThumbnailTransitionState(enter), appWidth, appHeight, orientation, transit,
1058 containingFrame, contentInsets, surfaceInsets, resizedWindow);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001059 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
1060 String animName = mNextAppTransitionScaleUp ?
Winson Chunga4ccb862014-08-22 15:26:27 -07001061 "ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN";
Craig Mautner164d4bb2012-11-26 13:51:23 -08001062 Slog.v(TAG, "applyAnimation:"
1063 + " anim=" + a + " nextAppTransition=" + animName
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001064 + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
Craig Mautner164d4bb2012-11-26 13:51:23 -08001065 + " Callers=" + Debug.getCallers(3));
1066 }
1067 } else {
1068 int animAttr = 0;
1069 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08001070 case TRANSIT_ACTIVITY_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001071 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001072 ? WindowAnimation_activityOpenEnterAnimation
1073 : WindowAnimation_activityOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001074 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001075 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001076 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001077 ? WindowAnimation_activityCloseEnterAnimation
1078 : WindowAnimation_activityCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001079 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001080 case TRANSIT_TASK_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001081 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001082 ? WindowAnimation_taskOpenEnterAnimation
1083 : WindowAnimation_taskOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001084 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001085 case TRANSIT_TASK_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001086 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001087 ? WindowAnimation_taskCloseEnterAnimation
1088 : WindowAnimation_taskCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001089 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001090 case TRANSIT_TASK_TO_FRONT:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001091 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001092 ? WindowAnimation_taskToFrontEnterAnimation
1093 : WindowAnimation_taskToFrontExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001094 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001095 case TRANSIT_TASK_TO_BACK:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001096 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001097 ? WindowAnimation_taskToBackEnterAnimation
1098 : WindowAnimation_taskToBackExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001099 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001100 case TRANSIT_WALLPAPER_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001101 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001102 ? WindowAnimation_wallpaperOpenEnterAnimation
1103 : WindowAnimation_wallpaperOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001104 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001105 case TRANSIT_WALLPAPER_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001106 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001107 ? WindowAnimation_wallpaperCloseEnterAnimation
1108 : WindowAnimation_wallpaperCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001109 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001110 case TRANSIT_WALLPAPER_INTRA_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001111 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001112 ? WindowAnimation_wallpaperIntraOpenEnterAnimation
1113 : WindowAnimation_wallpaperIntraOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001114 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001115 case TRANSIT_WALLPAPER_INTRA_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001116 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001117 ? WindowAnimation_wallpaperIntraCloseEnterAnimation
1118 : WindowAnimation_wallpaperIntraCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001119 break;
Craig Mautnerbb742462014-07-07 15:28:55 -07001120 case TRANSIT_TASK_OPEN_BEHIND:
1121 animAttr = enter
1122 ? WindowAnimation_launchTaskBehindSourceAnimation
Craig Mautner3b2cd1d2014-08-25 14:25:54 -07001123 : WindowAnimation_launchTaskBehindTargetAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001124 }
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001125 a = animAttr != 0 ? loadAnimationAttr(lp, animAttr) : null;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001126 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1127 "applyAnimation:"
1128 + " anim=" + a
1129 + " animAttr=0x" + Integer.toHexString(animAttr)
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001130 + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
Craig Mautner164d4bb2012-11-26 13:51:23 -08001131 + " Callers=" + Debug.getCallers(3));
1132 }
1133 return a;
1134 }
1135
1136 void postAnimationCallback() {
1137 if (mNextAppTransitionCallback != null) {
1138 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, mNextAppTransitionCallback));
1139 mNextAppTransitionCallback = null;
1140 }
1141 }
1142
1143 void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
1144 IRemoteCallback startedCallback) {
1145 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001146 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001147 mNextAppTransitionPackage = packageName;
1148 mNextAppTransitionThumbnail = null;
1149 mNextAppTransitionEnter = enterAnim;
1150 mNextAppTransitionExit = exitAnim;
1151 postAnimationCallback();
1152 mNextAppTransitionCallback = startedCallback;
1153 } else {
1154 postAnimationCallback();
1155 }
1156 }
1157
1158 void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
1159 int startHeight) {
1160 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001161 mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001162 mNextAppTransitionPackage = null;
1163 mNextAppTransitionThumbnail = null;
1164 mNextAppTransitionStartX = startX;
1165 mNextAppTransitionStartY = startY;
1166 mNextAppTransitionStartWidth = startWidth;
1167 mNextAppTransitionStartHeight = startHeight;
1168 postAnimationCallback();
1169 mNextAppTransitionCallback = null;
1170 }
1171 }
1172
Chet Haase10e23ab2015-02-11 15:08:38 -08001173 void overridePendingAppTransitionClipReveal(int startX, int startY,
1174 int startWidth, int startHeight) {
1175 if (isTransitionSet()) {
1176 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL;
1177 mNextAppTransitionStartX = startX;
1178 mNextAppTransitionStartY = startY;
1179 mNextAppTransitionStartWidth = startWidth;
1180 mNextAppTransitionStartHeight = startHeight;
1181 postAnimationCallback();
1182 mNextAppTransitionCallback = null;
1183 }
1184 }
1185
Craig Mautner164d4bb2012-11-26 13:51:23 -08001186 void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
1187 IRemoteCallback startedCallback, boolean scaleUp) {
1188 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001189 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP
1190 : NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001191 mNextAppTransitionPackage = null;
1192 mNextAppTransitionThumbnail = srcThumb;
1193 mNextAppTransitionScaleUp = scaleUp;
1194 mNextAppTransitionStartX = startX;
1195 mNextAppTransitionStartY = startY;
1196 postAnimationCallback();
1197 mNextAppTransitionCallback = startedCallback;
1198 } else {
1199 postAnimationCallback();
1200 }
1201 }
1202
Winson Chunga4ccb862014-08-22 15:26:27 -07001203 void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX, int startY,
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001204 int targetWidth, int targetHeight, IRemoteCallback startedCallback, boolean scaleUp) {
Winson Chunga4ccb862014-08-22 15:26:27 -07001205 if (isTransitionSet()) {
1206 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
1207 : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
1208 mNextAppTransitionPackage = null;
1209 mNextAppTransitionThumbnail = srcThumb;
1210 mNextAppTransitionScaleUp = scaleUp;
1211 mNextAppTransitionStartX = startX;
1212 mNextAppTransitionStartY = startY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001213 mNextAppTransitionStartWidth = targetWidth;
1214 mNextAppTransitionStartHeight = targetHeight;
Winson Chunga4ccb862014-08-22 15:26:27 -07001215 postAnimationCallback();
1216 mNextAppTransitionCallback = startedCallback;
1217 } else {
1218 postAnimationCallback();
1219 }
1220 }
1221
Winson Chung044d5292014-11-06 11:05:19 -08001222 void overrideInPlaceAppTransition(String packageName, int anim) {
1223 if (isTransitionSet()) {
1224 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE;
1225 mNextAppTransitionPackage = packageName;
1226 mNextAppTransitionInPlace = anim;
1227 } else {
1228 postAnimationCallback();
1229 }
1230 }
1231
Craig Mautner164d4bb2012-11-26 13:51:23 -08001232 @Override
1233 public String toString() {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001234 return "mNextAppTransition=" + appTransitionToString(mNextAppTransition);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001235 }
1236
Craig Mautner4b71aa12012-12-27 17:20:01 -08001237 /**
1238 * Returns the human readable name of a window transition.
1239 *
1240 * @param transition The window transition.
1241 * @return The transition symbolic name.
1242 */
1243 public static String appTransitionToString(int transition) {
1244 switch (transition) {
1245 case TRANSIT_UNSET: {
1246 return "TRANSIT_UNSET";
1247 }
1248 case TRANSIT_NONE: {
1249 return "TRANSIT_NONE";
1250 }
Craig Mautner4b71aa12012-12-27 17:20:01 -08001251 case TRANSIT_ACTIVITY_OPEN: {
1252 return "TRANSIT_ACTIVITY_OPEN";
1253 }
1254 case TRANSIT_ACTIVITY_CLOSE: {
1255 return "TRANSIT_ACTIVITY_CLOSE";
1256 }
1257 case TRANSIT_TASK_OPEN: {
1258 return "TRANSIT_TASK_OPEN";
1259 }
1260 case TRANSIT_TASK_CLOSE: {
1261 return "TRANSIT_TASK_CLOSE";
1262 }
1263 case TRANSIT_TASK_TO_FRONT: {
1264 return "TRANSIT_TASK_TO_FRONT";
1265 }
1266 case TRANSIT_TASK_TO_BACK: {
1267 return "TRANSIT_TASK_TO_BACK";
1268 }
1269 case TRANSIT_WALLPAPER_CLOSE: {
1270 return "TRANSIT_WALLPAPER_CLOSE";
1271 }
1272 case TRANSIT_WALLPAPER_OPEN: {
1273 return "TRANSIT_WALLPAPER_OPEN";
1274 }
1275 case TRANSIT_WALLPAPER_INTRA_OPEN: {
1276 return "TRANSIT_WALLPAPER_INTRA_OPEN";
1277 }
1278 case TRANSIT_WALLPAPER_INTRA_CLOSE: {
1279 return "TRANSIT_WALLPAPER_INTRA_CLOSE";
1280 }
Craig Mautnerbb742462014-07-07 15:28:55 -07001281 case TRANSIT_TASK_OPEN_BEHIND: {
1282 return "TRANSIT_TASK_OPEN_BEHIND";
1283 }
Craig Mautner4b71aa12012-12-27 17:20:01 -08001284 default: {
1285 return "<UNKNOWN>";
1286 }
1287 }
1288 }
1289
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001290 private String appStateToString() {
1291 switch (mAppTransitionState) {
1292 case APP_STATE_IDLE:
1293 return "APP_STATE_IDLE";
1294 case APP_STATE_READY:
1295 return "APP_STATE_READY";
1296 case APP_STATE_RUNNING:
1297 return "APP_STATE_RUNNING";
1298 case APP_STATE_TIMEOUT:
1299 return "APP_STATE_TIMEOUT";
1300 default:
1301 return "unknown state=" + mAppTransitionState;
1302 }
1303 }
1304
1305 private String transitTypeToString() {
1306 switch (mNextAppTransitionType) {
1307 case NEXT_TRANSIT_TYPE_NONE:
1308 return "NEXT_TRANSIT_TYPE_NONE";
1309 case NEXT_TRANSIT_TYPE_CUSTOM:
1310 return "NEXT_TRANSIT_TYPE_CUSTOM";
Winson Chung044d5292014-11-06 11:05:19 -08001311 case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
1312 return "NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE";
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001313 case NEXT_TRANSIT_TYPE_SCALE_UP:
1314 return "NEXT_TRANSIT_TYPE_SCALE_UP";
1315 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
1316 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP";
1317 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
1318 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN";
Winson Chunga4ccb862014-08-22 15:26:27 -07001319 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
1320 return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP";
1321 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
1322 return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN";
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001323 default:
1324 return "unknown type=" + mNextAppTransitionType;
1325 }
1326 }
1327
Craig Mautner164d4bb2012-11-26 13:51:23 -08001328 @Override
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001329 public void dump(PrintWriter pw, String prefix) {
1330 pw.print(prefix); pw.println(this);
1331 pw.print(prefix); pw.print("mAppTransitionState="); pw.println(appStateToString());
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001332 if (mNextAppTransitionType != NEXT_TRANSIT_TYPE_NONE) {
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001333 pw.print(prefix); pw.print("mNextAppTransitionType=");
1334 pw.println(transitTypeToString());
Craig Mautner164d4bb2012-11-26 13:51:23 -08001335 }
1336 switch (mNextAppTransitionType) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001337 case NEXT_TRANSIT_TYPE_CUSTOM:
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001338 pw.print(prefix); pw.print("mNextAppTransitionPackage=");
Craig Mautner164d4bb2012-11-26 13:51:23 -08001339 pw.println(mNextAppTransitionPackage);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001340 pw.print(prefix); pw.print("mNextAppTransitionEnter=0x");
Craig Mautner164d4bb2012-11-26 13:51:23 -08001341 pw.print(Integer.toHexString(mNextAppTransitionEnter));
1342 pw.print(" mNextAppTransitionExit=0x");
1343 pw.println(Integer.toHexString(mNextAppTransitionExit));
1344 break;
Winson Chung044d5292014-11-06 11:05:19 -08001345 case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001346 pw.print(prefix); pw.print("mNextAppTransitionPackage=");
Winson Chung044d5292014-11-06 11:05:19 -08001347 pw.println(mNextAppTransitionPackage);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001348 pw.print(prefix); pw.print("mNextAppTransitionInPlace=0x");
Winson Chung044d5292014-11-06 11:05:19 -08001349 pw.print(Integer.toHexString(mNextAppTransitionInPlace));
1350 break;
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001351 case NEXT_TRANSIT_TYPE_SCALE_UP:
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001352 pw.print(prefix); pw.print("mNextAppTransitionStartX=");
1353 pw.print(mNextAppTransitionStartX);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001354 pw.print(" mNextAppTransitionStartY=");
1355 pw.println(mNextAppTransitionStartY);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001356 pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
Craig Mautner164d4bb2012-11-26 13:51:23 -08001357 pw.print(mNextAppTransitionStartWidth);
1358 pw.print(" mNextAppTransitionStartHeight=");
1359 pw.println(mNextAppTransitionStartHeight);
1360 break;
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001361 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
1362 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -07001363 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
1364 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001365 pw.print(prefix); pw.print("mNextAppTransitionThumbnail=");
Craig Mautner164d4bb2012-11-26 13:51:23 -08001366 pw.print(mNextAppTransitionThumbnail);
1367 pw.print(" mNextAppTransitionStartX=");
1368 pw.print(mNextAppTransitionStartX);
1369 pw.print(" mNextAppTransitionStartY=");
1370 pw.println(mNextAppTransitionStartY);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001371 pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001372 pw.print(mNextAppTransitionStartWidth);
1373 pw.print(" mNextAppTransitionStartHeight=");
1374 pw.println(mNextAppTransitionStartHeight);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001375 pw.print(prefix); pw.print("mNextAppTransitionScaleUp=");
1376 pw.println(mNextAppTransitionScaleUp);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001377 break;
1378 }
1379 if (mNextAppTransitionCallback != null) {
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001380 pw.print(prefix); pw.print("mNextAppTransitionCallback=");
1381 pw.println(mNextAppTransitionCallback);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001382 }
1383 }
Amith Yamasani4befbec2013-07-10 16:18:01 -07001384
1385 public void setCurrentUser(int newUserId) {
1386 mCurrentUserId = newUserId;
1387 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08001388}