Merge "Implement rotation animations."
This commit is contained in:
committed by
Android (Google) Code Review
commit
4a4f0cd86f
@@ -249201,7 +249201,7 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="arg0" type="T">
|
||||
<parameter name="t" type="T">
|
||||
</parameter>
|
||||
</method>
|
||||
</interface>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
25
core/res/res/anim/screen_rotate_0_enter.xml
Normal file
25
core/res/res/anim/screen_rotate_0_enter.xml
Normal 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>
|
||||
25
core/res/res/anim/screen_rotate_0_exit.xml
Normal file
25
core/res/res/anim/screen_rotate_0_exit.xml
Normal 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>
|
||||
27
core/res/res/anim/screen_rotate_180_enter.xml
Normal file
27
core/res/res/anim/screen_rotate_180_enter.xml
Normal 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>
|
||||
30
core/res/res/anim/screen_rotate_180_exit.xml
Normal file
30
core/res/res/anim/screen_rotate_180_exit.xml
Normal 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>
|
||||
31
core/res/res/anim/screen_rotate_minus_90_enter.xml
Normal file
31
core/res/res/anim/screen_rotate_minus_90_enter.xml
Normal 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>
|
||||
34
core/res/res/anim/screen_rotate_minus_90_exit.xml
Normal file
34
core/res/res/anim/screen_rotate_minus_90_exit.xml
Normal 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>
|
||||
31
core/res/res/anim/screen_rotate_plus_90_enter.xml
Normal file
31
core/res/res/anim/screen_rotate_plus_90_enter.xml
Normal 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>
|
||||
34
core/res/res/anim/screen_rotate_plus_90_exit.xml
Normal file
34
core/res/res/anim/screen_rotate_plus_90_exit.xml
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user