blob: 142c60d68852931fa9a4daf51783b44ae0ae294b [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;
Dianne Hackborna1111872010-11-23 20:55:11 -080045 Surface mSurface;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070046 BlackFrame mCustomBlackFrame;
47 BlackFrame mExitingBlackFrame;
48 BlackFrame mEnteringBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080049 int mWidth, mHeight;
50
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080051 int mOriginalRotation;
52 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080053 int mCurRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -080054
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080055 // For all animations, "exit" is for the UI elements that are going
56 // away (that is the snapshot of the old screen), and "enter" is for
57 // the new UI elements that are appearing (that is the active windows
58 // in their final orientation).
59
60 // The starting animation for the exiting and entering elements. This
61 // animation applies a transformation while the rotation is in progress.
62 // It is started immediately, before the new entering UI is ready.
63 Animation mStartExitAnimation;
64 final Transformation mStartExitTransformation = new Transformation();
65 Animation mStartEnterAnimation;
66 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080067 Animation mStartFrameAnimation;
68 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080069
70 // The finishing animation for the exiting and entering elements. This
71 // animation needs to undo the transformation of the starting animation.
72 // It starts running once the new rotation UI elements are ready to be
73 // displayed.
74 Animation mFinishExitAnimation;
75 final Transformation mFinishExitTransformation = new Transformation();
76 Animation mFinishEnterAnimation;
77 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080078 Animation mFinishFrameAnimation;
79 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080080
81 // The current active animation to move from the old to the new rotated
82 // state. Which animation is run here will depend on the old and new
83 // rotations.
84 Animation mRotateExitAnimation;
85 final Transformation mRotateExitTransformation = new Transformation();
86 Animation mRotateEnterAnimation;
87 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080088 Animation mRotateFrameAnimation;
89 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080090
91 // A previously running rotate animation. This will be used if we need
92 // to switch to a new rotation before finishing the previous one.
93 Animation mLastRotateExitAnimation;
94 final Transformation mLastRotateExitTransformation = new Transformation();
95 Animation mLastRotateEnterAnimation;
96 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080097 Animation mLastRotateFrameAnimation;
98 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080099
100 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800101 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800102 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800103 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800104
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800105 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800106 boolean mAnimRunning;
107 boolean mFinishAnimReady;
108 long mFinishAnimStartTime;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800109
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800110 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800111 final Matrix mSnapshotInitialMatrix = new Matrix();
112 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700113 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800114 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800115 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800116 private boolean mMoreRotateEnter;
117 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800118 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800119 private boolean mMoreFinishEnter;
120 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800121 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800122 private boolean mMoreStartEnter;
123 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800124 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700125 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800126
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800127 public void printTo(String prefix, PrintWriter pw) {
128 pw.print(prefix); pw.print("mSurface="); pw.print(mSurface);
129 pw.print(" mWidth="); pw.print(mWidth);
130 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700131 if (USE_CUSTOM_BLACK_FRAME) {
132 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
133 if (mCustomBlackFrame != null) {
134 mCustomBlackFrame.printTo(prefix + " ", pw);
135 }
136 }
137 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
138 if (mExitingBlackFrame != null) {
139 mExitingBlackFrame.printTo(prefix + " ", pw);
140 }
141 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
142 if (mEnteringBlackFrame != null) {
143 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800144 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700145 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
146 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
147 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800148 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
149 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
150 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
151 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
152 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
153 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
154 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
155 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
156 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800157 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
158 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800159 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
160 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
161 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
162 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800163 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
164 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800165 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
166 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
167 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
168 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800169 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
170 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800171 pw.print(prefix); pw.print("mExitTransformation=");
172 mExitTransformation.printShortString(pw); pw.println();
173 pw.print(prefix); pw.print("mEnterTransformation=");
174 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800175 pw.print(prefix); pw.print("mFrameTransformation=");
176 mEnterTransformation.printShortString(pw); pw.println();
177 pw.print(prefix); pw.print("mFrameInitialMatrix=");
178 mFrameInitialMatrix.printShortString(pw);
179 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800180 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
181 mSnapshotInitialMatrix.printShortString(pw);
182 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
183 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700184 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
185 mExitFrameFinalMatrix.printShortString(pw);
186 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800187 }
188
Jeff Brownbc68a592011-07-25 12:58:12 -0700189 public ScreenRotationAnimation(Context context, SurfaceSession session,
190 boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800191 mContext = context;
Dianne Hackborna1111872010-11-23 20:55:11 -0800192
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800193 // Screenshot does NOT include rotation!
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700194 if (originalRotation == Surface.ROTATION_90
195 || originalRotation == Surface.ROTATION_270) {
196 mWidth = originalHeight;
197 mHeight = originalWidth;
198 } else {
199 mWidth = originalWidth;
200 mHeight = originalHeight;
201 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800202
Jeff Brownbc68a592011-07-25 12:58:12 -0700203 mOriginalRotation = originalRotation;
204 mOriginalWidth = originalWidth;
205 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800206
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800207 if (!inTransaction) {
Dianne Hackborn36991742011-10-11 21:35:26 -0700208 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800209 ">>> OPEN TRANSACTION ScreenRotationAnimation");
210 Surface.openTransaction();
211 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700212
Dianne Hackborna1111872010-11-23 20:55:11 -0800213 try {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800214 try {
Craig Mautner7d8df392012-04-06 15:26:23 -0700215 if (WindowManagerService.DEBUG_SURFACE_TRACE) {
Craig Mautner6881a102012-07-27 13:04:51 -0700216 mSurface = new SurfaceTrace(session, 0, "FreezeSurface", Display.DEFAULT_DISPLAY,
217 mWidth, mHeight,
Craig Mautner7d8df392012-04-06 15:26:23 -0700218 PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
219 } else {
Craig Mautner6881a102012-07-27 13:04:51 -0700220 mSurface = new Surface(session, 0, "FreezeSurface", Display.DEFAULT_DISPLAY,
221 mWidth, mHeight,
Craig Mautner7d8df392012-04-06 15:26:23 -0700222 PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
223 }
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700224 if (!mSurface.isValid()) {
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700225 // Screenshot failed, punt.
226 mSurface = null;
227 return;
228 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700229 mSurface.setLayer(FREEZE_LAYER + 1);
Craig Mautner7d8df392012-04-06 15:26:23 -0700230 mSurface.setAlpha(0);
Mathias Agopiane65beaa2011-11-01 14:39:06 -0700231 mSurface.show();
Dianne Hackborn352cc982011-01-04 11:34:18 -0800232 } catch (Surface.OutOfResourcesException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800233 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800234 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800235
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700236 if (WindowManagerService.SHOW_TRANSACTIONS ||
237 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
238 " FREEZE " + mSurface + ": CREATE");
239
Jeff Brownbc68a592011-07-25 12:58:12 -0700240 setRotation(originalRotation);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800241 } finally {
242 if (!inTransaction) {
243 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -0700244 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800245 "<<< CLOSE TRANSACTION ScreenRotationAnimation");
Dianne Hackborn352cc982011-01-04 11:34:18 -0800246 }
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800247 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800248 }
249
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800250 boolean hasScreenshot() {
251 return mSurface != null;
252 }
253
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800254 static int deltaRotation(int oldRotation, int newRotation) {
255 int delta = newRotation - oldRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800256 if (delta < 0) delta += 4;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800257 return delta;
258 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800259
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800260 void setSnapshotTransform(Matrix matrix, float alpha) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800261 if (mSurface != null) {
262 matrix.getValues(mTmpFloats);
Dianne Hackbornd040edb2011-08-31 12:47:58 -0700263 mSurface.setPosition(mTmpFloats[Matrix.MTRANS_X],
264 mTmpFloats[Matrix.MTRANS_Y]);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800265 mSurface.setMatrix(
266 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
267 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
268 mSurface.setAlpha(alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800269 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800270 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
271 float[] dstPnts = new float[4];
272 matrix.mapPoints(dstPnts, srcPnts);
273 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
274 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
275 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
276 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
277 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800278 }
279 }
280
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800281 public static void createRotationMatrix(int rotation, int width, int height,
282 Matrix outMatrix) {
283 switch (rotation) {
284 case Surface.ROTATION_0:
285 outMatrix.reset();
286 break;
287 case Surface.ROTATION_90:
288 outMatrix.setRotate(90, 0, 0);
289 outMatrix.postTranslate(height, 0);
290 break;
291 case Surface.ROTATION_180:
292 outMatrix.setRotate(180, 0, 0);
293 outMatrix.postTranslate(width, height);
294 break;
295 case Surface.ROTATION_270:
296 outMatrix.setRotate(270, 0, 0);
297 outMatrix.postTranslate(0, width);
298 break;
299 }
300 }
301
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800302 // Must be called while in a transaction.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800303 private void setRotation(int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800304 mCurRotation = rotation;
305
306 // Compute the transformation matrix that must be applied
307 // to the snapshot to make it stay in the same original position
308 // with the current screen rotation.
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700309 int delta = deltaRotation(rotation, Surface.ROTATION_0);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800310 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800311
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800312 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800313 setSnapshotTransform(mSnapshotInitialMatrix, 1.0f);
314 }
315
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800316 // Must be called while in a transaction.
317 public boolean setRotation(int rotation, SurfaceSession session,
318 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
319 setRotation(rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700320 if (TWO_PHASE_ANIMATION) {
321 return startAnimation(session, maxAnimationDuration, animationScale,
322 finalWidth, finalHeight, false);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700323 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700324
325 // Don't start animation yet.
326 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800327 }
328
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800329 /**
330 * Returns true if animating.
331 */
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800332 private boolean startAnimation(SurfaceSession session, long maxAnimationDuration,
333 float animationScale, int finalWidth, int finalHeight, boolean dismissing) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800334 if (mSurface == null) {
335 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800336 return false;
337 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800338 if (mStarted) {
339 return true;
340 }
341
342 mStarted = true;
343
344 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800345
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800346 // Figure out how the screen has moved from the original rotation.
347 int delta = deltaRotation(mCurRotation, mOriginalRotation);
348
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700349 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
350 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800351 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
352 firstStart = true;
353 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
354 com.android.internal.R.anim.screen_rotate_start_exit);
355 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
356 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700357 if (USE_CUSTOM_BLACK_FRAME) {
358 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
359 com.android.internal.R.anim.screen_rotate_start_frame);
360 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800361 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
362 com.android.internal.R.anim.screen_rotate_finish_exit);
363 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
364 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700365 if (USE_CUSTOM_BLACK_FRAME) {
366 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
367 com.android.internal.R.anim.screen_rotate_finish_frame);
368 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800369 }
370
371 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
372 + finalWidth + " finalHeight=" + finalHeight
373 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
374
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800375 switch (delta) {
376 case Surface.ROTATION_0:
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800377 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800378 com.android.internal.R.anim.screen_rotate_0_exit);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800379 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800380 com.android.internal.R.anim.screen_rotate_0_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700381 if (USE_CUSTOM_BLACK_FRAME) {
382 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
383 com.android.internal.R.anim.screen_rotate_0_frame);
384 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800385 break;
386 case Surface.ROTATION_90:
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800387 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800388 com.android.internal.R.anim.screen_rotate_plus_90_exit);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800389 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800390 com.android.internal.R.anim.screen_rotate_plus_90_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700391 if (USE_CUSTOM_BLACK_FRAME) {
392 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
393 com.android.internal.R.anim.screen_rotate_plus_90_frame);
394 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800395 break;
396 case Surface.ROTATION_180:
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800397 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800398 com.android.internal.R.anim.screen_rotate_180_exit);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800399 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800400 com.android.internal.R.anim.screen_rotate_180_enter);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800401 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
402 com.android.internal.R.anim.screen_rotate_180_frame);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800403 break;
404 case Surface.ROTATION_270:
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800405 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800406 com.android.internal.R.anim.screen_rotate_minus_90_exit);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800407 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800408 com.android.internal.R.anim.screen_rotate_minus_90_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700409 if (USE_CUSTOM_BLACK_FRAME) {
410 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
411 com.android.internal.R.anim.screen_rotate_minus_90_frame);
412 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800413 break;
414 }
415
Dianne Hackborn191874e32012-03-09 11:03:36 -0800416 // Compute partial steps between original and final sizes. These
417 // are used for the dimensions of the exiting and entering elements,
418 // so they are never stretched too significantly.
419 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
420 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
421
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800422 // Initialize the animations. This is a hack, redefining what "parent"
423 // means to allow supplying the last and next size. In this definition
424 // "%p" is the original (let's call it "previous") size, and "%" is the
425 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700426 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800427 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
428 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800429 halfWidth, halfHeight);
430 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800431 mOriginalWidth, mOriginalHeight);
432 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800433 halfWidth, halfHeight);
434 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800435 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700436 if (USE_CUSTOM_BLACK_FRAME) {
437 mStartFrameAnimation.initialize(finalWidth, finalHeight,
438 mOriginalWidth, mOriginalHeight);
439 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
440 mOriginalWidth, mOriginalHeight);
441 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800442 }
443 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
444 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700445 if (USE_CUSTOM_BLACK_FRAME) {
446 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
447 mOriginalHeight);
448 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800449 mAnimRunning = false;
450 mFinishAnimReady = false;
451 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800452
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700453 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800454 mStartExitAnimation.restrictDuration(maxAnimationDuration);
455 mStartExitAnimation.scaleCurrentDuration(animationScale);
456 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
457 mStartEnterAnimation.scaleCurrentDuration(animationScale);
458 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
459 mFinishExitAnimation.scaleCurrentDuration(animationScale);
460 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
461 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700462 if (USE_CUSTOM_BLACK_FRAME) {
463 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
464 mStartFrameAnimation.scaleCurrentDuration(animationScale);
465 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
466 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
467 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800468 }
469 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
470 mRotateExitAnimation.scaleCurrentDuration(animationScale);
471 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
472 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700473 if (USE_CUSTOM_BLACK_FRAME) {
474 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
475 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
476 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800477
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700478 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800479 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
480 WindowManagerService.TAG,
481 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
482 Surface.openTransaction();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800483
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800484 // Compute the transformation matrix that must be applied
485 // the the black frame to make it stay in the initial position
486 // before the new screen rotation. This is different than the
487 // snapshot transformation because the snapshot is always based
488 // of the native orientation of the screen, not the orientation
489 // we were last in.
490 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
491
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800492 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800493 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
494 mOriginalWidth*2, mOriginalHeight*2);
495 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700496 mCustomBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 3);
497 mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
498 } catch (Surface.OutOfResourcesException e) {
499 Slog.w(TAG, "Unable to allocate black surface", e);
500 } finally {
501 Surface.closeTransaction();
502 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
503 WindowManagerService.TAG,
504 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
505 }
506 }
507
508 if (mExitingBlackFrame == null) {
509 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
510 WindowManagerService.TAG,
511 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
512 Surface.openTransaction();
513
514 // Compute the transformation matrix that must be applied
515 // the the black frame to make it stay in the initial position
516 // before the new screen rotation. This is different than the
517 // snapshot transformation because the snapshot is always based
518 // of the native orientation of the screen, not the orientation
519 // we were last in.
520 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
521
522 try {
523 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
524 mOriginalWidth*2, mOriginalHeight*2);
525 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
526 mExitingBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 2);
527 mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
528 } catch (Surface.OutOfResourcesException e) {
529 Slog.w(TAG, "Unable to allocate black surface", e);
530 } finally {
531 Surface.closeTransaction();
532 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
533 WindowManagerService.TAG,
534 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
535 }
536 }
537
538 if (false && mEnteringBlackFrame == null) {
539 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
540 WindowManagerService.TAG,
541 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
542 Surface.openTransaction();
543
544 try {
545 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
546 finalWidth*2, finalHeight*2);
547 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
548 mEnteringBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800549 } catch (Surface.OutOfResourcesException e) {
550 Slog.w(TAG, "Unable to allocate black surface", e);
551 } finally {
552 Surface.closeTransaction();
553 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
554 WindowManagerService.TAG,
555 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
556 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800557 }
558
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800559 return true;
560 }
561
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800562 /**
563 * Returns true if animating.
564 */
565 public boolean dismiss(SurfaceSession session, long maxAnimationDuration,
566 float animationScale, int finalWidth, int finalHeight) {
567 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
568 if (mSurface == null) {
569 // Can't do animation.
570 return false;
571 }
572 if (!mStarted) {
573 startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight,
574 true);
575 }
576 if (!mStarted) {
577 return false;
578 }
579 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
580 mFinishAnimReady = true;
581 return true;
582 }
583
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800584 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800585 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800586 if (mSurface != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700587 if (WindowManagerService.SHOW_TRANSACTIONS ||
588 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
589 " FREEZE " + mSurface + ": DESTROY");
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800590 mSurface.destroy();
591 mSurface = null;
592 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700593 if (mCustomBlackFrame != null) {
594 mCustomBlackFrame.kill();
595 mCustomBlackFrame = null;
596 }
597 if (mExitingBlackFrame != null) {
598 mExitingBlackFrame.kill();
599 mExitingBlackFrame = null;
600 }
601 if (mEnteringBlackFrame != null) {
602 mEnteringBlackFrame.kill();
603 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800604 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700605 if (TWO_PHASE_ANIMATION) {
606 if (mStartExitAnimation != null) {
607 mStartExitAnimation.cancel();
608 mStartExitAnimation = null;
609 }
610 if (mStartEnterAnimation != null) {
611 mStartEnterAnimation.cancel();
612 mStartEnterAnimation = null;
613 }
614 if (mFinishExitAnimation != null) {
615 mFinishExitAnimation.cancel();
616 mFinishExitAnimation = null;
617 }
618 if (mFinishEnterAnimation != null) {
619 mFinishEnterAnimation.cancel();
620 mFinishEnterAnimation = null;
621 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800622 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700623 if (USE_CUSTOM_BLACK_FRAME) {
624 if (mStartFrameAnimation != null) {
625 mStartFrameAnimation.cancel();
626 mStartFrameAnimation = null;
627 }
628 if (mRotateFrameAnimation != null) {
629 mRotateFrameAnimation.cancel();
630 mRotateFrameAnimation = null;
631 }
632 if (mFinishFrameAnimation != null) {
633 mFinishFrameAnimation.cancel();
634 mFinishFrameAnimation = null;
635 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800636 }
637 if (mRotateExitAnimation != null) {
638 mRotateExitAnimation.cancel();
639 mRotateExitAnimation = null;
640 }
641 if (mRotateEnterAnimation != null) {
642 mRotateEnterAnimation.cancel();
643 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800644 }
645 }
646
647 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700648 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700649 }
650
651 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700652 return (TWO_PHASE_ANIMATION &&
653 (mStartEnterAnimation != null || mStartExitAnimation != null
654 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
655 || (USE_CUSTOM_BLACK_FRAME &&
656 (mStartFrameAnimation != null || mRotateFrameAnimation != null
657 || mFinishFrameAnimation != null))
658 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800659 }
660
Craig Mautnere32c3072012-03-12 15:25:35 -0700661 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700662 if (now > mHalfwayPoint) {
663 mHalfwayPoint = Long.MAX_VALUE;
664 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800665 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
666 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
667 mFinishAnimStartTime = now;
668 }
669
Craig Mautner7d8df392012-04-06 15:26:23 -0700670 if (TWO_PHASE_ANIMATION) {
671 mMoreStartExit = false;
672 if (mStartExitAnimation != null) {
673 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
674 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
675 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800676
Craig Mautner7d8df392012-04-06 15:26:23 -0700677 mMoreStartEnter = false;
678 if (mStartEnterAnimation != null) {
679 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
680 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
681 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800682 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700683 if (USE_CUSTOM_BLACK_FRAME) {
684 mMoreStartFrame = false;
685 if (mStartFrameAnimation != null) {
686 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
687 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
688 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800689 }
690
Craig Mautnerdbb79912012-03-01 18:59:14 -0800691 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
692 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
693
Craig Mautner7d8df392012-04-06 15:26:23 -0700694 if (TWO_PHASE_ANIMATION) {
695 mMoreFinishExit = false;
696 if (mFinishExitAnimation != null) {
697 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
698 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
699 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800700
Craig Mautner7d8df392012-04-06 15:26:23 -0700701 mMoreFinishEnter = false;
702 if (mFinishEnterAnimation != null) {
703 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
704 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
705 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800706 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700707 if (USE_CUSTOM_BLACK_FRAME) {
708 mMoreFinishFrame = false;
709 if (mFinishFrameAnimation != null) {
710 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
711 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
712 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800713 }
714
Craig Mautnerdbb79912012-03-01 18:59:14 -0800715 mMoreRotateExit = false;
716 if (mRotateExitAnimation != null) {
717 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
718 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700719 }
720
721 mMoreRotateEnter = false;
722 if (mRotateEnterAnimation != null) {
723 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
724 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
725 }
726
Craig Mautner7d8df392012-04-06 15:26:23 -0700727 if (USE_CUSTOM_BLACK_FRAME) {
728 mMoreRotateFrame = false;
729 if (mRotateFrameAnimation != null) {
730 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
731 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
732 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700733 }
734
Craig Mautner7d8df392012-04-06 15:26:23 -0700735 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
736 if (TWO_PHASE_ANIMATION) {
737 if (mStartExitAnimation != null) {
738 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
739 mStartExitAnimation.cancel();
740 mStartExitAnimation = null;
741 mStartExitTransformation.clear();
742 }
743 if (mFinishExitAnimation != null) {
744 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
745 mFinishExitAnimation.cancel();
746 mFinishExitAnimation = null;
747 mFinishExitTransformation.clear();
748 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700749 }
750 if (mRotateExitAnimation != null) {
751 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800752 mRotateExitAnimation.cancel();
753 mRotateExitAnimation = null;
754 mRotateExitTransformation.clear();
755 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800756 }
757
Craig Mautner7d8df392012-04-06 15:26:23 -0700758 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
759 if (TWO_PHASE_ANIMATION) {
760 if (mStartEnterAnimation != null) {
761 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
762 mStartEnterAnimation.cancel();
763 mStartEnterAnimation = null;
764 mStartEnterTransformation.clear();
765 }
766 if (mFinishEnterAnimation != null) {
767 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
768 mFinishEnterAnimation.cancel();
769 mFinishEnterAnimation = null;
770 mFinishEnterTransformation.clear();
771 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700772 }
773 if (mRotateEnterAnimation != null) {
774 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800775 mRotateEnterAnimation.cancel();
776 mRotateEnterAnimation = null;
777 mRotateEnterTransformation.clear();
778 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800779 }
780
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700781 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
782 if (mStartFrameAnimation != null) {
783 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
784 mStartFrameAnimation.cancel();
785 mStartFrameAnimation = null;
786 mStartFrameTransformation.clear();
787 }
788 if (mFinishFrameAnimation != null) {
789 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
790 mFinishFrameAnimation.cancel();
791 mFinishFrameAnimation = null;
792 mFinishFrameTransformation.clear();
793 }
794 if (mRotateFrameAnimation != null) {
795 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800796 mRotateFrameAnimation.cancel();
797 mRotateFrameAnimation = null;
798 mRotateFrameTransformation.clear();
799 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800800 }
801
802 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800803 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700804 if (TWO_PHASE_ANIMATION) {
805 mExitTransformation.compose(mStartExitTransformation);
806 mExitTransformation.compose(mFinishExitTransformation);
807
808 mEnterTransformation.compose(mStartEnterTransformation);
809 mEnterTransformation.compose(mFinishEnterTransformation);
810 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800811
812 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
813 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700814
815 if (USE_CUSTOM_BLACK_FRAME) {
816 //mFrameTransformation.set(mRotateExitTransformation);
817 //mFrameTransformation.compose(mStartExitTransformation);
818 //mFrameTransformation.compose(mFinishExitTransformation);
819 mFrameTransformation.set(mRotateFrameTransformation);
820 mFrameTransformation.compose(mStartFrameTransformation);
821 mFrameTransformation.compose(mFinishFrameTransformation);
822 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
823 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
824 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800825
Craig Mautner7d8df392012-04-06 15:26:23 -0700826 final boolean more = (TWO_PHASE_ANIMATION
827 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
828 || (USE_CUSTOM_BLACK_FRAME
829 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
830 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800831 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800832
833 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
834
835 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
836
837 return more;
838 }
839
840 void updateSurfaces() {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700841 if (!mStarted) {
842 return;
843 }
844
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700845 if (mSurface != null) {
846 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800847 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
848 mSurface.hide();
849 }
850 }
851
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700852 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700853 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800854 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700855 mCustomBlackFrame.hide();
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700856 } else {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700857 mCustomBlackFrame.setMatrix(mFrameTransformation.getMatrix());
858 }
859 }
860
861 if (mExitingBlackFrame != null) {
862 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
863 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
864 mExitingBlackFrame.hide();
865 } else {
866 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
867 mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700868 }
869 }
870
871 if (mEnteringBlackFrame != null) {
872 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
873 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
874 mEnteringBlackFrame.hide();
875 } else {
876 mEnteringBlackFrame.setMatrix(mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800877 }
878 }
879
880 setSnapshotTransform(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
881 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700882
Craig Mautnere32c3072012-03-12 15:25:35 -0700883 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700884 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800885 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800886 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800887 return false;
888 }
889
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800890 if (!mAnimRunning) {
891 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700892 if (TWO_PHASE_ANIMATION) {
893 if (mStartEnterAnimation != null) {
894 mStartEnterAnimation.setStartTime(now);
895 }
896 if (mStartExitAnimation != null) {
897 mStartExitAnimation.setStartTime(now);
898 }
899 if (mFinishEnterAnimation != null) {
900 mFinishEnterAnimation.setStartTime(0);
901 }
902 if (mFinishExitAnimation != null) {
903 mFinishExitAnimation.setStartTime(0);
904 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700905 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700906 if (USE_CUSTOM_BLACK_FRAME) {
907 if (mStartFrameAnimation != null) {
908 mStartFrameAnimation.setStartTime(now);
909 }
910 if (mFinishFrameAnimation != null) {
911 mFinishFrameAnimation.setStartTime(0);
912 }
913 if (mRotateFrameAnimation != null) {
914 mRotateFrameAnimation.setStartTime(now);
915 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800916 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800917 if (mRotateEnterAnimation != null) {
918 mRotateEnterAnimation.setStartTime(now);
919 }
920 if (mRotateExitAnimation != null) {
921 mRotateExitAnimation.setStartTime(now);
922 }
923 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -0700924 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800925 }
Craig Mautnere32c3072012-03-12 15:25:35 -0700926
927 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800928 }
929
930 public Transformation getEnterTransformation() {
931 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800932 }
933}