blob: b96119b166c9fc3b5bb21f76269f81ca1d38b24e [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
19import android.app.ActivityOptions;
20import android.content.Context;
21import android.graphics.Bitmap;
22import android.graphics.Point;
23import android.os.Debug;
24import android.os.Handler;
25import android.os.IRemoteCallback;
26import android.util.Slog;
27import android.view.WindowManager;
Craig Mautner164d4bb2012-11-26 13:51:23 -080028import android.view.animation.AlphaAnimation;
29import android.view.animation.Animation;
30import android.view.animation.AnimationSet;
31import android.view.animation.AnimationUtils;
Craig Mautner164d4bb2012-11-26 13:51:23 -080032import android.view.animation.Interpolator;
33import android.view.animation.ScaleAnimation;
34
35import com.android.internal.util.DumpUtils.Dump;
36import com.android.server.AttributeCache;
37import com.android.server.wm.WindowManagerService.H;
38
39import java.io.PrintWriter;
40
Craig Mautner164d4bb2012-11-26 13:51:23 -080041// State management of app transitions. When we are preparing for a
42// transition, mNextAppTransition will be the kind of transition to
43// perform or TRANSIT_NONE if we are not waiting. If we are waiting,
44// mOpeningApps and mClosingApps are the lists of tokens that will be
45// made visible or hidden at the next transition.
46public class AppTransition implements Dump {
47 private static final String TAG = "AppTransition";
Craig Mautner321bdf52012-12-18 09:53:24 -080048 private static final boolean DEBUG_APP_TRANSITIONS =
49 WindowManagerService.DEBUG_APP_TRANSITIONS;
50 private static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
51
Craig Mautner4b71aa12012-12-27 17:20:01 -080052 /**
53 * Bit mask that is set for all enter transition.
54 */
55 public static final int TRANSIT_ENTER_MASK = 0x1000;
56
57 /**
58 * Bit mask that is set for all exit transitions.
59 */
60 public static final int TRANSIT_EXIT_MASK = 0x2000;
61
62 /** Not set up for a transition. */
63 public static final int TRANSIT_UNSET = -1;
64 /** No animation for transition. */
65 public static final int TRANSIT_NONE = 0;
66 /** A window in a new activity is being opened on top of an existing one in the same task. */
67 public static final int TRANSIT_ACTIVITY_OPEN = 6 | TRANSIT_ENTER_MASK;
68 /** The window in the top-most activity is being closed to reveal the
69 * previous activity in the same task. */
70 public static final int TRANSIT_ACTIVITY_CLOSE = 7 | TRANSIT_EXIT_MASK;
71 /** A window in a new task is being opened on top of an existing one
72 * in another activity's task. */
73 public static final int TRANSIT_TASK_OPEN = 8 | TRANSIT_ENTER_MASK;
74 /** A window in the top-most activity is being closed to reveal the
75 * previous activity in a different task. */
76 public static final int TRANSIT_TASK_CLOSE = 9 | TRANSIT_EXIT_MASK;
77 /** A window in an existing task is being displayed on top of an existing one
78 * in another activity's task. */
79 public static final int TRANSIT_TASK_TO_FRONT = 10 | TRANSIT_ENTER_MASK;
80 /** A window in an existing task is being put below all other tasks. */
81 public static final int TRANSIT_TASK_TO_BACK = 11 | TRANSIT_EXIT_MASK;
82 /** A window in a new activity that doesn't have a wallpaper is being
83 * opened on top of one that does, effectively closing the wallpaper. */
84 public static final int TRANSIT_WALLPAPER_CLOSE = 12 | TRANSIT_EXIT_MASK;
85 /** A window in a new activity that does have a wallpaper is being
86 * opened on one that didn't, effectively opening the wallpaper. */
87 public static final int TRANSIT_WALLPAPER_OPEN = 13 | TRANSIT_ENTER_MASK;
88 /** A window in a new activity is being opened on top of an existing one,
89 * and both are on top of the wallpaper. */
90 public static final int TRANSIT_WALLPAPER_INTRA_OPEN = 14 | TRANSIT_ENTER_MASK;
91 /** The window in the top-most activity is being closed to reveal the
92 * previous activity, and both are on top of he wallpaper. */
93 public static final int TRANSIT_WALLPAPER_INTRA_CLOSE = 15 | TRANSIT_EXIT_MASK;
94
95
Craig Mautner321bdf52012-12-18 09:53:24 -080096 /** Fraction of animation at which the recents thumbnail becomes completely transparent */
97 static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.25f;
98
99 static final long DEFAULT_APP_TRANSITION_DURATION = 250;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800100
101 final Context mContext;
102 final Handler mH;
103
104 int mNextAppTransition = TRANSIT_UNSET;
105 int mNextAppTransitionType = ActivityOptions.ANIM_NONE;
106 String mNextAppTransitionPackage;
107 Bitmap mNextAppTransitionThumbnail;
108 // Used for thumbnail transitions. True if we're scaling up, false if scaling down
109 boolean mNextAppTransitionScaleUp;
110 IRemoteCallback mNextAppTransitionCallback;
111 int mNextAppTransitionEnter;
112 int mNextAppTransitionExit;
113 int mNextAppTransitionStartX;
114 int mNextAppTransitionStartY;
115 int mNextAppTransitionStartWidth;
116 int mNextAppTransitionStartHeight;
117 boolean mAppTransitionReady = false;
118 boolean mAppTransitionRunning = false;
119 boolean mAppTransitionTimeout = false;
120
121 final int mConfigShortAnimTime;
Craig Mautner321bdf52012-12-18 09:53:24 -0800122 private final Interpolator mDecelerateInterpolator;
123 private final Interpolator mThumbnailFadeoutInterpolator;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800124
125 AppTransition(Context context, Handler h) {
126 mContext = context;
127 mH = h;
128 mConfigShortAnimTime = context.getResources().getInteger(
129 com.android.internal.R.integer.config_shortAnimTime);
Craig Mautner321bdf52012-12-18 09:53:24 -0800130 mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
131 com.android.internal.R.interpolator.decelerate_cubic);
132 mThumbnailFadeoutInterpolator = new Interpolator() {
133 @Override
134 public float getInterpolation(float input) {
135 // Linear response for first fraction, then complete after that.
136 if (input < RECENTS_THUMBNAIL_FADEOUT_FRACTION) {
137 return input / RECENTS_THUMBNAIL_FADEOUT_FRACTION;
138 }
139 return 1.0f;
140 }
141 };
Craig Mautner164d4bb2012-11-26 13:51:23 -0800142 }
143
144 boolean isTransitionSet() {
145 return mNextAppTransition != TRANSIT_UNSET;
146 }
147
148 boolean isTransitionNone() {
149 return mNextAppTransition == TRANSIT_NONE;
150 }
151
152 boolean isTransitionEqual(int transit) {
153 return mNextAppTransition == transit;
154 }
155
156 int getAppTransition() {
Craig Mautner321bdf52012-12-18 09:53:24 -0800157 return mNextAppTransition;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800158 }
159
160 void setAppTransition(int transit) {
161 mNextAppTransition = transit;
162 }
163
164 boolean isReady() {
165 return mAppTransitionReady;
166 }
167
Craig Mautnerae446592012-12-06 19:05:05 -0800168 void setReady() {
169 mAppTransitionReady = true;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800170 }
171
172 boolean isRunning() {
173 return mAppTransitionRunning;
174 }
175
176 void setRunning(boolean running) {
177 mAppTransitionRunning = running;
178 }
179
180 boolean isTimeout() {
181 return mAppTransitionTimeout;
182 }
183
184 void setTimeout(boolean timeout) {
185 mAppTransitionTimeout = timeout;
186 }
187
188 Bitmap getNextAppTransitionThumbnail() {
189 return mNextAppTransitionThumbnail;
190 }
191
192 void getStartingPoint(Point outPoint) {
193 outPoint.x = mNextAppTransitionStartX;
194 outPoint.y = mNextAppTransitionStartY;
195 }
196
197 int getType() {
198 return mNextAppTransitionType;
199 }
200
201 void prepare() {
202 mAppTransitionReady = false;
203 mAppTransitionTimeout = false;
204 }
205
206 void goodToGo() {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800207 mNextAppTransition = TRANSIT_UNSET;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800208 mAppTransitionReady = false;
209 mAppTransitionRunning = true;
210 mAppTransitionTimeout = false;
211 }
212
213 void clear() {
214 mNextAppTransitionType = ActivityOptions.ANIM_NONE;
215 mNextAppTransitionPackage = null;
216 mNextAppTransitionThumbnail = null;
217 }
218
219 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
220 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
221 + (lp != null ? lp.packageName : null)
222 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
223 if (lp != null && lp.windowAnimations != 0) {
224 // If this is a system resource, don't try to load it from the
225 // application resources. It is nice to avoid loading application
226 // resources if we can.
227 String packageName = lp.packageName != null ? lp.packageName : "android";
228 int resId = lp.windowAnimations;
229 if ((resId&0xFF000000) == 0x01000000) {
230 packageName = "android";
231 }
232 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
233 + packageName);
234 return AttributeCache.instance().get(packageName, resId,
235 com.android.internal.R.styleable.WindowAnimation);
236 }
237 return null;
238 }
239
240 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
241 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
242 + packageName + " resId=0x" + Integer.toHexString(resId));
243 if (packageName != null) {
244 if ((resId&0xFF000000) == 0x01000000) {
245 packageName = "android";
246 }
247 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
248 + packageName);
249 return AttributeCache.instance().get(packageName, resId,
250 com.android.internal.R.styleable.WindowAnimation);
251 }
252 return null;
253 }
254
255 Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
256 int anim = 0;
257 Context context = mContext;
258 if (animAttr >= 0) {
259 AttributeCache.Entry ent = getCachedAnimations(lp);
260 if (ent != null) {
261 context = ent.context;
262 anim = ent.array.getResourceId(animAttr, 0);
263 }
264 }
265 if (anim != 0) {
266 return AnimationUtils.loadAnimation(context, anim);
267 }
268 return null;
269 }
270
271 private Animation loadAnimation(String packageName, int resId) {
272 int anim = 0;
273 Context context = mContext;
274 if (resId >= 0) {
275 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
276 if (ent != null) {
277 context = ent.context;
278 anim = resId;
279 }
280 }
281 if (anim != 0) {
282 return AnimationUtils.loadAnimation(context, anim);
283 }
284 return null;
285 }
286
Craig Mautner164d4bb2012-11-26 13:51:23 -0800287 /**
288 * Compute the pivot point for an animation that is scaling from a small
289 * rect on screen to a larger rect. The pivot point varies depending on
290 * the distance between the inner and outer edges on both sides. This
291 * function computes the pivot point for one dimension.
292 * @param startPos Offset from left/top edge of outer rectangle to
293 * left/top edge of inner rectangle.
294 * @param finalScale The scaling factor between the size of the outer
295 * and inner rectangles.
296 */
297 private static float computePivot(int startPos, float finalScale) {
298 final float denom = finalScale-1;
299 if (Math.abs(denom) < .0001f) {
300 return startPos;
301 }
302 return -startPos / denom;
303 }
304
305 private Animation createScaleUpAnimationLocked(int transit, boolean enter,
306 int appWidth, int appHeight) {
307 Animation a = null;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800308 if (enter) {
309 // Entering app zooms out from the center of the initial rect.
310 float scaleW = mNextAppTransitionStartWidth / (float) appWidth;
311 float scaleH = mNextAppTransitionStartHeight / (float) appHeight;
312 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
313 computePivot(mNextAppTransitionStartX, scaleW),
314 computePivot(mNextAppTransitionStartY, scaleH));
Craig Mautner321bdf52012-12-18 09:53:24 -0800315 scale.setInterpolator(mDecelerateInterpolator);
316
Craig Mautner164d4bb2012-11-26 13:51:23 -0800317 Animation alpha = new AlphaAnimation(0, 1);
Craig Mautner321bdf52012-12-18 09:53:24 -0800318 alpha.setInterpolator(mThumbnailFadeoutInterpolator);
319
320 AnimationSet set = new AnimationSet(false);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800321 set.addAnimation(scale);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800322 set.addAnimation(alpha);
323 set.setDetachWallpaper(true);
324 a = set;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800325 } else if (transit == TRANSIT_WALLPAPER_INTRA_OPEN ||
326 transit == TRANSIT_WALLPAPER_INTRA_CLOSE) {
Craig Mautner321bdf52012-12-18 09:53:24 -0800327 // If we are on top of the wallpaper, we need an animation that
328 // correctly handles the wallpaper staying static behind all of
329 // the animated elements. To do this, will just have the existing
330 // element fade out.
331 a = new AlphaAnimation(1, 0);
332 a.setDetachWallpaper(true);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800333 } else {
Craig Mautner321bdf52012-12-18 09:53:24 -0800334 // For normal animations, the exiting element just holds in place.
335 a = new AlphaAnimation(1, 1);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800336 }
Craig Mautner321bdf52012-12-18 09:53:24 -0800337
338 // Pick the desired duration. If this is an inter-activity transition,
339 // it is the standard duration for that. Otherwise we use the longer
340 // task transition duration.
341 final long duration;
342 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800343 case TRANSIT_ACTIVITY_OPEN:
344 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner321bdf52012-12-18 09:53:24 -0800345 duration = mConfigShortAnimTime;
346 break;
347 default:
348 duration = DEFAULT_APP_TRANSITION_DURATION;
349 break;
350 }
351 a.setDuration(duration);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800352 a.setFillAfter(true);
Craig Mautner321bdf52012-12-18 09:53:24 -0800353 a.setInterpolator(mDecelerateInterpolator);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800354 a.initialize(appWidth, appHeight, appWidth, appHeight);
355 return a;
356 }
357
358 Animation createThumbnailAnimationLocked(int transit, boolean enter, boolean thumb,
359 int appWidth, int appHeight) {
360 Animation a;
361 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
362 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
363 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
364 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800365 if (thumb) {
366 // Animation for zooming thumbnail from its initial size to
367 // filling the screen.
368 if (mNextAppTransitionScaleUp) {
369 float scaleW = appWidth / thumbWidth;
370 float scaleH = appHeight / thumbHeight;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800371 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
372 computePivot(mNextAppTransitionStartX, 1 / scaleW),
373 computePivot(mNextAppTransitionStartY, 1 / scaleH));
Craig Mautner321bdf52012-12-18 09:53:24 -0800374 scale.setInterpolator(mDecelerateInterpolator);
375
Craig Mautner164d4bb2012-11-26 13:51:23 -0800376 Animation alpha = new AlphaAnimation(1, 0);
Craig Mautner321bdf52012-12-18 09:53:24 -0800377 alpha.setInterpolator(mThumbnailFadeoutInterpolator);
378
379 // This AnimationSet uses the Interpolators assigned above.
380 AnimationSet set = new AnimationSet(false);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800381 set.addAnimation(scale);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800382 set.addAnimation(alpha);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800383 a = set;
384 } else {
385 float scaleW = appWidth / thumbWidth;
386 float scaleH = appHeight / thumbHeight;
Craig Mautner321bdf52012-12-18 09:53:24 -0800387 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
Craig Mautner164d4bb2012-11-26 13:51:23 -0800388 computePivot(mNextAppTransitionStartX, 1 / scaleW),
389 computePivot(mNextAppTransitionStartY, 1 / scaleH));
Craig Mautner164d4bb2012-11-26 13:51:23 -0800390 }
391 } else if (enter) {
392 // Entering app zooms out from the center of the thumbnail.
393 if (mNextAppTransitionScaleUp) {
394 float scaleW = thumbWidth / appWidth;
395 float scaleH = thumbHeight / appHeight;
Craig Mautner321bdf52012-12-18 09:53:24 -0800396 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
Craig Mautner164d4bb2012-11-26 13:51:23 -0800397 computePivot(mNextAppTransitionStartX, scaleW),
398 computePivot(mNextAppTransitionStartY, scaleH));
Craig Mautner164d4bb2012-11-26 13:51:23 -0800399 } else {
400 // noop animation
401 a = new AlphaAnimation(1, 1);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800402 }
403 } else {
404 // Exiting app
405 if (mNextAppTransitionScaleUp) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800406 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
Craig Mautner164d4bb2012-11-26 13:51:23 -0800407 // Fade out while bringing up selected activity. This keeps the
408 // current activity from showing through a launching wallpaper
409 // activity.
410 a = new AlphaAnimation(1, 0);
411 } else {
412 // noop animation
413 a = new AlphaAnimation(1, 1);
414 }
Craig Mautner164d4bb2012-11-26 13:51:23 -0800415 } else {
416 float scaleW = thumbWidth / appWidth;
417 float scaleH = thumbHeight / appHeight;
418 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
419 computePivot(mNextAppTransitionStartX, scaleW),
420 computePivot(mNextAppTransitionStartY, scaleH));
Craig Mautner321bdf52012-12-18 09:53:24 -0800421
Craig Mautner164d4bb2012-11-26 13:51:23 -0800422 Animation alpha = new AlphaAnimation(1, 0);
Craig Mautner321bdf52012-12-18 09:53:24 -0800423
424 AnimationSet set = new AnimationSet(true);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800425 set.addAnimation(scale);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800426 set.addAnimation(alpha);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800427 set.setZAdjustment(Animation.ZORDER_TOP);
428 a = set;
429 }
430 }
Craig Mautner321bdf52012-12-18 09:53:24 -0800431
432 // Pick the desired duration. If this is an inter-activity transition,
433 // it is the standard duration for that. Otherwise we use the longer
434 // task transition duration.
435 final long duration;
436 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800437 case TRANSIT_ACTIVITY_OPEN:
438 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner321bdf52012-12-18 09:53:24 -0800439 duration = mConfigShortAnimTime;
440 break;
441 default:
442 duration = DEFAULT_APP_TRANSITION_DURATION;
443 break;
444 }
445 a.setDuration(duration);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800446 a.setFillAfter(true);
Craig Mautner321bdf52012-12-18 09:53:24 -0800447 a.setInterpolator(mDecelerateInterpolator);
Craig Mautner164d4bb2012-11-26 13:51:23 -0800448 a.initialize(appWidth, appHeight, appWidth, appHeight);
449 return a;
450 }
451
452
453 Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
454 int appWidth, int appHeight) {
455 Animation a;
456 if (mNextAppTransitionType == ActivityOptions.ANIM_CUSTOM) {
457 a = loadAnimation(mNextAppTransitionPackage, enter ?
458 mNextAppTransitionEnter : mNextAppTransitionExit);
459 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
460 "applyAnimation:"
461 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
462 + " transit=" + transit + " isEntrance=" + enter
463 + " Callers=" + Debug.getCallers(3));
464 } else if (mNextAppTransitionType == ActivityOptions.ANIM_SCALE_UP) {
465 a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight);
466 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
467 "applyAnimation:"
468 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
469 + " transit=" + transit + " isEntrance=" + enter
470 + " Callers=" + Debug.getCallers(3));
471 } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP ||
472 mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN) {
473 mNextAppTransitionScaleUp =
474 (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP);
475 a = createThumbnailAnimationLocked(transit, enter, false, appWidth, appHeight);
476 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
477 String animName = mNextAppTransitionScaleUp ?
478 "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
479 Slog.v(TAG, "applyAnimation:"
480 + " anim=" + a + " nextAppTransition=" + animName
481 + " transit=" + transit + " isEntrance=" + enter
482 + " Callers=" + Debug.getCallers(3));
483 }
484 } else {
485 int animAttr = 0;
486 switch (transit) {
Craig Mautner4b71aa12012-12-27 17:20:01 -0800487 case TRANSIT_ACTIVITY_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800488 animAttr = enter
489 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
490 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
491 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800492 case TRANSIT_ACTIVITY_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800493 animAttr = enter
494 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
495 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
496 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800497 case TRANSIT_TASK_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800498 animAttr = enter
499 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
500 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
501 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800502 case TRANSIT_TASK_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800503 animAttr = enter
504 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
505 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
506 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800507 case TRANSIT_TASK_TO_FRONT:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800508 animAttr = enter
509 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
510 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
511 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800512 case TRANSIT_TASK_TO_BACK:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800513 animAttr = enter
514 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
515 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
516 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800517 case TRANSIT_WALLPAPER_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800518 animAttr = enter
519 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
520 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
521 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800522 case TRANSIT_WALLPAPER_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800523 animAttr = enter
524 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
525 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
526 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800527 case TRANSIT_WALLPAPER_INTRA_OPEN:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800528 animAttr = enter
529 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
530 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
531 break;
Craig Mautner4b71aa12012-12-27 17:20:01 -0800532 case TRANSIT_WALLPAPER_INTRA_CLOSE:
Craig Mautner164d4bb2012-11-26 13:51:23 -0800533 animAttr = enter
534 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
535 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
536 break;
537 }
538 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
539 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
540 "applyAnimation:"
541 + " anim=" + a
542 + " animAttr=0x" + Integer.toHexString(animAttr)
543 + " transit=" + transit + " isEntrance=" + enter
544 + " Callers=" + Debug.getCallers(3));
545 }
546 return a;
547 }
548
549 void postAnimationCallback() {
550 if (mNextAppTransitionCallback != null) {
551 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, mNextAppTransitionCallback));
552 mNextAppTransitionCallback = null;
553 }
554 }
555
556 void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
557 IRemoteCallback startedCallback) {
558 if (isTransitionSet()) {
559 mNextAppTransitionType = ActivityOptions.ANIM_CUSTOM;
560 mNextAppTransitionPackage = packageName;
561 mNextAppTransitionThumbnail = null;
562 mNextAppTransitionEnter = enterAnim;
563 mNextAppTransitionExit = exitAnim;
564 postAnimationCallback();
565 mNextAppTransitionCallback = startedCallback;
566 } else {
567 postAnimationCallback();
568 }
569 }
570
571 void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
572 int startHeight) {
573 if (isTransitionSet()) {
574 mNextAppTransitionType = ActivityOptions.ANIM_SCALE_UP;
575 mNextAppTransitionPackage = null;
576 mNextAppTransitionThumbnail = null;
577 mNextAppTransitionStartX = startX;
578 mNextAppTransitionStartY = startY;
579 mNextAppTransitionStartWidth = startWidth;
580 mNextAppTransitionStartHeight = startHeight;
581 postAnimationCallback();
582 mNextAppTransitionCallback = null;
583 }
584 }
585
586 void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
587 IRemoteCallback startedCallback, boolean scaleUp) {
588 if (isTransitionSet()) {
589 mNextAppTransitionType = scaleUp ? ActivityOptions.ANIM_THUMBNAIL_SCALE_UP
590 : ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
591 mNextAppTransitionPackage = null;
592 mNextAppTransitionThumbnail = srcThumb;
593 mNextAppTransitionScaleUp = scaleUp;
594 mNextAppTransitionStartX = startX;
595 mNextAppTransitionStartY = startY;
596 postAnimationCallback();
597 mNextAppTransitionCallback = startedCallback;
598 } else {
599 postAnimationCallback();
600 }
601 }
602
603 @Override
604 public String toString() {
605 return "mNextAppTransition=0x" + Integer.toHexString(mNextAppTransition);
606 }
607
Craig Mautner4b71aa12012-12-27 17:20:01 -0800608 /**
609 * Returns the human readable name of a window transition.
610 *
611 * @param transition The window transition.
612 * @return The transition symbolic name.
613 */
614 public static String appTransitionToString(int transition) {
615 switch (transition) {
616 case TRANSIT_UNSET: {
617 return "TRANSIT_UNSET";
618 }
619 case TRANSIT_NONE: {
620 return "TRANSIT_NONE";
621 }
622 case TRANSIT_EXIT_MASK: {
623 return "TRANSIT_EXIT_MASK";
624 }
625 case TRANSIT_ACTIVITY_OPEN: {
626 return "TRANSIT_ACTIVITY_OPEN";
627 }
628 case TRANSIT_ACTIVITY_CLOSE: {
629 return "TRANSIT_ACTIVITY_CLOSE";
630 }
631 case TRANSIT_TASK_OPEN: {
632 return "TRANSIT_TASK_OPEN";
633 }
634 case TRANSIT_TASK_CLOSE: {
635 return "TRANSIT_TASK_CLOSE";
636 }
637 case TRANSIT_TASK_TO_FRONT: {
638 return "TRANSIT_TASK_TO_FRONT";
639 }
640 case TRANSIT_TASK_TO_BACK: {
641 return "TRANSIT_TASK_TO_BACK";
642 }
643 case TRANSIT_WALLPAPER_CLOSE: {
644 return "TRANSIT_WALLPAPER_CLOSE";
645 }
646 case TRANSIT_WALLPAPER_OPEN: {
647 return "TRANSIT_WALLPAPER_OPEN";
648 }
649 case TRANSIT_WALLPAPER_INTRA_OPEN: {
650 return "TRANSIT_WALLPAPER_INTRA_OPEN";
651 }
652 case TRANSIT_WALLPAPER_INTRA_CLOSE: {
653 return "TRANSIT_WALLPAPER_INTRA_CLOSE";
654 }
655 default: {
656 return "<UNKNOWN>";
657 }
658 }
659 }
660
Craig Mautner164d4bb2012-11-26 13:51:23 -0800661 @Override
662 public void dump(PrintWriter pw) {
663 pw.print(" " + this);
664 pw.print(" mAppTransitionReady="); pw.println(mAppTransitionReady);
665 pw.print(" mAppTransitionRunning="); pw.print(mAppTransitionRunning);
666 pw.print(" mAppTransitionTimeout="); pw.println(mAppTransitionTimeout);
667 if (mNextAppTransitionType != ActivityOptions.ANIM_NONE) {
668 pw.print(" mNextAppTransitionType="); pw.println(mNextAppTransitionType);
669 }
670 switch (mNextAppTransitionType) {
671 case ActivityOptions.ANIM_CUSTOM:
672 pw.print(" mNextAppTransitionPackage=");
673 pw.println(mNextAppTransitionPackage);
674 pw.print(" mNextAppTransitionEnter=0x");
675 pw.print(Integer.toHexString(mNextAppTransitionEnter));
676 pw.print(" mNextAppTransitionExit=0x");
677 pw.println(Integer.toHexString(mNextAppTransitionExit));
678 break;
679 case ActivityOptions.ANIM_SCALE_UP:
680 pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
681 pw.print(" mNextAppTransitionStartY=");
682 pw.println(mNextAppTransitionStartY);
683 pw.print(" mNextAppTransitionStartWidth=");
684 pw.print(mNextAppTransitionStartWidth);
685 pw.print(" mNextAppTransitionStartHeight=");
686 pw.println(mNextAppTransitionStartHeight);
687 break;
688 case ActivityOptions.ANIM_THUMBNAIL_SCALE_UP:
689 case ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN:
690 pw.print(" mNextAppTransitionThumbnail=");
691 pw.print(mNextAppTransitionThumbnail);
692 pw.print(" mNextAppTransitionStartX=");
693 pw.print(mNextAppTransitionStartX);
694 pw.print(" mNextAppTransitionStartY=");
695 pw.println(mNextAppTransitionStartY);
696 pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp);
697 break;
698 }
699 if (mNextAppTransitionCallback != null) {
700 pw.print(" mNextAppTransitionCallback=");
701 pw.println(mNextAppTransitionCallback);
702 }
703 }
704}