blob: dfdb29c1071a3f79feafa60adf4d1fd33b322826 [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 */
Filip Gruszczynskidfb25d32015-08-14 11:06:18 -0700654 Animation createThumbnailAspectScaleAnimationLocked(Rect appRect) {
Winson Chung399f6202014-03-19 10:47:20 -0700655 Animation a;
656 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
657 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
658 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
659 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
Filip Gruszczynskidfb25d32015-08-14 11:06:18 -0700660 final int appWidth = appRect.width();
Winson Chung399f6202014-03-19 10:47:20 -0700661
Filip Gruszczynskidfb25d32015-08-14 11:06:18 -0700662 float scaleW = appWidth / 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);
Filip Gruszczynskidfb25d32015-08-14 11:06:18 -0700675 final float toX = appRect.left + appRect.width() / 2 -
676 (mNextAppTransitionStartX + thumbWidth / 2);
677 final float toY = appRect.top + mNextAppTransitionInsets.top + -unscaledStartY;
678 Animation translate = new TranslateAnimation(0, toX, 0, toY);
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700679 translate.setInterpolator(mTouchResponseInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700680 translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Winson Chung399f6202014-03-19 10:47:20 -0700681
682 // This AnimationSet uses the Interpolators assigned above.
683 AnimationSet set = new AnimationSet(false);
684 set.addAnimation(scale);
685 set.addAnimation(alpha);
Winson Chunga4ccb862014-08-22 15:26:27 -0700686 set.addAnimation(translate);
Winson Chung399f6202014-03-19 10:47:20 -0700687 a = set;
688 } else {
Winson Chunga4ccb862014-08-22 15:26:27 -0700689 // Animation down from the full screen to the thumbnail
690 Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f,
691 mNextAppTransitionStartX + (thumbWidth / 2f),
692 mNextAppTransitionStartY + (thumbHeight / 2f));
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700693 scale.setInterpolator(mTouchResponseInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700694 scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
695 Animation alpha = new AlphaAnimation(0f, 1f);
696 alpha.setInterpolator(mThumbnailFadeInInterpolator);
697 alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
698 Animation translate = new TranslateAnimation(0, 0, -unscaledStartY +
699 mNextAppTransitionInsets.top, 0);
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700700 translate.setInterpolator(mTouchResponseInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700701 translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Winson Chung399f6202014-03-19 10:47:20 -0700702
Winson Chunga4ccb862014-08-22 15:26:27 -0700703 // This AnimationSet uses the Interpolators assigned above.
704 AnimationSet set = new AnimationSet(false);
705 set.addAnimation(scale);
706 set.addAnimation(alpha);
707 set.addAnimation(translate);
708 a = set;
709
710 }
Filip Gruszczynskidfb25d32015-08-14 11:06:18 -0700711 return prepareThumbnailAnimationWithDuration(a, appWidth, appRect.height(), 0,
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700712 mTouchResponseInterpolator);
Winson Chung399f6202014-03-19 10:47:20 -0700713 }
714
715 /**
716 * This alternate animation is created when we are doing a thumbnail transition, for the
717 * activity that is leaving, and the activity that is entering.
718 */
Winson Chunga4ccb862014-08-22 15:26:27 -0700719 Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState,
720 int appWidth, int appHeight, int orientation, int transit, Rect containingFrame,
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700721 Rect contentInsets, @Nullable Rect surfaceInsets, boolean resizedWindow) {
Winson Chung399f6202014-03-19 10:47:20 -0700722 Animation a;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200723 final int thumbWidthI = mNextAppTransitionStartWidth;
Winson Chung399f6202014-03-19 10:47:20 -0700724 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200725 final int thumbHeightI = mNextAppTransitionStartHeight;
Winson Chung399f6202014-03-19 10:47:20 -0700726 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
727
Winson Chung2820c452014-04-15 15:34:44 -0700728 // Used for the ENTER_SCALE_UP and EXIT_SCALE_DOWN transitions
729 float scale = 1f;
730 int scaledTopDecor = 0;
731
Winson Chung399f6202014-03-19 10:47:20 -0700732 switch (thumbTransitState) {
733 case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700734 if (resizedWindow) {
735 a = createAspectScaledThumbnailEnterNonFullscreenAnimationLocked(
736 containingFrame, surfaceInsets);
Winson Chung2820c452014-04-15 15:34:44 -0700737 } else {
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700738 // App window scaling up to become full screen
739 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
740 // In portrait, we scale the width and clip to the top/left square
741 scale = thumbWidth / appWidth;
742 scaledTopDecor = (int) (scale * contentInsets.top);
743 int unscaledThumbHeight = (int) (thumbHeight / scale);
744 mTmpFromClipRect.set(containingFrame);
745 mTmpFromClipRect.bottom = (mTmpFromClipRect.top + unscaledThumbHeight);
746 mTmpToClipRect.set(containingFrame);
747 } else {
748 // In landscape, we scale the height and clip to the top/left square
749 scale = thumbHeight / (appHeight - contentInsets.top);
750 scaledTopDecor = (int) (scale * contentInsets.top);
751 int unscaledThumbWidth = (int) (thumbWidth / scale);
752 mTmpFromClipRect.set(containingFrame);
753 mTmpFromClipRect.right = (mTmpFromClipRect.left + unscaledThumbWidth);
754 mTmpToClipRect.set(containingFrame);
755 }
756 // exclude top screen decor (status bar) region from the source clip.
757 mTmpFromClipRect.top = contentInsets.top;
758
759 mNextAppTransitionInsets.set(contentInsets);
760
761 Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1,
762 computePivot(mNextAppTransitionStartX, scale),
763 computePivot(mNextAppTransitionStartY, scale));
764 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
765 Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0);
766
767 AnimationSet set = new AnimationSet(true);
768 set.addAnimation(clipAnim);
769 set.addAnimation(scaleAnim);
770 set.addAnimation(translateAnim);
771 a = set;
Winson Chung2820c452014-04-15 15:34:44 -0700772 }
Winson Chung399f6202014-03-19 10:47:20 -0700773 break;
774 }
775 case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
Winson Chunga4ccb862014-08-22 15:26:27 -0700776 // Previous app window during the scale up
Winson Chung399f6202014-03-19 10:47:20 -0700777 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
Winson Chunga4ccb862014-08-22 15:26:27 -0700778 // Fade out the source activity if we are animating to a wallpaper
Winson Chung399f6202014-03-19 10:47:20 -0700779 // activity.
780 a = new AlphaAnimation(1, 0);
781 } else {
Winson Chung399f6202014-03-19 10:47:20 -0700782 a = new AlphaAnimation(1, 1);
783 }
784 break;
785 }
786 case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
Winson Chunga4ccb862014-08-22 15:26:27 -0700787 // Target app window during the scale down
788 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
789 // Fade in the destination activity if we are animating from a wallpaper
790 // activity.
791 a = new AlphaAnimation(0, 1);
792 } else {
793 a = new AlphaAnimation(1, 1);
794 }
Winson Chung399f6202014-03-19 10:47:20 -0700795 break;
796 }
797 case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
Winson Chunga4ccb862014-08-22 15:26:27 -0700798 // App window scaling down from full screen
Winson Chung2820c452014-04-15 15:34:44 -0700799 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
800 // In portrait, we scale the width and clip to the top/left square
801 scale = thumbWidth / appWidth;
802 scaledTopDecor = (int) (scale * contentInsets.top);
803 int unscaledThumbHeight = (int) (thumbHeight / scale);
804 mTmpFromClipRect.set(containingFrame);
805 mTmpToClipRect.set(containingFrame);
806 mTmpToClipRect.bottom = (mTmpToClipRect.top + unscaledThumbHeight);
807 } else {
808 // In landscape, we scale the height and clip to the top/left square
809 scale = thumbHeight / (appHeight - contentInsets.top);
810 scaledTopDecor = (int) (scale * contentInsets.top);
811 int unscaledThumbWidth = (int) (thumbWidth / scale);
812 mTmpFromClipRect.set(containingFrame);
813 mTmpToClipRect.set(containingFrame);
814 mTmpToClipRect.right = (mTmpToClipRect.left + unscaledThumbWidth);
815 }
Wale Ogunwale35a57f82015-07-01 15:07:36 -0700816 // exclude top screen decor (status bar) region from the destination clip.
817 mTmpToClipRect.top = contentInsets.top;
818
Winson Chunga4ccb862014-08-22 15:26:27 -0700819 mNextAppTransitionInsets.set(contentInsets);
Winson Chung399f6202014-03-19 10:47:20 -0700820
821 Animation scaleAnim = new ScaleAnimation(1, scale, 1, scale,
822 computePivot(mNextAppTransitionStartX, scale),
823 computePivot(mNextAppTransitionStartY, scale));
Winson Chung2820c452014-04-15 15:34:44 -0700824 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
Winson Chung399f6202014-03-19 10:47:20 -0700825 Animation translateAnim = new TranslateAnimation(0, 0, 0, -scaledTopDecor);
826
827 AnimationSet set = new AnimationSet(true);
Winson Chung399f6202014-03-19 10:47:20 -0700828 set.addAnimation(clipAnim);
829 set.addAnimation(scaleAnim);
830 set.addAnimation(translateAnim);
831
832 a = set;
833 a.setZAdjustment(Animation.ZORDER_TOP);
834 break;
835 }
836 default:
837 throw new RuntimeException("Invalid thumbnail transition state");
838 }
839
Winson Chungab79fce2014-11-04 16:15:22 -0800840 int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
841 THUMBNAIL_APP_TRANSITION_DURATION);
842 return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
Jorim Jaggi1d763a62015-06-02 17:07:39 -0700843 mTouchResponseInterpolator);
Winson Chung399f6202014-03-19 10:47:20 -0700844 }
845
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700846 private Animation createAspectScaledThumbnailEnterNonFullscreenAnimationLocked(
847 Rect containingFrame, @Nullable Rect surfaceInsets) {
848 float width = containingFrame.width();
849 float height = containingFrame.height();
850 float scaleWidth = mNextAppTransitionStartWidth / width;
851 float scaleHeight = mNextAppTransitionStartHeight / height;
852 AnimationSet set = new AnimationSet(true);
853 int surfaceInsetsHorizontal = surfaceInsets == null
854 ? 0 : surfaceInsets.left + surfaceInsets.right;
855 int surfaceInsetsVertical = surfaceInsets == null
856 ? 0 : surfaceInsets.top + surfaceInsets.bottom;
857 // We want the scaling to happen from the center of the surface. In order to achieve that,
858 // we need to account for surface insets that will be used to enlarge the surface.
859 ScaleAnimation scale = new ScaleAnimation(scaleWidth, 1, scaleHeight, 1,
860 (width + surfaceInsetsHorizontal) / 2, (height + surfaceInsetsVertical) / 2);
861 int fromX = mNextAppTransitionStartX + mNextAppTransitionStartWidth / 2
862 - (containingFrame.left + containingFrame.width() / 2);
863 int fromY = mNextAppTransitionStartY + mNextAppTransitionStartHeight / 2
864 - (containingFrame.top + containingFrame.height() / 2);
865 TranslateAnimation translation = new TranslateAnimation(fromX, 0, fromY, 0);
866 set.addAnimation(scale);
867 set.addAnimation(translation);
868 return set;
869 }
870
Winson Chung399f6202014-03-19 10:47:20 -0700871 /**
Winson Chunga4ccb862014-08-22 15:26:27 -0700872 * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
873 * when a thumbnail is specified with the activity options.
874 */
875 Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit) {
876 Animation a;
877 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
878 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
879 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
880 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
881
882 if (mNextAppTransitionScaleUp) {
883 // Animation for the thumbnail zooming from its initial size to the full screen
884 float scaleW = appWidth / thumbWidth;
885 float scaleH = appHeight / thumbHeight;
886 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
887 computePivot(mNextAppTransitionStartX, 1 / scaleW),
888 computePivot(mNextAppTransitionStartY, 1 / scaleH));
889 scale.setInterpolator(mDecelerateInterpolator);
890
891 Animation alpha = new AlphaAnimation(1, 0);
892 alpha.setInterpolator(mThumbnailFadeOutInterpolator);
893
894 // This AnimationSet uses the Interpolators assigned above.
895 AnimationSet set = new AnimationSet(false);
896 set.addAnimation(scale);
897 set.addAnimation(alpha);
898 a = set;
899 } else {
900 // Animation for the thumbnail zooming down from the full screen to its final size
901 float scaleW = appWidth / thumbWidth;
902 float scaleH = appHeight / thumbHeight;
903 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
904 computePivot(mNextAppTransitionStartX, 1 / scaleW),
905 computePivot(mNextAppTransitionStartY, 1 / scaleH));
906 }
907
908 return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
909 }
910
911 /**
Winson Chung399f6202014-03-19 10:47:20 -0700912 * This animation is created when we are doing a thumbnail transition, for the activity that is
913 * leaving, and the activity that is entering.
914 */
915 Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700916 int appHeight, int transit) {
Winson Chung399f6202014-03-19 10:47:20 -0700917 Animation a;
918 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
919 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
920 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
921 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
922
923 switch (thumbTransitState) {
924 case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
925 // Entering app scales up with the thumbnail
926 float scaleW = thumbWidth / appWidth;
927 float scaleH = thumbHeight / appHeight;
928 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
929 computePivot(mNextAppTransitionStartX, scaleW),
930 computePivot(mNextAppTransitionStartY, scaleH));
931 break;
932 }
933 case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
934 // Exiting app while the thumbnail is scaling up should fade or stay in place
935 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
936 // Fade out while bringing up selected activity. This keeps the
937 // current activity from showing through a launching wallpaper
938 // activity.
939 a = new AlphaAnimation(1, 0);
940 } else {
941 // noop animation
942 a = new AlphaAnimation(1, 1);
943 }
944 break;
945 }
946 case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
947 // Entering the other app, it should just be visible while we scale the thumbnail
948 // down above it
949 a = new AlphaAnimation(1, 1);
950 break;
951 }
952 case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
953 // Exiting the current app, the app should scale down with the thumbnail
954 float scaleW = thumbWidth / appWidth;
955 float scaleH = thumbHeight / appHeight;
956 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
957 computePivot(mNextAppTransitionStartX, scaleW),
958 computePivot(mNextAppTransitionStartY, scaleH));
959
960 Animation alpha = new AlphaAnimation(1, 0);
961
962 AnimationSet set = new AnimationSet(true);
963 set.addAnimation(scale);
964 set.addAnimation(alpha);
965 set.setZAdjustment(Animation.ZORDER_TOP);
966 a = set;
967 break;
968 }
969 default:
970 throw new RuntimeException("Invalid thumbnail transition state");
971 }
972
973 return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
974 }
975
Jorim Jaggic554b772015-06-04 16:07:57 -0700976 /**
977 * @return true if and only if the first frame of the transition can be skipped, i.e. the first
978 * frame of the transition doesn't change the visuals on screen, so we can start
979 * directly with the second one
980 */
981 boolean canSkipFirstFrame() {
982 return mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM
983 && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE
984 && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL;
985 }
Craig Mautner164d4bb2012-11-26 13:51:23 -0800986
987 Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700988 int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets,
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -0700989 @Nullable Rect surfaceInsets, Rect appFrame, boolean isVoiceInteraction,
990 boolean resizedWindow) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800991 Animation a;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700992 if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
993 || transit == TRANSIT_TASK_OPEN
994 || transit == TRANSIT_TASK_TO_FRONT)) {
995 a = loadAnimationRes(lp, enter
996 ? com.android.internal.R.anim.voice_activity_open_enter
997 : com.android.internal.R.anim.voice_activity_open_exit);
998 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
999 "applyAnimation voice:"
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001000 + " anim=" + a + " transit=" + appTransitionToString(transit)
1001 + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001002 } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE
1003 || transit == TRANSIT_TASK_CLOSE
1004 || transit == TRANSIT_TASK_TO_BACK)) {
1005 a = loadAnimationRes(lp, enter
1006 ? com.android.internal.R.anim.voice_activity_close_enter
1007 : com.android.internal.R.anim.voice_activity_close_exit);
1008 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1009 "applyAnimation voice:"
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001010 + " anim=" + a + " transit=" + appTransitionToString(transit)
1011 + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001012 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
1013 a = loadAnimationRes(mNextAppTransitionPackage, enter ?
Craig Mautner164d4bb2012-11-26 13:51:23 -08001014 mNextAppTransitionEnter : mNextAppTransitionExit);
1015 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1016 "applyAnimation:"
1017 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001018 + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
Craig Mautner164d4bb2012-11-26 13:51:23 -08001019 + " Callers=" + Debug.getCallers(3));
Winson Chung044d5292014-11-06 11:05:19 -08001020 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
1021 a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
1022 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1023 "applyAnimation:"
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001024 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
1025 + " transit=" + appTransitionToString(transit)
1026 + " Callers=" + Debug.getCallers(3));
Chet Haase10e23ab2015-02-11 15:08:38 -08001027 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
Craig Mautner80b1f642015-04-22 10:59:09 -07001028 a = createClipRevealAnimationLocked(transit, enter, appFrame);
Chet Haase10e23ab2015-02-11 15:08:38 -08001029 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1030 "applyAnimation:"
1031 + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL"
1032 + " Callers=" + Debug.getCallers(3));
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001033 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08001034 a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight);
1035 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1036 "applyAnimation:"
1037 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001038 + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
Craig Mautner164d4bb2012-11-26 13:51:23 -08001039 + " Callers=" + Debug.getCallers(3));
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001040 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
1041 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
Craig Mautner164d4bb2012-11-26 13:51:23 -08001042 mNextAppTransitionScaleUp =
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001043 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
Winson Chunga4ccb862014-08-22 15:26:27 -07001044 a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
1045 appWidth, appHeight, transit);
1046 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
1047 String animName = mNextAppTransitionScaleUp ?
1048 "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
1049 Slog.v(TAG, "applyAnimation:"
1050 + " anim=" + a + " nextAppTransition=" + animName
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001051 + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
Winson Chunga4ccb862014-08-22 15:26:27 -07001052 + " Callers=" + Debug.getCallers(3));
1053 }
1054 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
1055 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN) {
1056 mNextAppTransitionScaleUp =
1057 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP);
1058 a = createAspectScaledThumbnailEnterExitAnimationLocked(
Filip Gruszczynski71b0d2d2015-08-12 18:52:26 -07001059 getThumbnailTransitionState(enter), appWidth, appHeight, orientation, transit,
1060 containingFrame, contentInsets, surfaceInsets, resizedWindow);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001061 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
1062 String animName = mNextAppTransitionScaleUp ?
Winson Chunga4ccb862014-08-22 15:26:27 -07001063 "ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN";
Craig Mautner164d4bb2012-11-26 13:51:23 -08001064 Slog.v(TAG, "applyAnimation:"
1065 + " anim=" + a + " nextAppTransition=" + animName
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001066 + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
Craig Mautner164d4bb2012-11-26 13:51:23 -08001067 + " Callers=" + Debug.getCallers(3));
1068 }
1069 } else {
1070 int animAttr = 0;
1071 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -08001072 case TRANSIT_ACTIVITY_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001073 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001074 ? WindowAnimation_activityOpenEnterAnimation
1075 : WindowAnimation_activityOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001076 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001077 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001078 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001079 ? WindowAnimation_activityCloseEnterAnimation
1080 : WindowAnimation_activityCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001081 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001082 case TRANSIT_TASK_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001083 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001084 ? WindowAnimation_taskOpenEnterAnimation
1085 : WindowAnimation_taskOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001086 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001087 case TRANSIT_TASK_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001088 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001089 ? WindowAnimation_taskCloseEnterAnimation
1090 : WindowAnimation_taskCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001091 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001092 case TRANSIT_TASK_TO_FRONT:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001093 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001094 ? WindowAnimation_taskToFrontEnterAnimation
1095 : WindowAnimation_taskToFrontExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001096 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001097 case TRANSIT_TASK_TO_BACK:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001098 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001099 ? WindowAnimation_taskToBackEnterAnimation
1100 : WindowAnimation_taskToBackExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001101 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001102 case TRANSIT_WALLPAPER_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001103 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001104 ? WindowAnimation_wallpaperOpenEnterAnimation
1105 : WindowAnimation_wallpaperOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001106 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001107 case TRANSIT_WALLPAPER_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001108 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001109 ? WindowAnimation_wallpaperCloseEnterAnimation
1110 : WindowAnimation_wallpaperCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001111 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001112 case TRANSIT_WALLPAPER_INTRA_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001113 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001114 ? WindowAnimation_wallpaperIntraOpenEnterAnimation
1115 : WindowAnimation_wallpaperIntraOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001116 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001117 case TRANSIT_WALLPAPER_INTRA_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001118 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001119 ? WindowAnimation_wallpaperIntraCloseEnterAnimation
1120 : WindowAnimation_wallpaperIntraCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001121 break;
Craig Mautnerbb742462014-07-07 15:28:55 -07001122 case TRANSIT_TASK_OPEN_BEHIND:
1123 animAttr = enter
1124 ? WindowAnimation_launchTaskBehindSourceAnimation
Craig Mautner3b2cd1d2014-08-25 14:25:54 -07001125 : WindowAnimation_launchTaskBehindTargetAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001126 }
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001127 a = animAttr != 0 ? loadAnimationAttr(lp, animAttr) : null;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001128 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1129 "applyAnimation:"
1130 + " anim=" + a
1131 + " animAttr=0x" + Integer.toHexString(animAttr)
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001132 + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
Craig Mautner164d4bb2012-11-26 13:51:23 -08001133 + " Callers=" + Debug.getCallers(3));
1134 }
1135 return a;
1136 }
1137
1138 void postAnimationCallback() {
1139 if (mNextAppTransitionCallback != null) {
1140 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, mNextAppTransitionCallback));
1141 mNextAppTransitionCallback = null;
1142 }
1143 }
1144
1145 void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
1146 IRemoteCallback startedCallback) {
1147 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001148 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001149 mNextAppTransitionPackage = packageName;
1150 mNextAppTransitionThumbnail = null;
1151 mNextAppTransitionEnter = enterAnim;
1152 mNextAppTransitionExit = exitAnim;
1153 postAnimationCallback();
1154 mNextAppTransitionCallback = startedCallback;
1155 } else {
1156 postAnimationCallback();
1157 }
1158 }
1159
1160 void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
1161 int startHeight) {
1162 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001163 mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001164 mNextAppTransitionPackage = null;
1165 mNextAppTransitionThumbnail = null;
1166 mNextAppTransitionStartX = startX;
1167 mNextAppTransitionStartY = startY;
1168 mNextAppTransitionStartWidth = startWidth;
1169 mNextAppTransitionStartHeight = startHeight;
1170 postAnimationCallback();
1171 mNextAppTransitionCallback = null;
1172 }
1173 }
1174
Chet Haase10e23ab2015-02-11 15:08:38 -08001175 void overridePendingAppTransitionClipReveal(int startX, int startY,
1176 int startWidth, int startHeight) {
1177 if (isTransitionSet()) {
1178 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL;
1179 mNextAppTransitionStartX = startX;
1180 mNextAppTransitionStartY = startY;
1181 mNextAppTransitionStartWidth = startWidth;
1182 mNextAppTransitionStartHeight = startHeight;
1183 postAnimationCallback();
1184 mNextAppTransitionCallback = null;
1185 }
1186 }
1187
Craig Mautner164d4bb2012-11-26 13:51:23 -08001188 void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
1189 IRemoteCallback startedCallback, boolean scaleUp) {
1190 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001191 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP
1192 : NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001193 mNextAppTransitionPackage = null;
1194 mNextAppTransitionThumbnail = srcThumb;
1195 mNextAppTransitionScaleUp = scaleUp;
1196 mNextAppTransitionStartX = startX;
1197 mNextAppTransitionStartY = startY;
1198 postAnimationCallback();
1199 mNextAppTransitionCallback = startedCallback;
1200 } else {
1201 postAnimationCallback();
1202 }
1203 }
1204
Winson Chunga4ccb862014-08-22 15:26:27 -07001205 void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX, int startY,
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001206 int targetWidth, int targetHeight, IRemoteCallback startedCallback, boolean scaleUp) {
Winson Chunga4ccb862014-08-22 15:26:27 -07001207 if (isTransitionSet()) {
1208 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
1209 : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
1210 mNextAppTransitionPackage = null;
1211 mNextAppTransitionThumbnail = srcThumb;
1212 mNextAppTransitionScaleUp = scaleUp;
1213 mNextAppTransitionStartX = startX;
1214 mNextAppTransitionStartY = startY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001215 mNextAppTransitionStartWidth = targetWidth;
1216 mNextAppTransitionStartHeight = targetHeight;
Winson Chunga4ccb862014-08-22 15:26:27 -07001217 postAnimationCallback();
1218 mNextAppTransitionCallback = startedCallback;
1219 } else {
1220 postAnimationCallback();
1221 }
1222 }
1223
Winson Chung044d5292014-11-06 11:05:19 -08001224 void overrideInPlaceAppTransition(String packageName, int anim) {
1225 if (isTransitionSet()) {
1226 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE;
1227 mNextAppTransitionPackage = packageName;
1228 mNextAppTransitionInPlace = anim;
1229 } else {
1230 postAnimationCallback();
1231 }
1232 }
1233
Craig Mautner164d4bb2012-11-26 13:51:23 -08001234 @Override
1235 public String toString() {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -07001236 return "mNextAppTransition=" + appTransitionToString(mNextAppTransition);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001237 }
1238
Craig Mautner4b71aa12012-12-27 17:20:01 -08001239 /**
1240 * Returns the human readable name of a window transition.
1241 *
1242 * @param transition The window transition.
1243 * @return The transition symbolic name.
1244 */
1245 public static String appTransitionToString(int transition) {
1246 switch (transition) {
1247 case TRANSIT_UNSET: {
1248 return "TRANSIT_UNSET";
1249 }
1250 case TRANSIT_NONE: {
1251 return "TRANSIT_NONE";
1252 }
Craig Mautner4b71aa12012-12-27 17:20:01 -08001253 case TRANSIT_ACTIVITY_OPEN: {
1254 return "TRANSIT_ACTIVITY_OPEN";
1255 }
1256 case TRANSIT_ACTIVITY_CLOSE: {
1257 return "TRANSIT_ACTIVITY_CLOSE";
1258 }
1259 case TRANSIT_TASK_OPEN: {
1260 return "TRANSIT_TASK_OPEN";
1261 }
1262 case TRANSIT_TASK_CLOSE: {
1263 return "TRANSIT_TASK_CLOSE";
1264 }
1265 case TRANSIT_TASK_TO_FRONT: {
1266 return "TRANSIT_TASK_TO_FRONT";
1267 }
1268 case TRANSIT_TASK_TO_BACK: {
1269 return "TRANSIT_TASK_TO_BACK";
1270 }
1271 case TRANSIT_WALLPAPER_CLOSE: {
1272 return "TRANSIT_WALLPAPER_CLOSE";
1273 }
1274 case TRANSIT_WALLPAPER_OPEN: {
1275 return "TRANSIT_WALLPAPER_OPEN";
1276 }
1277 case TRANSIT_WALLPAPER_INTRA_OPEN: {
1278 return "TRANSIT_WALLPAPER_INTRA_OPEN";
1279 }
1280 case TRANSIT_WALLPAPER_INTRA_CLOSE: {
1281 return "TRANSIT_WALLPAPER_INTRA_CLOSE";
1282 }
Craig Mautnerbb742462014-07-07 15:28:55 -07001283 case TRANSIT_TASK_OPEN_BEHIND: {
1284 return "TRANSIT_TASK_OPEN_BEHIND";
1285 }
Craig Mautner4b71aa12012-12-27 17:20:01 -08001286 default: {
1287 return "<UNKNOWN>";
1288 }
1289 }
1290 }
1291
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001292 private String appStateToString() {
1293 switch (mAppTransitionState) {
1294 case APP_STATE_IDLE:
1295 return "APP_STATE_IDLE";
1296 case APP_STATE_READY:
1297 return "APP_STATE_READY";
1298 case APP_STATE_RUNNING:
1299 return "APP_STATE_RUNNING";
1300 case APP_STATE_TIMEOUT:
1301 return "APP_STATE_TIMEOUT";
1302 default:
1303 return "unknown state=" + mAppTransitionState;
1304 }
1305 }
1306
1307 private String transitTypeToString() {
1308 switch (mNextAppTransitionType) {
1309 case NEXT_TRANSIT_TYPE_NONE:
1310 return "NEXT_TRANSIT_TYPE_NONE";
1311 case NEXT_TRANSIT_TYPE_CUSTOM:
1312 return "NEXT_TRANSIT_TYPE_CUSTOM";
Winson Chung044d5292014-11-06 11:05:19 -08001313 case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
1314 return "NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE";
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001315 case NEXT_TRANSIT_TYPE_SCALE_UP:
1316 return "NEXT_TRANSIT_TYPE_SCALE_UP";
1317 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
1318 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP";
1319 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
1320 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN";
Winson Chunga4ccb862014-08-22 15:26:27 -07001321 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
1322 return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP";
1323 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
1324 return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN";
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001325 default:
1326 return "unknown type=" + mNextAppTransitionType;
1327 }
1328 }
1329
Craig Mautner164d4bb2012-11-26 13:51:23 -08001330 @Override
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001331 public void dump(PrintWriter pw, String prefix) {
1332 pw.print(prefix); pw.println(this);
1333 pw.print(prefix); pw.print("mAppTransitionState="); pw.println(appStateToString());
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001334 if (mNextAppTransitionType != NEXT_TRANSIT_TYPE_NONE) {
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001335 pw.print(prefix); pw.print("mNextAppTransitionType=");
1336 pw.println(transitTypeToString());
Craig Mautner164d4bb2012-11-26 13:51:23 -08001337 }
1338 switch (mNextAppTransitionType) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001339 case NEXT_TRANSIT_TYPE_CUSTOM:
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001340 pw.print(prefix); pw.print("mNextAppTransitionPackage=");
Craig Mautner164d4bb2012-11-26 13:51:23 -08001341 pw.println(mNextAppTransitionPackage);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001342 pw.print(prefix); pw.print("mNextAppTransitionEnter=0x");
Craig Mautner164d4bb2012-11-26 13:51:23 -08001343 pw.print(Integer.toHexString(mNextAppTransitionEnter));
1344 pw.print(" mNextAppTransitionExit=0x");
1345 pw.println(Integer.toHexString(mNextAppTransitionExit));
1346 break;
Winson Chung044d5292014-11-06 11:05:19 -08001347 case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001348 pw.print(prefix); pw.print("mNextAppTransitionPackage=");
Winson Chung044d5292014-11-06 11:05:19 -08001349 pw.println(mNextAppTransitionPackage);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001350 pw.print(prefix); pw.print("mNextAppTransitionInPlace=0x");
Winson Chung044d5292014-11-06 11:05:19 -08001351 pw.print(Integer.toHexString(mNextAppTransitionInPlace));
1352 break;
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001353 case NEXT_TRANSIT_TYPE_SCALE_UP:
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001354 pw.print(prefix); pw.print("mNextAppTransitionStartX=");
1355 pw.print(mNextAppTransitionStartX);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001356 pw.print(" mNextAppTransitionStartY=");
1357 pw.println(mNextAppTransitionStartY);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001358 pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
Craig Mautner164d4bb2012-11-26 13:51:23 -08001359 pw.print(mNextAppTransitionStartWidth);
1360 pw.print(" mNextAppTransitionStartHeight=");
1361 pw.println(mNextAppTransitionStartHeight);
1362 break;
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001363 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
1364 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -07001365 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
1366 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001367 pw.print(prefix); pw.print("mNextAppTransitionThumbnail=");
Craig Mautner164d4bb2012-11-26 13:51:23 -08001368 pw.print(mNextAppTransitionThumbnail);
1369 pw.print(" mNextAppTransitionStartX=");
1370 pw.print(mNextAppTransitionStartX);
1371 pw.print(" mNextAppTransitionStartY=");
1372 pw.println(mNextAppTransitionStartY);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001373 pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001374 pw.print(mNextAppTransitionStartWidth);
1375 pw.print(" mNextAppTransitionStartHeight=");
1376 pw.println(mNextAppTransitionStartHeight);
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001377 pw.print(prefix); pw.print("mNextAppTransitionScaleUp=");
1378 pw.println(mNextAppTransitionScaleUp);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001379 break;
1380 }
1381 if (mNextAppTransitionCallback != null) {
Dianne Hackbornae6688b2015-02-11 17:02:41 -08001382 pw.print(prefix); pw.print("mNextAppTransitionCallback=");
1383 pw.println(mNextAppTransitionCallback);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001384 }
1385 }
Amith Yamasani4befbec2013-07-10 16:18:01 -07001386
1387 public void setCurrentUser(int newUserId) {
1388 mCurrentUserId = newUserId;
1389 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08001390}