Merge "Implement rotation animations."

This commit is contained in:
Dianne Hackborn
2010-11-28 18:30:09 -08:00
committed by Android (Google) Code Review
13 changed files with 572 additions and 59 deletions

View File

@@ -249201,7 +249201,7 @@
deprecated="not deprecated"
visibility="public"
>
<parameter name="arg0" type="T">
<parameter name="t" type="T">
</parameter>
</method>
</interface>

View File

@@ -17,8 +17,10 @@
package android.view.animation;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.TypedValue;
/**
* An animation that controls the scale of an object. You can specify the point
@@ -26,11 +28,23 @@ import android.util.AttributeSet;
*
*/
public class ScaleAnimation extends Animation {
private final Resources mResources;
private float mFromX;
private float mToX;
private float mFromY;
private float mToY;
private int mFromXType = TypedValue.TYPE_NULL;
private int mToXType = TypedValue.TYPE_NULL;
private int mFromYType = TypedValue.TYPE_NULL;
private int mToYType = TypedValue.TYPE_NULL;
private int mFromXData = 0;
private int mToXData = 0;
private int mFromYData = 0;
private int mToYData = 0;
private int mPivotXType = ABSOLUTE;
private int mPivotYType = ABSOLUTE;
private float mPivotXValue = 0.0f;
@@ -48,14 +62,60 @@ public class ScaleAnimation extends Animation {
public ScaleAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
mResources = context.getResources();
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.ScaleAnimation);
mFromX = a.getFloat(com.android.internal.R.styleable.ScaleAnimation_fromXScale, 0.0f);
mToX = a.getFloat(com.android.internal.R.styleable.ScaleAnimation_toXScale, 0.0f);
TypedValue tv = a.peekValue(
com.android.internal.R.styleable.ScaleAnimation_fromXScale);
mFromX = 0.0f;
if (tv != null) {
if (tv.type == TypedValue.TYPE_FLOAT) {
// This is a scaling factor.
mFromX = tv.getFloat();
} else {
mFromXType = tv.type;
mFromXData = tv.data;
}
}
tv = a.peekValue(
com.android.internal.R.styleable.ScaleAnimation_toXScale);
mToX = 0.0f;
if (tv != null) {
if (tv.type == TypedValue.TYPE_FLOAT) {
// This is a scaling factor.
mToX = tv.getFloat();
} else {
mToXType = tv.type;
mToXData = tv.data;
}
}
mFromY = a.getFloat(com.android.internal.R.styleable.ScaleAnimation_fromYScale, 0.0f);
mToY = a.getFloat(com.android.internal.R.styleable.ScaleAnimation_toYScale, 0.0f);
tv = a.peekValue(
com.android.internal.R.styleable.ScaleAnimation_fromYScale);
mFromY = 0.0f;
if (tv != null) {
if (tv.type == TypedValue.TYPE_FLOAT) {
// This is a scaling factor.
mFromY = tv.getFloat();
} else {
mFromYType = tv.type;
mFromYData = tv.data;
}
}
tv = a.peekValue(
com.android.internal.R.styleable.ScaleAnimation_toYScale);
mToY = 0.0f;
if (tv != null) {
if (tv.type == TypedValue.TYPE_FLOAT) {
// This is a scaling factor.
mToY = tv.getFloat();
} else {
mToYType = tv.type;
mToYData = tv.data;
}
}
Description d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.ScaleAnimation_pivotX));
@@ -81,6 +141,7 @@ public class ScaleAnimation extends Animation {
* @param toY Vertical scaling factor to apply at the end of the animation
*/
public ScaleAnimation(float fromX, float toX, float fromY, float toY) {
mResources = null;
mFromX = fromX;
mToX = toX;
mFromY = fromY;
@@ -107,6 +168,7 @@ public class ScaleAnimation extends Animation {
*/
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
float pivotX, float pivotY) {
mResources = null;
mFromX = fromX;
mToX = toX;
mFromY = fromY;
@@ -146,6 +208,7 @@ public class ScaleAnimation extends Animation {
*/
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
mResources = null;
mFromX = fromX;
mToX = toX;
mFromY = fromY;
@@ -177,10 +240,32 @@ public class ScaleAnimation extends Animation {
}
}
float resolveScale(float scale, int type, int data, int size, int psize) {
float targetSize;
if (type == TypedValue.TYPE_FRACTION) {
targetSize = TypedValue.complexToFraction(data, size, psize);
} else if (type == TypedValue.TYPE_DIMENSION) {
targetSize = TypedValue.complexToDimension(data, mResources.getDisplayMetrics());
} else {
return scale;
}
if (size == 0) {
return 1;
}
return targetSize/(float)size;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mFromX = resolveScale(mFromX, mFromXType, mFromXData, width, parentWidth);
mToX = resolveScale(mToX, mToXType, mToXData, width, parentWidth);
mFromY = resolveScale(mFromY, mFromYType, mFromYData, height, parentHeight);
mToY = resolveScale(mToY, mToYType, mToYData, height, parentHeight);
mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
}

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2010, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<alpha android:fromAlpha="1.0" android:toAlpha="1.0"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_shortAnimTime" />
</set>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2010, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<alpha android:fromAlpha="1.0" android:toAlpha="0"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_shortAnimTime" />
</set>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2010, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale android:fromXScale="1.0" android:toXScale="1.0"
android:fromYScale=".9" android:toYScale="1.0"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2010, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale android:fromXScale="1.0" android:toXScale="1.0"
android:fromYScale="1.0" android:toYScale=".9"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
<alpha android:fromAlpha="1.0" android:toAlpha="0"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2010, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale android:fromXScale="100%p" android:toXScale="100%"
android:fromYScale="100%p" android:toYScale="100%"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
<rotate android:fromDegrees="-90" android:toDegrees="0"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2010, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale android:fromXScale="100%" android:toXScale="100%p"
android:fromYScale="100%" android:toYScale="100%p"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
<rotate android:fromDegrees="0" android:toDegrees="90"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
<alpha android:fromAlpha="1.0" android:toAlpha="0"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2010, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale android:fromXScale="100%p" android:toXScale="100%"
android:fromYScale="100%p" android:toYScale="100%"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
<rotate android:fromDegrees="90" android:toDegrees="0"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2010, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<scale android:fromXScale="100%" android:toXScale="100%p"
android:fromYScale="100%" android:toYScale="100%p"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
<rotate android:fromDegrees="0" android:toDegrees="-90"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
<alpha android:fromAlpha="1.0" android:toAlpha="0"
android:interpolator="@anim/decelerate_quint_interpolator"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View File

@@ -3233,10 +3233,10 @@
</declare-styleable>
<declare-styleable name="ScaleAnimation">
<attr name="fromXScale" format="float" />
<attr name="toXScale" format="float" />
<attr name="fromYScale" format="float" />
<attr name="toYScale" format="float" />
<attr name="fromXScale" format="float|fraction|dimension" />
<attr name="toXScale" format="float|fraction|dimension" />
<attr name="fromYScale" format="float|fraction|dimension" />
<attr name="toYScale" format="float|fraction|dimension" />
<attr name="pivotX" />
<attr name="pivotY" />
</declare-styleable>

View File

@@ -16,6 +16,7 @@
package com.android.server; // TODO: use com.android.server.wm, once things move there
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -28,38 +29,60 @@ import android.util.Slog;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceSession;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;
class ScreenRotationAnimation {
private static final String TAG = "ScreenRotationAnimation";
static final String TAG = "ScreenRotationAnimation";
static final boolean DEBUG = false;
final Context mContext;
final Display mDisplay;
Surface mSurface;
int mWidth, mHeight;
int mBaseRotation;
int mSnapshotRotation;
int mSnapshotDeltaRotation;
int mOriginalRotation;
int mOriginalWidth, mOriginalHeight;
int mCurRotation;
int mDeltaRotation;
final Matrix mMatrix = new Matrix();
Animation mExitAnimation;
final Transformation mExitTransformation = new Transformation();
Animation mEnterAnimation;
final Transformation mEnterTransformation = new Transformation();
boolean mStarted;
final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
final Matrix mSnapshotInitialMatrix = new Matrix();
final Matrix mSnapshotFinalMatrix = new Matrix();
final float[] mTmpFloats = new float[9];
public ScreenRotationAnimation(Display display, SurfaceSession session) {
final DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
public ScreenRotationAnimation(Context context, Display display, SurfaceSession session) {
mContext = context;
mDisplay = display;
display.getMetrics(mDisplayMetrics);
Bitmap screenshot = Surface.screenshot(0, 0);
if (screenshot != null) {
// Screenshot does NOT include rotation!
mBaseRotation = 0;
mSnapshotRotation = 0;
mWidth = screenshot.getWidth();
mHeight = screenshot.getHeight();
} else {
// Just in case.
mBaseRotation = display.getRotation();
mWidth = dm.widthPixels;
mHeight = dm.heightPixels;
mSnapshotRotation = display.getRotation();
mWidth = mDisplayMetrics.widthPixels;
mHeight = mDisplayMetrics.heightPixels;
}
mOriginalRotation = display.getRotation();
mOriginalWidth = mDisplayMetrics.widthPixels;
mOriginalHeight = mDisplayMetrics.heightPixels;
Surface.openTransaction();
if (mSurface != null) {
mSurface.destroy();
@@ -102,43 +125,24 @@ class ScreenRotationAnimation {
screenshot.recycle();
}
// Must be called while in a transaction.
public void setRotation(int rotation) {
mCurRotation = rotation;
int delta = mCurRotation - mBaseRotation;
static int deltaRotation(int oldRotation, int newRotation) {
int delta = newRotation - oldRotation;
if (delta < 0) delta += 4;
mDeltaRotation = delta;
return delta;
}
switch (delta) {
case Surface.ROTATION_0:
mMatrix.reset();
break;
case Surface.ROTATION_90:
mMatrix.setRotate(90, 0, 0);
mMatrix.postTranslate(0, mWidth);
break;
case Surface.ROTATION_180:
mMatrix.setRotate(180, 0, 0);
mMatrix.postTranslate(mWidth, mHeight);
break;
case Surface.ROTATION_270:
mMatrix.setRotate(270, 0, 0);
mMatrix.postTranslate(mHeight, 0);
break;
}
mMatrix.getValues(mTmpFloats);
void setSnapshotTransform(Matrix matrix, float alpha) {
matrix.getValues(mTmpFloats);
mSurface.setPosition((int)mTmpFloats[Matrix.MTRANS_X],
(int)mTmpFloats[Matrix.MTRANS_Y]);
mSurface.setMatrix(
mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_X],
mTmpFloats[Matrix.MSKEW_Y], mTmpFloats[Matrix.MSCALE_Y]);
if (false) {
mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
mSurface.setAlpha(alpha);
if (DEBUG) {
float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
float[] dstPnts = new float[8];
mMatrix.mapPoints(dstPnts, srcPnts);
Slog.i(TAG, "**** ROTATION: " + delta);
float[] dstPnts = new float[4];
matrix.mapPoints(dstPnts, srcPnts);
Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
+ ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
@@ -146,7 +150,165 @@ class ScreenRotationAnimation {
}
}
public void dismiss() {
mSurface.destroy();
// Must be called while in a transaction.
public void setRotation(int rotation) {
mCurRotation = rotation;
// Compute the transformation matrix that must be applied
// to the snapshot to make it stay in the same original position
// with the current screen rotation.
int delta = deltaRotation(rotation, mSnapshotRotation);
switch (delta) {
case Surface.ROTATION_0:
mSnapshotInitialMatrix.reset();
break;
case Surface.ROTATION_90:
mSnapshotInitialMatrix.setRotate(90, 0, 0);
mSnapshotInitialMatrix.postTranslate(mHeight, 0);
break;
case Surface.ROTATION_180:
mSnapshotInitialMatrix.setRotate(180, 0, 0);
mSnapshotInitialMatrix.postTranslate(mWidth, mHeight);
break;
case Surface.ROTATION_270:
mSnapshotInitialMatrix.setRotate(270, 0, 0);
mSnapshotInitialMatrix.postTranslate(0, mWidth);
break;
}
if (DEBUG) Slog.v(TAG, "**** ROTATION: " + delta);
setSnapshotTransform(mSnapshotInitialMatrix, 1.0f);
}
/**
* Returns true if animating.
*/
public boolean dismiss(long maxAnimationDuration, float animationScale) {
// Figure out how the screen has moved from the original rotation.
int delta = deltaRotation(mCurRotation, mOriginalRotation);
if (false && delta == 0) {
// Nothing changed, just remove the snapshot.
if (mSurface != null) {
mSurface.destroy();
mSurface = null;
}
return false;
}
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;
}
mDisplay.getMetrics(mDisplayMetrics);
// 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(mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels,
mOriginalWidth, mOriginalHeight);
mExitAnimation.initialize(mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels,
mOriginalWidth, mOriginalHeight);
mStarted = false;
mExitAnimation.restrictDuration(maxAnimationDuration);
mExitAnimation.scaleCurrentDuration(animationScale);
mEnterAnimation.restrictDuration(maxAnimationDuration);
mEnterAnimation.scaleCurrentDuration(animationScale);
return true;
}
public void kill() {
if (mSurface != null) {
mSurface.destroy();
mSurface = null;
}
if (mExitAnimation != null) {
mExitAnimation.cancel();
mExitAnimation = null;
}
if (mEnterAnimation != null) {
mEnterAnimation.cancel();
mEnterAnimation = null;
}
}
public boolean isAnimating() {
return mEnterAnimation != null || mExitAnimation != null;
}
public boolean stepAnimation(long now) {
if (mEnterAnimation == null && mExitAnimation == null) {
return false;
}
if (!mStarted) {
mEnterAnimation.setStartTime(now);
mExitAnimation.setStartTime(now);
mStarted = true;
}
mExitTransformation.clear();
boolean moreExit = false;
if (mExitAnimation != null) {
moreExit = mExitAnimation.getTransformation(now, mExitTransformation);
if (DEBUG) Slog.v(TAG, "Stepped exit: " + mExitTransformation);
if (!moreExit) {
if (DEBUG) Slog.v(TAG, "Exit animation done!");
mExitAnimation.cancel();
mExitAnimation = null;
mExitTransformation.clear();
if (mSurface != null) {
mSurface.destroy();
mSurface = null;
}
}
}
mEnterTransformation.clear();
boolean moreEnter = false;
if (mEnterAnimation != null) {
moreEnter = mEnterAnimation.getTransformation(now, mEnterTransformation);
if (!moreEnter) {
mEnterAnimation.cancel();
mEnterAnimation = null;
mEnterTransformation.clear();
}
}
if (mSurface != null) {
mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
setSnapshotTransform(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
}
return moreEnter || moreExit;
}
public Transformation getEnterTransformation() {
return mEnterTransformation;
}
}

View File

@@ -7487,8 +7487,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
if (appTransformation != null) {
mShownAlpha *= appTransformation.getAlpha();
}
if (screenAnimation) {
mShownAlpha *=
mScreenRotationAnimation.getEnterTransformation().getAlpha();
}
} else {
//Slog.i(TAG, "Not applying alpha transform");
}
@@ -9397,6 +9407,16 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
}
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 @@ public class WindowManagerService extends IWindowManager.Stub
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);