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);