blob: cfcf8413e0beae368b97fb500bb4cf43c10f682a [file] [log] [blame]
Dianne Hackborna1111872010-11-23 20:55:11 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080017package com.android.server.wm;
Dianne Hackborna1111872010-11-23 20:55:11 -080018
Dianne Hackborn4dcece82012-02-10 14:50:32 -080019import java.io.PrintWriter;
20
Craig Mautner7d8df392012-04-06 15:26:23 -070021import static com.android.server.wm.WindowStateAnimator.SurfaceTrace;
22
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080023import android.content.Context;
Dianne Hackborna1111872010-11-23 20:55:11 -080024import android.graphics.Matrix;
Dianne Hackborna1111872010-11-23 20:55:11 -080025import android.graphics.PixelFormat;
26import android.graphics.Rect;
Dianne Hackborna1111872010-11-23 20:55:11 -080027import android.util.Slog;
Craig Mautner6881a102012-07-27 13:04:51 -070028import android.view.Display;
Dianne Hackborna1111872010-11-23 20:55:11 -080029import android.view.Surface;
30import android.view.SurfaceSession;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080031import android.view.animation.Animation;
32import android.view.animation.AnimationUtils;
33import android.view.animation.Transformation;
Dianne Hackborna1111872010-11-23 20:55:11 -080034
Craig Mautnere32c3072012-03-12 15:25:35 -070035class ScreenRotationAnimation {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080036 static final String TAG = "ScreenRotationAnimation";
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080037 static final boolean DEBUG_STATE = false;
38 static final boolean DEBUG_TRANSFORMS = false;
Dianne Hackborn187ae2102012-04-11 18:12:06 -070039 static final boolean TWO_PHASE_ANIMATION = false;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070040 static final boolean USE_CUSTOM_BLACK_FRAME = false;
Dianne Hackborna1111872010-11-23 20:55:11 -080041
Dianne Hackborn50660e22011-02-02 17:12:25 -080042 static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200;
43
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080044 final Context mContext;
Jeff Brown98365d72012-08-19 20:30:52 -070045 final Display mDisplay;
Dianne Hackborna1111872010-11-23 20:55:11 -080046 Surface mSurface;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070047 BlackFrame mCustomBlackFrame;
48 BlackFrame mExitingBlackFrame;
49 BlackFrame mEnteringBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080050 int mWidth, mHeight;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070051 int mExitAnimId, mEnterAnimId;
Dianne Hackborna1111872010-11-23 20:55:11 -080052
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080053 int mOriginalRotation;
54 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080055 int mCurRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -080056
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080057 // For all animations, "exit" is for the UI elements that are going
58 // away (that is the snapshot of the old screen), and "enter" is for
59 // the new UI elements that are appearing (that is the active windows
60 // in their final orientation).
61
62 // The starting animation for the exiting and entering elements. This
63 // animation applies a transformation while the rotation is in progress.
64 // It is started immediately, before the new entering UI is ready.
65 Animation mStartExitAnimation;
66 final Transformation mStartExitTransformation = new Transformation();
67 Animation mStartEnterAnimation;
68 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080069 Animation mStartFrameAnimation;
70 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080071
72 // The finishing animation for the exiting and entering elements. This
73 // animation needs to undo the transformation of the starting animation.
74 // It starts running once the new rotation UI elements are ready to be
75 // displayed.
76 Animation mFinishExitAnimation;
77 final Transformation mFinishExitTransformation = new Transformation();
78 Animation mFinishEnterAnimation;
79 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080080 Animation mFinishFrameAnimation;
81 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080082
83 // The current active animation to move from the old to the new rotated
84 // state. Which animation is run here will depend on the old and new
85 // rotations.
86 Animation mRotateExitAnimation;
87 final Transformation mRotateExitTransformation = new Transformation();
88 Animation mRotateEnterAnimation;
89 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080090 Animation mRotateFrameAnimation;
91 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080092
93 // A previously running rotate animation. This will be used if we need
94 // to switch to a new rotation before finishing the previous one.
95 Animation mLastRotateExitAnimation;
96 final Transformation mLastRotateExitTransformation = new Transformation();
97 Animation mLastRotateEnterAnimation;
98 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080099 Animation mLastRotateFrameAnimation;
100 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800101
102 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800103 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800104 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800105 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800106
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800107 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800108 boolean mAnimRunning;
109 boolean mFinishAnimReady;
110 long mFinishAnimStartTime;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800111
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800112 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800113 final Matrix mSnapshotInitialMatrix = new Matrix();
114 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700115 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800116 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800117 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800118 private boolean mMoreRotateEnter;
119 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800120 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800121 private boolean mMoreFinishEnter;
122 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800123 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800124 private boolean mMoreStartEnter;
125 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800126 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700127 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800128
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800129 public void printTo(String prefix, PrintWriter pw) {
130 pw.print(prefix); pw.print("mSurface="); pw.print(mSurface);
131 pw.print(" mWidth="); pw.print(mWidth);
132 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700133 if (USE_CUSTOM_BLACK_FRAME) {
134 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
135 if (mCustomBlackFrame != null) {
136 mCustomBlackFrame.printTo(prefix + " ", pw);
137 }
138 }
139 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
140 if (mExitingBlackFrame != null) {
141 mExitingBlackFrame.printTo(prefix + " ", pw);
142 }
143 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
144 if (mEnteringBlackFrame != null) {
145 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800146 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700147 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
148 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
149 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800150 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
151 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
152 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
153 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
154 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
155 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
156 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
157 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
158 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800159 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
160 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800161 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
162 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
163 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
164 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800165 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
166 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800167 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
168 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
169 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
170 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800171 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
172 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800173 pw.print(prefix); pw.print("mExitTransformation=");
174 mExitTransformation.printShortString(pw); pw.println();
175 pw.print(prefix); pw.print("mEnterTransformation=");
176 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800177 pw.print(prefix); pw.print("mFrameTransformation=");
178 mEnterTransformation.printShortString(pw); pw.println();
179 pw.print(prefix); pw.print("mFrameInitialMatrix=");
180 mFrameInitialMatrix.printShortString(pw);
181 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800182 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
183 mSnapshotInitialMatrix.printShortString(pw);
184 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
185 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700186 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
187 mExitFrameFinalMatrix.printShortString(pw);
188 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800189 }
190
Jeff Brown98365d72012-08-19 20:30:52 -0700191 public ScreenRotationAnimation(Context context, Display display, SurfaceSession session,
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700192 boolean inTransaction, int originalWidth, int originalHeight, int originalRotation,
193 int exitAnim, int enterAnim) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800194 mContext = context;
Jeff Brown98365d72012-08-19 20:30:52 -0700195 mDisplay = display;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700196 mExitAnimId = exitAnim;
197 mEnterAnimId = enterAnim;
Dianne Hackborna1111872010-11-23 20:55:11 -0800198
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800199 // Screenshot does NOT include rotation!
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700200 if (originalRotation == Surface.ROTATION_90
201 || originalRotation == Surface.ROTATION_270) {
202 mWidth = originalHeight;
203 mHeight = originalWidth;
204 } else {
205 mWidth = originalWidth;
206 mHeight = originalHeight;
207 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800208
Jeff Brownbc68a592011-07-25 12:58:12 -0700209 mOriginalRotation = originalRotation;
210 mOriginalWidth = originalWidth;
211 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800212
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800213 if (!inTransaction) {
Dianne Hackborn36991742011-10-11 21:35:26 -0700214 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800215 ">>> OPEN TRANSACTION ScreenRotationAnimation");
216 Surface.openTransaction();
217 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700218
Dianne Hackborna1111872010-11-23 20:55:11 -0800219 try {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800220 try {
Craig Mautner7d8df392012-04-06 15:26:23 -0700221 if (WindowManagerService.DEBUG_SURFACE_TRACE) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700222 mSurface = new SurfaceTrace(session, "FreezeSurface",
223 mWidth, mHeight,
Jeff Brown98365d72012-08-19 20:30:52 -0700224 PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
Craig Mautner7d8df392012-04-06 15:26:23 -0700225 } else {
Jeff Brown64a55af2012-08-26 02:47:39 -0700226 mSurface = new Surface(session, "FreezeSurface",
227 mWidth, mHeight,
Jeff Brown98365d72012-08-19 20:30:52 -0700228 PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
Craig Mautner7d8df392012-04-06 15:26:23 -0700229 }
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700230 if (!mSurface.isValid()) {
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700231 // Screenshot failed, punt.
232 mSurface = null;
233 return;
234 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700235 mSurface.setLayerStack(mDisplay.getLayerStack());
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700236 mSurface.setLayer(FREEZE_LAYER + 1);
Craig Mautner7d8df392012-04-06 15:26:23 -0700237 mSurface.setAlpha(0);
Mathias Agopiane65beaa2011-11-01 14:39:06 -0700238 mSurface.show();
Dianne Hackborn352cc982011-01-04 11:34:18 -0800239 } catch (Surface.OutOfResourcesException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800240 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800241 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800242
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700243 if (WindowManagerService.SHOW_TRANSACTIONS ||
244 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
245 " FREEZE " + mSurface + ": CREATE");
246
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700247 setRotationInTransaction(originalRotation);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800248 } finally {
249 if (!inTransaction) {
250 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -0700251 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800252 "<<< CLOSE TRANSACTION ScreenRotationAnimation");
Dianne Hackborn352cc982011-01-04 11:34:18 -0800253 }
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800254 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800255 }
256
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800257 boolean hasScreenshot() {
258 return mSurface != null;
259 }
260
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800261 static int deltaRotation(int oldRotation, int newRotation) {
262 int delta = newRotation - oldRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800263 if (delta < 0) delta += 4;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800264 return delta;
265 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800266
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700267 private void setSnapshotTransformInTransaction(Matrix matrix, float alpha) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800268 if (mSurface != null) {
269 matrix.getValues(mTmpFloats);
Dianne Hackbornd040edb2011-08-31 12:47:58 -0700270 mSurface.setPosition(mTmpFloats[Matrix.MTRANS_X],
271 mTmpFloats[Matrix.MTRANS_Y]);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800272 mSurface.setMatrix(
273 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
274 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
275 mSurface.setAlpha(alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800276 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800277 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
278 float[] dstPnts = new float[4];
279 matrix.mapPoints(dstPnts, srcPnts);
280 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
281 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
282 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
283 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
284 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800285 }
286 }
287
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800288 public static void createRotationMatrix(int rotation, int width, int height,
289 Matrix outMatrix) {
290 switch (rotation) {
291 case Surface.ROTATION_0:
292 outMatrix.reset();
293 break;
294 case Surface.ROTATION_90:
295 outMatrix.setRotate(90, 0, 0);
296 outMatrix.postTranslate(height, 0);
297 break;
298 case Surface.ROTATION_180:
299 outMatrix.setRotate(180, 0, 0);
300 outMatrix.postTranslate(width, height);
301 break;
302 case Surface.ROTATION_270:
303 outMatrix.setRotate(270, 0, 0);
304 outMatrix.postTranslate(0, width);
305 break;
306 }
307 }
308
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800309 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700310 private void setRotationInTransaction(int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800311 mCurRotation = rotation;
312
313 // Compute the transformation matrix that must be applied
314 // to the snapshot to make it stay in the same original position
315 // with the current screen rotation.
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700316 int delta = deltaRotation(rotation, Surface.ROTATION_0);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800317 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800318
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800319 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700320 setSnapshotTransformInTransaction(mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800321 }
322
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800323 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700324 public boolean setRotationInTransaction(int rotation, SurfaceSession session,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800325 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700326 setRotationInTransaction(rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700327 if (TWO_PHASE_ANIMATION) {
328 return startAnimation(session, maxAnimationDuration, animationScale,
329 finalWidth, finalHeight, false);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700330 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700331
332 // Don't start animation yet.
333 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800334 }
335
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800336 /**
337 * Returns true if animating.
338 */
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800339 private boolean startAnimation(SurfaceSession session, long maxAnimationDuration,
340 float animationScale, int finalWidth, int finalHeight, boolean dismissing) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800341 if (mSurface == null) {
342 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800343 return false;
344 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800345 if (mStarted) {
346 return true;
347 }
348
349 mStarted = true;
350
351 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800352
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800353 // Figure out how the screen has moved from the original rotation.
354 int delta = deltaRotation(mCurRotation, mOriginalRotation);
355
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700356 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
357 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800358 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
359 firstStart = true;
360 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
361 com.android.internal.R.anim.screen_rotate_start_exit);
362 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
363 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700364 if (USE_CUSTOM_BLACK_FRAME) {
365 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
366 com.android.internal.R.anim.screen_rotate_start_frame);
367 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800368 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
369 com.android.internal.R.anim.screen_rotate_finish_exit);
370 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
371 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700372 if (USE_CUSTOM_BLACK_FRAME) {
373 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
374 com.android.internal.R.anim.screen_rotate_finish_frame);
375 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800376 }
377
378 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
379 + finalWidth + " finalHeight=" + finalHeight
380 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
381
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700382 final boolean customAnim;
383 if (mExitAnimId != 0 && mEnterAnimId != 0) {
384 customAnim = true;
385 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, mExitAnimId);
386 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, mEnterAnimId);
387 } else {
388 customAnim = false;
389 switch (delta) {
390 case Surface.ROTATION_0:
391 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
392 com.android.internal.R.anim.screen_rotate_0_exit);
393 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
394 com.android.internal.R.anim.screen_rotate_0_enter);
395 if (USE_CUSTOM_BLACK_FRAME) {
396 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
397 com.android.internal.R.anim.screen_rotate_0_frame);
398 }
399 break;
400 case Surface.ROTATION_90:
401 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
402 com.android.internal.R.anim.screen_rotate_plus_90_exit);
403 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
404 com.android.internal.R.anim.screen_rotate_plus_90_enter);
405 if (USE_CUSTOM_BLACK_FRAME) {
406 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
407 com.android.internal.R.anim.screen_rotate_plus_90_frame);
408 }
409 break;
410 case Surface.ROTATION_180:
411 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
412 com.android.internal.R.anim.screen_rotate_180_exit);
413 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
414 com.android.internal.R.anim.screen_rotate_180_enter);
415 if (USE_CUSTOM_BLACK_FRAME) {
416 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
417 com.android.internal.R.anim.screen_rotate_180_frame);
418 }
419 break;
420 case Surface.ROTATION_270:
421 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
422 com.android.internal.R.anim.screen_rotate_minus_90_exit);
423 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
424 com.android.internal.R.anim.screen_rotate_minus_90_enter);
425 if (USE_CUSTOM_BLACK_FRAME) {
426 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
427 com.android.internal.R.anim.screen_rotate_minus_90_frame);
428 }
429 break;
430 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800431 }
432
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800433 // Initialize the animations. This is a hack, redefining what "parent"
434 // means to allow supplying the last and next size. In this definition
435 // "%p" is the original (let's call it "previous") size, and "%" is the
436 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700437 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700438 // Compute partial steps between original and final sizes. These
439 // are used for the dimensions of the exiting and entering elements,
440 // so they are never stretched too significantly.
441 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
442 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
443
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800444 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
445 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800446 halfWidth, halfHeight);
447 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800448 mOriginalWidth, mOriginalHeight);
449 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800450 halfWidth, halfHeight);
451 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800452 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700453 if (USE_CUSTOM_BLACK_FRAME) {
454 mStartFrameAnimation.initialize(finalWidth, finalHeight,
455 mOriginalWidth, mOriginalHeight);
456 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
457 mOriginalWidth, mOriginalHeight);
458 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800459 }
460 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
461 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700462 if (USE_CUSTOM_BLACK_FRAME) {
463 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
464 mOriginalHeight);
465 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800466 mAnimRunning = false;
467 mFinishAnimReady = false;
468 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800469
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700470 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800471 mStartExitAnimation.restrictDuration(maxAnimationDuration);
472 mStartExitAnimation.scaleCurrentDuration(animationScale);
473 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
474 mStartEnterAnimation.scaleCurrentDuration(animationScale);
475 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
476 mFinishExitAnimation.scaleCurrentDuration(animationScale);
477 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
478 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700479 if (USE_CUSTOM_BLACK_FRAME) {
480 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
481 mStartFrameAnimation.scaleCurrentDuration(animationScale);
482 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
483 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
484 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800485 }
486 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
487 mRotateExitAnimation.scaleCurrentDuration(animationScale);
488 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
489 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700490 if (USE_CUSTOM_BLACK_FRAME) {
491 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
492 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
493 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800494
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700495 final int layerStack = mDisplay.getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700496 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800497 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
498 WindowManagerService.TAG,
499 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
500 Surface.openTransaction();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800501
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800502 // Compute the transformation matrix that must be applied
503 // the the black frame to make it stay in the initial position
504 // before the new screen rotation. This is different than the
505 // snapshot transformation because the snapshot is always based
506 // of the native orientation of the screen, not the orientation
507 // we were last in.
508 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
509
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800510 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800511 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
512 mOriginalWidth*2, mOriginalHeight*2);
513 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700514 mCustomBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 3,
515 layerStack);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700516 mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
517 } catch (Surface.OutOfResourcesException e) {
518 Slog.w(TAG, "Unable to allocate black surface", e);
519 } finally {
520 Surface.closeTransaction();
521 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
522 WindowManagerService.TAG,
523 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
524 }
525 }
526
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700527 if (!customAnim && mExitingBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700528 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
529 WindowManagerService.TAG,
530 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
531 Surface.openTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700532 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700533 // Compute the transformation matrix that must be applied
534 // the the black frame to make it stay in the initial position
535 // before the new screen rotation. This is different than the
536 // snapshot transformation because the snapshot is always based
537 // of the native orientation of the screen, not the orientation
538 // we were last in.
539 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
540
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700541 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
542 mOriginalWidth*2, mOriginalHeight*2);
543 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700544 mExitingBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 2,
545 layerStack);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700546 mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
547 } catch (Surface.OutOfResourcesException e) {
548 Slog.w(TAG, "Unable to allocate black surface", e);
549 } finally {
550 Surface.closeTransaction();
551 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
552 WindowManagerService.TAG,
553 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
554 }
555 }
556
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700557 if (customAnim && mEnteringBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700558 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
559 WindowManagerService.TAG,
560 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
561 Surface.openTransaction();
562
563 try {
564 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
565 finalWidth*2, finalHeight*2);
566 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700567 mEnteringBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER,
568 layerStack);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800569 } catch (Surface.OutOfResourcesException e) {
570 Slog.w(TAG, "Unable to allocate black surface", e);
571 } finally {
572 Surface.closeTransaction();
573 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
574 WindowManagerService.TAG,
575 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
576 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800577 }
578
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800579 return true;
580 }
581
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800582 /**
583 * Returns true if animating.
584 */
585 public boolean dismiss(SurfaceSession session, long maxAnimationDuration,
586 float animationScale, int finalWidth, int finalHeight) {
587 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
588 if (mSurface == null) {
589 // Can't do animation.
590 return false;
591 }
592 if (!mStarted) {
593 startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight,
594 true);
595 }
596 if (!mStarted) {
597 return false;
598 }
599 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
600 mFinishAnimReady = true;
601 return true;
602 }
603
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800604 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800605 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800606 if (mSurface != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700607 if (WindowManagerService.SHOW_TRANSACTIONS ||
608 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
609 " FREEZE " + mSurface + ": DESTROY");
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800610 mSurface.destroy();
611 mSurface = null;
612 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700613 if (mCustomBlackFrame != null) {
614 mCustomBlackFrame.kill();
615 mCustomBlackFrame = null;
616 }
617 if (mExitingBlackFrame != null) {
618 mExitingBlackFrame.kill();
619 mExitingBlackFrame = null;
620 }
621 if (mEnteringBlackFrame != null) {
622 mEnteringBlackFrame.kill();
623 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800624 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700625 if (TWO_PHASE_ANIMATION) {
626 if (mStartExitAnimation != null) {
627 mStartExitAnimation.cancel();
628 mStartExitAnimation = null;
629 }
630 if (mStartEnterAnimation != null) {
631 mStartEnterAnimation.cancel();
632 mStartEnterAnimation = null;
633 }
634 if (mFinishExitAnimation != null) {
635 mFinishExitAnimation.cancel();
636 mFinishExitAnimation = null;
637 }
638 if (mFinishEnterAnimation != null) {
639 mFinishEnterAnimation.cancel();
640 mFinishEnterAnimation = null;
641 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800642 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700643 if (USE_CUSTOM_BLACK_FRAME) {
644 if (mStartFrameAnimation != null) {
645 mStartFrameAnimation.cancel();
646 mStartFrameAnimation = null;
647 }
648 if (mRotateFrameAnimation != null) {
649 mRotateFrameAnimation.cancel();
650 mRotateFrameAnimation = null;
651 }
652 if (mFinishFrameAnimation != null) {
653 mFinishFrameAnimation.cancel();
654 mFinishFrameAnimation = null;
655 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800656 }
657 if (mRotateExitAnimation != null) {
658 mRotateExitAnimation.cancel();
659 mRotateExitAnimation = null;
660 }
661 if (mRotateEnterAnimation != null) {
662 mRotateEnterAnimation.cancel();
663 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800664 }
665 }
666
667 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700668 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700669 }
670
Dianne Hackborn4b169692012-11-29 17:51:24 -0800671 public boolean isRotating() {
672 return mCurRotation != mOriginalRotation;
673 }
674
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700675 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700676 return (TWO_PHASE_ANIMATION &&
677 (mStartEnterAnimation != null || mStartExitAnimation != null
678 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
679 || (USE_CUSTOM_BLACK_FRAME &&
680 (mStartFrameAnimation != null || mRotateFrameAnimation != null
681 || mFinishFrameAnimation != null))
682 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800683 }
684
Craig Mautnere32c3072012-03-12 15:25:35 -0700685 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700686 if (now > mHalfwayPoint) {
687 mHalfwayPoint = Long.MAX_VALUE;
688 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800689 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
690 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
691 mFinishAnimStartTime = now;
692 }
693
Craig Mautner7d8df392012-04-06 15:26:23 -0700694 if (TWO_PHASE_ANIMATION) {
695 mMoreStartExit = false;
696 if (mStartExitAnimation != null) {
697 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
698 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
699 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800700
Craig Mautner7d8df392012-04-06 15:26:23 -0700701 mMoreStartEnter = false;
702 if (mStartEnterAnimation != null) {
703 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
704 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
705 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800706 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700707 if (USE_CUSTOM_BLACK_FRAME) {
708 mMoreStartFrame = false;
709 if (mStartFrameAnimation != null) {
710 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
711 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
712 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800713 }
714
Craig Mautnerdbb79912012-03-01 18:59:14 -0800715 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
716 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
717
Craig Mautner7d8df392012-04-06 15:26:23 -0700718 if (TWO_PHASE_ANIMATION) {
719 mMoreFinishExit = false;
720 if (mFinishExitAnimation != null) {
721 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
722 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
723 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800724
Craig Mautner7d8df392012-04-06 15:26:23 -0700725 mMoreFinishEnter = false;
726 if (mFinishEnterAnimation != null) {
727 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
728 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
729 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800730 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700731 if (USE_CUSTOM_BLACK_FRAME) {
732 mMoreFinishFrame = false;
733 if (mFinishFrameAnimation != null) {
734 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
735 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
736 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800737 }
738
Craig Mautnerdbb79912012-03-01 18:59:14 -0800739 mMoreRotateExit = false;
740 if (mRotateExitAnimation != null) {
741 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
742 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700743 }
744
745 mMoreRotateEnter = false;
746 if (mRotateEnterAnimation != null) {
747 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
748 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
749 }
750
Craig Mautner7d8df392012-04-06 15:26:23 -0700751 if (USE_CUSTOM_BLACK_FRAME) {
752 mMoreRotateFrame = false;
753 if (mRotateFrameAnimation != null) {
754 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
755 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
756 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700757 }
758
Craig Mautner7d8df392012-04-06 15:26:23 -0700759 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
760 if (TWO_PHASE_ANIMATION) {
761 if (mStartExitAnimation != null) {
762 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
763 mStartExitAnimation.cancel();
764 mStartExitAnimation = null;
765 mStartExitTransformation.clear();
766 }
767 if (mFinishExitAnimation != null) {
768 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
769 mFinishExitAnimation.cancel();
770 mFinishExitAnimation = null;
771 mFinishExitTransformation.clear();
772 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700773 }
774 if (mRotateExitAnimation != null) {
775 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800776 mRotateExitAnimation.cancel();
777 mRotateExitAnimation = null;
778 mRotateExitTransformation.clear();
779 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800780 }
781
Craig Mautner7d8df392012-04-06 15:26:23 -0700782 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
783 if (TWO_PHASE_ANIMATION) {
784 if (mStartEnterAnimation != null) {
785 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
786 mStartEnterAnimation.cancel();
787 mStartEnterAnimation = null;
788 mStartEnterTransformation.clear();
789 }
790 if (mFinishEnterAnimation != null) {
791 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
792 mFinishEnterAnimation.cancel();
793 mFinishEnterAnimation = null;
794 mFinishEnterTransformation.clear();
795 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700796 }
797 if (mRotateEnterAnimation != null) {
798 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800799 mRotateEnterAnimation.cancel();
800 mRotateEnterAnimation = null;
801 mRotateEnterTransformation.clear();
802 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800803 }
804
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700805 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
806 if (mStartFrameAnimation != null) {
807 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
808 mStartFrameAnimation.cancel();
809 mStartFrameAnimation = null;
810 mStartFrameTransformation.clear();
811 }
812 if (mFinishFrameAnimation != null) {
813 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
814 mFinishFrameAnimation.cancel();
815 mFinishFrameAnimation = null;
816 mFinishFrameTransformation.clear();
817 }
818 if (mRotateFrameAnimation != null) {
819 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800820 mRotateFrameAnimation.cancel();
821 mRotateFrameAnimation = null;
822 mRotateFrameTransformation.clear();
823 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800824 }
825
826 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800827 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700828 if (TWO_PHASE_ANIMATION) {
829 mExitTransformation.compose(mStartExitTransformation);
830 mExitTransformation.compose(mFinishExitTransformation);
831
832 mEnterTransformation.compose(mStartEnterTransformation);
833 mEnterTransformation.compose(mFinishEnterTransformation);
834 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800835
836 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
837 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700838
839 if (USE_CUSTOM_BLACK_FRAME) {
840 //mFrameTransformation.set(mRotateExitTransformation);
841 //mFrameTransformation.compose(mStartExitTransformation);
842 //mFrameTransformation.compose(mFinishExitTransformation);
843 mFrameTransformation.set(mRotateFrameTransformation);
844 mFrameTransformation.compose(mStartFrameTransformation);
845 mFrameTransformation.compose(mFinishFrameTransformation);
846 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
847 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
848 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800849
Craig Mautner7d8df392012-04-06 15:26:23 -0700850 final boolean more = (TWO_PHASE_ANIMATION
851 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
852 || (USE_CUSTOM_BLACK_FRAME
853 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
854 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800855 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800856
857 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
858
859 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
860
861 return more;
862 }
863
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700864 void updateSurfacesInTransaction() {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700865 if (!mStarted) {
866 return;
867 }
868
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700869 if (mSurface != null) {
870 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800871 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
872 mSurface.hide();
873 }
874 }
875
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700876 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700877 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800878 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700879 mCustomBlackFrame.hide();
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700880 } else {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700881 mCustomBlackFrame.setMatrix(mFrameTransformation.getMatrix());
882 }
883 }
884
885 if (mExitingBlackFrame != null) {
886 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
887 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
888 mExitingBlackFrame.hide();
889 } else {
890 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
891 mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700892 }
893 }
894
895 if (mEnteringBlackFrame != null) {
896 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
897 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
898 mEnteringBlackFrame.hide();
899 } else {
900 mEnteringBlackFrame.setMatrix(mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800901 }
902 }
903
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700904 setSnapshotTransformInTransaction(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800905 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700906
Craig Mautnere32c3072012-03-12 15:25:35 -0700907 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700908 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800909 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800910 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800911 return false;
912 }
913
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800914 if (!mAnimRunning) {
915 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700916 if (TWO_PHASE_ANIMATION) {
917 if (mStartEnterAnimation != null) {
918 mStartEnterAnimation.setStartTime(now);
919 }
920 if (mStartExitAnimation != null) {
921 mStartExitAnimation.setStartTime(now);
922 }
923 if (mFinishEnterAnimation != null) {
924 mFinishEnterAnimation.setStartTime(0);
925 }
926 if (mFinishExitAnimation != null) {
927 mFinishExitAnimation.setStartTime(0);
928 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700929 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700930 if (USE_CUSTOM_BLACK_FRAME) {
931 if (mStartFrameAnimation != null) {
932 mStartFrameAnimation.setStartTime(now);
933 }
934 if (mFinishFrameAnimation != null) {
935 mFinishFrameAnimation.setStartTime(0);
936 }
937 if (mRotateFrameAnimation != null) {
938 mRotateFrameAnimation.setStartTime(now);
939 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800940 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800941 if (mRotateEnterAnimation != null) {
942 mRotateEnterAnimation.setStartTime(now);
943 }
944 if (mRotateExitAnimation != null) {
945 mRotateExitAnimation.setStartTime(now);
946 }
947 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -0700948 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800949 }
Craig Mautnere32c3072012-03-12 15:25:35 -0700950
951 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800952 }
953
954 public Transformation getEnterTransformation() {
955 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800956 }
957}