blob: 55fb03831b6c38d4b9f1b900de1211f43d303ee4 [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 Hackbornf9d0be92010-11-24 12:35:25 -080019import android.content.Context;
Dianne Hackborna1111872010-11-23 20:55:11 -080020import android.graphics.Matrix;
Dianne Hackborna1111872010-11-23 20:55:11 -080021import android.graphics.PixelFormat;
22import android.graphics.Rect;
Dianne Hackborna1111872010-11-23 20:55:11 -080023import android.util.Slog;
Dianne Hackborna1111872010-11-23 20:55:11 -080024import android.view.Surface;
25import android.view.SurfaceSession;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080026import android.view.animation.Animation;
27import android.view.animation.AnimationUtils;
28import android.view.animation.Transformation;
Dianne Hackborna1111872010-11-23 20:55:11 -080029
30class ScreenRotationAnimation {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080031 static final String TAG = "ScreenRotationAnimation";
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080032 static final boolean DEBUG_STATE = false;
33 static final boolean DEBUG_TRANSFORMS = false;
Dianne Hackborna1111872010-11-23 20:55:11 -080034
Dianne Hackborn50660e22011-02-02 17:12:25 -080035 static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200;
36
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080037 final Context mContext;
Dianne Hackborna1111872010-11-23 20:55:11 -080038 Surface mSurface;
Dianne Hackborn7916ac62011-05-16 20:45:48 -070039 BlackFrame mBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080040 int mWidth, mHeight;
41
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080042 int mSnapshotRotation;
43 int mSnapshotDeltaRotation;
44 int mOriginalRotation;
45 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080046 int mCurRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -080047
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080048 // For all animations, "exit" is for the UI elements that are going
49 // away (that is the snapshot of the old screen), and "enter" is for
50 // the new UI elements that are appearing (that is the active windows
51 // in their final orientation).
52
53 // The starting animation for the exiting and entering elements. This
54 // animation applies a transformation while the rotation is in progress.
55 // It is started immediately, before the new entering UI is ready.
56 Animation mStartExitAnimation;
57 final Transformation mStartExitTransformation = new Transformation();
58 Animation mStartEnterAnimation;
59 final Transformation mStartEnterTransformation = new Transformation();
60
61 // The finishing animation for the exiting and entering elements. This
62 // animation needs to undo the transformation of the starting animation.
63 // It starts running once the new rotation UI elements are ready to be
64 // displayed.
65 Animation mFinishExitAnimation;
66 final Transformation mFinishExitTransformation = new Transformation();
67 Animation mFinishEnterAnimation;
68 final Transformation mFinishEnterTransformation = new Transformation();
69
70 // The current active animation to move from the old to the new rotated
71 // state. Which animation is run here will depend on the old and new
72 // rotations.
73 Animation mRotateExitAnimation;
74 final Transformation mRotateExitTransformation = new Transformation();
75 Animation mRotateEnterAnimation;
76 final Transformation mRotateEnterTransformation = new Transformation();
77
78 // A previously running rotate animation. This will be used if we need
79 // to switch to a new rotation before finishing the previous one.
80 Animation mLastRotateExitAnimation;
81 final Transformation mLastRotateExitTransformation = new Transformation();
82 Animation mLastRotateEnterAnimation;
83 final Transformation mLastRotateEnterTransformation = new Transformation();
84
85 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080086 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080087 final Transformation mEnterTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080088
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080089 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080090 boolean mAnimRunning;
91 boolean mFinishAnimReady;
92 long mFinishAnimStartTime;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080093
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080094 final Matrix mSnapshotInitialMatrix = new Matrix();
95 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -080096 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -080097 final float[] mTmpFloats = new float[9];
98
Jeff Brownbc68a592011-07-25 12:58:12 -070099 public ScreenRotationAnimation(Context context, SurfaceSession session,
100 boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800101 mContext = context;
Dianne Hackborna1111872010-11-23 20:55:11 -0800102
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800103 // Screenshot does NOT include rotation!
104 mSnapshotRotation = 0;
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700105 if (originalRotation == Surface.ROTATION_90
106 || originalRotation == Surface.ROTATION_270) {
107 mWidth = originalHeight;
108 mHeight = originalWidth;
109 } else {
110 mWidth = originalWidth;
111 mHeight = originalHeight;
112 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800113
Jeff Brownbc68a592011-07-25 12:58:12 -0700114 mOriginalRotation = originalRotation;
115 mOriginalWidth = originalWidth;
116 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800117
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800118 if (!inTransaction) {
Dianne Hackborn36991742011-10-11 21:35:26 -0700119 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800120 ">>> OPEN TRANSACTION ScreenRotationAnimation");
121 Surface.openTransaction();
122 }
Dianne Hackborn352cc982011-01-04 11:34:18 -0800123
Dianne Hackborna1111872010-11-23 20:55:11 -0800124 try {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800125 try {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800126 mSurface = new Surface(session, 0, "FreezeSurface",
Mathias Agopiane65beaa2011-11-01 14:39:06 -0700127 -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700128 if (mSurface == null || !mSurface.isValid()) {
129 // Screenshot failed, punt.
130 mSurface = null;
131 return;
132 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800133 mSurface.setLayer(FREEZE_LAYER + 1);
Mathias Agopiane65beaa2011-11-01 14:39:06 -0700134 mSurface.show();
Dianne Hackborn352cc982011-01-04 11:34:18 -0800135 } catch (Surface.OutOfResourcesException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800136 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800137 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800138
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700139 if (WindowManagerService.SHOW_TRANSACTIONS ||
140 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
141 " FREEZE " + mSurface + ": CREATE");
142
Jeff Brownbc68a592011-07-25 12:58:12 -0700143 setRotation(originalRotation);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800144 } finally {
145 if (!inTransaction) {
146 Surface.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -0700147 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800148 "<<< CLOSE TRANSACTION ScreenRotationAnimation");
Dianne Hackborn352cc982011-01-04 11:34:18 -0800149 }
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800150 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800151 }
152
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800153 boolean hasScreenshot() {
154 return mSurface != null;
155 }
156
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800157 static int deltaRotation(int oldRotation, int newRotation) {
158 int delta = newRotation - oldRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800159 if (delta < 0) delta += 4;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800160 return delta;
161 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800162
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800163 void setSnapshotTransform(Matrix matrix, float alpha) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800164 if (mSurface != null) {
165 matrix.getValues(mTmpFloats);
Dianne Hackbornd040edb2011-08-31 12:47:58 -0700166 mSurface.setPosition(mTmpFloats[Matrix.MTRANS_X],
167 mTmpFloats[Matrix.MTRANS_Y]);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800168 mSurface.setMatrix(
169 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
170 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
171 mSurface.setAlpha(alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800172 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800173 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
174 float[] dstPnts = new float[4];
175 matrix.mapPoints(dstPnts, srcPnts);
176 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
177 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
178 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
179 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
180 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800181 }
182 }
183
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800184 public static void createRotationMatrix(int rotation, int width, int height,
185 Matrix outMatrix) {
186 switch (rotation) {
187 case Surface.ROTATION_0:
188 outMatrix.reset();
189 break;
190 case Surface.ROTATION_90:
191 outMatrix.setRotate(90, 0, 0);
192 outMatrix.postTranslate(height, 0);
193 break;
194 case Surface.ROTATION_180:
195 outMatrix.setRotate(180, 0, 0);
196 outMatrix.postTranslate(width, height);
197 break;
198 case Surface.ROTATION_270:
199 outMatrix.setRotate(270, 0, 0);
200 outMatrix.postTranslate(0, width);
201 break;
202 }
203 }
204
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800205 // Must be called while in a transaction.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800206 private void setRotation(int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800207 mCurRotation = rotation;
208
209 // Compute the transformation matrix that must be applied
210 // to the snapshot to make it stay in the same original position
211 // with the current screen rotation.
212 int delta = deltaRotation(rotation, mSnapshotRotation);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800213 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800214
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800215 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800216 setSnapshotTransform(mSnapshotInitialMatrix, 1.0f);
217 }
218
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800219 // Must be called while in a transaction.
220 public boolean setRotation(int rotation, SurfaceSession session,
221 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
222 setRotation(rotation);
223 return startAnimation(session, maxAnimationDuration, animationScale,
224 finalWidth, finalHeight, false);
225 }
226
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800227 /**
228 * Returns true if animating.
229 */
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800230 private boolean startAnimation(SurfaceSession session, long maxAnimationDuration,
231 float animationScale, int finalWidth, int finalHeight, boolean dismissing) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800232 if (mSurface == null) {
233 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800234 return false;
235 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800236 if (mStarted) {
237 return true;
238 }
239
240 mStarted = true;
241
242 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800243
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800244 // Figure out how the screen has moved from the original rotation.
245 int delta = deltaRotation(mCurRotation, mOriginalRotation);
246
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800247 if (mFinishExitAnimation == null && (!dismissing || delta != Surface.ROTATION_0)) {
248 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
249 firstStart = true;
250 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
251 com.android.internal.R.anim.screen_rotate_start_exit);
252 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
253 com.android.internal.R.anim.screen_rotate_start_enter);
254 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
255 com.android.internal.R.anim.screen_rotate_finish_exit);
256 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
257 com.android.internal.R.anim.screen_rotate_finish_enter);
258 }
259
260 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
261 + finalWidth + " finalHeight=" + finalHeight
262 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
263
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800264 switch (delta) {
265 case Surface.ROTATION_0:
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800266 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800267 com.android.internal.R.anim.screen_rotate_0_exit);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800268 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800269 com.android.internal.R.anim.screen_rotate_0_enter);
270 break;
271 case Surface.ROTATION_90:
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800272 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800273 com.android.internal.R.anim.screen_rotate_plus_90_exit);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800274 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800275 com.android.internal.R.anim.screen_rotate_plus_90_enter);
276 break;
277 case Surface.ROTATION_180:
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800278 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800279 com.android.internal.R.anim.screen_rotate_180_exit);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800280 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800281 com.android.internal.R.anim.screen_rotate_180_enter);
282 break;
283 case Surface.ROTATION_270:
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800284 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800285 com.android.internal.R.anim.screen_rotate_minus_90_exit);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800286 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800287 com.android.internal.R.anim.screen_rotate_minus_90_enter);
288 break;
289 }
290
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800291 // Initialize the animations. This is a hack, redefining what "parent"
292 // means to allow supplying the last and next size. In this definition
293 // "%p" is the original (let's call it "previous") size, and "%" is the
294 // screen's current/new size.
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800295 if (firstStart) {
296 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
297 mStartEnterAnimation.initialize(finalWidth, finalHeight,
298 mOriginalWidth, mOriginalHeight);
299 mStartExitAnimation.initialize(finalWidth, finalHeight,
300 mOriginalWidth, mOriginalHeight);
301 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
302 mOriginalWidth, mOriginalHeight);
303 mFinishExitAnimation.initialize(finalWidth, finalHeight,
304 mOriginalWidth, mOriginalHeight);
305 }
306 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
307 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
308 mAnimRunning = false;
309 mFinishAnimReady = false;
310 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800311
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800312 if (firstStart) {
313 mStartExitAnimation.restrictDuration(maxAnimationDuration);
314 mStartExitAnimation.scaleCurrentDuration(animationScale);
315 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
316 mStartEnterAnimation.scaleCurrentDuration(animationScale);
317 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
318 mFinishExitAnimation.scaleCurrentDuration(animationScale);
319 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
320 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
321 }
322 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
323 mRotateExitAnimation.scaleCurrentDuration(animationScale);
324 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
325 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800326
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800327 if (mBlackFrame == null) {
328 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
329 WindowManagerService.TAG,
330 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
331 Surface.openTransaction();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800332
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800333 try {
334 Rect outer = new Rect(-finalWidth*1, -finalHeight*1, finalWidth*2, finalHeight*2);
335 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
336 mBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER);
337 } catch (Surface.OutOfResourcesException e) {
338 Slog.w(TAG, "Unable to allocate black surface", e);
339 } finally {
340 Surface.closeTransaction();
341 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
342 WindowManagerService.TAG,
343 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
344 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800345 }
346
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800347 return true;
348 }
349
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800350 /**
351 * Returns true if animating.
352 */
353 public boolean dismiss(SurfaceSession session, long maxAnimationDuration,
354 float animationScale, int finalWidth, int finalHeight) {
355 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
356 if (mSurface == null) {
357 // Can't do animation.
358 return false;
359 }
360 if (!mStarted) {
361 startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight,
362 true);
363 }
364 if (!mStarted) {
365 return false;
366 }
367 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
368 mFinishAnimReady = true;
369 return true;
370 }
371
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800372 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800373 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800374 if (mSurface != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700375 if (WindowManagerService.SHOW_TRANSACTIONS ||
376 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
377 " FREEZE " + mSurface + ": DESTROY");
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800378 mSurface.destroy();
379 mSurface = null;
380 }
Dianne Hackborn7916ac62011-05-16 20:45:48 -0700381 if (mBlackFrame != null) {
382 mBlackFrame.kill();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800383 mBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800384 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800385 if (mStartExitAnimation != null) {
386 mStartExitAnimation.cancel();
387 mStartExitAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800388 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800389 if (mStartEnterAnimation != null) {
390 mStartEnterAnimation.cancel();
391 mStartEnterAnimation = null;
392 }
393 if (mFinishExitAnimation != null) {
394 mFinishExitAnimation.cancel();
395 mFinishExitAnimation = null;
396 }
397 if (mStartEnterAnimation != null) {
398 mStartEnterAnimation.cancel();
399 mStartEnterAnimation = null;
400 }
401 if (mRotateExitAnimation != null) {
402 mRotateExitAnimation.cancel();
403 mRotateExitAnimation = null;
404 }
405 if (mRotateEnterAnimation != null) {
406 mRotateEnterAnimation.cancel();
407 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800408 }
409 }
410
411 public boolean isAnimating() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800412 return mStartEnterAnimation != null || mStartExitAnimation != null
413 && mFinishEnterAnimation != null || mFinishExitAnimation != null
414 && mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800415 }
416
417 public boolean stepAnimation(long now) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800418 if (!isAnimating()) {
419 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800420 return false;
421 }
422
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800423 if (!mAnimRunning) {
424 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
425 if (mStartEnterAnimation != null) {
426 mStartEnterAnimation.setStartTime(now);
Dianne Hackborn89620282011-09-11 12:47:45 -0700427 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800428 if (mStartExitAnimation != null) {
429 mStartExitAnimation.setStartTime(now);
Dianne Hackborn89620282011-09-11 12:47:45 -0700430 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800431 if (mFinishEnterAnimation != null) {
432 mFinishEnterAnimation.setStartTime(0);
433 }
434 if (mFinishExitAnimation != null) {
435 mFinishExitAnimation.setStartTime(0);
436 }
437 if (mRotateEnterAnimation != null) {
438 mRotateEnterAnimation.setStartTime(now);
439 }
440 if (mRotateExitAnimation != null) {
441 mRotateExitAnimation.setStartTime(now);
442 }
443 mAnimRunning = true;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800444 }
445
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800446 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
447 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
448 mFinishAnimStartTime = now;
449 }
450
451 // If the start animation is no longer running, we want to keep its
452 // transformation intact until the finish animation also completes.
453
454 boolean moreStartExit = false;
455 if (mStartExitAnimation != null) {
456 mStartExitTransformation.clear();
457 moreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
458 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
459 if (!moreStartExit) {
460 if (DEBUG_STATE) Slog.v(TAG, "Start exit animation done!");
461 mStartExitAnimation.cancel();
462 mStartExitAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800463 }
464 }
465
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800466 boolean moreStartEnter = false;
467 if (mStartEnterAnimation != null) {
468 mStartEnterTransformation.clear();
469 moreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
470 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
471 if (!moreStartEnter) {
472 if (DEBUG_STATE) Slog.v(TAG, "Start enter animation done!");
473 mStartEnterAnimation.cancel();
474 mStartEnterAnimation = null;
475 }
476 }
477
478 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
479 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
480
481 mFinishExitTransformation.clear();
482 boolean moreFinishExit = false;
483 if (mFinishExitAnimation != null) {
484 moreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
485 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
486 if (!moreStartExit && !moreFinishExit) {
487 if (DEBUG_STATE) Slog.v(TAG, "Finish exit animation done, clearing start/finish anims!");
488 mStartExitTransformation.clear();
489 mFinishExitAnimation.cancel();
490 mFinishExitAnimation = null;
491 mFinishExitTransformation.clear();
492 }
493 }
494
495 mFinishEnterTransformation.clear();
496 boolean moreFinishEnter = false;
497 if (mFinishEnterAnimation != null) {
498 moreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
499 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
500 if (!moreStartEnter && !moreFinishEnter) {
501 if (DEBUG_STATE) Slog.v(TAG, "Finish enter animation done, clearing start/finish anims!");
502 mStartEnterTransformation.clear();
503 mFinishEnterAnimation.cancel();
504 mFinishEnterAnimation = null;
505 mFinishEnterTransformation.clear();
506 }
507 }
508
509 mRotateExitTransformation.clear();
510 boolean moreRotateExit = false;
511 if (mRotateExitAnimation != null) {
512 moreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
513 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
514 }
515
516 if (!moreFinishExit && !moreRotateExit) {
517 if (DEBUG_STATE) Slog.v(TAG, "Rotate exit animation done!");
518 mRotateExitAnimation.cancel();
519 mRotateExitAnimation = null;
520 mRotateExitTransformation.clear();
521 }
522
523 mRotateEnterTransformation.clear();
524 boolean moreRotateEnter = false;
525 if (mRotateEnterAnimation != null) {
526 moreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
527 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
528 }
529
530 if (!moreFinishEnter && !moreRotateEnter) {
531 if (DEBUG_STATE) Slog.v(TAG, "Rotate enter animation done!");
532 mRotateEnterAnimation.cancel();
533 mRotateEnterAnimation = null;
534 mRotateEnterTransformation.clear();
535 }
536
537 mExitTransformation.set(mRotateExitTransformation);
538 mExitTransformation.compose(mStartExitTransformation);
539 mExitTransformation.compose(mFinishExitTransformation);
540
541 mEnterTransformation.set(mRotateEnterTransformation);
542 mEnterTransformation.compose(mStartEnterTransformation);
543 mEnterTransformation.compose(mFinishEnterTransformation);
544
545 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
546 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
547
548 if (!moreStartExit && !moreFinishExit && !moreRotateExit) {
549 if (mSurface != null) {
550 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
551 mSurface.hide();
552 }
553 }
554
555 if (!moreStartEnter && !moreFinishEnter && !moreRotateEnter) {
556 if (mBlackFrame != null) {
557 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, hiding black frame");
558 mBlackFrame.hide();
559 }
560 } else {
561 if (mBlackFrame != null) {
562 mBlackFrame.setMatrix(mEnterTransformation.getMatrix());
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800563 }
564 }
565
Dianne Hackborn352cc982011-01-04 11:34:18 -0800566 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
567 setSnapshotTransform(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800568
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800569 final boolean more = moreStartEnter || moreStartExit || moreFinishEnter || moreFinishExit
570 || moreRotateEnter || moreRotateExit || !mFinishAnimReady;
571
572 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
573
574 return more;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800575 }
576
577 public Transformation getEnterTransformation() {
578 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800579 }
580}