/** Returns true if animating. */ public boolean dismiss( SurfaceSession session, long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) { if (mSurface == null) { // Can't do animation. return false; } // Figure out how the screen has moved from the original rotation. int delta = deltaRotation(mCurRotation, mOriginalRotation); switch (delta) { case Surface.ROTATION_0: mExitAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_0_exit); mEnterAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_0_enter); break; case Surface.ROTATION_90: mExitAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_plus_90_exit); mEnterAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_plus_90_enter); break; case Surface.ROTATION_180: mExitAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_180_exit); mEnterAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_180_enter); break; case Surface.ROTATION_270: mExitAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_minus_90_exit); mEnterAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_minus_90_enter); break; } // Initialize the animations. This is a hack, redefining what "parent" // means to allow supplying the last and next size. In this definition // "%p" is the original (let's call it "previous") size, and "%" is the // screen's current/new size. mEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); mExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); mStarted = false; mExitAnimation.restrictDuration(maxAnimationDuration); mExitAnimation.scaleCurrentDuration(animationScale); mEnterAnimation.restrictDuration(maxAnimationDuration); mEnterAnimation.scaleCurrentDuration(animationScale); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION ScreenRotationAnimation.dismiss"); Surface.openTransaction(); try { Rect outer = new Rect(-finalWidth, -finalHeight, finalWidth * 2, finalHeight * 2); Rect inner = new Rect(0, 0, finalWidth, finalHeight); mBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER); } catch (Surface.OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate black surface", e); } finally { Surface.closeTransaction(); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION ScreenRotationAnimation.dismiss"); } return true; }
/** Returns true if animating. */ private boolean startAnimation( SurfaceSession session, long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight, boolean dismissing) { if (mSurface == null) { // Can't do animation. return false; } if (mStarted) { return true; } mStarted = true; boolean firstStart = false; // Figure out how the screen has moved from the original rotation. int delta = deltaRotation(mCurRotation, mOriginalRotation); if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null && (!dismissing || delta != Surface.ROTATION_0)) { if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations"); firstStart = true; mStartExitAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_start_exit); mStartEnterAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_start_enter); if (USE_CUSTOM_BLACK_FRAME) { mStartFrameAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_start_frame); } mFinishExitAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_finish_exit); mFinishEnterAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_finish_enter); if (USE_CUSTOM_BLACK_FRAME) { mFinishFrameAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_finish_frame); } } if (DEBUG_STATE) Slog.v( TAG, "Rotation delta: " + delta + " finalWidth=" + finalWidth + " finalHeight=" + finalHeight + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight); final boolean customAnim; if (mExitAnimId != 0 && mEnterAnimId != 0) { customAnim = true; mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, mExitAnimId); mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, mEnterAnimId); } else { customAnim = false; switch (delta) { case Surface.ROTATION_0: mRotateExitAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_0_exit); mRotateEnterAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_0_enter); if (USE_CUSTOM_BLACK_FRAME) { mRotateFrameAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_0_frame); } break; case Surface.ROTATION_90: mRotateExitAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_plus_90_exit); mRotateEnterAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_plus_90_enter); if (USE_CUSTOM_BLACK_FRAME) { mRotateFrameAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_plus_90_frame); } break; case Surface.ROTATION_180: mRotateExitAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_180_exit); mRotateEnterAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_180_enter); if (USE_CUSTOM_BLACK_FRAME) { mRotateFrameAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_180_frame); } break; case Surface.ROTATION_270: mRotateExitAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_minus_90_exit); mRotateEnterAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_minus_90_enter); if (USE_CUSTOM_BLACK_FRAME) { mRotateFrameAnimation = AnimationUtils.loadAnimation( mContext, com.android.internal.R.anim.screen_rotate_minus_90_frame); } break; } } // Initialize the animations. This is a hack, redefining what "parent" // means to allow supplying the last and next size. In this definition // "%p" is the original (let's call it "previous") size, and "%" is the // screen's current/new size. if (TWO_PHASE_ANIMATION && firstStart) { // Compute partial steps between original and final sizes. These // are used for the dimensions of the exiting and entering elements, // so they are never stretched too significantly. final int halfWidth = (finalWidth + mOriginalWidth) / 2; final int halfHeight = (finalHeight + mOriginalHeight) / 2; if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations"); mStartEnterAnimation.initialize(finalWidth, finalHeight, halfWidth, halfHeight); mStartExitAnimation.initialize(halfWidth, halfHeight, mOriginalWidth, mOriginalHeight); mFinishEnterAnimation.initialize(finalWidth, finalHeight, halfWidth, halfHeight); mFinishExitAnimation.initialize(halfWidth, halfHeight, mOriginalWidth, mOriginalHeight); if (USE_CUSTOM_BLACK_FRAME) { mStartFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); mFinishFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); } } mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); if (USE_CUSTOM_BLACK_FRAME) { mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); } mAnimRunning = false; mFinishAnimReady = false; mFinishAnimStartTime = -1; if (TWO_PHASE_ANIMATION && firstStart) { mStartExitAnimation.restrictDuration(maxAnimationDuration); mStartExitAnimation.scaleCurrentDuration(animationScale); mStartEnterAnimation.restrictDuration(maxAnimationDuration); mStartEnterAnimation.scaleCurrentDuration(animationScale); mFinishExitAnimation.restrictDuration(maxAnimationDuration); mFinishExitAnimation.scaleCurrentDuration(animationScale); mFinishEnterAnimation.restrictDuration(maxAnimationDuration); mFinishEnterAnimation.scaleCurrentDuration(animationScale); if (USE_CUSTOM_BLACK_FRAME) { mStartFrameAnimation.restrictDuration(maxAnimationDuration); mStartFrameAnimation.scaleCurrentDuration(animationScale); mFinishFrameAnimation.restrictDuration(maxAnimationDuration); mFinishFrameAnimation.scaleCurrentDuration(animationScale); } } mRotateExitAnimation.restrictDuration(maxAnimationDuration); mRotateExitAnimation.scaleCurrentDuration(animationScale); mRotateEnterAnimation.restrictDuration(maxAnimationDuration); mRotateEnterAnimation.scaleCurrentDuration(animationScale); if (USE_CUSTOM_BLACK_FRAME) { mRotateFrameAnimation.restrictDuration(maxAnimationDuration); mRotateFrameAnimation.scaleCurrentDuration(animationScale); } final int layerStack = mDisplay.getLayerStack(); if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) { if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation"); Surface.openTransaction(); // Compute the transformation matrix that must be applied // the the black frame to make it stay in the initial position // before the new screen rotation. This is different than the // snapshot transformation because the snapshot is always based // of the native orientation of the screen, not the orientation // we were last in. createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix); try { Rect outer = new Rect( -mOriginalWidth * 1, -mOriginalHeight * 1, mOriginalWidth * 2, mOriginalHeight * 2); Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight); mCustomBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 3, layerStack); mCustomBlackFrame.setMatrix(mFrameInitialMatrix); } catch (Surface.OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate black surface", e); } finally { Surface.closeTransaction(); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation"); } } if (!customAnim && mExitingBlackFrame == null) { if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation"); Surface.openTransaction(); try { // Compute the transformation matrix that must be applied // the the black frame to make it stay in the initial position // before the new screen rotation. This is different than the // snapshot transformation because the snapshot is always based // of the native orientation of the screen, not the orientation // we were last in. createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix); Rect outer = new Rect( -mOriginalWidth * 1, -mOriginalHeight * 1, mOriginalWidth * 2, mOriginalHeight * 2); Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight); mExitingBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 2, layerStack); mExitingBlackFrame.setMatrix(mFrameInitialMatrix); } catch (Surface.OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate black surface", e); } finally { Surface.closeTransaction(); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation"); } } if (customAnim && mEnteringBlackFrame == null) { if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation"); Surface.openTransaction(); try { Rect outer = new Rect(-finalWidth * 1, -finalHeight * 1, finalWidth * 2, finalHeight * 2); Rect inner = new Rect(0, 0, finalWidth, finalHeight); mEnteringBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER, layerStack); } catch (Surface.OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate black surface", e); } finally { Surface.closeTransaction(); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation"); } } return true; }