Implement rotation animations.
This introduces a small new feature for ScaleAnimation allowing
the scaling factor to be expressed as a percentage of the object
(which is the same as the existing float interpretation), a
percentage of the container, or a fixed dimension. Maybe not
useful for anything else, but I needed it for this.
Also fix a bug in how transformation matrices were propagated
from the Animation to Surface Flinger, so that rotate and skew
animations will actually work. :p
Change-Id: I301f4caa2147aa35564b5e511cb9c0b368d2425d
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 89512ae..cbb35c6 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -7487,8 +7487,10 @@
}
}
+ final boolean screenAnimation = mScreenRotationAnimation != null
+ && mScreenRotationAnimation.isAnimating();
if (selfTransformation || attachedTransformation != null
- || appTransformation != null) {
+ || appTransformation != null || screenAnimation) {
// cache often used attributes locally
final Rect frame = mFrame;
final float tmpFloats[] = mTmpFloats;
@@ -7506,6 +7508,10 @@
if (appTransformation != null) {
tmpMatrix.postConcat(appTransformation.getMatrix());
}
+ if (screenAnimation) {
+ tmpMatrix.postConcat(
+ mScreenRotationAnimation.getEnterTransformation().getMatrix());
+ }
// "convert" it into SurfaceFlinger's format
// (a 2x2 matrix + an offset)
@@ -7515,8 +7521,8 @@
tmpMatrix.getValues(tmpFloats);
mDsDx = tmpFloats[Matrix.MSCALE_X];
- mDtDx = tmpFloats[Matrix.MSKEW_X];
- mDsDy = tmpFloats[Matrix.MSKEW_Y];
+ mDtDx = tmpFloats[Matrix.MSKEW_Y];
+ mDsDy = tmpFloats[Matrix.MSKEW_X];
mDtDy = tmpFloats[Matrix.MSCALE_Y];
int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
@@ -7544,6 +7550,10 @@
if (appTransformation != null) {
mShownAlpha *= appTransformation.getAlpha();
}
+ if (screenAnimation) {
+ mShownAlpha *=
+ mScreenRotationAnimation.getEnterTransformation().getAlpha();
+ }
} else {
//Slog.i(TAG, "Not applying alpha transform");
}
@@ -9397,6 +9407,16 @@
animating = tokensAnimating;
+ if (mScreenRotationAnimation != null) {
+ if (mScreenRotationAnimation.isAnimating()) {
+ if (mScreenRotationAnimation.stepAnimation(currentTime)) {
+ animating = true;
+ } else {
+ mScreenRotationAnimation = null;
+ }
+ }
+ }
+
boolean tokenMayBeDrawn = false;
boolean wallpaperMayChange = false;
boolean forceHiding = false;
@@ -10841,8 +10861,13 @@
}
if (CUSTOM_SCREEN_ROTATION) {
+ if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
+ mScreenRotationAnimation.kill();
+ mScreenRotationAnimation = null;
+ }
if (mScreenRotationAnimation == null) {
- mScreenRotationAnimation = new ScreenRotationAnimation(mDisplay, mFxSession);
+ mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
+ mDisplay, mFxSession);
}
} else {
Surface.freezeDisplay(0);
@@ -10866,8 +10891,12 @@
if (CUSTOM_SCREEN_ROTATION) {
if (mScreenRotationAnimation != null) {
- mScreenRotationAnimation.dismiss();
- mScreenRotationAnimation = null;
+ if (mScreenRotationAnimation.dismiss(MAX_ANIMATION_DURATION,
+ mTransitionAnimationScale)) {
+ requestAnimationLocked(0);
+ } else {
+ mScreenRotationAnimation = null;
+ }
}
} else {
Surface.unfreezeDisplay(0);