blob: f17b2f48ce4bf5c148e19c311db5513b524a7e10 [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;
Winson Chung2820c452014-04-15 15:34:44 -070020import android.content.res.Configuration;
Craig Mautner164d4bb2012-11-26 13:51:23 -080021import android.graphics.Bitmap;
22import android.graphics.Point;
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;
26import android.os.IRemoteCallback;
Winson Chung399f6202014-03-19 10:47:20 -070027import android.os.SystemProperties;
Craig Mautner164d4bb2012-11-26 13:51:23 -080028import 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;
Craig Mautner164d4bb2012-11-26 13:51:23 -080035import android.view.animation.Interpolator;
36import android.view.animation.ScaleAnimation;
37
Winson Chung399f6202014-03-19 10:47:20 -070038import android.view.animation.TranslateAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -080039import com.android.internal.util.DumpUtils.Dump;
40import com.android.server.AttributeCache;
41import com.android.server.wm.WindowManagerService.H;
42
43import java.io.PrintWriter;
44
Craig Mautner9a29a5d2012-12-27 19:03:40 -080045import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
46import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
47import static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation;
48import static com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
49import static com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation;
50import static com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
51import static com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation;
52import static com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
53import static com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation;
54import static com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
55import static com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation;
56import static com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
57import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
58import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
59import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation;
60import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
61import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation;
62import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
63import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation;
64import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
65
Craig Mautner164d4bb2012-11-26 13:51:23 -080066// State management of app transitions. When we are preparing for a
67// transition, mNextAppTransition will be the kind of transition to
68// perform or TRANSIT_NONE if we are not waiting. If we are waiting,
69// mOpeningApps and mClosingApps are the lists of tokens that will be
70// made visible or hidden at the next transition.
71public class AppTransition implements Dump {
72 private static final String TAG = "AppTransition";
Craig Mautner321bdf52012-12-18 09:53:24 -080073 private static final boolean DEBUG_APP_TRANSITIONS =
74 WindowManagerService.DEBUG_APP_TRANSITIONS;
75 private static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
76
Craig Mautner9a29a5d2012-12-27 19:03:40 -080077 /** Bit mask that is set for all enter transition. */
Craig Mautner4b71aa12012-12-27 17:20:01 -080078 public static final int TRANSIT_ENTER_MASK = 0x1000;
Craig Mautner9a29a5d2012-12-27 19:03:40 -080079
80 /** Bit mask that is set for all exit transitions. */
Craig Mautner4b71aa12012-12-27 17:20:01 -080081 public static final int TRANSIT_EXIT_MASK = 0x2000;
Craig Mautner9a29a5d2012-12-27 19:03:40 -080082
Craig Mautner4b71aa12012-12-27 17:20:01 -080083 /** Not set up for a transition. */
84 public static final int TRANSIT_UNSET = -1;
85 /** No animation for transition. */
86 public static final int TRANSIT_NONE = 0;
87 /** A window in a new activity is being opened on top of an existing one in the same task. */
88 public static final int TRANSIT_ACTIVITY_OPEN = 6 | TRANSIT_ENTER_MASK;
89 /** The window in the top-most activity is being closed to reveal the
90 * previous activity in the same task. */
91 public static final int TRANSIT_ACTIVITY_CLOSE = 7 | TRANSIT_EXIT_MASK;
92 /** A window in a new task is being opened on top of an existing one
93 * in another activity's task. */
94 public static final int TRANSIT_TASK_OPEN = 8 | TRANSIT_ENTER_MASK;
95 /** A window in the top-most activity is being closed to reveal the
96 * previous activity in a different task. */
97 public static final int TRANSIT_TASK_CLOSE = 9 | TRANSIT_EXIT_MASK;
98 /** A window in an existing task is being displayed on top of an existing one
99 * in another activity's task. */
100 public static final int TRANSIT_TASK_TO_FRONT = 10 | TRANSIT_ENTER_MASK;
101 /** A window in an existing task is being put below all other tasks. */
102 public static final int TRANSIT_TASK_TO_BACK = 11 | TRANSIT_EXIT_MASK;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800103 /** A window in a new activity that doesn't have a wallpaper is being opened on top of one that
104 * does, effectively closing the wallpaper. */
Craig Mautner4b71aa12012-12-27 17:20:01 -0800105 public static final int TRANSIT_WALLPAPER_CLOSE = 12 | TRANSIT_EXIT_MASK;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800106 /** A window in a new activity that does have a wallpaper is being opened on one that didn't,
107 * effectively opening the wallpaper. */
Craig Mautner4b71aa12012-12-27 17:20:01 -0800108 public static final int TRANSIT_WALLPAPER_OPEN = 13 | TRANSIT_ENTER_MASK;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800109 /** A window in a new activity is being opened on top of an existing one, and both are on top
110 * of the wallpaper. */
Craig Mautner4b71aa12012-12-27 17:20:01 -0800111 public static final int TRANSIT_WALLPAPER_INTRA_OPEN = 14 | TRANSIT_ENTER_MASK;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800112 /** The window in the top-most activity is being closed to reveal the previous activity, and
113 * both are on top of the wallpaper. */
Craig Mautner4b71aa12012-12-27 17:20:01 -0800114 public static final int TRANSIT_WALLPAPER_INTRA_CLOSE = 15 | TRANSIT_EXIT_MASK;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800115
Craig Mautner321bdf52012-12-18 09:53:24 -0800116 /** Fraction of animation at which the recents thumbnail becomes completely transparent */
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800117 private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.25f;
Craig Mautner321bdf52012-12-18 09:53:24 -0800118
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800119 private static final long DEFAULT_APP_TRANSITION_DURATION = 250;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800120
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800121 private final Context mContext;
122 private final Handler mH;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800123
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800124 private int mNextAppTransition = TRANSIT_UNSET;
125
126 private static final int NEXT_TRANSIT_TYPE_NONE = 0;
127 private static final int NEXT_TRANSIT_TYPE_CUSTOM = 1;
128 private static final int NEXT_TRANSIT_TYPE_SCALE_UP = 2;
129 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP = 3;
130 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN = 4;
131 private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
132
Winson Chung399f6202014-03-19 10:47:20 -0700133 // These are the possible states for the enter/exit activities during a thumbnail transition
134 private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
135 private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_UP = 1;
136 private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN = 2;
137 private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;
138
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800139 private String mNextAppTransitionPackage;
140 private Bitmap mNextAppTransitionThumbnail;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800141 // Used for thumbnail transitions. True if we're scaling up, false if scaling down
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800142 private boolean mNextAppTransitionScaleUp;
143 private IRemoteCallback mNextAppTransitionCallback;
144 private int mNextAppTransitionEnter;
145 private int mNextAppTransitionExit;
146 private int mNextAppTransitionStartX;
147 private int mNextAppTransitionStartY;
148 private int mNextAppTransitionStartWidth;
149 private int mNextAppTransitionStartHeight;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800150
Winson Chung2820c452014-04-15 15:34:44 -0700151 private Rect mTmpFromClipRect = new Rect();
152 private Rect mTmpToClipRect = new Rect();
153
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800154 private final static int APP_STATE_IDLE = 0;
155 private final static int APP_STATE_READY = 1;
156 private final static int APP_STATE_RUNNING = 2;
157 private final static int APP_STATE_TIMEOUT = 3;
158 private int mAppTransitionState = APP_STATE_IDLE;
159
160 private final int mConfigShortAnimTime;
Craig Mautner321bdf52012-12-18 09:53:24 -0800161 private final Interpolator mDecelerateInterpolator;
162 private final Interpolator mThumbnailFadeoutInterpolator;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800163
Amith Yamasani4befbec2013-07-10 16:18:01 -0700164 private int mCurrentUserId = 0;
Winson Chung399f6202014-03-19 10:47:20 -0700165 private boolean mUseAlternateThumbnailAnimation;
Amith Yamasani4befbec2013-07-10 16:18:01 -0700166
Craig Mautner164d4bb2012-11-26 13:51:23 -0800167 AppTransition(Context context, Handler h) {
168 mContext = context;
169 mH = h;
Winson Chung399f6202014-03-19 10:47:20 -0700170 mUseAlternateThumbnailAnimation =
171 SystemProperties.getBoolean("persist.anim.use_alt_thumbnail", false);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800172 mConfigShortAnimTime = context.getResources().getInteger(
173 com.android.internal.R.integer.config_shortAnimTime);
Craig Mautner321bdf52012-12-18 09:53:24 -0800174 mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
175 com.android.internal.R.interpolator.decelerate_cubic);
176 mThumbnailFadeoutInterpolator = new Interpolator() {
177 @Override
178 public float getInterpolation(float input) {
179 // Linear response for first fraction, then complete after that.
180 if (input < RECENTS_THUMBNAIL_FADEOUT_FRACTION) {
181 return input / RECENTS_THUMBNAIL_FADEOUT_FRACTION;
182 }
183 return 1.0f;
184 }
185 };
Craig Mautner164d4bb2012-11-26 13:51:23 -0800186 }
187
188 boolean isTransitionSet() {
189 return mNextAppTransition != TRANSIT_UNSET;
190 }
191
192 boolean isTransitionNone() {
193 return mNextAppTransition == TRANSIT_NONE;
194 }
195
196 boolean isTransitionEqual(int transit) {
197 return mNextAppTransition == transit;
198 }
199
200 int getAppTransition() {
Craig Mautner321bdf52012-12-18 09:53:24 -0800201 return mNextAppTransition;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800202 }
203
204 void setAppTransition(int transit) {
205 mNextAppTransition = transit;
206 }
207
208 boolean isReady() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800209 return mAppTransitionState == APP_STATE_READY
210 || mAppTransitionState == APP_STATE_TIMEOUT;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800211 }
212
Craig Mautnerae446592012-12-06 19:05:05 -0800213 void setReady() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800214 mAppTransitionState = APP_STATE_READY;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800215 }
216
217 boolean isRunning() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800218 return mAppTransitionState == APP_STATE_RUNNING;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800219 }
220
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800221 void setIdle() {
222 mAppTransitionState = APP_STATE_IDLE;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800223 }
224
225 boolean isTimeout() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800226 return mAppTransitionState == APP_STATE_TIMEOUT;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800227 }
228
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800229 void setTimeout() {
230 mAppTransitionState = APP_STATE_TIMEOUT;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800231 }
232
233 Bitmap getNextAppTransitionThumbnail() {
234 return mNextAppTransitionThumbnail;
235 }
236
237 void getStartingPoint(Point outPoint) {
238 outPoint.x = mNextAppTransitionStartX;
239 outPoint.y = mNextAppTransitionStartY;
240 }
241
Craig Mautner164d4bb2012-11-26 13:51:23 -0800242 void prepare() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800243 if (!isRunning()) {
244 mAppTransitionState = APP_STATE_IDLE;
245 }
Craig Mautner164d4bb2012-11-26 13:51:23 -0800246 }
247
248 void goodToGo() {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800249 mNextAppTransition = TRANSIT_UNSET;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800250 mAppTransitionState = APP_STATE_RUNNING;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800251 }
252
253 void clear() {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800254 mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800255 mNextAppTransitionPackage = null;
256 mNextAppTransitionThumbnail = null;
257 }
258
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800259 void freeze() {
260 setAppTransition(AppTransition.TRANSIT_UNSET);
261 clear();
262 setReady();
263 }
264
Craig Mautner164d4bb2012-11-26 13:51:23 -0800265 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
266 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
267 + (lp != null ? lp.packageName : null)
268 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
269 if (lp != null && lp.windowAnimations != 0) {
270 // If this is a system resource, don't try to load it from the
271 // application resources. It is nice to avoid loading application
272 // resources if we can.
273 String packageName = lp.packageName != null ? lp.packageName : "android";
274 int resId = lp.windowAnimations;
275 if ((resId&0xFF000000) == 0x01000000) {
276 packageName = "android";
277 }
278 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
279 + packageName);
280 return AttributeCache.instance().get(packageName, resId,
Amith Yamasani4befbec2013-07-10 16:18:01 -0700281 com.android.internal.R.styleable.WindowAnimation, mCurrentUserId);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800282 }
283 return null;
284 }
285
286 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
287 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
288 + packageName + " resId=0x" + Integer.toHexString(resId));
289 if (packageName != null) {
290 if ((resId&0xFF000000) == 0x01000000) {
291 packageName = "android";
292 }
293 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
294 + packageName);
295 return AttributeCache.instance().get(packageName, resId,
Amith Yamasani4befbec2013-07-10 16:18:01 -0700296 com.android.internal.R.styleable.WindowAnimation, mCurrentUserId);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800297 }
298 return null;
299 }
300
301 Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
302 int anim = 0;
303 Context context = mContext;
304 if (animAttr >= 0) {
305 AttributeCache.Entry ent = getCachedAnimations(lp);
306 if (ent != null) {
307 context = ent.context;
308 anim = ent.array.getResourceId(animAttr, 0);
309 }
310 }
311 if (anim != 0) {
312 return AnimationUtils.loadAnimation(context, anim);
313 }
314 return null;
315 }
316
317 private Animation loadAnimation(String packageName, int resId) {
318 int anim = 0;
319 Context context = mContext;
320 if (resId >= 0) {
321 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
322 if (ent != null) {
323 context = ent.context;
324 anim = resId;
325 }
326 }
327 if (anim != 0) {
328 return AnimationUtils.loadAnimation(context, anim);
329 }
330 return null;
331 }
332
Craig Mautner164d4bb2012-11-26 13:51:23 -0800333 /**
334 * Compute the pivot point for an animation that is scaling from a small
335 * rect on screen to a larger rect. The pivot point varies depending on
336 * the distance between the inner and outer edges on both sides. This
337 * function computes the pivot point for one dimension.
338 * @param startPos Offset from left/top edge of outer rectangle to
339 * left/top edge of inner rectangle.
340 * @param finalScale The scaling factor between the size of the outer
341 * and inner rectangles.
342 */
343 private static float computePivot(int startPos, float finalScale) {
344 final float denom = finalScale-1;
345 if (Math.abs(denom) < .0001f) {
346 return startPos;
347 }
348 return -startPos / denom;
349 }
350
351 private Animation createScaleUpAnimationLocked(int transit, boolean enter,
352 int appWidth, int appHeight) {
353 Animation a = null;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800354 if (enter) {
355 // Entering app zooms out from the center of the initial rect.
356 float scaleW = mNextAppTransitionStartWidth / (float) appWidth;
357 float scaleH = mNextAppTransitionStartHeight / (float) appHeight;
358 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
359 computePivot(mNextAppTransitionStartX, scaleW),
360 computePivot(mNextAppTransitionStartY, scaleH));
Craig Mautner321bdf52012-12-18 09:53:24 -0800361 scale.setInterpolator(mDecelerateInterpolator);
362
Craig Mautner164d4bb2012-11-26 13:51:23 -0800363 Animation alpha = new AlphaAnimation(0, 1);
Craig Mautner321bdf52012-12-18 09:53:24 -0800364 alpha.setInterpolator(mThumbnailFadeoutInterpolator);
365
366 AnimationSet set = new AnimationSet(false);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800367 set.addAnimation(scale);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800368 set.addAnimation(alpha);
369 set.setDetachWallpaper(true);
370 a = set;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800371 } else if (transit == TRANSIT_WALLPAPER_INTRA_OPEN ||
372 transit == TRANSIT_WALLPAPER_INTRA_CLOSE) {
Craig Mautner321bdf52012-12-18 09:53:24 -0800373 // If we are on top of the wallpaper, we need an animation that
374 // correctly handles the wallpaper staying static behind all of
375 // the animated elements. To do this, will just have the existing
376 // element fade out.
377 a = new AlphaAnimation(1, 0);
378 a.setDetachWallpaper(true);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800379 } else {
Craig Mautner321bdf52012-12-18 09:53:24 -0800380 // For normal animations, the exiting element just holds in place.
381 a = new AlphaAnimation(1, 1);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800382 }
Craig Mautner321bdf52012-12-18 09:53:24 -0800383
384 // Pick the desired duration. If this is an inter-activity transition,
385 // it is the standard duration for that. Otherwise we use the longer
386 // task transition duration.
387 final long duration;
388 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800389 case TRANSIT_ACTIVITY_OPEN:
390 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner321bdf52012-12-18 09:53:24 -0800391 duration = mConfigShortAnimTime;
392 break;
393 default:
394 duration = DEFAULT_APP_TRANSITION_DURATION;
395 break;
396 }
397 a.setDuration(duration);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800398 a.setFillAfter(true);
Craig Mautner321bdf52012-12-18 09:53:24 -0800399 a.setInterpolator(mDecelerateInterpolator);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800400 a.initialize(appWidth, appHeight, appWidth, appHeight);
401 return a;
402 }
403
Winson Chung399f6202014-03-19 10:47:20 -0700404 /**
405 * Prepares the specified animation with a standard duration, interpolator, etc.
406 */
407 Animation prepareThumbnailAnimation(Animation a, int appWidth, int appHeight, int transit) {
Craig Mautner321bdf52012-12-18 09:53:24 -0800408 // Pick the desired duration. If this is an inter-activity transition,
409 // it is the standard duration for that. Otherwise we use the longer
410 // task transition duration.
411 final long duration;
412 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800413 case TRANSIT_ACTIVITY_OPEN:
414 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner321bdf52012-12-18 09:53:24 -0800415 duration = mConfigShortAnimTime;
416 break;
417 default:
418 duration = DEFAULT_APP_TRANSITION_DURATION;
419 break;
420 }
421 a.setDuration(duration);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800422 a.setFillAfter(true);
Craig Mautner321bdf52012-12-18 09:53:24 -0800423 a.setInterpolator(mDecelerateInterpolator);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800424 a.initialize(appWidth, appHeight, appWidth, appHeight);
425 return a;
426 }
427
Winson Chung399f6202014-03-19 10:47:20 -0700428 /**
429 * Return the current thumbnail transition state.
430 */
431 int getThumbnailTransitionState(boolean enter) {
432 if (enter) {
433 if (mNextAppTransitionScaleUp) {
434 return THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
435 } else {
436 return THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN;
437 }
438 } else {
439 if (mNextAppTransitionScaleUp) {
440 return THUMBNAIL_TRANSITION_EXIT_SCALE_UP;
441 } else {
442 return THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN;
443 }
444 }
445 }
446
447 /**
448 * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
449 * when a thumbnail is specified with the activity options.
450 */
451 Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit) {
452 Animation a;
453 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
454 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
455 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
456 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
457
458 if (mNextAppTransitionScaleUp) {
459 // Animation for the thumbnail zooming from its initial size to the full screen
460 float scaleW = appWidth / thumbWidth;
461 float scaleH = appHeight / thumbHeight;
462 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
463 computePivot(mNextAppTransitionStartX, 1 / scaleW),
464 computePivot(mNextAppTransitionStartY, 1 / scaleH));
465 scale.setInterpolator(mDecelerateInterpolator);
466
467 Animation alpha = new AlphaAnimation(1, 0);
468 alpha.setInterpolator(mThumbnailFadeoutInterpolator);
469
470 // This AnimationSet uses the Interpolators assigned above.
471 AnimationSet set = new AnimationSet(false);
472 set.addAnimation(scale);
473 set.addAnimation(alpha);
474 a = set;
475 } else {
476 // Animation for the thumbnail zooming down from the full screen to its final size
477 float scaleW = appWidth / thumbWidth;
478 float scaleH = appHeight / thumbHeight;
479 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
480 computePivot(mNextAppTransitionStartX, 1 / scaleW),
481 computePivot(mNextAppTransitionStartY, 1 / scaleH));
482 }
483
484 return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
485 }
486
487 /**
488 * This alternate animation is created when we are doing a thumbnail transition, for the
489 * activity that is leaving, and the activity that is entering.
490 */
491 Animation createAlternateThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
Winson Chung2820c452014-04-15 15:34:44 -0700492 int appHeight, int orientation, int transit,
Winson Chung399f6202014-03-19 10:47:20 -0700493 Rect containingFrame, Rect contentInsets) {
494 Animation a;
495 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
496 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
497 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
498 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
499
Winson Chung2820c452014-04-15 15:34:44 -0700500 // Used for the ENTER_SCALE_UP and EXIT_SCALE_DOWN transitions
501 float scale = 1f;
502 int scaledTopDecor = 0;
503
Winson Chung399f6202014-03-19 10:47:20 -0700504 switch (thumbTransitState) {
505 case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
506 // Entering app scales up with the thumbnail
Winson Chung2820c452014-04-15 15:34:44 -0700507 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
508 // In portrait, we scale the width and clip to the top/left square
509 scale = thumbWidth / appWidth;
510 scaledTopDecor = (int) (scale * contentInsets.top);
511 int unscaledThumbHeight = (int) (thumbHeight / scale);
512 mTmpFromClipRect.set(containingFrame);
513 mTmpFromClipRect.bottom = (mTmpFromClipRect.top + unscaledThumbHeight);
514 mTmpToClipRect.set(containingFrame);
515 } else {
516 // In landscape, we scale the height and clip to the top/left square
517 scale = thumbHeight / (appHeight - contentInsets.top);
518 scaledTopDecor = (int) (scale * contentInsets.top);
519 int unscaledThumbWidth = (int) (thumbWidth / scale);
520 mTmpFromClipRect.set(containingFrame);
521 mTmpFromClipRect.right = (mTmpFromClipRect.left + unscaledThumbWidth);
522 mTmpToClipRect.set(containingFrame);
523 }
Winson Chung399f6202014-03-19 10:47:20 -0700524
525 Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1,
526 computePivot(mNextAppTransitionStartX, scale),
527 computePivot(mNextAppTransitionStartY, scale));
528 Animation alphaAnim = new AlphaAnimation(1, 1);
Winson Chung2820c452014-04-15 15:34:44 -0700529 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
Winson Chung399f6202014-03-19 10:47:20 -0700530 Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0);
531
532 AnimationSet set = new AnimationSet(true);
533 set.addAnimation(alphaAnim);
534 set.addAnimation(clipAnim);
535 set.addAnimation(scaleAnim);
536 set.addAnimation(translateAnim);
537 a = set;
538 break;
539 }
540 case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
541 // Exiting app while the thumbnail is scaling up should fade
542 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
543 // Fade out while bringing up selected activity. This keeps the
544 // current activity from showing through a launching wallpaper
545 // activity.
546 a = new AlphaAnimation(1, 0);
547 } else {
548 // noop animation
549 a = new AlphaAnimation(1, 1);
550 }
551 break;
552 }
553 case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
554 // Entering the other app, it should just be visible while we scale the thumbnail
555 // down above it
556 a = new AlphaAnimation(1, 1);
557 break;
558 }
559 case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
560 // Exiting the current app, the app should scale down with the thumbnail
Winson Chung2820c452014-04-15 15:34:44 -0700561 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
562 // In portrait, we scale the width and clip to the top/left square
563 scale = thumbWidth / appWidth;
564 scaledTopDecor = (int) (scale * contentInsets.top);
565 int unscaledThumbHeight = (int) (thumbHeight / scale);
566 mTmpFromClipRect.set(containingFrame);
567 mTmpToClipRect.set(containingFrame);
568 mTmpToClipRect.bottom = (mTmpToClipRect.top + unscaledThumbHeight);
569 } else {
570 // In landscape, we scale the height and clip to the top/left square
571 scale = thumbHeight / (appHeight - contentInsets.top);
572 scaledTopDecor = (int) (scale * contentInsets.top);
573 int unscaledThumbWidth = (int) (thumbWidth / scale);
574 mTmpFromClipRect.set(containingFrame);
575 mTmpToClipRect.set(containingFrame);
576 mTmpToClipRect.right = (mTmpToClipRect.left + unscaledThumbWidth);
577 }
Winson Chung399f6202014-03-19 10:47:20 -0700578
579 Animation scaleAnim = new ScaleAnimation(1, scale, 1, scale,
580 computePivot(mNextAppTransitionStartX, scale),
581 computePivot(mNextAppTransitionStartY, scale));
582 Animation alphaAnim = new AlphaAnimation(1, 1);
Winson Chung2820c452014-04-15 15:34:44 -0700583 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
Winson Chung399f6202014-03-19 10:47:20 -0700584 Animation translateAnim = new TranslateAnimation(0, 0, 0, -scaledTopDecor);
585
586 AnimationSet set = new AnimationSet(true);
587 set.addAnimation(alphaAnim);
588 set.addAnimation(clipAnim);
589 set.addAnimation(scaleAnim);
590 set.addAnimation(translateAnim);
591
592 a = set;
593 a.setZAdjustment(Animation.ZORDER_TOP);
594 break;
595 }
596 default:
597 throw new RuntimeException("Invalid thumbnail transition state");
598 }
599
600 return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
601 }
602
603 /**
604 * This animation is created when we are doing a thumbnail transition, for the activity that is
605 * leaving, and the activity that is entering.
606 */
607 Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
608 int appHeight, int transit) {
609 Animation a;
610 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
611 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
612 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
613 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
614
615 switch (thumbTransitState) {
616 case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
617 // Entering app scales up with the thumbnail
618 float scaleW = thumbWidth / appWidth;
619 float scaleH = thumbHeight / appHeight;
620 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
621 computePivot(mNextAppTransitionStartX, scaleW),
622 computePivot(mNextAppTransitionStartY, scaleH));
623 break;
624 }
625 case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
626 // Exiting app while the thumbnail is scaling up should fade or stay in place
627 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
628 // Fade out while bringing up selected activity. This keeps the
629 // current activity from showing through a launching wallpaper
630 // activity.
631 a = new AlphaAnimation(1, 0);
632 } else {
633 // noop animation
634 a = new AlphaAnimation(1, 1);
635 }
636 break;
637 }
638 case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
639 // Entering the other app, it should just be visible while we scale the thumbnail
640 // down above it
641 a = new AlphaAnimation(1, 1);
642 break;
643 }
644 case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
645 // Exiting the current app, the app should scale down with the thumbnail
646 float scaleW = thumbWidth / appWidth;
647 float scaleH = thumbHeight / appHeight;
648 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
649 computePivot(mNextAppTransitionStartX, scaleW),
650 computePivot(mNextAppTransitionStartY, scaleH));
651
652 Animation alpha = new AlphaAnimation(1, 0);
653
654 AnimationSet set = new AnimationSet(true);
655 set.addAnimation(scale);
656 set.addAnimation(alpha);
657 set.setZAdjustment(Animation.ZORDER_TOP);
658 a = set;
659 break;
660 }
661 default:
662 throw new RuntimeException("Invalid thumbnail transition state");
663 }
664
665 return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
666 }
667
Craig Mautner164d4bb2012-11-26 13:51:23 -0800668
669 Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
Winson Chung2820c452014-04-15 15:34:44 -0700670 int appWidth, int appHeight, int orientation,
671 Rect containingFrame, Rect contentInsets) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800672 Animation a;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800673 if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800674 a = loadAnimation(mNextAppTransitionPackage, enter ?
675 mNextAppTransitionEnter : mNextAppTransitionExit);
676 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
677 "applyAnimation:"
678 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
679 + " transit=" + transit + " isEntrance=" + enter
680 + " Callers=" + Debug.getCallers(3));
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800681 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800682 a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight);
683 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
684 "applyAnimation:"
685 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
686 + " transit=" + transit + " isEntrance=" + enter
687 + " Callers=" + Debug.getCallers(3));
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800688 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
689 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800690 mNextAppTransitionScaleUp =
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800691 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
Winson Chung399f6202014-03-19 10:47:20 -0700692 if (mUseAlternateThumbnailAnimation) {
693 a = createAlternateThumbnailEnterExitAnimationLocked(
Winson Chung2820c452014-04-15 15:34:44 -0700694 getThumbnailTransitionState(enter), appWidth, appHeight, orientation,
695 transit, containingFrame, contentInsets);
Winson Chung399f6202014-03-19 10:47:20 -0700696 } else {
697 a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
698 appWidth, appHeight, transit);
699 }
Craig Mautner164d4bb2012-11-26 13:51:23 -0800700 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
701 String animName = mNextAppTransitionScaleUp ?
702 "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
703 Slog.v(TAG, "applyAnimation:"
704 + " anim=" + a + " nextAppTransition=" + animName
705 + " transit=" + transit + " isEntrance=" + enter
706 + " Callers=" + Debug.getCallers(3));
707 }
708 } else {
709 int animAttr = 0;
710 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800711 case TRANSIT_ACTIVITY_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800712 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800713 ? WindowAnimation_activityOpenEnterAnimation
714 : WindowAnimation_activityOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800715 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800716 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800717 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800718 ? WindowAnimation_activityCloseEnterAnimation
719 : WindowAnimation_activityCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800720 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800721 case TRANSIT_TASK_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800722 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800723 ? WindowAnimation_taskOpenEnterAnimation
724 : WindowAnimation_taskOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800725 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800726 case TRANSIT_TASK_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800727 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800728 ? WindowAnimation_taskCloseEnterAnimation
729 : WindowAnimation_taskCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800730 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800731 case TRANSIT_TASK_TO_FRONT:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800732 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800733 ? WindowAnimation_taskToFrontEnterAnimation
734 : WindowAnimation_taskToFrontExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800735 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800736 case TRANSIT_TASK_TO_BACK:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800737 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800738 ? WindowAnimation_taskToBackEnterAnimation
739 : WindowAnimation_taskToBackExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800740 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800741 case TRANSIT_WALLPAPER_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800742 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800743 ? WindowAnimation_wallpaperOpenEnterAnimation
744 : WindowAnimation_wallpaperOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800745 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800746 case TRANSIT_WALLPAPER_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800747 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800748 ? WindowAnimation_wallpaperCloseEnterAnimation
749 : WindowAnimation_wallpaperCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800750 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800751 case TRANSIT_WALLPAPER_INTRA_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800752 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800753 ? WindowAnimation_wallpaperIntraOpenEnterAnimation
754 : WindowAnimation_wallpaperIntraOpenExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800755 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800756 case TRANSIT_WALLPAPER_INTRA_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800757 animAttr = enter
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800758 ? WindowAnimation_wallpaperIntraCloseEnterAnimation
759 : WindowAnimation_wallpaperIntraCloseExitAnimation;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800760 break;
761 }
762 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
763 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
764 "applyAnimation:"
765 + " anim=" + a
766 + " animAttr=0x" + Integer.toHexString(animAttr)
767 + " transit=" + transit + " isEntrance=" + enter
768 + " Callers=" + Debug.getCallers(3));
769 }
770 return a;
771 }
772
773 void postAnimationCallback() {
774 if (mNextAppTransitionCallback != null) {
775 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, mNextAppTransitionCallback));
776 mNextAppTransitionCallback = null;
777 }
778 }
779
780 void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
781 IRemoteCallback startedCallback) {
782 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800783 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800784 mNextAppTransitionPackage = packageName;
785 mNextAppTransitionThumbnail = null;
786 mNextAppTransitionEnter = enterAnim;
787 mNextAppTransitionExit = exitAnim;
788 postAnimationCallback();
789 mNextAppTransitionCallback = startedCallback;
790 } else {
791 postAnimationCallback();
792 }
793 }
794
795 void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
796 int startHeight) {
797 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800798 mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800799 mNextAppTransitionPackage = null;
800 mNextAppTransitionThumbnail = null;
801 mNextAppTransitionStartX = startX;
802 mNextAppTransitionStartY = startY;
803 mNextAppTransitionStartWidth = startWidth;
804 mNextAppTransitionStartHeight = startHeight;
805 postAnimationCallback();
806 mNextAppTransitionCallback = null;
807 }
808 }
809
810 void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
811 IRemoteCallback startedCallback, boolean scaleUp) {
812 if (isTransitionSet()) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800813 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP
814 : NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800815 mNextAppTransitionPackage = null;
816 mNextAppTransitionThumbnail = srcThumb;
817 mNextAppTransitionScaleUp = scaleUp;
818 mNextAppTransitionStartX = startX;
819 mNextAppTransitionStartY = startY;
820 postAnimationCallback();
821 mNextAppTransitionCallback = startedCallback;
822 } else {
823 postAnimationCallback();
824 }
825 }
826
827 @Override
828 public String toString() {
829 return "mNextAppTransition=0x" + Integer.toHexString(mNextAppTransition);
830 }
831
Craig Mautner4b71aa12012-12-27 17:20:01 -0800832 /**
833 * Returns the human readable name of a window transition.
834 *
835 * @param transition The window transition.
836 * @return The transition symbolic name.
837 */
838 public static String appTransitionToString(int transition) {
839 switch (transition) {
840 case TRANSIT_UNSET: {
841 return "TRANSIT_UNSET";
842 }
843 case TRANSIT_NONE: {
844 return "TRANSIT_NONE";
845 }
846 case TRANSIT_EXIT_MASK: {
847 return "TRANSIT_EXIT_MASK";
848 }
849 case TRANSIT_ACTIVITY_OPEN: {
850 return "TRANSIT_ACTIVITY_OPEN";
851 }
852 case TRANSIT_ACTIVITY_CLOSE: {
853 return "TRANSIT_ACTIVITY_CLOSE";
854 }
855 case TRANSIT_TASK_OPEN: {
856 return "TRANSIT_TASK_OPEN";
857 }
858 case TRANSIT_TASK_CLOSE: {
859 return "TRANSIT_TASK_CLOSE";
860 }
861 case TRANSIT_TASK_TO_FRONT: {
862 return "TRANSIT_TASK_TO_FRONT";
863 }
864 case TRANSIT_TASK_TO_BACK: {
865 return "TRANSIT_TASK_TO_BACK";
866 }
867 case TRANSIT_WALLPAPER_CLOSE: {
868 return "TRANSIT_WALLPAPER_CLOSE";
869 }
870 case TRANSIT_WALLPAPER_OPEN: {
871 return "TRANSIT_WALLPAPER_OPEN";
872 }
873 case TRANSIT_WALLPAPER_INTRA_OPEN: {
874 return "TRANSIT_WALLPAPER_INTRA_OPEN";
875 }
876 case TRANSIT_WALLPAPER_INTRA_CLOSE: {
877 return "TRANSIT_WALLPAPER_INTRA_CLOSE";
878 }
879 default: {
880 return "<UNKNOWN>";
881 }
882 }
883 }
884
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800885 private String appStateToString() {
886 switch (mAppTransitionState) {
887 case APP_STATE_IDLE:
888 return "APP_STATE_IDLE";
889 case APP_STATE_READY:
890 return "APP_STATE_READY";
891 case APP_STATE_RUNNING:
892 return "APP_STATE_RUNNING";
893 case APP_STATE_TIMEOUT:
894 return "APP_STATE_TIMEOUT";
895 default:
896 return "unknown state=" + mAppTransitionState;
897 }
898 }
899
900 private String transitTypeToString() {
901 switch (mNextAppTransitionType) {
902 case NEXT_TRANSIT_TYPE_NONE:
903 return "NEXT_TRANSIT_TYPE_NONE";
904 case NEXT_TRANSIT_TYPE_CUSTOM:
905 return "NEXT_TRANSIT_TYPE_CUSTOM";
906 case NEXT_TRANSIT_TYPE_SCALE_UP:
907 return "NEXT_TRANSIT_TYPE_SCALE_UP";
908 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
909 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP";
910 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
911 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN";
912 default:
913 return "unknown type=" + mNextAppTransitionType;
914 }
915 }
916
Craig Mautner164d4bb2012-11-26 13:51:23 -0800917 @Override
918 public void dump(PrintWriter pw) {
919 pw.print(" " + this);
Craig Mautner28816302013-10-10 20:31:00 -0700920 pw.print(" mAppTransitionState="); pw.println(appStateToString());
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800921 if (mNextAppTransitionType != NEXT_TRANSIT_TYPE_NONE) {
922 pw.print(" mNextAppTransitionType="); pw.println(transitTypeToString());
Craig Mautner164d4bb2012-11-26 13:51:23 -0800923 }
924 switch (mNextAppTransitionType) {
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800925 case NEXT_TRANSIT_TYPE_CUSTOM:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800926 pw.print(" mNextAppTransitionPackage=");
927 pw.println(mNextAppTransitionPackage);
928 pw.print(" mNextAppTransitionEnter=0x");
929 pw.print(Integer.toHexString(mNextAppTransitionEnter));
930 pw.print(" mNextAppTransitionExit=0x");
931 pw.println(Integer.toHexString(mNextAppTransitionExit));
932 break;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800933 case NEXT_TRANSIT_TYPE_SCALE_UP:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800934 pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
935 pw.print(" mNextAppTransitionStartY=");
936 pw.println(mNextAppTransitionStartY);
937 pw.print(" mNextAppTransitionStartWidth=");
938 pw.print(mNextAppTransitionStartWidth);
939 pw.print(" mNextAppTransitionStartHeight=");
940 pw.println(mNextAppTransitionStartHeight);
941 break;
Craig Mautner9a29a5d2012-12-27 19:03:40 -0800942 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
943 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800944 pw.print(" mNextAppTransitionThumbnail=");
945 pw.print(mNextAppTransitionThumbnail);
946 pw.print(" mNextAppTransitionStartX=");
947 pw.print(mNextAppTransitionStartX);
948 pw.print(" mNextAppTransitionStartY=");
949 pw.println(mNextAppTransitionStartY);
950 pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp);
951 break;
952 }
953 if (mNextAppTransitionCallback != null) {
954 pw.print(" mNextAppTransitionCallback=");
955 pw.println(mNextAppTransitionCallback);
956 }
957 }
Amith Yamasani4befbec2013-07-10 16:18:01 -0700958
959 public void setCurrentUser(int newUserId) {
960 mCurrentUserId = newUserId;
961 }
Craig Mautner164d4bb2012-11-26 13:51:23 -0800962}