blob: 92fd68bf1816addf292f764fb5f7afcb4c1057f3 [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;
28import android.view.WindowManagerPolicy;
29import android.view.animation.AlphaAnimation;
30import android.view.animation.Animation;
31import android.view.animation.AnimationSet;
32import android.view.animation.AnimationUtils;
33import android.view.animation.DecelerateInterpolator;
34import android.view.animation.Interpolator;
35import android.view.animation.ScaleAnimation;
36
37import com.android.internal.util.DumpUtils.Dump;
38import com.android.server.AttributeCache;
39import com.android.server.wm.WindowManagerService.H;
40
41import java.io.PrintWriter;
42
43import static android.view.WindowManagerPolicy.TRANSIT_NONE;
44import static android.view.WindowManagerPolicy.TRANSIT_UNSET;
45
46// State management of app transitions. When we are preparing for a
47// transition, mNextAppTransition will be the kind of transition to
48// perform or TRANSIT_NONE if we are not waiting. If we are waiting,
49// mOpeningApps and mClosingApps are the lists of tokens that will be
50// made visible or hidden at the next transition.
51public class AppTransition implements Dump {
52 private static final String TAG = "AppTransition";
53 private static final float THUMBNAIL_ANIMATION_DECELERATE_FACTOR = 1.5f;
54 private static final boolean DEBUG_APP_TRANSITIONS = WindowManagerService.DEBUG_APP_TRANSITIONS;
55 private static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_APP_TRANSITIONS;
56
57 final Context mContext;
58 final Handler mH;
59
60 int mNextAppTransition = TRANSIT_UNSET;
61 int mNextAppTransitionType = ActivityOptions.ANIM_NONE;
62 String mNextAppTransitionPackage;
63 Bitmap mNextAppTransitionThumbnail;
64 // Used for thumbnail transitions. True if we're scaling up, false if scaling down
65 boolean mNextAppTransitionScaleUp;
66 IRemoteCallback mNextAppTransitionCallback;
67 int mNextAppTransitionEnter;
68 int mNextAppTransitionExit;
69 int mNextAppTransitionStartX;
70 int mNextAppTransitionStartY;
71 int mNextAppTransitionStartWidth;
72 int mNextAppTransitionStartHeight;
73 boolean mAppTransitionReady = false;
74 boolean mAppTransitionRunning = false;
75 boolean mAppTransitionTimeout = false;
76
77 final int mConfigShortAnimTime;
78 final Interpolator mInterpolator;
79
80 AppTransition(Context context, Handler h) {
81 mContext = context;
82 mH = h;
83 mConfigShortAnimTime = context.getResources().getInteger(
84 com.android.internal.R.integer.config_shortAnimTime);
85 mInterpolator = AnimationUtils.loadInterpolator(context,
86 com.android.internal.R.interpolator.decelerate_quad);
87 }
88
89 boolean isTransitionSet() {
90 return mNextAppTransition != TRANSIT_UNSET;
91 }
92
93 boolean isTransitionNone() {
94 return mNextAppTransition == TRANSIT_NONE;
95 }
96
97 boolean isTransitionEqual(int transit) {
98 return mNextAppTransition == transit;
99 }
100
101 int getAppTransition() {
102 return mNextAppTransition;
103 }
104
105 void setAppTransition(int transit) {
106 mNextAppTransition = transit;
107 }
108
109 boolean isReady() {
110 return mAppTransitionReady;
111 }
112
Craig Mautnerae446592012-12-06 19:05:05 -0800113 void setReady() {
114 mAppTransitionReady = true;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800115 }
116
117 boolean isRunning() {
118 return mAppTransitionRunning;
119 }
120
121 void setRunning(boolean running) {
122 mAppTransitionRunning = running;
123 }
124
125 boolean isTimeout() {
126 return mAppTransitionTimeout;
127 }
128
129 void setTimeout(boolean timeout) {
130 mAppTransitionTimeout = timeout;
131 }
132
133 Bitmap getNextAppTransitionThumbnail() {
134 return mNextAppTransitionThumbnail;
135 }
136
137 void getStartingPoint(Point outPoint) {
138 outPoint.x = mNextAppTransitionStartX;
139 outPoint.y = mNextAppTransitionStartY;
140 }
141
142 int getType() {
143 return mNextAppTransitionType;
144 }
145
146 void prepare() {
147 mAppTransitionReady = false;
148 mAppTransitionTimeout = false;
149 }
150
151 void goodToGo() {
152 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
153 mAppTransitionReady = false;
154 mAppTransitionRunning = true;
155 mAppTransitionTimeout = false;
156 }
157
158 void clear() {
159 mNextAppTransitionType = ActivityOptions.ANIM_NONE;
160 mNextAppTransitionPackage = null;
161 mNextAppTransitionThumbnail = null;
162 }
163
164 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
165 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
166 + (lp != null ? lp.packageName : null)
167 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
168 if (lp != null && lp.windowAnimations != 0) {
169 // If this is a system resource, don't try to load it from the
170 // application resources. It is nice to avoid loading application
171 // resources if we can.
172 String packageName = lp.packageName != null ? lp.packageName : "android";
173 int resId = lp.windowAnimations;
174 if ((resId&0xFF000000) == 0x01000000) {
175 packageName = "android";
176 }
177 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
178 + packageName);
179 return AttributeCache.instance().get(packageName, resId,
180 com.android.internal.R.styleable.WindowAnimation);
181 }
182 return null;
183 }
184
185 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
186 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
187 + packageName + " resId=0x" + Integer.toHexString(resId));
188 if (packageName != null) {
189 if ((resId&0xFF000000) == 0x01000000) {
190 packageName = "android";
191 }
192 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
193 + packageName);
194 return AttributeCache.instance().get(packageName, resId,
195 com.android.internal.R.styleable.WindowAnimation);
196 }
197 return null;
198 }
199
200 Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) {
201 int anim = 0;
202 Context context = mContext;
203 if (animAttr >= 0) {
204 AttributeCache.Entry ent = getCachedAnimations(lp);
205 if (ent != null) {
206 context = ent.context;
207 anim = ent.array.getResourceId(animAttr, 0);
208 }
209 }
210 if (anim != 0) {
211 return AnimationUtils.loadAnimation(context, anim);
212 }
213 return null;
214 }
215
216 private Animation loadAnimation(String packageName, int resId) {
217 int anim = 0;
218 Context context = mContext;
219 if (resId >= 0) {
220 AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
221 if (ent != null) {
222 context = ent.context;
223 anim = resId;
224 }
225 }
226 if (anim != 0) {
227 return AnimationUtils.loadAnimation(context, anim);
228 }
229 return null;
230 }
231
232 private Animation createExitAnimationLocked(int transit, int duration) {
233 if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN ||
234 transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE) {
235 // If we are on top of the wallpaper, we need an animation that
236 // correctly handles the wallpaper staying static behind all of
237 // the animated elements. To do this, will just have the existing
238 // element fade out.
239 Animation a = new AlphaAnimation(1, 0);
240 a.setDetachWallpaper(true);
241 a.setDuration(duration);
242 return a;
243 }
244 // For normal animations, the exiting element just holds in place.
245 Animation a = new AlphaAnimation(1, 1);
246 a.setDuration(duration);
247 return a;
248 }
249
250 /**
251 * Compute the pivot point for an animation that is scaling from a small
252 * rect on screen to a larger rect. The pivot point varies depending on
253 * the distance between the inner and outer edges on both sides. This
254 * function computes the pivot point for one dimension.
255 * @param startPos Offset from left/top edge of outer rectangle to
256 * left/top edge of inner rectangle.
257 * @param finalScale The scaling factor between the size of the outer
258 * and inner rectangles.
259 */
260 private static float computePivot(int startPos, float finalScale) {
261 final float denom = finalScale-1;
262 if (Math.abs(denom) < .0001f) {
263 return startPos;
264 }
265 return -startPos / denom;
266 }
267
268 private Animation createScaleUpAnimationLocked(int transit, boolean enter,
269 int appWidth, int appHeight) {
270 Animation a = null;
271 // Pick the desired duration. If this is an inter-activity transition,
272 // it is the standard duration for that. Otherwise we use the longer
273 // task transition duration.
274 int duration;
275 switch (transit) {
276 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
277 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
278 duration = mContext.getResources().getInteger(
279 com.android.internal.R.integer.config_shortAnimTime);
280 break;
281 default:
282 duration = 300;
283 break;
284 }
285 if (enter) {
286 // Entering app zooms out from the center of the initial rect.
287 float scaleW = mNextAppTransitionStartWidth / (float) appWidth;
288 float scaleH = mNextAppTransitionStartHeight / (float) appHeight;
289 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
290 computePivot(mNextAppTransitionStartX, scaleW),
291 computePivot(mNextAppTransitionStartY, scaleH));
292 scale.setDuration(duration);
293 AnimationSet set = new AnimationSet(true);
294 Animation alpha = new AlphaAnimation(0, 1);
295 scale.setDuration(duration);
296 set.addAnimation(scale);
297 alpha.setDuration(duration);
298 set.addAnimation(alpha);
299 set.setDetachWallpaper(true);
300 a = set;
301 } else {
302 a = createExitAnimationLocked(transit, duration);
303 }
304 a.setFillAfter(true);
305 final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
306 com.android.internal.R.interpolator.decelerate_cubic);
307 a.setInterpolator(interpolator);
308 a.initialize(appWidth, appHeight, appWidth, appHeight);
309 return a;
310 }
311
312 Animation createThumbnailAnimationLocked(int transit, boolean enter, boolean thumb,
313 int appWidth, int appHeight) {
314 Animation a;
315 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
316 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
317 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
318 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
319 // Pick the desired duration. If this is an inter-activity transition,
320 // it is the standard duration for that. Otherwise we use the longer
321 // task transition duration.
322 int duration;
323 switch (transit) {
324 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
325 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
326 duration = mConfigShortAnimTime;
327 break;
328 default:
329 duration = 250;
330 break;
331 }
332 if (thumb) {
333 // Animation for zooming thumbnail from its initial size to
334 // filling the screen.
335 if (mNextAppTransitionScaleUp) {
336 float scaleW = appWidth / thumbWidth;
337 float scaleH = appHeight / thumbHeight;
338
339 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
340 computePivot(mNextAppTransitionStartX, 1 / scaleW),
341 computePivot(mNextAppTransitionStartY, 1 / scaleH));
342 AnimationSet set = new AnimationSet(true);
343 Animation alpha = new AlphaAnimation(1, 0);
344 scale.setDuration(duration);
345 scale.setInterpolator(
346 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
347 set.addAnimation(scale);
348 alpha.setDuration(duration);
349 set.addAnimation(alpha);
350 set.setFillBefore(true);
351 a = set;
352 } else {
353 float scaleW = appWidth / thumbWidth;
354 float scaleH = appHeight / thumbHeight;
355
356 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
357 computePivot(mNextAppTransitionStartX, 1 / scaleW),
358 computePivot(mNextAppTransitionStartY, 1 / scaleH));
359 AnimationSet set = new AnimationSet(true);
360 Animation alpha = new AlphaAnimation(1, 1);
361 scale.setDuration(duration);
362 scale.setInterpolator(
363 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
364 set.addAnimation(scale);
365 alpha.setDuration(duration);
366 set.addAnimation(alpha);
367 set.setFillBefore(true);
368
369 a = set;
370 }
371 } else if (enter) {
372 // Entering app zooms out from the center of the thumbnail.
373 if (mNextAppTransitionScaleUp) {
374 float scaleW = thumbWidth / appWidth;
375 float scaleH = thumbHeight / appHeight;
376 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
377 computePivot(mNextAppTransitionStartX, scaleW),
378 computePivot(mNextAppTransitionStartY, scaleH));
379 scale.setDuration(duration);
380 scale.setInterpolator(
381 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
382 scale.setFillBefore(true);
383 a = scale;
384 } else {
385 // noop animation
386 a = new AlphaAnimation(1, 1);
387 a.setDuration(duration);
388 }
389 } else {
390 // Exiting app
391 if (mNextAppTransitionScaleUp) {
392 if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN) {
393 // Fade out while bringing up selected activity. This keeps the
394 // current activity from showing through a launching wallpaper
395 // activity.
396 a = new AlphaAnimation(1, 0);
397 } else {
398 // noop animation
399 a = new AlphaAnimation(1, 1);
400 }
401 a.setDuration(duration);
402 } else {
403 float scaleW = thumbWidth / appWidth;
404 float scaleH = thumbHeight / appHeight;
405 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
406 computePivot(mNextAppTransitionStartX, scaleW),
407 computePivot(mNextAppTransitionStartY, scaleH));
408 scale.setDuration(duration);
409 scale.setInterpolator(
410 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
411 scale.setFillBefore(true);
412 AnimationSet set = new AnimationSet(true);
413 Animation alpha = new AlphaAnimation(1, 0);
414 set.addAnimation(scale);
415 alpha.setDuration(duration);
416 alpha.setInterpolator(new DecelerateInterpolator(
417 THUMBNAIL_ANIMATION_DECELERATE_FACTOR));
418 set.addAnimation(alpha);
419 set.setFillBefore(true);
420 set.setZAdjustment(Animation.ZORDER_TOP);
421 a = set;
422 }
423 }
424 a.setFillAfter(true);
425 a.setInterpolator(mInterpolator);
426 a.initialize(appWidth, appHeight, appWidth, appHeight);
427 return a;
428 }
429
430
431 Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
432 int appWidth, int appHeight) {
433 Animation a;
434 if (mNextAppTransitionType == ActivityOptions.ANIM_CUSTOM) {
435 a = loadAnimation(mNextAppTransitionPackage, enter ?
436 mNextAppTransitionEnter : mNextAppTransitionExit);
437 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
438 "applyAnimation:"
439 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
440 + " transit=" + transit + " isEntrance=" + enter
441 + " Callers=" + Debug.getCallers(3));
442 } else if (mNextAppTransitionType == ActivityOptions.ANIM_SCALE_UP) {
443 a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight);
444 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
445 "applyAnimation:"
446 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
447 + " transit=" + transit + " isEntrance=" + enter
448 + " Callers=" + Debug.getCallers(3));
449 } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP ||
450 mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN) {
451 mNextAppTransitionScaleUp =
452 (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP);
453 a = createThumbnailAnimationLocked(transit, enter, false, appWidth, appHeight);
454 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
455 String animName = mNextAppTransitionScaleUp ?
456 "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
457 Slog.v(TAG, "applyAnimation:"
458 + " anim=" + a + " nextAppTransition=" + animName
459 + " transit=" + transit + " isEntrance=" + enter
460 + " Callers=" + Debug.getCallers(3));
461 }
462 } else {
463 int animAttr = 0;
464 switch (transit) {
465 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
466 animAttr = enter
467 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation
468 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
469 break;
470 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
471 animAttr = enter
472 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation
473 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
474 break;
475 case WindowManagerPolicy.TRANSIT_TASK_OPEN:
476 animAttr = enter
477 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation
478 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
479 break;
480 case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
481 animAttr = enter
482 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation
483 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
484 break;
485 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
486 animAttr = enter
487 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation
488 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
489 break;
490 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
491 animAttr = enter
492 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
493 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
494 break;
495 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN:
496 animAttr = enter
497 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
498 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
499 break;
500 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE:
501 animAttr = enter
502 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
503 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
504 break;
505 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN:
506 animAttr = enter
507 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
508 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
509 break;
510 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE:
511 animAttr = enter
512 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
513 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
514 break;
515 }
516 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null;
517 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
518 "applyAnimation:"
519 + " anim=" + a
520 + " animAttr=0x" + Integer.toHexString(animAttr)
521 + " transit=" + transit + " isEntrance=" + enter
522 + " Callers=" + Debug.getCallers(3));
523 }
524 return a;
525 }
526
527 void postAnimationCallback() {
528 if (mNextAppTransitionCallback != null) {
529 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, mNextAppTransitionCallback));
530 mNextAppTransitionCallback = null;
531 }
532 }
533
534 void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
535 IRemoteCallback startedCallback) {
536 if (isTransitionSet()) {
537 mNextAppTransitionType = ActivityOptions.ANIM_CUSTOM;
538 mNextAppTransitionPackage = packageName;
539 mNextAppTransitionThumbnail = null;
540 mNextAppTransitionEnter = enterAnim;
541 mNextAppTransitionExit = exitAnim;
542 postAnimationCallback();
543 mNextAppTransitionCallback = startedCallback;
544 } else {
545 postAnimationCallback();
546 }
547 }
548
549 void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
550 int startHeight) {
551 if (isTransitionSet()) {
552 mNextAppTransitionType = ActivityOptions.ANIM_SCALE_UP;
553 mNextAppTransitionPackage = null;
554 mNextAppTransitionThumbnail = null;
555 mNextAppTransitionStartX = startX;
556 mNextAppTransitionStartY = startY;
557 mNextAppTransitionStartWidth = startWidth;
558 mNextAppTransitionStartHeight = startHeight;
559 postAnimationCallback();
560 mNextAppTransitionCallback = null;
561 }
562 }
563
564 void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
565 IRemoteCallback startedCallback, boolean scaleUp) {
566 if (isTransitionSet()) {
567 mNextAppTransitionType = scaleUp ? ActivityOptions.ANIM_THUMBNAIL_SCALE_UP
568 : ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
569 mNextAppTransitionPackage = null;
570 mNextAppTransitionThumbnail = srcThumb;
571 mNextAppTransitionScaleUp = scaleUp;
572 mNextAppTransitionStartX = startX;
573 mNextAppTransitionStartY = startY;
574 postAnimationCallback();
575 mNextAppTransitionCallback = startedCallback;
576 } else {
577 postAnimationCallback();
578 }
579 }
580
581 @Override
582 public String toString() {
583 return "mNextAppTransition=0x" + Integer.toHexString(mNextAppTransition);
584 }
585
586 @Override
587 public void dump(PrintWriter pw) {
588 pw.print(" " + this);
589 pw.print(" mAppTransitionReady="); pw.println(mAppTransitionReady);
590 pw.print(" mAppTransitionRunning="); pw.print(mAppTransitionRunning);
591 pw.print(" mAppTransitionTimeout="); pw.println(mAppTransitionTimeout);
592 if (mNextAppTransitionType != ActivityOptions.ANIM_NONE) {
593 pw.print(" mNextAppTransitionType="); pw.println(mNextAppTransitionType);
594 }
595 switch (mNextAppTransitionType) {
596 case ActivityOptions.ANIM_CUSTOM:
597 pw.print(" mNextAppTransitionPackage=");
598 pw.println(mNextAppTransitionPackage);
599 pw.print(" mNextAppTransitionEnter=0x");
600 pw.print(Integer.toHexString(mNextAppTransitionEnter));
601 pw.print(" mNextAppTransitionExit=0x");
602 pw.println(Integer.toHexString(mNextAppTransitionExit));
603 break;
604 case ActivityOptions.ANIM_SCALE_UP:
605 pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
606 pw.print(" mNextAppTransitionStartY=");
607 pw.println(mNextAppTransitionStartY);
608 pw.print(" mNextAppTransitionStartWidth=");
609 pw.print(mNextAppTransitionStartWidth);
610 pw.print(" mNextAppTransitionStartHeight=");
611 pw.println(mNextAppTransitionStartHeight);
612 break;
613 case ActivityOptions.ANIM_THUMBNAIL_SCALE_UP:
614 case ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN:
615 pw.print(" mNextAppTransitionThumbnail=");
616 pw.print(mNextAppTransitionThumbnail);
617 pw.print(" mNextAppTransitionStartX=");
618 pw.print(mNextAppTransitionStartX);
619 pw.print(" mNextAppTransitionStartY=");
620 pw.println(mNextAppTransitionStartY);
621 pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp);
622 break;
623 }
624 if (mNextAppTransitionCallback != null) {
625 pw.print(" mNextAppTransitionCallback=");
626 pw.println(mNextAppTransitionCallback);
627 }
628 }
629}