ScreenRotationAnimation.java revision 4dcece8e509027cd28e20b1f9f14d2c0446d84c0
1/* 2 * Copyright (C) 2010 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 java.io.PrintWriter; 20 21import android.content.Context; 22import android.graphics.Matrix; 23import android.graphics.PixelFormat; 24import android.graphics.Rect; 25import android.util.Slog; 26import android.view.Surface; 27import android.view.SurfaceSession; 28import android.view.animation.Animation; 29import android.view.animation.AnimationUtils; 30import android.view.animation.Transformation; 31 32class ScreenRotationAnimation { 33 static final String TAG = "ScreenRotationAnimation"; 34 static final boolean DEBUG_STATE = false; 35 static final boolean DEBUG_TRANSFORMS = false; 36 37 static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200; 38 39 final Context mContext; 40 Surface mSurface; 41 BlackFrame mBlackFrame; 42 int mWidth, mHeight; 43 44 int mSnapshotRotation; 45 int mSnapshotDeltaRotation; 46 int mOriginalRotation; 47 int mOriginalWidth, mOriginalHeight; 48 int mCurRotation; 49 50 // For all animations, "exit" is for the UI elements that are going 51 // away (that is the snapshot of the old screen), and "enter" is for 52 // the new UI elements that are appearing (that is the active windows 53 // in their final orientation). 54 55 // The starting animation for the exiting and entering elements. This 56 // animation applies a transformation while the rotation is in progress. 57 // It is started immediately, before the new entering UI is ready. 58 Animation mStartExitAnimation; 59 final Transformation mStartExitTransformation = new Transformation(); 60 Animation mStartEnterAnimation; 61 final Transformation mStartEnterTransformation = new Transformation(); 62 63 // The finishing animation for the exiting and entering elements. This 64 // animation needs to undo the transformation of the starting animation. 65 // It starts running once the new rotation UI elements are ready to be 66 // displayed. 67 Animation mFinishExitAnimation; 68 final Transformation mFinishExitTransformation = new Transformation(); 69 Animation mFinishEnterAnimation; 70 final Transformation mFinishEnterTransformation = new Transformation(); 71 72 // The current active animation to move from the old to the new rotated 73 // state. Which animation is run here will depend on the old and new 74 // rotations. 75 Animation mRotateExitAnimation; 76 final Transformation mRotateExitTransformation = new Transformation(); 77 Animation mRotateEnterAnimation; 78 final Transformation mRotateEnterTransformation = new Transformation(); 79 80 // A previously running rotate animation. This will be used if we need 81 // to switch to a new rotation before finishing the previous one. 82 Animation mLastRotateExitAnimation; 83 final Transformation mLastRotateExitTransformation = new Transformation(); 84 Animation mLastRotateEnterAnimation; 85 final Transformation mLastRotateEnterTransformation = new Transformation(); 86 87 // Complete transformations being applied. 88 final Transformation mExitTransformation = new Transformation(); 89 final Transformation mEnterTransformation = new Transformation(); 90 91 boolean mStarted; 92 boolean mAnimRunning; 93 boolean mFinishAnimReady; 94 long mFinishAnimStartTime; 95 96 final Matrix mSnapshotInitialMatrix = new Matrix(); 97 final Matrix mSnapshotFinalMatrix = new Matrix(); 98 final Matrix mTmpMatrix = new Matrix(); 99 final float[] mTmpFloats = new float[9]; 100 101 public void printTo(String prefix, PrintWriter pw) { 102 pw.print(prefix); pw.print("mSurface="); pw.print(mSurface); 103 pw.print(" mWidth="); pw.print(mWidth); 104 pw.print(" mHeight="); pw.println(mHeight); 105 pw.print(prefix); pw.print("mBlackFrame="); pw.println(mBlackFrame); 106 pw.print(prefix); pw.print("mSnapshotRotation="); pw.print(mSnapshotRotation); 107 pw.print(" mSnapshotDeltaRotation="); pw.print(mSnapshotDeltaRotation); 108 pw.print(" mCurRotation="); pw.println(mCurRotation); 109 pw.print(prefix); pw.print("mOriginalRotation="); pw.print(mOriginalRotation); 110 pw.print(" mOriginalWidth="); pw.print(mOriginalWidth); 111 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight); 112 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted); 113 pw.print(" mAnimRunning="); pw.print(mAnimRunning); 114 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady); 115 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime); 116 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation); 117 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println(); 118 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation); 119 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println(); 120 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation); 121 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println(); 122 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation); 123 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println(); 124 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation); 125 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println(); 126 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation); 127 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println(); 128 pw.print(prefix); pw.print("mLastRotateExitAnimation="); 129 pw.print(mLastRotateExitAnimation); 130 pw.print(" "); mLastRotateExitTransformation.printShortString(pw); pw.println(); 131 pw.print(prefix); pw.print("mExitTransformation="); 132 mExitTransformation.printShortString(pw); pw.println(); 133 pw.print(prefix); pw.print("mEnterTransformation="); 134 mEnterTransformation.printShortString(pw); pw.println(); 135 pw.print(prefix); pw.print("mSnapshotInitialMatrix="); 136 mSnapshotInitialMatrix.printShortString(pw); 137 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw); 138 pw.println(); 139 } 140 141 public ScreenRotationAnimation(Context context, SurfaceSession session, 142 boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) { 143 mContext = context; 144 145 // Screenshot does NOT include rotation! 146 mSnapshotRotation = 0; 147 if (originalRotation == Surface.ROTATION_90 148 || originalRotation == Surface.ROTATION_270) { 149 mWidth = originalHeight; 150 mHeight = originalWidth; 151 } else { 152 mWidth = originalWidth; 153 mHeight = originalHeight; 154 } 155 156 mOriginalRotation = originalRotation; 157 mOriginalWidth = originalWidth; 158 mOriginalHeight = originalHeight; 159 160 if (!inTransaction) { 161 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, 162 ">>> OPEN TRANSACTION ScreenRotationAnimation"); 163 Surface.openTransaction(); 164 } 165 166 try { 167 try { 168 mSurface = new Surface(session, 0, "FreezeSurface", 169 -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN); 170 if (mSurface == null || !mSurface.isValid()) { 171 // Screenshot failed, punt. 172 mSurface = null; 173 return; 174 } 175 mSurface.setLayer(FREEZE_LAYER + 1); 176 mSurface.show(); 177 } catch (Surface.OutOfResourcesException e) { 178 Slog.w(TAG, "Unable to allocate freeze surface", e); 179 } 180 181 if (WindowManagerService.SHOW_TRANSACTIONS || 182 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG, 183 " FREEZE " + mSurface + ": CREATE"); 184 185 setRotation(originalRotation); 186 } finally { 187 if (!inTransaction) { 188 Surface.closeTransaction(); 189 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, 190 "<<< CLOSE TRANSACTION ScreenRotationAnimation"); 191 } 192 } 193 } 194 195 boolean hasScreenshot() { 196 return mSurface != null; 197 } 198 199 static int deltaRotation(int oldRotation, int newRotation) { 200 int delta = newRotation - oldRotation; 201 if (delta < 0) delta += 4; 202 return delta; 203 } 204 205 void setSnapshotTransform(Matrix matrix, float alpha) { 206 if (mSurface != null) { 207 matrix.getValues(mTmpFloats); 208 mSurface.setPosition(mTmpFloats[Matrix.MTRANS_X], 209 mTmpFloats[Matrix.MTRANS_Y]); 210 mSurface.setMatrix( 211 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], 212 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); 213 mSurface.setAlpha(alpha); 214 if (DEBUG_TRANSFORMS) { 215 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight }; 216 float[] dstPnts = new float[4]; 217 matrix.mapPoints(dstPnts, srcPnts); 218 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1] 219 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")"); 220 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1] 221 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")"); 222 } 223 } 224 } 225 226 public static void createRotationMatrix(int rotation, int width, int height, 227 Matrix outMatrix) { 228 switch (rotation) { 229 case Surface.ROTATION_0: 230 outMatrix.reset(); 231 break; 232 case Surface.ROTATION_90: 233 outMatrix.setRotate(90, 0, 0); 234 outMatrix.postTranslate(height, 0); 235 break; 236 case Surface.ROTATION_180: 237 outMatrix.setRotate(180, 0, 0); 238 outMatrix.postTranslate(width, height); 239 break; 240 case Surface.ROTATION_270: 241 outMatrix.setRotate(270, 0, 0); 242 outMatrix.postTranslate(0, width); 243 break; 244 } 245 } 246 247 // Must be called while in a transaction. 248 private void setRotation(int rotation) { 249 mCurRotation = rotation; 250 251 // Compute the transformation matrix that must be applied 252 // to the snapshot to make it stay in the same original position 253 // with the current screen rotation. 254 int delta = deltaRotation(rotation, mSnapshotRotation); 255 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix); 256 257 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta); 258 setSnapshotTransform(mSnapshotInitialMatrix, 1.0f); 259 } 260 261 // Must be called while in a transaction. 262 public boolean setRotation(int rotation, SurfaceSession session, 263 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) { 264 setRotation(rotation); 265 return startAnimation(session, maxAnimationDuration, animationScale, 266 finalWidth, finalHeight, false); 267 } 268 269 /** 270 * Returns true if animating. 271 */ 272 private boolean startAnimation(SurfaceSession session, long maxAnimationDuration, 273 float animationScale, int finalWidth, int finalHeight, boolean dismissing) { 274 if (mSurface == null) { 275 // Can't do animation. 276 return false; 277 } 278 if (mStarted) { 279 return true; 280 } 281 282 mStarted = true; 283 284 boolean firstStart = false; 285 286 // Figure out how the screen has moved from the original rotation. 287 int delta = deltaRotation(mCurRotation, mOriginalRotation); 288 289 if (mFinishExitAnimation == null && (!dismissing || delta != Surface.ROTATION_0)) { 290 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations"); 291 firstStart = true; 292 mStartExitAnimation = AnimationUtils.loadAnimation(mContext, 293 com.android.internal.R.anim.screen_rotate_start_exit); 294 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext, 295 com.android.internal.R.anim.screen_rotate_start_enter); 296 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext, 297 com.android.internal.R.anim.screen_rotate_finish_exit); 298 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext, 299 com.android.internal.R.anim.screen_rotate_finish_enter); 300 } 301 302 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth=" 303 + finalWidth + " finalHeight=" + finalHeight 304 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight); 305 306 switch (delta) { 307 case Surface.ROTATION_0: 308 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, 309 com.android.internal.R.anim.screen_rotate_0_exit); 310 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, 311 com.android.internal.R.anim.screen_rotate_0_enter); 312 break; 313 case Surface.ROTATION_90: 314 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, 315 com.android.internal.R.anim.screen_rotate_plus_90_exit); 316 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, 317 com.android.internal.R.anim.screen_rotate_plus_90_enter); 318 break; 319 case Surface.ROTATION_180: 320 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, 321 com.android.internal.R.anim.screen_rotate_180_exit); 322 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, 323 com.android.internal.R.anim.screen_rotate_180_enter); 324 break; 325 case Surface.ROTATION_270: 326 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, 327 com.android.internal.R.anim.screen_rotate_minus_90_exit); 328 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, 329 com.android.internal.R.anim.screen_rotate_minus_90_enter); 330 break; 331 } 332 333 // Initialize the animations. This is a hack, redefining what "parent" 334 // means to allow supplying the last and next size. In this definition 335 // "%p" is the original (let's call it "previous") size, and "%" is the 336 // screen's current/new size. 337 if (firstStart) { 338 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations"); 339 mStartEnterAnimation.initialize(finalWidth, finalHeight, 340 mOriginalWidth, mOriginalHeight); 341 mStartExitAnimation.initialize(finalWidth, finalHeight, 342 mOriginalWidth, mOriginalHeight); 343 mFinishEnterAnimation.initialize(finalWidth, finalHeight, 344 mOriginalWidth, mOriginalHeight); 345 mFinishExitAnimation.initialize(finalWidth, finalHeight, 346 mOriginalWidth, mOriginalHeight); 347 } 348 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); 349 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); 350 mAnimRunning = false; 351 mFinishAnimReady = false; 352 mFinishAnimStartTime = -1; 353 354 if (firstStart) { 355 mStartExitAnimation.restrictDuration(maxAnimationDuration); 356 mStartExitAnimation.scaleCurrentDuration(animationScale); 357 mStartEnterAnimation.restrictDuration(maxAnimationDuration); 358 mStartEnterAnimation.scaleCurrentDuration(animationScale); 359 mFinishExitAnimation.restrictDuration(maxAnimationDuration); 360 mFinishExitAnimation.scaleCurrentDuration(animationScale); 361 mFinishEnterAnimation.restrictDuration(maxAnimationDuration); 362 mFinishEnterAnimation.scaleCurrentDuration(animationScale); 363 } 364 mRotateExitAnimation.restrictDuration(maxAnimationDuration); 365 mRotateExitAnimation.scaleCurrentDuration(animationScale); 366 mRotateEnterAnimation.restrictDuration(maxAnimationDuration); 367 mRotateEnterAnimation.scaleCurrentDuration(animationScale); 368 369 if (mBlackFrame == null) { 370 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( 371 WindowManagerService.TAG, 372 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation"); 373 Surface.openTransaction(); 374 375 try { 376 Rect outer = new Rect(-finalWidth*1, -finalHeight*1, finalWidth*2, finalHeight*2); 377 Rect inner = new Rect(0, 0, finalWidth, finalHeight); 378 mBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER); 379 } catch (Surface.OutOfResourcesException e) { 380 Slog.w(TAG, "Unable to allocate black surface", e); 381 } finally { 382 Surface.closeTransaction(); 383 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( 384 WindowManagerService.TAG, 385 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation"); 386 } 387 } 388 389 return true; 390 } 391 392 /** 393 * Returns true if animating. 394 */ 395 public boolean dismiss(SurfaceSession session, long maxAnimationDuration, 396 float animationScale, int finalWidth, int finalHeight) { 397 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!"); 398 if (mSurface == null) { 399 // Can't do animation. 400 return false; 401 } 402 if (!mStarted) { 403 startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight, 404 true); 405 } 406 if (!mStarted) { 407 return false; 408 } 409 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true"); 410 mFinishAnimReady = true; 411 return true; 412 } 413 414 public void kill() { 415 if (DEBUG_STATE) Slog.v(TAG, "Kill!"); 416 if (mSurface != null) { 417 if (WindowManagerService.SHOW_TRANSACTIONS || 418 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG, 419 " FREEZE " + mSurface + ": DESTROY"); 420 mSurface.destroy(); 421 mSurface = null; 422 } 423 if (mBlackFrame != null) { 424 mBlackFrame.kill(); 425 mBlackFrame = null; 426 } 427 if (mStartExitAnimation != null) { 428 mStartExitAnimation.cancel(); 429 mStartExitAnimation = null; 430 } 431 if (mStartEnterAnimation != null) { 432 mStartEnterAnimation.cancel(); 433 mStartEnterAnimation = null; 434 } 435 if (mFinishExitAnimation != null) { 436 mFinishExitAnimation.cancel(); 437 mFinishExitAnimation = null; 438 } 439 if (mStartEnterAnimation != null) { 440 mStartEnterAnimation.cancel(); 441 mStartEnterAnimation = null; 442 } 443 if (mRotateExitAnimation != null) { 444 mRotateExitAnimation.cancel(); 445 mRotateExitAnimation = null; 446 } 447 if (mRotateEnterAnimation != null) { 448 mRotateEnterAnimation.cancel(); 449 mRotateEnterAnimation = null; 450 } 451 } 452 453 public boolean isAnimating() { 454 return mStartEnterAnimation != null || mStartExitAnimation != null 455 && mFinishEnterAnimation != null || mFinishExitAnimation != null 456 && mRotateEnterAnimation != null || mRotateExitAnimation != null; 457 } 458 459 public boolean stepAnimation(long now) { 460 if (!isAnimating()) { 461 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running"); 462 return false; 463 } 464 465 if (!mAnimRunning) { 466 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate"); 467 if (mStartEnterAnimation != null) { 468 mStartEnterAnimation.setStartTime(now); 469 } 470 if (mStartExitAnimation != null) { 471 mStartExitAnimation.setStartTime(now); 472 } 473 if (mFinishEnterAnimation != null) { 474 mFinishEnterAnimation.setStartTime(0); 475 } 476 if (mFinishExitAnimation != null) { 477 mFinishExitAnimation.setStartTime(0); 478 } 479 if (mRotateEnterAnimation != null) { 480 mRotateEnterAnimation.setStartTime(now); 481 } 482 if (mRotateExitAnimation != null) { 483 mRotateExitAnimation.setStartTime(now); 484 } 485 mAnimRunning = true; 486 } 487 488 if (mFinishAnimReady && mFinishAnimStartTime < 0) { 489 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready"); 490 mFinishAnimStartTime = now; 491 } 492 493 // If the start animation is no longer running, we want to keep its 494 // transformation intact until the finish animation also completes. 495 496 boolean moreStartExit = false; 497 if (mStartExitAnimation != null) { 498 mStartExitTransformation.clear(); 499 moreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation); 500 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation); 501 if (!moreStartExit) { 502 if (DEBUG_STATE) Slog.v(TAG, "Start exit animation done!"); 503 mStartExitAnimation.cancel(); 504 mStartExitAnimation = null; 505 } 506 } 507 508 boolean moreStartEnter = false; 509 if (mStartEnterAnimation != null) { 510 mStartEnterTransformation.clear(); 511 moreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation); 512 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation); 513 if (!moreStartEnter) { 514 if (DEBUG_STATE) Slog.v(TAG, "Start enter animation done!"); 515 mStartEnterAnimation.cancel(); 516 mStartEnterAnimation = null; 517 } 518 } 519 520 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0; 521 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow); 522 523 mFinishExitTransformation.clear(); 524 boolean moreFinishExit = false; 525 if (mFinishExitAnimation != null) { 526 moreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation); 527 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation); 528 if (!moreStartExit && !moreFinishExit) { 529 if (DEBUG_STATE) Slog.v(TAG, "Finish exit animation done, clearing start/finish anims!"); 530 mStartExitTransformation.clear(); 531 mFinishExitAnimation.cancel(); 532 mFinishExitAnimation = null; 533 mFinishExitTransformation.clear(); 534 } 535 } 536 537 mFinishEnterTransformation.clear(); 538 boolean moreFinishEnter = false; 539 if (mFinishEnterAnimation != null) { 540 moreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation); 541 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation); 542 if (!moreStartEnter && !moreFinishEnter) { 543 if (DEBUG_STATE) Slog.v(TAG, "Finish enter animation done, clearing start/finish anims!"); 544 mStartEnterTransformation.clear(); 545 mFinishEnterAnimation.cancel(); 546 mFinishEnterAnimation = null; 547 mFinishEnterTransformation.clear(); 548 } 549 } 550 551 mRotateExitTransformation.clear(); 552 boolean moreRotateExit = false; 553 if (mRotateExitAnimation != null) { 554 moreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation); 555 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation); 556 } 557 558 if (!moreFinishExit && !moreRotateExit) { 559 if (DEBUG_STATE) Slog.v(TAG, "Rotate exit animation done!"); 560 mRotateExitAnimation.cancel(); 561 mRotateExitAnimation = null; 562 mRotateExitTransformation.clear(); 563 } 564 565 mRotateEnterTransformation.clear(); 566 boolean moreRotateEnter = false; 567 if (mRotateEnterAnimation != null) { 568 moreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation); 569 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation); 570 } 571 572 if (!moreFinishEnter && !moreRotateEnter) { 573 if (DEBUG_STATE) Slog.v(TAG, "Rotate enter animation done!"); 574 mRotateEnterAnimation.cancel(); 575 mRotateEnterAnimation = null; 576 mRotateEnterTransformation.clear(); 577 } 578 579 mExitTransformation.set(mRotateExitTransformation); 580 mExitTransformation.compose(mStartExitTransformation); 581 mExitTransformation.compose(mFinishExitTransformation); 582 583 mEnterTransformation.set(mRotateEnterTransformation); 584 mEnterTransformation.compose(mStartEnterTransformation); 585 mEnterTransformation.compose(mFinishEnterTransformation); 586 587 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation); 588 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation); 589 590 if (!moreStartExit && !moreFinishExit && !moreRotateExit) { 591 if (mSurface != null) { 592 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface"); 593 mSurface.hide(); 594 } 595 } 596 597 if (!moreStartEnter && !moreFinishEnter && !moreRotateEnter) { 598 if (mBlackFrame != null) { 599 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, hiding black frame"); 600 mBlackFrame.hide(); 601 } 602 } else { 603 if (mBlackFrame != null) { 604 mBlackFrame.setMatrix(mEnterTransformation.getMatrix()); 605 } 606 } 607 608 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix); 609 setSnapshotTransform(mSnapshotFinalMatrix, mExitTransformation.getAlpha()); 610 611 final boolean more = moreStartEnter || moreStartExit || moreFinishEnter || moreFinishExit 612 || moreRotateEnter || moreRotateExit || !mFinishAnimReady; 613 614 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more); 615 616 return more; 617 } 618 619 public Transformation getEnterTransformation() { 620 return mEnterTransformation; 621 } 622} 623