blob: a569322ba2959782d664c89675f696a6a879ba6c [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
Craig Mautner164d4bb2012-11-26 13:51:23 -080019import android.content.Context;
Chet Haase10e23ab2015-02-11 15:08:38 -080020import android.content.pm.PackageManager;
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;
Chet Haase10e23ab2015-02-11 15:08:38 -080024import android.graphics.drawable.Drawable;
Craig Mautner164d4bb2012-11-26 13:51:23 -080025import android.os.Debug;
26import android.os.Handler;
27import android.os.IRemoteCallback;
Chet Haase10e23ab2015-02-11 15:08:38 -080028import android.os.UserHandle;
29import android.util.Log;
Craig Mautner164d4bb2012-11-26 13:51:23 -080030import android.util.Slog;
31import android.view.WindowManager;
Craig Mautner164d4bb2012-11-26 13:51:23 -080032import android.view.animation.AlphaAnimation;
33import android.view.animation.Animation;
34import android.view.animation.AnimationSet;
35import android.view.animation.AnimationUtils;
Winson Chung399f6202014-03-19 10:47:20 -070036import android.view.animation.ClipRectAnimation;
Chet Haase10e23ab2015-02-11 15:08:38 -080037import android.view.animation.ClipRectLRAnimation;
38import android.view.animation.ClipRectTBAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -080039import android.view.animation.Interpolator;
Chet Haase10e23ab2015-02-11 15:08:38 -080040import android.view.animation.LinearInterpolator;
Craig Mautner164d4bb2012-11-26 13:51:23 -080041import android.view.animation.ScaleAnimation;
Winson Chung399f6202014-03-19 10:47:20 -070042import android.view.animation.TranslateAnimation;
Chet Haase10e23ab2015-02-11 15:08:38 -080043import android.view.animation.TranslateXAnimation;
44import android.view.animation.TranslateYAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -080045import com.android.internal.util.DumpUtils.Dump;
46import com.android.server.AttributeCache;
47import com.android.server.wm.WindowManagerService.H;
48
49import java.io.PrintWriter;
50
Craig Mautner9a29a5d2012-12-27 19:03:40 -080051import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
52import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
53import static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation;
54import static com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
55import static com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation;
56import static com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
Craig Mautner3b2cd1d2014-08-25 14:25:54 -070057import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindTargetAnimation;
Craig Mautnerbb742462014-07-07 15:28:55 -070058import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindSourceAnimation;
Craig Mautner9a29a5d2012-12-27 19:03:40 -080059import static com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation;
60import static com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
61import static com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation;
62import static com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
63import static com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation;
64import static com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
65import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
66import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
67import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation;
68import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
69import 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_wallpaperIntraCloseEnterAnimation;
72import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
73
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;
84
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 */
125 private static final float RECENTS_THUMBNAIL_FADEIN_FRACTION = 0.7f;
Craig Mautner321bdf52012-12-18 09:53:24 -0800126 /** Fraction of animation at which the recents thumbnail becomes completely transparent */
Winson Chunga4ccb862014-08-22 15:26:27 -0700127 private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.3f;
Craig Mautner321bdf52012-12-18 09:53:24 -0800128
Winson Chung5393dff2014-05-08 14:25:43 -0700129 private static final int DEFAULT_APP_TRANSITION_DURATION = 250;
Winson Chungb255e492014-12-03 13:45:36 -0800130 private static final int THUMBNAIL_APP_TRANSITION_DURATION = 325;
Winson Chunga4ccb862014-08-22 15:26:27 -0700131 private static final int THUMBNAIL_APP_TRANSITION_ALPHA_DURATION = 325;
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;
183 private final Interpolator mFastOutSlowInInterpolator;
184 private final LinearInterpolator mLinearInterpolator;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800185
Amith Yamasani4befbec2013-07-10 16:18:01 -0700186 private int mCurrentUserId = 0;
187
Craig Mautner164d4bb2012-11-26 13:51:23 -0800188 AppTransition(Context context, Handler h) {
189 mContext = context;
190 mH = h;
Chet Haase10e23ab2015-02-11 15:08:38 -0800191 mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
192 com.android.internal.R.interpolator.linear_out_slow_in);
193 mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
194 com.android.internal.R.interpolator.fast_out_slow_in);
195 mLinearInterpolator = new LinearInterpolator();
Craig Mautner164d4bb2012-11-26 13:51:23 -0800196 mConfigShortAnimTime = context.getResources().getInteger(
197 com.android.internal.R.integer.config_shortAnimTime);
Craig Mautner321bdf52012-12-18 09:53:24 -0800198 mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
199 com.android.internal.R.interpolator.decelerate_cubic);
Winson Chunga4ccb862014-08-22 15:26:27 -0700200 mThumbnailFadeInInterpolator = new Interpolator() {
201 @Override
202 public float getInterpolation(float input) {
203 // Linear response for first fraction, then complete after that.
204 if (input < RECENTS_THUMBNAIL_FADEIN_FRACTION) {
205 return 0f;
206 }
207 return (input - RECENTS_THUMBNAIL_FADEIN_FRACTION) /
208 (1f - RECENTS_THUMBNAIL_FADEIN_FRACTION);
209 }
210 };
211 mThumbnailFadeOutInterpolator = new Interpolator() {
Craig Mautner321bdf52012-12-18 09:53:24 -0800212 @Override
213 public float getInterpolation(float input) {
214 // Linear response for first fraction, then complete after that.
215 if (input < RECENTS_THUMBNAIL_FADEOUT_FRACTION) {
216 return input / RECENTS_THUMBNAIL_FADEOUT_FRACTION;
217 }
Winson Chunga4ccb862014-08-22 15:26:27 -0700218 return 1f;
Craig Mautner321bdf52012-12-18 09:53:24 -0800219 }
220 };
Craig Mautner164d4bb2012-11-26 13:51:23 -0800221 }
222
223 boolean isTransitionSet() {
224 return mNextAppTransition != TRANSIT_UNSET;
225 }
226
227 boolean isTransitionNone() {
228 return mNextAppTransition == TRANSIT_NONE;
229 }
230
231 boolean isTransitionEqual(int transit) {
232 return mNextAppTransition == transit;
233 }
234
235 int getAppTransition() {
Craig Mautner321bdf52012-12-18 09:53:24 -0800236 return mNextAppTransition;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800237 }
238
239 void setAppTransition(int transit) {
240 mNextAppTransition = transit;
241 }
242
243 boolean isReady() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800244 return mAppTransitionState == APP_STATE_READY
245 || mAppTransitionState == APP_STATE_TIMEOUT;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800246 }
247
Craig Mautnerae446592012-12-06 19:05:05 -0800248 void setReady() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800249 mAppTransitionState = APP_STATE_READY;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800250 }
251
252 boolean isRunning() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800253 return mAppTransitionState == APP_STATE_RUNNING;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800254 }
255
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800256 void setIdle() {
257 mAppTransitionState = APP_STATE_IDLE;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800258 }
259
260 boolean isTimeout() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800261 return mAppTransitionState == APP_STATE_TIMEOUT;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800262 }
263
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800264 void setTimeout() {
265 mAppTransitionState = APP_STATE_TIMEOUT;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800266 }
267
268 Bitmap getNextAppTransitionThumbnail() {
269 return mNextAppTransitionThumbnail;
270 }
271
Winson Chunga4ccb862014-08-22 15:26:27 -0700272 /** Returns whether the next thumbnail transition is aspect scaled up. */
273 boolean isNextThumbnailTransitionAspectScaled() {
274 return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
275 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
276 }
277
278 /** Returns whether the next thumbnail transition is scaling up. */
279 boolean isNextThumbnailTransitionScaleUp() {
280 return mNextAppTransitionScaleUp;
281 }
282
283 int getStartingX() {
284 return mNextAppTransitionStartX;
285 }
286
287 int getStartingY() {
288 return mNextAppTransitionStartY;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800289 }
290
Craig Mautner164d4bb2012-11-26 13:51:23 -0800291 void prepare() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800292 if (!isRunning()) {
293 mAppTransitionState = APP_STATE_IDLE;
294 }
Craig Mautner164d4bb2012-11-26 13:51:23 -0800295 }
296
297 void goodToGo() {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800298 mNextAppTransition = TRANSIT_UNSET;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800299 mAppTransitionState = APP_STATE_RUNNING;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800300 }
301
302 void clear() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800303 mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800304 mNextAppTransitionPackage = null;
305 mNextAppTransitionThumbnail = null;
306 }
307
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800308 void freeze() {
309 setAppTransition(AppTransition.TRANSIT_UNSET);
310 clear();
311 setReady();
312 }
313
Craig Mautner164d4bb2012-11-26 13:51:23 -0800314 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
315 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
316 + (lp != null ? lp.packageName : null)
317 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
318 if (lp != null && lp.windowAnimations != 0) {
319 // If this is a system resource, don't try to load it from the
320 // application resources. It is nice to avoid loading application
321 // resources if we can.
322 String packageName = lp.packageName != null ? lp.packageName : "android";
323 int resId = lp.windowAnimations;
324 if ((resId&0xFF000000) == 0x01000000) {
325 packageName = "android";
326 }
327 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
328 + packageName);
329 return AttributeCache.instance().get(packageName, resId,
Amith Yamasani4befbec2013-07-10 16:18:01 -0700330 com.android.internal.R.styleable.WindowAnimation, mCurrentUserId);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800331 }
332 return null;
333 }
334
335 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
336 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
337 + packageName + " resId=0x" + Integer.toHexString(resId));
338 if (packageName != null) {
339 if ((resId&0xFF000000) == 0x01000000) {
340 packageName = "android";
341 }
342 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
343 + packageName);
344 return AttributeCache.instance().get(packageName, resId,
Amith Yamasani4befbec2013-07-10 16:18:01 -0700345 com.android.internal.R.styleable.WindowAnimation, mCurrentUserId);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800346 }
347 return null;
348 }
349
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700350 Animation loadAnimationAttr(WindowManager.LayoutParams lp, int animAttr) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800351 int anim = 0;
352 Context context = mContext;
353 if (animAttr >= 0) {
354 AttributeCache.Entry ent = getCachedAnimations(lp);
355 if (ent != null) {
356 context = ent.context;
357 anim = ent.array.getResourceId(animAttr, 0);
358 }
359 }
360 if (anim != 0) {
361 return AnimationUtils.loadAnimation(context, anim);
362 }
363 return null;
364 }
365
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700366 Animation loadAnimationRes(WindowManager.LayoutParams lp, int resId) {
367 Context context = mContext;
368 if (resId >= 0) {
369 AttributeCache.Entry ent = getCachedAnimations(lp);
370 if (ent != null) {
371 context = ent.context;
372 }
373 return AnimationUtils.loadAnimation(context, resId);
374 }
375 return null;
376 }
377
378 private Animation loadAnimationRes(String packageName, int resId) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800379 int anim = 0;
380 Context context = mContext;
381 if (resId >= 0) {
382 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
383 if (ent != null) {
384 context = ent.context;
385 anim = resId;
386 }
387 }
388 if (anim != 0) {
389 return AnimationUtils.loadAnimation(context, anim);
390 }
391 return null;
392 }
393
Craig Mautner164d4bb2012-11-26 13:51:23 -0800394 /**
395 * Compute the pivot point for an animation that is scaling from a small
396 * rect on screen to a larger rect. The pivot point varies depending on
397 * the distance between the inner and outer edges on both sides. This
398 * function computes the pivot point for one dimension.
399 * @param startPos Offset from left/top edge of outer rectangle to
400 * left/top edge of inner rectangle.
401 * @param finalScale The scaling factor between the size of the outer
402 * and inner rectangles.
403 */
404 private static float computePivot(int startPos, float finalScale) {
405 final float denom = finalScale-1;
406 if (Math.abs(denom) < .0001f) {
407 return startPos;
408 }
409 return -startPos / denom;
410 }
411
412 private Animation createScaleUpAnimationLocked(int transit, boolean enter,
413 int appWidth, int appHeight) {
414 Animation a = null;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800415 if (enter) {
416 // Entering app zooms out from the center of the initial rect.
417 float scaleW = mNextAppTransitionStartWidth / (float) appWidth;
418 float scaleH = mNextAppTransitionStartHeight / (float) appHeight;
419 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
420 computePivot(mNextAppTransitionStartX, scaleW),
421 computePivot(mNextAppTransitionStartY, scaleH));
Craig Mautner321bdf52012-12-18 09:53:24 -0800422 scale.setInterpolator(mDecelerateInterpolator);
423
Craig Mautner164d4bb2012-11-26 13:51:23 -0800424 Animation alpha = new AlphaAnimation(0, 1);
Winson Chunga4ccb862014-08-22 15:26:27 -0700425 alpha.setInterpolator(mThumbnailFadeOutInterpolator);
Craig Mautner321bdf52012-12-18 09:53:24 -0800426
427 AnimationSet set = new AnimationSet(false);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800428 set.addAnimation(scale);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800429 set.addAnimation(alpha);
430 set.setDetachWallpaper(true);
431 a = set;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800432 } else if (transit == TRANSIT_WALLPAPER_INTRA_OPEN ||
433 transit == TRANSIT_WALLPAPER_INTRA_CLOSE) {
Craig Mautner321bdf52012-12-18 09:53:24 -0800434 // If we are on top of the wallpaper, we need an animation that
435 // correctly handles the wallpaper staying static behind all of
436 // the animated elements. To do this, will just have the existing
437 // element fade out.
438 a = new AlphaAnimation(1, 0);
439 a.setDetachWallpaper(true);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800440 } else {
Craig Mautner321bdf52012-12-18 09:53:24 -0800441 // For normal animations, the exiting element just holds in place.
442 a = new AlphaAnimation(1, 1);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800443 }
Craig Mautner321bdf52012-12-18 09:53:24 -0800444
445 // Pick the desired duration. If this is an inter-activity transition,
446 // it is the standard duration for that. Otherwise we use the longer
447 // task transition duration.
448 final long duration;
449 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800450 case TRANSIT_ACTIVITY_OPEN:
451 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner321bdf52012-12-18 09:53:24 -0800452 duration = mConfigShortAnimTime;
453 break;
454 default:
455 duration = DEFAULT_APP_TRANSITION_DURATION;
456 break;
457 }
458 a.setDuration(duration);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800459 a.setFillAfter(true);
Craig Mautner321bdf52012-12-18 09:53:24 -0800460 a.setInterpolator(mDecelerateInterpolator);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800461 a.initialize(appWidth, appHeight, appWidth, appHeight);
462 return a;
463 }
464
Chet Haase10e23ab2015-02-11 15:08:38 -0800465 private Animation createClipRevealAnimationLocked(int transit, boolean enter,
466 int appWidth, int appHeight) {
467 final Animation anim;
468 if (enter) {
469 // Reveal will expand and move faster in horizontal direction
470
471 // Start from size of launch icon, expand to full width/height
472 Animation clipAnimLR = new ClipRectLRAnimation(
473 (appWidth - mNextAppTransitionStartWidth) / 2,
474 (appWidth + mNextAppTransitionStartWidth) / 2, 0, appWidth);
475 clipAnimLR.setInterpolator(mLinearOutSlowInInterpolator);
476 clipAnimLR.setDuration(DEFAULT_APP_TRANSITION_DURATION);
477 Animation clipAnimTB = new ClipRectTBAnimation(
478 (appHeight - mNextAppTransitionStartHeight) / 2,
479 (appHeight + mNextAppTransitionStartHeight) / 2, 0, appHeight);
480 clipAnimTB.setInterpolator(mFastOutSlowInInterpolator);
481 clipAnimTB.setDuration(DEFAULT_APP_TRANSITION_DURATION);
482
483 // Start from middle of launch icon area, move to 0, 0
484 int startMiddleX = mNextAppTransitionStartX +
485 (mNextAppTransitionStartWidth - appWidth) / 2;
486 int startMiddleY = mNextAppTransitionStartY +
487 (mNextAppTransitionStartHeight - appHeight) / 2;
488
489 TranslateXAnimation translateX = new TranslateXAnimation(
490 Animation.ABSOLUTE, startMiddleX, Animation.ABSOLUTE, 0);
491 translateX.setInterpolator(mLinearOutSlowInInterpolator);
492 translateX.setDuration(DEFAULT_APP_TRANSITION_DURATION);
493 TranslateYAnimation translateY = new TranslateYAnimation(
494 Animation.ABSOLUTE, startMiddleY, Animation.ABSOLUTE, 0);
495 translateY.setInterpolator(mFastOutSlowInInterpolator);
496 translateY.setDuration(DEFAULT_APP_TRANSITION_DURATION);
497
498 // Quick fade-in from icon to app window
499 final int alphaDuration = 100;
500 AlphaAnimation alpha = new AlphaAnimation(0.1f, 1);
501 alpha.setDuration(alphaDuration);
502 alpha.setInterpolator(mLinearInterpolator);
503
504 AnimationSet set = new AnimationSet(false);
505 set.addAnimation(clipAnimLR);
506 set.addAnimation(clipAnimTB);
507 set.addAnimation(translateX);
508 set.addAnimation(translateY);
509 set.addAnimation(alpha);
510 set.initialize(appWidth, appHeight, appWidth, appHeight);
511 anim = set;
512 } else {
513 final long duration;
514 switch (transit) {
515 case TRANSIT_ACTIVITY_OPEN:
516 case TRANSIT_ACTIVITY_CLOSE:
517 duration = mConfigShortAnimTime;
518 break;
519 default:
520 duration = DEFAULT_APP_TRANSITION_DURATION;
521 break;
522 }
523 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN ||
524 transit == TRANSIT_WALLPAPER_INTRA_CLOSE) {
525 // If we are on top of the wallpaper, we need an animation that
526 // correctly handles the wallpaper staying static behind all of
527 // the animated elements. To do this, will just have the existing
528 // element fade out.
529 anim = new AlphaAnimation(1, 0);
530 anim.setDetachWallpaper(true);
531 } else {
532 // For normal animations, the exiting element just holds in place.
533 anim = new AlphaAnimation(1, 1);
534 }
535 anim.setInterpolator(mDecelerateInterpolator);
536 anim.setDuration(duration);
537 anim.setFillAfter(true);
538 }
539 return anim;
540 }
541
Winson Chung399f6202014-03-19 10:47:20 -0700542 /**
543 * Prepares the specified animation with a standard duration, interpolator, etc.
544 */
Winson Chung5393dff2014-05-08 14:25:43 -0700545 Animation prepareThumbnailAnimationWithDuration(Animation a, int appWidth, int appHeight,
546 int duration, Interpolator interpolator) {
Winson Chunga4ccb862014-08-22 15:26:27 -0700547 if (duration > 0) {
548 a.setDuration(duration);
549 }
Winson Chung5393dff2014-05-08 14:25:43 -0700550 a.setFillAfter(true);
551 a.setInterpolator(interpolator);
552 a.initialize(appWidth, appHeight, appWidth, appHeight);
553 return a;
554 }
555
556 /**
557 * Prepares the specified animation with a standard duration, interpolator, etc.
558 */
Winson Chung399f6202014-03-19 10:47:20 -0700559 Animation prepareThumbnailAnimation(Animation a, int appWidth, int appHeight, int transit) {
Craig Mautner321bdf52012-12-18 09:53:24 -0800560 // Pick the desired duration. If this is an inter-activity transition,
561 // it is the standard duration for that. Otherwise we use the longer
562 // task transition duration.
Winson Chung5393dff2014-05-08 14:25:43 -0700563 final int duration;
Craig Mautner321bdf52012-12-18 09:53:24 -0800564 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800565 case TRANSIT_ACTIVITY_OPEN:
566 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner321bdf52012-12-18 09:53:24 -0800567 duration = mConfigShortAnimTime;
568 break;
569 default:
570 duration = DEFAULT_APP_TRANSITION_DURATION;
571 break;
572 }
Winson Chung5393dff2014-05-08 14:25:43 -0700573 return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
574 mDecelerateInterpolator);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800575 }
576
Winson Chung399f6202014-03-19 10:47:20 -0700577 /**
578 * Return the current thumbnail transition state.
579 */
580 int getThumbnailTransitionState(boolean enter) {
581 if (enter) {
582 if (mNextAppTransitionScaleUp) {
583 return THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
584 } else {
585 return THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN;
586 }
587 } else {
588 if (mNextAppTransitionScaleUp) {
589 return THUMBNAIL_TRANSITION_EXIT_SCALE_UP;
590 } else {
591 return THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN;
592 }
593 }
594 }
595
596 /**
597 * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
598 * when a thumbnail is specified with the activity options.
599 */
Winson Chunga4ccb862014-08-22 15:26:27 -0700600 Animation createThumbnailAspectScaleAnimationLocked(int appWidth, int appHeight,
601 int deviceWidth, int transit) {
Winson Chung399f6202014-03-19 10:47:20 -0700602 Animation a;
603 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
604 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
605 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
606 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
607
Winson Chunga4ccb862014-08-22 15:26:27 -0700608 float scaleW = deviceWidth / thumbWidth;
609 float unscaledWidth = deviceWidth;
610 float unscaledHeight = thumbHeight * scaleW;
611 float unscaledStartY = mNextAppTransitionStartY - (unscaledHeight - thumbHeight) / 2f;
Winson Chung399f6202014-03-19 10:47:20 -0700612 if (mNextAppTransitionScaleUp) {
Winson Chunga4ccb862014-08-22 15:26:27 -0700613 // Animation up from the thumbnail to the full screen
614 Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW,
615 mNextAppTransitionStartX + (thumbWidth / 2f),
616 mNextAppTransitionStartY + (thumbHeight / 2f));
Chet Haase10e23ab2015-02-11 15:08:38 -0800617 scale.setInterpolator(mFastOutSlowInInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700618 scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Winson Chung399f6202014-03-19 10:47:20 -0700619 Animation alpha = new AlphaAnimation(1, 0);
Winson Chunga4ccb862014-08-22 15:26:27 -0700620 alpha.setInterpolator(mThumbnailFadeOutInterpolator);
621 alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
622 Animation translate = new TranslateAnimation(0, 0, 0, -unscaledStartY +
623 mNextAppTransitionInsets.top);
Chet Haase10e23ab2015-02-11 15:08:38 -0800624 translate.setInterpolator(mFastOutSlowInInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700625 translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Winson Chung399f6202014-03-19 10:47:20 -0700626
627 // This AnimationSet uses the Interpolators assigned above.
628 AnimationSet set = new AnimationSet(false);
629 set.addAnimation(scale);
630 set.addAnimation(alpha);
Winson Chunga4ccb862014-08-22 15:26:27 -0700631 set.addAnimation(translate);
Winson Chung399f6202014-03-19 10:47:20 -0700632 a = set;
633 } else {
Winson Chunga4ccb862014-08-22 15:26:27 -0700634 // Animation down from the full screen to the thumbnail
635 Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f,
636 mNextAppTransitionStartX + (thumbWidth / 2f),
637 mNextAppTransitionStartY + (thumbHeight / 2f));
Chet Haase10e23ab2015-02-11 15:08:38 -0800638 scale.setInterpolator(mFastOutSlowInInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700639 scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
640 Animation alpha = new AlphaAnimation(0f, 1f);
641 alpha.setInterpolator(mThumbnailFadeInInterpolator);
642 alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
643 Animation translate = new TranslateAnimation(0, 0, -unscaledStartY +
644 mNextAppTransitionInsets.top, 0);
Chet Haase10e23ab2015-02-11 15:08:38 -0800645 translate.setInterpolator(mFastOutSlowInInterpolator);
Winson Chunga4ccb862014-08-22 15:26:27 -0700646 translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Winson Chung399f6202014-03-19 10:47:20 -0700647
Winson Chunga4ccb862014-08-22 15:26:27 -0700648 // This AnimationSet uses the Interpolators assigned above.
649 AnimationSet set = new AnimationSet(false);
650 set.addAnimation(scale);
651 set.addAnimation(alpha);
652 set.addAnimation(translate);
653 a = set;
654
655 }
656 return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, 0,
Chet Haase10e23ab2015-02-11 15:08:38 -0800657 mFastOutSlowInInterpolator);
Winson Chung399f6202014-03-19 10:47:20 -0700658 }
659
660 /**
661 * This alternate animation is created when we are doing a thumbnail transition, for the
662 * activity that is leaving, and the activity that is entering.
663 */
Winson Chunga4ccb862014-08-22 15:26:27 -0700664 Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState,
665 int appWidth, int appHeight, int orientation, int transit, Rect containingFrame,
666 Rect contentInsets, boolean isFullScreen) {
Winson Chung399f6202014-03-19 10:47:20 -0700667 Animation a;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200668 final int thumbWidthI = mNextAppTransitionStartWidth;
Winson Chung399f6202014-03-19 10:47:20 -0700669 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
Winson Chung2e7f3bd2014-09-05 13:17:22 +0200670 final int thumbHeightI = mNextAppTransitionStartHeight;
Winson Chung399f6202014-03-19 10:47:20 -0700671 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
672
Winson Chung2820c452014-04-15 15:34:44 -0700673 // Used for the ENTER_SCALE_UP and EXIT_SCALE_DOWN transitions
674 float scale = 1f;
675 int scaledTopDecor = 0;
676
Winson Chung399f6202014-03-19 10:47:20 -0700677 switch (thumbTransitState) {
678 case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
Winson Chunga4ccb862014-08-22 15:26:27 -0700679 // App window scaling up to become full screen
Winson Chung2820c452014-04-15 15:34:44 -0700680 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
681 // In portrait, we scale the width and clip to the top/left square
682 scale = thumbWidth / appWidth;
683 scaledTopDecor = (int) (scale * contentInsets.top);
684 int unscaledThumbHeight = (int) (thumbHeight / scale);
685 mTmpFromClipRect.set(containingFrame);
Winson Chungae084412014-05-20 14:17:22 -0700686 if (isFullScreen) {
687 mTmpFromClipRect.top = contentInsets.top;
688 }
Winson Chung2820c452014-04-15 15:34:44 -0700689 mTmpFromClipRect.bottom = (mTmpFromClipRect.top + unscaledThumbHeight);
690 mTmpToClipRect.set(containingFrame);
691 } else {
692 // In landscape, we scale the height and clip to the top/left square
693 scale = thumbHeight / (appHeight - contentInsets.top);
694 scaledTopDecor = (int) (scale * contentInsets.top);
695 int unscaledThumbWidth = (int) (thumbWidth / scale);
Winson Chungae084412014-05-20 14:17:22 -0700696 int unscaledThumbHeight = (int) (thumbHeight / scale);
Winson Chung2820c452014-04-15 15:34:44 -0700697 mTmpFromClipRect.set(containingFrame);
Winson Chungae084412014-05-20 14:17:22 -0700698 if (isFullScreen) {
699 mTmpFromClipRect.top = contentInsets.top;
700 mTmpFromClipRect.bottom = (mTmpFromClipRect.top + unscaledThumbHeight);
701 }
Winson Chung2820c452014-04-15 15:34:44 -0700702 mTmpFromClipRect.right = (mTmpFromClipRect.left + unscaledThumbWidth);
703 mTmpToClipRect.set(containingFrame);
704 }
Winson Chunga4ccb862014-08-22 15:26:27 -0700705 mNextAppTransitionInsets.set(contentInsets);
Winson Chung399f6202014-03-19 10:47:20 -0700706
707 Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1,
708 computePivot(mNextAppTransitionStartX, scale),
709 computePivot(mNextAppTransitionStartY, scale));
Winson Chung2820c452014-04-15 15:34:44 -0700710 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
Winson Chung399f6202014-03-19 10:47:20 -0700711 Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0);
712
713 AnimationSet set = new AnimationSet(true);
Winson Chung399f6202014-03-19 10:47:20 -0700714 set.addAnimation(clipAnim);
715 set.addAnimation(scaleAnim);
716 set.addAnimation(translateAnim);
717 a = set;
718 break;
719 }
720 case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
Winson Chunga4ccb862014-08-22 15:26:27 -0700721 // Previous app window during the scale up
Winson Chung399f6202014-03-19 10:47:20 -0700722 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
Winson Chunga4ccb862014-08-22 15:26:27 -0700723 // Fade out the source activity if we are animating to a wallpaper
Winson Chung399f6202014-03-19 10:47:20 -0700724 // activity.
725 a = new AlphaAnimation(1, 0);
726 } else {
Winson Chung399f6202014-03-19 10:47:20 -0700727 a = new AlphaAnimation(1, 1);
728 }
729 break;
730 }
731 case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
Winson Chunga4ccb862014-08-22 15:26:27 -0700732 // Target app window during the scale down
733 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
734 // Fade in the destination activity if we are animating from a wallpaper
735 // activity.
736 a = new AlphaAnimation(0, 1);
737 } else {
738 a = new AlphaAnimation(1, 1);
739 }
Winson Chung399f6202014-03-19 10:47:20 -0700740 break;
741 }
742 case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
Winson Chunga4ccb862014-08-22 15:26:27 -0700743 // App window scaling down from full screen
Winson Chung2820c452014-04-15 15:34:44 -0700744 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
745 // In portrait, we scale the width and clip to the top/left square
746 scale = thumbWidth / appWidth;
747 scaledTopDecor = (int) (scale * contentInsets.top);
748 int unscaledThumbHeight = (int) (thumbHeight / scale);
749 mTmpFromClipRect.set(containingFrame);
750 mTmpToClipRect.set(containingFrame);
Winson Chungae084412014-05-20 14:17:22 -0700751 if (isFullScreen) {
752 mTmpToClipRect.top = contentInsets.top;
753 }
Winson Chung2820c452014-04-15 15:34:44 -0700754 mTmpToClipRect.bottom = (mTmpToClipRect.top + unscaledThumbHeight);
755 } else {
756 // In landscape, we scale the height and clip to the top/left square
757 scale = thumbHeight / (appHeight - contentInsets.top);
758 scaledTopDecor = (int) (scale * contentInsets.top);
759 int unscaledThumbWidth = (int) (thumbWidth / scale);
Winson Chungae084412014-05-20 14:17:22 -0700760 int unscaledThumbHeight = (int) (thumbHeight / scale);
Winson Chung2820c452014-04-15 15:34:44 -0700761 mTmpFromClipRect.set(containingFrame);
762 mTmpToClipRect.set(containingFrame);
Winson Chungae084412014-05-20 14:17:22 -0700763 if (isFullScreen) {
764 mTmpToClipRect.top = contentInsets.top;
765 mTmpToClipRect.bottom = (mTmpToClipRect.top + unscaledThumbHeight);
766 }
Winson Chung2820c452014-04-15 15:34:44 -0700767 mTmpToClipRect.right = (mTmpToClipRect.left + unscaledThumbWidth);
768 }
Winson Chunga4ccb862014-08-22 15:26:27 -0700769 mNextAppTransitionInsets.set(contentInsets);
Winson Chung399f6202014-03-19 10:47:20 -0700770
771 Animation scaleAnim = new ScaleAnimation(1, scale, 1, scale,
772 computePivot(mNextAppTransitionStartX, scale),
773 computePivot(mNextAppTransitionStartY, scale));
Winson Chung2820c452014-04-15 15:34:44 -0700774 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
Winson Chung399f6202014-03-19 10:47:20 -0700775 Animation translateAnim = new TranslateAnimation(0, 0, 0, -scaledTopDecor);
776
777 AnimationSet set = new AnimationSet(true);
Winson Chung399f6202014-03-19 10:47:20 -0700778 set.addAnimation(clipAnim);
779 set.addAnimation(scaleAnim);
780 set.addAnimation(translateAnim);
781
782 a = set;
783 a.setZAdjustment(Animation.ZORDER_TOP);
784 break;
785 }
786 default:
787 throw new RuntimeException("Invalid thumbnail transition state");
788 }
789
Winson Chungab79fce2014-11-04 16:15:22 -0800790 int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
791 THUMBNAIL_APP_TRANSITION_DURATION);
792 return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
Chet Haase10e23ab2015-02-11 15:08:38 -0800793 mFastOutSlowInInterpolator);
Winson Chung399f6202014-03-19 10:47:20 -0700794 }
795
796 /**
Winson Chunga4ccb862014-08-22 15:26:27 -0700797 * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
798 * when a thumbnail is specified with the activity options.
799 */
800 Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit) {
801 Animation a;
802 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
803 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
804 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
805 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
806
807 if (mNextAppTransitionScaleUp) {
808 // Animation for the thumbnail zooming from its initial size to the full screen
809 float scaleW = appWidth / thumbWidth;
810 float scaleH = appHeight / thumbHeight;
811 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
812 computePivot(mNextAppTransitionStartX, 1 / scaleW),
813 computePivot(mNextAppTransitionStartY, 1 / scaleH));
814 scale.setInterpolator(mDecelerateInterpolator);
815
816 Animation alpha = new AlphaAnimation(1, 0);
817 alpha.setInterpolator(mThumbnailFadeOutInterpolator);
818
819 // This AnimationSet uses the Interpolators assigned above.
820 AnimationSet set = new AnimationSet(false);
821 set.addAnimation(scale);
822 set.addAnimation(alpha);
823 a = set;
824 } else {
825 // Animation for the thumbnail zooming down from the full screen to its final size
826 float scaleW = appWidth / thumbWidth;
827 float scaleH = appHeight / thumbHeight;
828 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
829 computePivot(mNextAppTransitionStartX, 1 / scaleW),
830 computePivot(mNextAppTransitionStartY, 1 / scaleH));
831 }
832
833 return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
834 }
835
836 /**
Winson Chung399f6202014-03-19 10:47:20 -0700837 * This animation is created when we are doing a thumbnail transition, for the activity that is
838 * leaving, and the activity that is entering.
839 */
840 Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
841 int appHeight, int transit) {
842 Animation a;
843 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
844 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
845 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
846 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
847
848 switch (thumbTransitState) {
849 case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
850 // Entering app scales up with the thumbnail
851 float scaleW = thumbWidth / appWidth;
852 float scaleH = thumbHeight / appHeight;
853 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
854 computePivot(mNextAppTransitionStartX, scaleW),
855 computePivot(mNextAppTransitionStartY, scaleH));
856 break;
857 }
858 case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
859 // Exiting app while the thumbnail is scaling up should fade or stay in place
860 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
861 // Fade out while bringing up selected activity. This keeps the
862 // current activity from showing through a launching wallpaper
863 // activity.
864 a = new AlphaAnimation(1, 0);
865 } else {
866 // noop animation
867 a = new AlphaAnimation(1, 1);
868 }
869 break;
870 }
871 case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
872 // Entering the other app, it should just be visible while we scale the thumbnail
873 // down above it
874 a = new AlphaAnimation(1, 1);
875 break;
876 }
877 case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
878 // Exiting the current app, the app should scale down with the thumbnail
879 float scaleW = thumbWidth / appWidth;
880 float scaleH = thumbHeight / appHeight;
881 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
882 computePivot(mNextAppTransitionStartX, scaleW),
883 computePivot(mNextAppTransitionStartY, scaleH));
884
885 Animation alpha = new AlphaAnimation(1, 0);
886
887 AnimationSet set = new AnimationSet(true);
888 set.addAnimation(scale);
889 set.addAnimation(alpha);
890 set.setZAdjustment(Animation.ZORDER_TOP);
891 a = set;
892 break;
893 }
894 default:
895 throw new RuntimeException("Invalid thumbnail transition state");
896 }
897
898 return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
899 }
900
Craig Mautner164d4bb2012-11-26 13:51:23 -0800901
902 Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700903 int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets,
904 boolean isFullScreen, boolean isVoiceInteraction) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800905 Animation a;
Dianne Hackborne30e02f2014-05-27 18:24:45 -0700906 if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
907 || transit == TRANSIT_TASK_OPEN
908 || transit == TRANSIT_TASK_TO_FRONT)) {
909 a = loadAnimationRes(lp, enter
910 ? com.android.internal.R.anim.voice_activity_open_enter
911 : com.android.internal.R.anim.voice_activity_open_exit);
912 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
913 "applyAnimation voice:"
914 + " anim=" + a + " transit=" + transit + " isEntrance=" + enter
915 + " Callers=" + Debug.getCallers(3));
916 } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE
917 || transit == TRANSIT_TASK_CLOSE
918 || transit == TRANSIT_TASK_TO_BACK)) {
919 a = loadAnimationRes(lp, enter
920 ? com.android.internal.R.anim.voice_activity_close_enter
921 : com.android.internal.R.anim.voice_activity_close_exit);
922 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
923 "applyAnimation voice:"
924 + " anim=" + a + " transit=" + transit + " isEntrance=" + enter
925 + " Callers=" + Debug.getCallers(3));
926 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
927 a = loadAnimationRes(mNextAppTransitionPackage, enter ?
Craig Mautner164d4bb2012-11-26 13:51:23 -0800928 mNextAppTransitionEnter : mNextAppTransitionExit);
929 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
930 "applyAnimation:"
931 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
932 + " transit=" + transit + " isEntrance=" + enter
933 + " Callers=" + Debug.getCallers(3));
Winson Chung044d5292014-11-06 11:05:19 -0800934 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
935 a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
936 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
937 "applyAnimation:"
938 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
939 + " transit=" + transit + " Callers=" + Debug.getCallers(3));
Chet Haase10e23ab2015-02-11 15:08:38 -0800940 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
941 a = createClipRevealAnimationLocked(transit, enter, appWidth, appHeight);
942 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
943 "applyAnimation:"
944 + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL"
945 + " Callers=" + Debug.getCallers(3));
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800946 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800947 a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight);
948 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
949 "applyAnimation:"
950 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
951 + " transit=" + transit + " isEntrance=" + enter
952 + " Callers=" + Debug.getCallers(3));
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800953 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
954 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800955 mNextAppTransitionScaleUp =
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800956 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
Winson Chunga4ccb862014-08-22 15:26:27 -0700957 a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
958 appWidth, appHeight, transit);
959 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
960 String animName = mNextAppTransitionScaleUp ?
961 "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
962 Slog.v(TAG, "applyAnimation:"
963 + " anim=" + a + " nextAppTransition=" + animName
964 + " transit=" + transit + " isEntrance=" + enter
965 + " Callers=" + Debug.getCallers(3));
966 }
967 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
968 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN) {
969 mNextAppTransitionScaleUp =
970 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP);
971 a = createAspectScaledThumbnailEnterExitAnimationLocked(
Winson Chungfd086222014-05-13 15:49:42 -0700972 getThumbnailTransitionState(enter), appWidth, appHeight, orientation,
Winson Chungae084412014-05-20 14:17:22 -0700973 transit, containingFrame, contentInsets, isFullScreen);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800974 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
975 String animName = mNextAppTransitionScaleUp ?
Winson Chunga4ccb862014-08-22 15:26:27 -0700976 "ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN";
Craig Mautner164d4bb2012-11-26 13:51:23 -0800977 Slog.v(TAG, "applyAnimation:"
978 + " anim=" + a + " nextAppTransition=" + animName
979 + " transit=" + transit + " isEntrance=" + enter
980 + " Callers=" + Debug.getCallers(3));
981 }
982 } else {
983 int animAttr = 0;
984 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800985 case TRANSIT_ACTIVITY_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800986 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800987 ? WindowAnimation_activityOpenEnterAnimation
988 : WindowAnimation_activityOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800989 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800990 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800991 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800992 ? WindowAnimation_activityCloseEnterAnimation
993 : WindowAnimation_activityCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800994 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800995 case TRANSIT_TASK_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800996 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800997 ? WindowAnimation_taskOpenEnterAnimation
998 : WindowAnimation_taskOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800999 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001000 case TRANSIT_TASK_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001001 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001002 ? WindowAnimation_taskCloseEnterAnimation
1003 : WindowAnimation_taskCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001004 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001005 case TRANSIT_TASK_TO_FRONT:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001006 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001007 ? WindowAnimation_taskToFrontEnterAnimation
1008 : WindowAnimation_taskToFrontExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001009 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001010 case TRANSIT_TASK_TO_BACK:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001011 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001012 ? WindowAnimation_taskToBackEnterAnimation
1013 : WindowAnimation_taskToBackExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001014 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001015 case TRANSIT_WALLPAPER_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001016 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001017 ? WindowAnimation_wallpaperOpenEnterAnimation
1018 : WindowAnimation_wallpaperOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001019 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001020 case TRANSIT_WALLPAPER_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001021 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001022 ? WindowAnimation_wallpaperCloseEnterAnimation
1023 : WindowAnimation_wallpaperCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001024 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001025 case TRANSIT_WALLPAPER_INTRA_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001026 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001027 ? WindowAnimation_wallpaperIntraOpenEnterAnimation
1028 : WindowAnimation_wallpaperIntraOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001029 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -08001030 case TRANSIT_WALLPAPER_INTRA_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001031 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001032 ? WindowAnimation_wallpaperIntraCloseEnterAnimation
1033 : WindowAnimation_wallpaperIntraCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001034 break;
Craig Mautnerbb742462014-07-07 15:28:55 -07001035 case TRANSIT_TASK_OPEN_BEHIND:
1036 animAttr = enter
1037 ? WindowAnimation_launchTaskBehindSourceAnimation
Craig Mautner3b2cd1d2014-08-25 14:25:54 -07001038 : WindowAnimation_launchTaskBehindTargetAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001039 }
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001040 a = animAttr != 0 ? loadAnimationAttr(lp, animAttr) : null;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001041 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
1042 "applyAnimation:"
1043 + " anim=" + a
1044 + " animAttr=0x" + Integer.toHexString(animAttr)
1045 + " transit=" + transit + " isEntrance=" + enter
1046 + " Callers=" + Debug.getCallers(3));
1047 }
1048 return a;
1049 }
1050
1051 void postAnimationCallback() {
1052 if (mNextAppTransitionCallback != null) {
1053 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, mNextAppTransitionCallback));
1054 mNextAppTransitionCallback = null;
1055 }
1056 }
1057
1058 void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
1059 IRemoteCallback startedCallback) {
1060 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001061 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001062 mNextAppTransitionPackage = packageName;
1063 mNextAppTransitionThumbnail = null;
1064 mNextAppTransitionEnter = enterAnim;
1065 mNextAppTransitionExit = exitAnim;
1066 postAnimationCallback();
1067 mNextAppTransitionCallback = startedCallback;
1068 } else {
1069 postAnimationCallback();
1070 }
1071 }
1072
1073 void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
1074 int startHeight) {
1075 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001076 mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001077 mNextAppTransitionPackage = null;
1078 mNextAppTransitionThumbnail = null;
1079 mNextAppTransitionStartX = startX;
1080 mNextAppTransitionStartY = startY;
1081 mNextAppTransitionStartWidth = startWidth;
1082 mNextAppTransitionStartHeight = startHeight;
1083 postAnimationCallback();
1084 mNextAppTransitionCallback = null;
1085 }
1086 }
1087
Chet Haase10e23ab2015-02-11 15:08:38 -08001088 void overridePendingAppTransitionClipReveal(int startX, int startY,
1089 int startWidth, int startHeight) {
1090 if (isTransitionSet()) {
1091 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL;
1092 mNextAppTransitionStartX = startX;
1093 mNextAppTransitionStartY = startY;
1094 mNextAppTransitionStartWidth = startWidth;
1095 mNextAppTransitionStartHeight = startHeight;
1096 postAnimationCallback();
1097 mNextAppTransitionCallback = null;
1098 }
1099 }
1100
Craig Mautner164d4bb2012-11-26 13:51:23 -08001101 void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
1102 IRemoteCallback startedCallback, boolean scaleUp) {
1103 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001104 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP
1105 : NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN;
Craig Mautner164d4bb2012-11-26 13:51:23 -08001106 mNextAppTransitionPackage = null;
1107 mNextAppTransitionThumbnail = srcThumb;
1108 mNextAppTransitionScaleUp = scaleUp;
1109 mNextAppTransitionStartX = startX;
1110 mNextAppTransitionStartY = startY;
1111 postAnimationCallback();
1112 mNextAppTransitionCallback = startedCallback;
1113 } else {
1114 postAnimationCallback();
1115 }
1116 }
1117
Winson Chunga4ccb862014-08-22 15:26:27 -07001118 void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX, int startY,
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001119 int targetWidth, int targetHeight, IRemoteCallback startedCallback, boolean scaleUp) {
Winson Chunga4ccb862014-08-22 15:26:27 -07001120 if (isTransitionSet()) {
1121 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
1122 : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
1123 mNextAppTransitionPackage = null;
1124 mNextAppTransitionThumbnail = srcThumb;
1125 mNextAppTransitionScaleUp = scaleUp;
1126 mNextAppTransitionStartX = startX;
1127 mNextAppTransitionStartY = startY;
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001128 mNextAppTransitionStartWidth = targetWidth;
1129 mNextAppTransitionStartHeight = targetHeight;
Winson Chunga4ccb862014-08-22 15:26:27 -07001130 postAnimationCallback();
1131 mNextAppTransitionCallback = startedCallback;
1132 } else {
1133 postAnimationCallback();
1134 }
1135 }
1136
Winson Chung044d5292014-11-06 11:05:19 -08001137 void overrideInPlaceAppTransition(String packageName, int anim) {
1138 if (isTransitionSet()) {
1139 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE;
1140 mNextAppTransitionPackage = packageName;
1141 mNextAppTransitionInPlace = anim;
1142 } else {
1143 postAnimationCallback();
1144 }
1145 }
1146
Craig Mautner164d4bb2012-11-26 13:51:23 -08001147 @Override
1148 public String toString() {
1149 return "mNextAppTransition=0x" + Integer.toHexString(mNextAppTransition);
1150 }
1151
Craig Mautner4b71aa12012-12-27 17:20:01 -08001152 /**
1153 * Returns the human readable name of a window transition.
1154 *
1155 * @param transition The window transition.
1156 * @return The transition symbolic name.
1157 */
1158 public static String appTransitionToString(int transition) {
1159 switch (transition) {
1160 case TRANSIT_UNSET: {
1161 return "TRANSIT_UNSET";
1162 }
1163 case TRANSIT_NONE: {
1164 return "TRANSIT_NONE";
1165 }
Craig Mautner4b71aa12012-12-27 17:20:01 -08001166 case TRANSIT_ACTIVITY_OPEN: {
1167 return "TRANSIT_ACTIVITY_OPEN";
1168 }
1169 case TRANSIT_ACTIVITY_CLOSE: {
1170 return "TRANSIT_ACTIVITY_CLOSE";
1171 }
1172 case TRANSIT_TASK_OPEN: {
1173 return "TRANSIT_TASK_OPEN";
1174 }
1175 case TRANSIT_TASK_CLOSE: {
1176 return "TRANSIT_TASK_CLOSE";
1177 }
1178 case TRANSIT_TASK_TO_FRONT: {
1179 return "TRANSIT_TASK_TO_FRONT";
1180 }
1181 case TRANSIT_TASK_TO_BACK: {
1182 return "TRANSIT_TASK_TO_BACK";
1183 }
1184 case TRANSIT_WALLPAPER_CLOSE: {
1185 return "TRANSIT_WALLPAPER_CLOSE";
1186 }
1187 case TRANSIT_WALLPAPER_OPEN: {
1188 return "TRANSIT_WALLPAPER_OPEN";
1189 }
1190 case TRANSIT_WALLPAPER_INTRA_OPEN: {
1191 return "TRANSIT_WALLPAPER_INTRA_OPEN";
1192 }
1193 case TRANSIT_WALLPAPER_INTRA_CLOSE: {
1194 return "TRANSIT_WALLPAPER_INTRA_CLOSE";
1195 }
Craig Mautnerbb742462014-07-07 15:28:55 -07001196 case TRANSIT_TASK_OPEN_BEHIND: {
1197 return "TRANSIT_TASK_OPEN_BEHIND";
1198 }
Craig Mautner4b71aa12012-12-27 17:20:01 -08001199 default: {
1200 return "<UNKNOWN>";
1201 }
1202 }
1203 }
1204
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001205 private String appStateToString() {
1206 switch (mAppTransitionState) {
1207 case APP_STATE_IDLE:
1208 return "APP_STATE_IDLE";
1209 case APP_STATE_READY:
1210 return "APP_STATE_READY";
1211 case APP_STATE_RUNNING:
1212 return "APP_STATE_RUNNING";
1213 case APP_STATE_TIMEOUT:
1214 return "APP_STATE_TIMEOUT";
1215 default:
1216 return "unknown state=" + mAppTransitionState;
1217 }
1218 }
1219
1220 private String transitTypeToString() {
1221 switch (mNextAppTransitionType) {
1222 case NEXT_TRANSIT_TYPE_NONE:
1223 return "NEXT_TRANSIT_TYPE_NONE";
1224 case NEXT_TRANSIT_TYPE_CUSTOM:
1225 return "NEXT_TRANSIT_TYPE_CUSTOM";
Winson Chung044d5292014-11-06 11:05:19 -08001226 case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
1227 return "NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE";
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001228 case NEXT_TRANSIT_TYPE_SCALE_UP:
1229 return "NEXT_TRANSIT_TYPE_SCALE_UP";
1230 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
1231 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP";
1232 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
1233 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN";
Winson Chunga4ccb862014-08-22 15:26:27 -07001234 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
1235 return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP";
1236 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
1237 return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN";
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001238 default:
1239 return "unknown type=" + mNextAppTransitionType;
1240 }
1241 }
1242
Craig Mautner164d4bb2012-11-26 13:51:23 -08001243 @Override
1244 public void dump(PrintWriter pw) {
1245 pw.print(" " + this);
Craig Mautner28816302013-10-10 20:31:00 -07001246 pw.print(" mAppTransitionState="); pw.println(appStateToString());
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001247 if (mNextAppTransitionType != NEXT_TRANSIT_TYPE_NONE) {
1248 pw.print(" mNextAppTransitionType="); pw.println(transitTypeToString());
Craig Mautner164d4bb2012-11-26 13:51:23 -08001249 }
1250 switch (mNextAppTransitionType) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001251 case NEXT_TRANSIT_TYPE_CUSTOM:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001252 pw.print(" mNextAppTransitionPackage=");
1253 pw.println(mNextAppTransitionPackage);
1254 pw.print(" mNextAppTransitionEnter=0x");
1255 pw.print(Integer.toHexString(mNextAppTransitionEnter));
1256 pw.print(" mNextAppTransitionExit=0x");
1257 pw.println(Integer.toHexString(mNextAppTransitionExit));
1258 break;
Winson Chung044d5292014-11-06 11:05:19 -08001259 case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
1260 pw.print(" mNextAppTransitionPackage=");
1261 pw.println(mNextAppTransitionPackage);
1262 pw.print(" mNextAppTransitionInPlace=0x");
1263 pw.print(Integer.toHexString(mNextAppTransitionInPlace));
1264 break;
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001265 case NEXT_TRANSIT_TYPE_SCALE_UP:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001266 pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
1267 pw.print(" mNextAppTransitionStartY=");
1268 pw.println(mNextAppTransitionStartY);
1269 pw.print(" mNextAppTransitionStartWidth=");
1270 pw.print(mNextAppTransitionStartWidth);
1271 pw.print(" mNextAppTransitionStartHeight=");
1272 pw.println(mNextAppTransitionStartHeight);
1273 break;
Craig Mautner9a29a5d2012-12-27 19:03:40 -08001274 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
1275 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
Winson Chunga4ccb862014-08-22 15:26:27 -07001276 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
1277 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
Craig Mautner164d4bb2012-11-26 13:51:23 -08001278 pw.print(" mNextAppTransitionThumbnail=");
1279 pw.print(mNextAppTransitionThumbnail);
1280 pw.print(" mNextAppTransitionStartX=");
1281 pw.print(mNextAppTransitionStartX);
1282 pw.print(" mNextAppTransitionStartY=");
1283 pw.println(mNextAppTransitionStartY);
Winson Chung2e7f3bd2014-09-05 13:17:22 +02001284 pw.print(" mNextAppTransitionStartWidth=");
1285 pw.print(mNextAppTransitionStartWidth);
1286 pw.print(" mNextAppTransitionStartHeight=");
1287 pw.println(mNextAppTransitionStartHeight);
Craig Mautner164d4bb2012-11-26 13:51:23 -08001288 pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp);
1289 break;
1290 }
1291 if (mNextAppTransitionCallback != null) {
1292 pw.print(" mNextAppTransitionCallback=");
1293 pw.println(mNextAppTransitionCallback);
1294 }
1295 }
Amith Yamasani4befbec2013-07-10 16:18:01 -07001296
1297 public void setCurrentUser(int newUserId) {
1298 mCurrentUserId = newUserId;
1299 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08001300}