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