blob: 5d4ab562b220e92dd9757b4884c7c56b613dd8de [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;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080030import android.view.SurfaceControl;
Dianne Hackborna1111872010-11-23 20:55:11 -080031import android.view.SurfaceSession;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080032import android.view.animation.Animation;
33import android.view.animation.AnimationUtils;
34import android.view.animation.Transformation;
Dianne Hackborna1111872010-11-23 20:55:11 -080035
Craig Mautnere32c3072012-03-12 15:25:35 -070036class ScreenRotationAnimation {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080037 static final String TAG = "ScreenRotationAnimation";
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080038 static final boolean DEBUG_STATE = false;
39 static final boolean DEBUG_TRANSFORMS = false;
Dianne Hackborn187ae2102012-04-11 18:12:06 -070040 static final boolean TWO_PHASE_ANIMATION = false;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070041 static final boolean USE_CUSTOM_BLACK_FRAME = false;
Dianne Hackborna1111872010-11-23 20:55:11 -080042
Dianne Hackborn50660e22011-02-02 17:12:25 -080043 static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200;
44
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080045 final Context mContext;
Jeff Brown98365d72012-08-19 20:30:52 -070046 final Display mDisplay;
Mathias Agopian29479eb2013-02-14 14:36:04 -080047 SurfaceControl mSurfaceControl;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070048 BlackFrame mCustomBlackFrame;
49 BlackFrame mExitingBlackFrame;
50 BlackFrame mEnteringBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080051 int mWidth, mHeight;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -070052 int mExitAnimId, mEnterAnimId;
Dianne Hackborna1111872010-11-23 20:55:11 -080053
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080054 int mOriginalRotation;
55 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080056 int mCurRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -080057
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080058 // For all animations, "exit" is for the UI elements that are going
59 // away (that is the snapshot of the old screen), and "enter" is for
60 // the new UI elements that are appearing (that is the active windows
61 // in their final orientation).
62
63 // The starting animation for the exiting and entering elements. This
64 // animation applies a transformation while the rotation is in progress.
65 // It is started immediately, before the new entering UI is ready.
66 Animation mStartExitAnimation;
67 final Transformation mStartExitTransformation = new Transformation();
68 Animation mStartEnterAnimation;
69 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080070 Animation mStartFrameAnimation;
71 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080072
73 // The finishing animation for the exiting and entering elements. This
74 // animation needs to undo the transformation of the starting animation.
75 // It starts running once the new rotation UI elements are ready to be
76 // displayed.
77 Animation mFinishExitAnimation;
78 final Transformation mFinishExitTransformation = new Transformation();
79 Animation mFinishEnterAnimation;
80 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080081 Animation mFinishFrameAnimation;
82 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080083
84 // The current active animation to move from the old to the new rotated
85 // state. Which animation is run here will depend on the old and new
86 // rotations.
87 Animation mRotateExitAnimation;
88 final Transformation mRotateExitTransformation = new Transformation();
89 Animation mRotateEnterAnimation;
90 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080091 Animation mRotateFrameAnimation;
92 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080093
94 // A previously running rotate animation. This will be used if we need
95 // to switch to a new rotation before finishing the previous one.
96 Animation mLastRotateExitAnimation;
97 final Transformation mLastRotateExitTransformation = new Transformation();
98 Animation mLastRotateEnterAnimation;
99 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800100 Animation mLastRotateFrameAnimation;
101 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800102
103 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800104 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800105 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800106 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800107
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800108 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800109 boolean mAnimRunning;
110 boolean mFinishAnimReady;
111 long mFinishAnimStartTime;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800112
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800113 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800114 final Matrix mSnapshotInitialMatrix = new Matrix();
115 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700116 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800117 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800118 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800119 private boolean mMoreRotateEnter;
120 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800121 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800122 private boolean mMoreFinishEnter;
123 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800124 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800125 private boolean mMoreStartEnter;
126 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800127 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700128 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800129
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800130 public void printTo(String prefix, PrintWriter pw) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800131 pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800132 pw.print(" mWidth="); pw.print(mWidth);
133 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700134 if (USE_CUSTOM_BLACK_FRAME) {
135 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
136 if (mCustomBlackFrame != null) {
137 mCustomBlackFrame.printTo(prefix + " ", pw);
138 }
139 }
140 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
141 if (mExitingBlackFrame != null) {
142 mExitingBlackFrame.printTo(prefix + " ", pw);
143 }
144 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
145 if (mEnteringBlackFrame != null) {
146 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800147 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700148 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
149 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
150 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800151 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
152 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
153 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
154 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
155 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
156 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
157 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
158 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
159 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800160 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
161 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800162 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
163 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
164 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
165 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800166 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
167 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800168 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
169 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
170 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
171 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800172 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
173 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800174 pw.print(prefix); pw.print("mExitTransformation=");
175 mExitTransformation.printShortString(pw); pw.println();
176 pw.print(prefix); pw.print("mEnterTransformation=");
177 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800178 pw.print(prefix); pw.print("mFrameTransformation=");
179 mEnterTransformation.printShortString(pw); pw.println();
180 pw.print(prefix); pw.print("mFrameInitialMatrix=");
181 mFrameInitialMatrix.printShortString(pw);
182 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800183 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
184 mSnapshotInitialMatrix.printShortString(pw);
185 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
186 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700187 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
188 mExitFrameFinalMatrix.printShortString(pw);
189 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800190 }
191
Jeff Brown98365d72012-08-19 20:30:52 -0700192 public ScreenRotationAnimation(Context context, Display display, SurfaceSession session,
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700193 boolean inTransaction, int originalWidth, int originalHeight, int originalRotation,
194 int exitAnim, int enterAnim) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800195 mContext = context;
Jeff Brown98365d72012-08-19 20:30:52 -0700196 mDisplay = display;
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700197 mExitAnimId = exitAnim;
198 mEnterAnimId = enterAnim;
Dianne Hackborna1111872010-11-23 20:55:11 -0800199
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800200 // Screenshot does NOT include rotation!
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700201 if (originalRotation == Surface.ROTATION_90
202 || originalRotation == Surface.ROTATION_270) {
203 mWidth = originalHeight;
204 mHeight = originalWidth;
205 } else {
206 mWidth = originalWidth;
207 mHeight = originalHeight;
208 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800209
Jeff Brownbc68a592011-07-25 12:58:12 -0700210 mOriginalRotation = originalRotation;
211 mOriginalWidth = originalWidth;
212 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800213
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800214 if (!inTransaction) {
Dianne Hackborn36991742011-10-11 21:35:26 -0700215 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800216 ">>> OPEN TRANSACTION ScreenRotationAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800217 SurfaceControl.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800218 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700219
Dianne Hackborna1111872010-11-23 20:55:11 -0800220 try {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800221 try {
Craig Mautner7d8df392012-04-06 15:26:23 -0700222 if (WindowManagerService.DEBUG_SURFACE_TRACE) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800223 mSurfaceControl = new SurfaceTrace(session, "FreezeSurface",
Jeff Brown64a55af2012-08-26 02:47:39 -0700224 mWidth, mHeight,
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800225 PixelFormat.OPAQUE, SurfaceControl.FX_SURFACE_SCREENSHOT | SurfaceControl.HIDDEN);
Craig Mautner7d8df392012-04-06 15:26:23 -0700226 } else {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800227 mSurfaceControl = new SurfaceControl(session, "FreezeSurface",
Jeff Brown64a55af2012-08-26 02:47:39 -0700228 mWidth, mHeight,
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800229 PixelFormat.OPAQUE, SurfaceControl.FX_SURFACE_SCREENSHOT | SurfaceControl.HIDDEN);
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700230 }
Mathias Agopian29479eb2013-02-14 14:36:04 -0800231 mSurfaceControl.setLayerStack(mDisplay.getLayerStack());
232 mSurfaceControl.setLayer(FREEZE_LAYER + 1);
233 mSurfaceControl.setAlpha(0);
234 mSurfaceControl.show();
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800235 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800236 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800237 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800238
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700239 if (WindowManagerService.SHOW_TRANSACTIONS ||
240 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800241 " FREEZE " + mSurfaceControl + ": CREATE");
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700242
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700243 setRotationInTransaction(originalRotation);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800244 } finally {
245 if (!inTransaction) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800246 SurfaceControl.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -0700247 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800248 "<<< CLOSE TRANSACTION ScreenRotationAnimation");
Dianne Hackborn352cc982011-01-04 11:34:18 -0800249 }
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800250 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800251 }
252
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800253 boolean hasScreenshot() {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800254 return mSurfaceControl != null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800255 }
256
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800257 static int deltaRotation(int oldRotation, int newRotation) {
258 int delta = newRotation - oldRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800259 if (delta < 0) delta += 4;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800260 return delta;
261 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800262
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700263 private void setSnapshotTransformInTransaction(Matrix matrix, float alpha) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800264 if (mSurfaceControl != null) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800265 matrix.getValues(mTmpFloats);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800266 mSurfaceControl.setPosition(mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]);
267 mSurfaceControl.setMatrix(
Dianne Hackborn352cc982011-01-04 11:34:18 -0800268 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
269 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800270 mSurfaceControl.setAlpha(alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800271 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800272 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
273 float[] dstPnts = new float[4];
274 matrix.mapPoints(dstPnts, srcPnts);
275 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
276 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
277 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
278 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
279 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800280 }
281 }
282
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800283 public static void createRotationMatrix(int rotation, int width, int height,
284 Matrix outMatrix) {
285 switch (rotation) {
286 case Surface.ROTATION_0:
287 outMatrix.reset();
288 break;
289 case Surface.ROTATION_90:
290 outMatrix.setRotate(90, 0, 0);
291 outMatrix.postTranslate(height, 0);
292 break;
293 case Surface.ROTATION_180:
294 outMatrix.setRotate(180, 0, 0);
295 outMatrix.postTranslate(width, height);
296 break;
297 case Surface.ROTATION_270:
298 outMatrix.setRotate(270, 0, 0);
299 outMatrix.postTranslate(0, width);
300 break;
301 }
302 }
303
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800304 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700305 private void setRotationInTransaction(int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800306 mCurRotation = rotation;
307
308 // Compute the transformation matrix that must be applied
309 // to the snapshot to make it stay in the same original position
310 // with the current screen rotation.
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700311 int delta = deltaRotation(rotation, Surface.ROTATION_0);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800312 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800313
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800314 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700315 setSnapshotTransformInTransaction(mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800316 }
317
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800318 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700319 public boolean setRotationInTransaction(int rotation, SurfaceSession session,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800320 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700321 setRotationInTransaction(rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700322 if (TWO_PHASE_ANIMATION) {
323 return startAnimation(session, maxAnimationDuration, animationScale,
324 finalWidth, finalHeight, false);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700325 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700326
327 // Don't start animation yet.
328 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800329 }
330
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800331 /**
332 * Returns true if animating.
333 */
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800334 private boolean startAnimation(SurfaceSession session, long maxAnimationDuration,
335 float animationScale, int finalWidth, int finalHeight, boolean dismissing) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800336 if (mSurfaceControl == null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800337 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800338 return false;
339 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800340 if (mStarted) {
341 return true;
342 }
343
344 mStarted = true;
345
346 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800347
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800348 // Figure out how the screen has moved from the original rotation.
349 int delta = deltaRotation(mCurRotation, mOriginalRotation);
350
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700351 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
352 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800353 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
354 firstStart = true;
355 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
356 com.android.internal.R.anim.screen_rotate_start_exit);
357 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
358 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700359 if (USE_CUSTOM_BLACK_FRAME) {
360 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
361 com.android.internal.R.anim.screen_rotate_start_frame);
362 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800363 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
364 com.android.internal.R.anim.screen_rotate_finish_exit);
365 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
366 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700367 if (USE_CUSTOM_BLACK_FRAME) {
368 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
369 com.android.internal.R.anim.screen_rotate_finish_frame);
370 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800371 }
372
373 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
374 + finalWidth + " finalHeight=" + finalHeight
375 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
376
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700377 final boolean customAnim;
378 if (mExitAnimId != 0 && mEnterAnimId != 0) {
379 customAnim = true;
380 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, mExitAnimId);
381 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, mEnterAnimId);
382 } else {
383 customAnim = false;
384 switch (delta) {
385 case Surface.ROTATION_0:
386 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
387 com.android.internal.R.anim.screen_rotate_0_exit);
388 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
389 com.android.internal.R.anim.screen_rotate_0_enter);
390 if (USE_CUSTOM_BLACK_FRAME) {
391 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
392 com.android.internal.R.anim.screen_rotate_0_frame);
393 }
394 break;
395 case Surface.ROTATION_90:
396 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
397 com.android.internal.R.anim.screen_rotate_plus_90_exit);
398 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
399 com.android.internal.R.anim.screen_rotate_plus_90_enter);
400 if (USE_CUSTOM_BLACK_FRAME) {
401 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
402 com.android.internal.R.anim.screen_rotate_plus_90_frame);
403 }
404 break;
405 case Surface.ROTATION_180:
406 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
407 com.android.internal.R.anim.screen_rotate_180_exit);
408 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
409 com.android.internal.R.anim.screen_rotate_180_enter);
410 if (USE_CUSTOM_BLACK_FRAME) {
411 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
412 com.android.internal.R.anim.screen_rotate_180_frame);
413 }
414 break;
415 case Surface.ROTATION_270:
416 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
417 com.android.internal.R.anim.screen_rotate_minus_90_exit);
418 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
419 com.android.internal.R.anim.screen_rotate_minus_90_enter);
420 if (USE_CUSTOM_BLACK_FRAME) {
421 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
422 com.android.internal.R.anim.screen_rotate_minus_90_frame);
423 }
424 break;
425 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800426 }
427
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800428 // Initialize the animations. This is a hack, redefining what "parent"
429 // means to allow supplying the last and next size. In this definition
430 // "%p" is the original (let's call it "previous") size, and "%" is the
431 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700432 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700433 // Compute partial steps between original and final sizes. These
434 // are used for the dimensions of the exiting and entering elements,
435 // so they are never stretched too significantly.
436 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
437 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
438
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800439 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
440 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800441 halfWidth, halfHeight);
442 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800443 mOriginalWidth, mOriginalHeight);
444 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800445 halfWidth, halfHeight);
446 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800447 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700448 if (USE_CUSTOM_BLACK_FRAME) {
449 mStartFrameAnimation.initialize(finalWidth, finalHeight,
450 mOriginalWidth, mOriginalHeight);
451 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
452 mOriginalWidth, mOriginalHeight);
453 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800454 }
455 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
456 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700457 if (USE_CUSTOM_BLACK_FRAME) {
458 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
459 mOriginalHeight);
460 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800461 mAnimRunning = false;
462 mFinishAnimReady = false;
463 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800464
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700465 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800466 mStartExitAnimation.restrictDuration(maxAnimationDuration);
467 mStartExitAnimation.scaleCurrentDuration(animationScale);
468 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
469 mStartEnterAnimation.scaleCurrentDuration(animationScale);
470 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
471 mFinishExitAnimation.scaleCurrentDuration(animationScale);
472 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
473 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700474 if (USE_CUSTOM_BLACK_FRAME) {
475 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
476 mStartFrameAnimation.scaleCurrentDuration(animationScale);
477 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
478 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
479 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800480 }
481 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
482 mRotateExitAnimation.scaleCurrentDuration(animationScale);
483 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
484 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700485 if (USE_CUSTOM_BLACK_FRAME) {
486 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
487 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
488 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800489
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700490 final int layerStack = mDisplay.getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700491 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800492 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
493 WindowManagerService.TAG,
494 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800495 SurfaceControl.openTransaction();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800496
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800497 // Compute the transformation matrix that must be applied
498 // the the black frame to make it stay in the initial position
499 // before the new screen rotation. This is different than the
500 // snapshot transformation because the snapshot is always based
501 // of the native orientation of the screen, not the orientation
502 // we were last in.
503 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
504
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800505 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800506 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
507 mOriginalWidth*2, mOriginalHeight*2);
508 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700509 mCustomBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 3,
510 layerStack);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700511 mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800512 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700513 Slog.w(TAG, "Unable to allocate black surface", e);
514 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800515 SurfaceControl.closeTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700516 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
517 WindowManagerService.TAG,
518 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
519 }
520 }
521
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700522 if (!customAnim && mExitingBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700523 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
524 WindowManagerService.TAG,
525 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800526 SurfaceControl.openTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700527 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700528 // Compute the transformation matrix that must be applied
529 // the the black frame to make it stay in the initial position
530 // before the new screen rotation. This is different than the
531 // snapshot transformation because the snapshot is always based
532 // of the native orientation of the screen, not the orientation
533 // we were last in.
534 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
535
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700536 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
537 mOriginalWidth*2, mOriginalHeight*2);
538 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700539 mExitingBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 2,
540 layerStack);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700541 mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800542 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700543 Slog.w(TAG, "Unable to allocate black surface", e);
544 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800545 SurfaceControl.closeTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700546 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
547 WindowManagerService.TAG,
548 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
549 }
550 }
551
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700552 if (customAnim && mEnteringBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700553 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
554 WindowManagerService.TAG,
555 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800556 SurfaceControl.openTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700557
558 try {
559 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
560 finalWidth*2, finalHeight*2);
561 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700562 mEnteringBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER,
563 layerStack);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800564 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800565 Slog.w(TAG, "Unable to allocate black surface", e);
566 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800567 SurfaceControl.closeTransaction();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800568 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
569 WindowManagerService.TAG,
570 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
571 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800572 }
573
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800574 return true;
575 }
576
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800577 /**
578 * Returns true if animating.
579 */
580 public boolean dismiss(SurfaceSession session, long maxAnimationDuration,
581 float animationScale, int finalWidth, int finalHeight) {
582 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800583 if (mSurfaceControl == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800584 // Can't do animation.
585 return false;
586 }
587 if (!mStarted) {
588 startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight,
589 true);
590 }
591 if (!mStarted) {
592 return false;
593 }
594 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
595 mFinishAnimReady = true;
596 return true;
597 }
598
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800599 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800600 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800601 if (mSurfaceControl != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700602 if (WindowManagerService.SHOW_TRANSACTIONS ||
603 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800604 " FREEZE " + mSurfaceControl + ": DESTROY");
605 mSurfaceControl.destroy();
606 mSurfaceControl = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800607 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700608 if (mCustomBlackFrame != null) {
609 mCustomBlackFrame.kill();
610 mCustomBlackFrame = null;
611 }
612 if (mExitingBlackFrame != null) {
613 mExitingBlackFrame.kill();
614 mExitingBlackFrame = null;
615 }
616 if (mEnteringBlackFrame != null) {
617 mEnteringBlackFrame.kill();
618 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800619 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700620 if (TWO_PHASE_ANIMATION) {
621 if (mStartExitAnimation != null) {
622 mStartExitAnimation.cancel();
623 mStartExitAnimation = null;
624 }
625 if (mStartEnterAnimation != null) {
626 mStartEnterAnimation.cancel();
627 mStartEnterAnimation = null;
628 }
629 if (mFinishExitAnimation != null) {
630 mFinishExitAnimation.cancel();
631 mFinishExitAnimation = null;
632 }
633 if (mFinishEnterAnimation != null) {
634 mFinishEnterAnimation.cancel();
635 mFinishEnterAnimation = null;
636 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800637 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700638 if (USE_CUSTOM_BLACK_FRAME) {
639 if (mStartFrameAnimation != null) {
640 mStartFrameAnimation.cancel();
641 mStartFrameAnimation = null;
642 }
643 if (mRotateFrameAnimation != null) {
644 mRotateFrameAnimation.cancel();
645 mRotateFrameAnimation = null;
646 }
647 if (mFinishFrameAnimation != null) {
648 mFinishFrameAnimation.cancel();
649 mFinishFrameAnimation = null;
650 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800651 }
652 if (mRotateExitAnimation != null) {
653 mRotateExitAnimation.cancel();
654 mRotateExitAnimation = null;
655 }
656 if (mRotateEnterAnimation != null) {
657 mRotateEnterAnimation.cancel();
658 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800659 }
660 }
661
662 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700663 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700664 }
665
Dianne Hackborn4b169692012-11-29 17:51:24 -0800666 public boolean isRotating() {
667 return mCurRotation != mOriginalRotation;
668 }
669
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700670 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700671 return (TWO_PHASE_ANIMATION &&
672 (mStartEnterAnimation != null || mStartExitAnimation != null
673 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
674 || (USE_CUSTOM_BLACK_FRAME &&
675 (mStartFrameAnimation != null || mRotateFrameAnimation != null
676 || mFinishFrameAnimation != null))
677 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800678 }
679
Craig Mautnere32c3072012-03-12 15:25:35 -0700680 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700681 if (now > mHalfwayPoint) {
682 mHalfwayPoint = Long.MAX_VALUE;
683 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800684 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
685 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
686 mFinishAnimStartTime = now;
687 }
688
Craig Mautner7d8df392012-04-06 15:26:23 -0700689 if (TWO_PHASE_ANIMATION) {
690 mMoreStartExit = false;
691 if (mStartExitAnimation != null) {
692 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
693 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
694 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800695
Craig Mautner7d8df392012-04-06 15:26:23 -0700696 mMoreStartEnter = false;
697 if (mStartEnterAnimation != null) {
698 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
699 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
700 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800701 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700702 if (USE_CUSTOM_BLACK_FRAME) {
703 mMoreStartFrame = false;
704 if (mStartFrameAnimation != null) {
705 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
706 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
707 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800708 }
709
Craig Mautnerdbb79912012-03-01 18:59:14 -0800710 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
711 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
712
Craig Mautner7d8df392012-04-06 15:26:23 -0700713 if (TWO_PHASE_ANIMATION) {
714 mMoreFinishExit = false;
715 if (mFinishExitAnimation != null) {
716 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
717 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
718 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800719
Craig Mautner7d8df392012-04-06 15:26:23 -0700720 mMoreFinishEnter = false;
721 if (mFinishEnterAnimation != null) {
722 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
723 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
724 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800725 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700726 if (USE_CUSTOM_BLACK_FRAME) {
727 mMoreFinishFrame = false;
728 if (mFinishFrameAnimation != null) {
729 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
730 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
731 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800732 }
733
Craig Mautnerdbb79912012-03-01 18:59:14 -0800734 mMoreRotateExit = false;
735 if (mRotateExitAnimation != null) {
736 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
737 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700738 }
739
740 mMoreRotateEnter = false;
741 if (mRotateEnterAnimation != null) {
742 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
743 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
744 }
745
Craig Mautner7d8df392012-04-06 15:26:23 -0700746 if (USE_CUSTOM_BLACK_FRAME) {
747 mMoreRotateFrame = false;
748 if (mRotateFrameAnimation != null) {
749 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
750 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
751 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700752 }
753
Craig Mautner7d8df392012-04-06 15:26:23 -0700754 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
755 if (TWO_PHASE_ANIMATION) {
756 if (mStartExitAnimation != null) {
757 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
758 mStartExitAnimation.cancel();
759 mStartExitAnimation = null;
760 mStartExitTransformation.clear();
761 }
762 if (mFinishExitAnimation != null) {
763 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
764 mFinishExitAnimation.cancel();
765 mFinishExitAnimation = null;
766 mFinishExitTransformation.clear();
767 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700768 }
769 if (mRotateExitAnimation != null) {
770 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800771 mRotateExitAnimation.cancel();
772 mRotateExitAnimation = null;
773 mRotateExitTransformation.clear();
774 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800775 }
776
Craig Mautner7d8df392012-04-06 15:26:23 -0700777 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
778 if (TWO_PHASE_ANIMATION) {
779 if (mStartEnterAnimation != null) {
780 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
781 mStartEnterAnimation.cancel();
782 mStartEnterAnimation = null;
783 mStartEnterTransformation.clear();
784 }
785 if (mFinishEnterAnimation != null) {
786 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
787 mFinishEnterAnimation.cancel();
788 mFinishEnterAnimation = null;
789 mFinishEnterTransformation.clear();
790 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700791 }
792 if (mRotateEnterAnimation != null) {
793 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800794 mRotateEnterAnimation.cancel();
795 mRotateEnterAnimation = null;
796 mRotateEnterTransformation.clear();
797 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800798 }
799
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700800 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
801 if (mStartFrameAnimation != null) {
802 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
803 mStartFrameAnimation.cancel();
804 mStartFrameAnimation = null;
805 mStartFrameTransformation.clear();
806 }
807 if (mFinishFrameAnimation != null) {
808 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
809 mFinishFrameAnimation.cancel();
810 mFinishFrameAnimation = null;
811 mFinishFrameTransformation.clear();
812 }
813 if (mRotateFrameAnimation != null) {
814 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800815 mRotateFrameAnimation.cancel();
816 mRotateFrameAnimation = null;
817 mRotateFrameTransformation.clear();
818 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800819 }
820
821 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800822 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700823 if (TWO_PHASE_ANIMATION) {
824 mExitTransformation.compose(mStartExitTransformation);
825 mExitTransformation.compose(mFinishExitTransformation);
826
827 mEnterTransformation.compose(mStartEnterTransformation);
828 mEnterTransformation.compose(mFinishEnterTransformation);
829 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800830
831 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
832 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700833
834 if (USE_CUSTOM_BLACK_FRAME) {
835 //mFrameTransformation.set(mRotateExitTransformation);
836 //mFrameTransformation.compose(mStartExitTransformation);
837 //mFrameTransformation.compose(mFinishExitTransformation);
838 mFrameTransformation.set(mRotateFrameTransformation);
839 mFrameTransformation.compose(mStartFrameTransformation);
840 mFrameTransformation.compose(mFinishFrameTransformation);
841 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
842 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
843 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800844
Craig Mautner7d8df392012-04-06 15:26:23 -0700845 final boolean more = (TWO_PHASE_ANIMATION
846 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
847 || (USE_CUSTOM_BLACK_FRAME
848 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
849 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800850 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800851
852 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
853
854 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
855
856 return more;
857 }
858
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700859 void updateSurfacesInTransaction() {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700860 if (!mStarted) {
861 return;
862 }
863
Mathias Agopian29479eb2013-02-14 14:36:04 -0800864 if (mSurfaceControl != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700865 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800866 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800867 mSurfaceControl.hide();
Craig Mautnerdbb79912012-03-01 18:59:14 -0800868 }
869 }
870
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700871 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700872 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800873 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700874 mCustomBlackFrame.hide();
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700875 } else {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700876 mCustomBlackFrame.setMatrix(mFrameTransformation.getMatrix());
877 }
878 }
879
880 if (mExitingBlackFrame != null) {
881 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
882 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
883 mExitingBlackFrame.hide();
884 } else {
885 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
886 mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700887 }
888 }
889
890 if (mEnteringBlackFrame != null) {
891 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
892 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
893 mEnteringBlackFrame.hide();
894 } else {
895 mEnteringBlackFrame.setMatrix(mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800896 }
897 }
898
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700899 setSnapshotTransformInTransaction(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800900 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700901
Craig Mautnere32c3072012-03-12 15:25:35 -0700902 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700903 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800904 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800905 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800906 return false;
907 }
908
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800909 if (!mAnimRunning) {
910 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700911 if (TWO_PHASE_ANIMATION) {
912 if (mStartEnterAnimation != null) {
913 mStartEnterAnimation.setStartTime(now);
914 }
915 if (mStartExitAnimation != null) {
916 mStartExitAnimation.setStartTime(now);
917 }
918 if (mFinishEnterAnimation != null) {
919 mFinishEnterAnimation.setStartTime(0);
920 }
921 if (mFinishExitAnimation != null) {
922 mFinishExitAnimation.setStartTime(0);
923 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700924 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700925 if (USE_CUSTOM_BLACK_FRAME) {
926 if (mStartFrameAnimation != null) {
927 mStartFrameAnimation.setStartTime(now);
928 }
929 if (mFinishFrameAnimation != null) {
930 mFinishFrameAnimation.setStartTime(0);
931 }
932 if (mRotateFrameAnimation != null) {
933 mRotateFrameAnimation.setStartTime(now);
934 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800935 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800936 if (mRotateEnterAnimation != null) {
937 mRotateEnterAnimation.setStartTime(now);
938 }
939 if (mRotateExitAnimation != null) {
940 mRotateExitAnimation.setStartTime(now);
941 }
942 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -0700943 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800944 }
Craig Mautnere32c3072012-03-12 15:25:35 -0700945
946 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800947 }
948
949 public Transformation getEnterTransformation() {
950 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800951 }
952}