blob: ae110dd7a71b289a1994b04b04ff02e14068894d [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;
52
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080053 int mOriginalRotation;
54 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080055 int mCurRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -080056
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080057 // For all animations, "exit" is for the UI elements that are going
58 // away (that is the snapshot of the old screen), and "enter" is for
59 // the new UI elements that are appearing (that is the active windows
60 // in their final orientation).
61
62 // The starting animation for the exiting and entering elements. This
63 // animation applies a transformation while the rotation is in progress.
64 // It is started immediately, before the new entering UI is ready.
65 Animation mStartExitAnimation;
66 final Transformation mStartExitTransformation = new Transformation();
67 Animation mStartEnterAnimation;
68 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080069 Animation mStartFrameAnimation;
70 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080071
72 // The finishing animation for the exiting and entering elements. This
73 // animation needs to undo the transformation of the starting animation.
74 // It starts running once the new rotation UI elements are ready to be
75 // displayed.
76 Animation mFinishExitAnimation;
77 final Transformation mFinishExitTransformation = new Transformation();
78 Animation mFinishEnterAnimation;
79 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080080 Animation mFinishFrameAnimation;
81 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080082
83 // The current active animation to move from the old to the new rotated
84 // state. Which animation is run here will depend on the old and new
85 // rotations.
86 Animation mRotateExitAnimation;
87 final Transformation mRotateExitTransformation = new Transformation();
88 Animation mRotateEnterAnimation;
89 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080090 Animation mRotateFrameAnimation;
91 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080092
93 // A previously running rotate animation. This will be used if we need
94 // to switch to a new rotation before finishing the previous one.
95 Animation mLastRotateExitAnimation;
96 final Transformation mLastRotateExitTransformation = new Transformation();
97 Animation mLastRotateEnterAnimation;
98 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080099 Animation mLastRotateFrameAnimation;
100 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800101
102 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800103 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800104 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800105 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800106
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800107 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800108 boolean mAnimRunning;
109 boolean mFinishAnimReady;
110 long mFinishAnimStartTime;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800111
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800112 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800113 final Matrix mSnapshotInitialMatrix = new Matrix();
114 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700115 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800116 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800117 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800118 private boolean mMoreRotateEnter;
119 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800120 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800121 private boolean mMoreFinishEnter;
122 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800123 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800124 private boolean mMoreStartEnter;
125 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800126 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700127 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800128
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800129 public void printTo(String prefix, PrintWriter pw) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800130 pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800131 pw.print(" mWidth="); pw.print(mWidth);
132 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700133 if (USE_CUSTOM_BLACK_FRAME) {
134 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
135 if (mCustomBlackFrame != null) {
136 mCustomBlackFrame.printTo(prefix + " ", pw);
137 }
138 }
139 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
140 if (mExitingBlackFrame != null) {
141 mExitingBlackFrame.printTo(prefix + " ", pw);
142 }
143 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
144 if (mEnteringBlackFrame != null) {
145 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800146 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700147 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
148 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
149 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800150 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
151 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
152 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
153 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
154 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
155 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
156 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
157 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
158 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800159 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
160 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800161 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
162 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
163 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
164 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800165 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
166 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800167 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
168 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
169 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
170 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800171 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
172 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800173 pw.print(prefix); pw.print("mExitTransformation=");
174 mExitTransformation.printShortString(pw); pw.println();
175 pw.print(prefix); pw.print("mEnterTransformation=");
176 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800177 pw.print(prefix); pw.print("mFrameTransformation=");
178 mEnterTransformation.printShortString(pw); pw.println();
179 pw.print(prefix); pw.print("mFrameInitialMatrix=");
180 mFrameInitialMatrix.printShortString(pw);
181 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800182 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
183 mSnapshotInitialMatrix.printShortString(pw);
184 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
185 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700186 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
187 mExitFrameFinalMatrix.printShortString(pw);
188 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800189 }
190
Jeff Brown98365d72012-08-19 20:30:52 -0700191 public ScreenRotationAnimation(Context context, Display display, SurfaceSession session,
Craig Mautner3c174372013-02-21 17:54:37 -0800192 boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800193 mContext = context;
Jeff Brown98365d72012-08-19 20:30:52 -0700194 mDisplay = display;
Dianne Hackborna1111872010-11-23 20:55:11 -0800195
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800196 // Screenshot does NOT include rotation!
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700197 if (originalRotation == Surface.ROTATION_90
198 || originalRotation == Surface.ROTATION_270) {
199 mWidth = originalHeight;
200 mHeight = originalWidth;
201 } else {
202 mWidth = originalWidth;
203 mHeight = originalHeight;
204 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800205
Jeff Brownbc68a592011-07-25 12:58:12 -0700206 mOriginalRotation = originalRotation;
207 mOriginalWidth = originalWidth;
208 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800209
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800210 if (!inTransaction) {
Dianne Hackborn36991742011-10-11 21:35:26 -0700211 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800212 ">>> OPEN TRANSACTION ScreenRotationAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800213 SurfaceControl.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800214 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700215
Dianne Hackborna1111872010-11-23 20:55:11 -0800216 try {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800217 try {
Craig Mautner7d8df392012-04-06 15:26:23 -0700218 if (WindowManagerService.DEBUG_SURFACE_TRACE) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800219 mSurfaceControl = new SurfaceTrace(session, "FreezeSurface",
Jeff Brown64a55af2012-08-26 02:47:39 -0700220 mWidth, mHeight,
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800221 PixelFormat.OPAQUE, SurfaceControl.FX_SURFACE_SCREENSHOT | SurfaceControl.HIDDEN);
Craig Mautner7d8df392012-04-06 15:26:23 -0700222 } else {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800223 mSurfaceControl = new SurfaceControl(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);
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700226 }
Mathias Agopian29479eb2013-02-14 14:36:04 -0800227 mSurfaceControl.setLayerStack(mDisplay.getLayerStack());
228 mSurfaceControl.setLayer(FREEZE_LAYER + 1);
229 mSurfaceControl.setAlpha(0);
230 mSurfaceControl.show();
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800231 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800232 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800233 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800234
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700235 if (WindowManagerService.SHOW_TRANSACTIONS ||
236 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800237 " FREEZE " + mSurfaceControl + ": CREATE");
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700238
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700239 setRotationInTransaction(originalRotation);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800240 } finally {
241 if (!inTransaction) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800242 SurfaceControl.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -0700243 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800244 "<<< CLOSE TRANSACTION ScreenRotationAnimation");
Dianne Hackborn352cc982011-01-04 11:34:18 -0800245 }
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800246 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800247 }
248
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800249 boolean hasScreenshot() {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800250 return mSurfaceControl != null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800251 }
252
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800253 static int deltaRotation(int oldRotation, int newRotation) {
254 int delta = newRotation - oldRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800255 if (delta < 0) delta += 4;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800256 return delta;
257 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800258
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700259 private void setSnapshotTransformInTransaction(Matrix matrix, float alpha) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800260 if (mSurfaceControl != null) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800261 matrix.getValues(mTmpFloats);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800262 mSurfaceControl.setPosition(mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]);
263 mSurfaceControl.setMatrix(
Dianne Hackborn352cc982011-01-04 11:34:18 -0800264 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
265 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800266 mSurfaceControl.setAlpha(alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800267 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800268 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
269 float[] dstPnts = new float[4];
270 matrix.mapPoints(dstPnts, srcPnts);
271 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
272 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
273 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
274 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
275 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800276 }
277 }
278
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800279 public static void createRotationMatrix(int rotation, int width, int height,
280 Matrix outMatrix) {
281 switch (rotation) {
282 case Surface.ROTATION_0:
283 outMatrix.reset();
284 break;
285 case Surface.ROTATION_90:
286 outMatrix.setRotate(90, 0, 0);
287 outMatrix.postTranslate(height, 0);
288 break;
289 case Surface.ROTATION_180:
290 outMatrix.setRotate(180, 0, 0);
291 outMatrix.postTranslate(width, height);
292 break;
293 case Surface.ROTATION_270:
294 outMatrix.setRotate(270, 0, 0);
295 outMatrix.postTranslate(0, width);
296 break;
297 }
298 }
299
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800300 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700301 private void setRotationInTransaction(int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800302 mCurRotation = rotation;
303
304 // Compute the transformation matrix that must be applied
305 // to the snapshot to make it stay in the same original position
306 // with the current screen rotation.
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700307 int delta = deltaRotation(rotation, Surface.ROTATION_0);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800308 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800309
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800310 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700311 setSnapshotTransformInTransaction(mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800312 }
313
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800314 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700315 public boolean setRotationInTransaction(int rotation, SurfaceSession session,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800316 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700317 setRotationInTransaction(rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700318 if (TWO_PHASE_ANIMATION) {
319 return startAnimation(session, maxAnimationDuration, animationScale,
Craig Mautner3c174372013-02-21 17:54:37 -0800320 finalWidth, finalHeight, false, 0, 0);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700321 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700322
323 // Don't start animation yet.
324 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800325 }
326
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800327 /**
328 * Returns true if animating.
329 */
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800330 private boolean startAnimation(SurfaceSession session, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800331 float animationScale, int finalWidth, int finalHeight, boolean dismissing,
332 int exitAnim, int enterAnim) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800333 if (mSurfaceControl == null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800334 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800335 return false;
336 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800337 if (mStarted) {
338 return true;
339 }
340
341 mStarted = true;
342
343 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800344
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800345 // Figure out how the screen has moved from the original rotation.
346 int delta = deltaRotation(mCurRotation, mOriginalRotation);
347
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700348 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
349 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800350 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
351 firstStart = true;
352 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
353 com.android.internal.R.anim.screen_rotate_start_exit);
354 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
355 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700356 if (USE_CUSTOM_BLACK_FRAME) {
357 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
358 com.android.internal.R.anim.screen_rotate_start_frame);
359 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800360 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
361 com.android.internal.R.anim.screen_rotate_finish_exit);
362 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
363 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700364 if (USE_CUSTOM_BLACK_FRAME) {
365 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
366 com.android.internal.R.anim.screen_rotate_finish_frame);
367 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800368 }
369
370 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
371 + finalWidth + " finalHeight=" + finalHeight
372 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
373
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700374 final boolean customAnim;
Craig Mautner3c174372013-02-21 17:54:37 -0800375 if (exitAnim != 0 && enterAnim != 0) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700376 customAnim = true;
Craig Mautner3c174372013-02-21 17:54:37 -0800377 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
378 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700379 } else {
380 customAnim = false;
381 switch (delta) {
382 case Surface.ROTATION_0:
383 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
384 com.android.internal.R.anim.screen_rotate_0_exit);
385 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
386 com.android.internal.R.anim.screen_rotate_0_enter);
387 if (USE_CUSTOM_BLACK_FRAME) {
388 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
389 com.android.internal.R.anim.screen_rotate_0_frame);
390 }
391 break;
392 case Surface.ROTATION_90:
393 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
394 com.android.internal.R.anim.screen_rotate_plus_90_exit);
395 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
396 com.android.internal.R.anim.screen_rotate_plus_90_enter);
397 if (USE_CUSTOM_BLACK_FRAME) {
398 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
399 com.android.internal.R.anim.screen_rotate_plus_90_frame);
400 }
401 break;
402 case Surface.ROTATION_180:
403 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
404 com.android.internal.R.anim.screen_rotate_180_exit);
405 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
406 com.android.internal.R.anim.screen_rotate_180_enter);
407 if (USE_CUSTOM_BLACK_FRAME) {
408 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
409 com.android.internal.R.anim.screen_rotate_180_frame);
410 }
411 break;
412 case Surface.ROTATION_270:
413 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
414 com.android.internal.R.anim.screen_rotate_minus_90_exit);
415 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
416 com.android.internal.R.anim.screen_rotate_minus_90_enter);
417 if (USE_CUSTOM_BLACK_FRAME) {
418 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
419 com.android.internal.R.anim.screen_rotate_minus_90_frame);
420 }
421 break;
422 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800423 }
424
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800425 // Initialize the animations. This is a hack, redefining what "parent"
426 // means to allow supplying the last and next size. In this definition
427 // "%p" is the original (let's call it "previous") size, and "%" is the
428 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700429 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700430 // Compute partial steps between original and final sizes. These
431 // are used for the dimensions of the exiting and entering elements,
432 // so they are never stretched too significantly.
433 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
434 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
435
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800436 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
437 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800438 halfWidth, halfHeight);
439 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800440 mOriginalWidth, mOriginalHeight);
441 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800442 halfWidth, halfHeight);
443 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800444 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700445 if (USE_CUSTOM_BLACK_FRAME) {
446 mStartFrameAnimation.initialize(finalWidth, finalHeight,
447 mOriginalWidth, mOriginalHeight);
448 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
449 mOriginalWidth, mOriginalHeight);
450 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800451 }
452 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
453 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700454 if (USE_CUSTOM_BLACK_FRAME) {
455 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
456 mOriginalHeight);
457 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800458 mAnimRunning = false;
459 mFinishAnimReady = false;
460 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800461
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700462 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800463 mStartExitAnimation.restrictDuration(maxAnimationDuration);
464 mStartExitAnimation.scaleCurrentDuration(animationScale);
465 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
466 mStartEnterAnimation.scaleCurrentDuration(animationScale);
467 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
468 mFinishExitAnimation.scaleCurrentDuration(animationScale);
469 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
470 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700471 if (USE_CUSTOM_BLACK_FRAME) {
472 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
473 mStartFrameAnimation.scaleCurrentDuration(animationScale);
474 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
475 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
476 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800477 }
478 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
479 mRotateExitAnimation.scaleCurrentDuration(animationScale);
480 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
481 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700482 if (USE_CUSTOM_BLACK_FRAME) {
483 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
484 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
485 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800486
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700487 final int layerStack = mDisplay.getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700488 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800489 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
490 WindowManagerService.TAG,
491 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800492 SurfaceControl.openTransaction();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800493
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800494 // Compute the transformation matrix that must be applied
495 // the the black frame to make it stay in the initial position
496 // before the new screen rotation. This is different than the
497 // snapshot transformation because the snapshot is always based
498 // of the native orientation of the screen, not the orientation
499 // we were last in.
500 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
501
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800502 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800503 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
504 mOriginalWidth*2, mOriginalHeight*2);
505 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700506 mCustomBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 3,
507 layerStack);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700508 mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800509 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700510 Slog.w(TAG, "Unable to allocate black surface", e);
511 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800512 SurfaceControl.closeTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700513 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
514 WindowManagerService.TAG,
515 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
516 }
517 }
518
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700519 if (!customAnim && mExitingBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700520 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
521 WindowManagerService.TAG,
522 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800523 SurfaceControl.openTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700524 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700525 // Compute the transformation matrix that must be applied
526 // the the black frame to make it stay in the initial position
527 // before the new screen rotation. This is different than the
528 // snapshot transformation because the snapshot is always based
529 // of the native orientation of the screen, not the orientation
530 // we were last in.
531 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
532
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700533 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
534 mOriginalWidth*2, mOriginalHeight*2);
535 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700536 mExitingBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 2,
537 layerStack);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700538 mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800539 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700540 Slog.w(TAG, "Unable to allocate black surface", e);
541 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800542 SurfaceControl.closeTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700543 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
544 WindowManagerService.TAG,
545 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
546 }
547 }
548
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700549 if (customAnim && mEnteringBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700550 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
551 WindowManagerService.TAG,
552 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800553 SurfaceControl.openTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700554
555 try {
556 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
557 finalWidth*2, finalHeight*2);
558 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700559 mEnteringBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER,
560 layerStack);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800561 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800562 Slog.w(TAG, "Unable to allocate black surface", e);
563 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800564 SurfaceControl.closeTransaction();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800565 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
566 WindowManagerService.TAG,
567 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
568 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800569 }
570
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800571 return true;
572 }
573
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800574 /**
575 * Returns true if animating.
576 */
577 public boolean dismiss(SurfaceSession session, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800578 float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800579 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800580 if (mSurfaceControl == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800581 // Can't do animation.
582 return false;
583 }
584 if (!mStarted) {
585 startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight,
Craig Mautner3c174372013-02-21 17:54:37 -0800586 true, exitAnim, enterAnim);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800587 }
588 if (!mStarted) {
589 return false;
590 }
591 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
592 mFinishAnimReady = true;
593 return true;
594 }
595
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800596 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800597 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800598 if (mSurfaceControl != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700599 if (WindowManagerService.SHOW_TRANSACTIONS ||
600 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800601 " FREEZE " + mSurfaceControl + ": DESTROY");
602 mSurfaceControl.destroy();
603 mSurfaceControl = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800604 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700605 if (mCustomBlackFrame != null) {
606 mCustomBlackFrame.kill();
607 mCustomBlackFrame = null;
608 }
609 if (mExitingBlackFrame != null) {
610 mExitingBlackFrame.kill();
611 mExitingBlackFrame = null;
612 }
613 if (mEnteringBlackFrame != null) {
614 mEnteringBlackFrame.kill();
615 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800616 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700617 if (TWO_PHASE_ANIMATION) {
618 if (mStartExitAnimation != null) {
619 mStartExitAnimation.cancel();
620 mStartExitAnimation = null;
621 }
622 if (mStartEnterAnimation != null) {
623 mStartEnterAnimation.cancel();
624 mStartEnterAnimation = null;
625 }
626 if (mFinishExitAnimation != null) {
627 mFinishExitAnimation.cancel();
628 mFinishExitAnimation = null;
629 }
630 if (mFinishEnterAnimation != null) {
631 mFinishEnterAnimation.cancel();
632 mFinishEnterAnimation = null;
633 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800634 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700635 if (USE_CUSTOM_BLACK_FRAME) {
636 if (mStartFrameAnimation != null) {
637 mStartFrameAnimation.cancel();
638 mStartFrameAnimation = null;
639 }
640 if (mRotateFrameAnimation != null) {
641 mRotateFrameAnimation.cancel();
642 mRotateFrameAnimation = null;
643 }
644 if (mFinishFrameAnimation != null) {
645 mFinishFrameAnimation.cancel();
646 mFinishFrameAnimation = null;
647 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800648 }
649 if (mRotateExitAnimation != null) {
650 mRotateExitAnimation.cancel();
651 mRotateExitAnimation = null;
652 }
653 if (mRotateEnterAnimation != null) {
654 mRotateEnterAnimation.cancel();
655 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800656 }
657 }
658
659 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700660 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700661 }
662
Dianne Hackborn4b169692012-11-29 17:51:24 -0800663 public boolean isRotating() {
664 return mCurRotation != mOriginalRotation;
665 }
666
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700667 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700668 return (TWO_PHASE_ANIMATION &&
669 (mStartEnterAnimation != null || mStartExitAnimation != null
670 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
671 || (USE_CUSTOM_BLACK_FRAME &&
672 (mStartFrameAnimation != null || mRotateFrameAnimation != null
673 || mFinishFrameAnimation != null))
674 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800675 }
676
Craig Mautnere32c3072012-03-12 15:25:35 -0700677 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700678 if (now > mHalfwayPoint) {
679 mHalfwayPoint = Long.MAX_VALUE;
680 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800681 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
682 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
683 mFinishAnimStartTime = now;
684 }
685
Craig Mautner7d8df392012-04-06 15:26:23 -0700686 if (TWO_PHASE_ANIMATION) {
687 mMoreStartExit = false;
688 if (mStartExitAnimation != null) {
689 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
690 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
691 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800692
Craig Mautner7d8df392012-04-06 15:26:23 -0700693 mMoreStartEnter = false;
694 if (mStartEnterAnimation != null) {
695 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
696 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
697 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800698 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700699 if (USE_CUSTOM_BLACK_FRAME) {
700 mMoreStartFrame = false;
701 if (mStartFrameAnimation != null) {
702 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
703 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
704 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800705 }
706
Craig Mautnerdbb79912012-03-01 18:59:14 -0800707 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
708 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
709
Craig Mautner7d8df392012-04-06 15:26:23 -0700710 if (TWO_PHASE_ANIMATION) {
711 mMoreFinishExit = false;
712 if (mFinishExitAnimation != null) {
713 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
714 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
715 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800716
Craig Mautner7d8df392012-04-06 15:26:23 -0700717 mMoreFinishEnter = false;
718 if (mFinishEnterAnimation != null) {
719 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
720 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
721 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800722 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700723 if (USE_CUSTOM_BLACK_FRAME) {
724 mMoreFinishFrame = false;
725 if (mFinishFrameAnimation != null) {
726 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
727 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
728 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800729 }
730
Craig Mautnerdbb79912012-03-01 18:59:14 -0800731 mMoreRotateExit = false;
732 if (mRotateExitAnimation != null) {
733 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
734 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700735 }
736
737 mMoreRotateEnter = false;
738 if (mRotateEnterAnimation != null) {
739 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
740 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
741 }
742
Craig Mautner7d8df392012-04-06 15:26:23 -0700743 if (USE_CUSTOM_BLACK_FRAME) {
744 mMoreRotateFrame = false;
745 if (mRotateFrameAnimation != null) {
746 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
747 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
748 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700749 }
750
Craig Mautner7d8df392012-04-06 15:26:23 -0700751 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
752 if (TWO_PHASE_ANIMATION) {
753 if (mStartExitAnimation != null) {
754 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
755 mStartExitAnimation.cancel();
756 mStartExitAnimation = null;
757 mStartExitTransformation.clear();
758 }
759 if (mFinishExitAnimation != null) {
760 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
761 mFinishExitAnimation.cancel();
762 mFinishExitAnimation = null;
763 mFinishExitTransformation.clear();
764 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700765 }
766 if (mRotateExitAnimation != null) {
767 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800768 mRotateExitAnimation.cancel();
769 mRotateExitAnimation = null;
770 mRotateExitTransformation.clear();
771 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800772 }
773
Craig Mautner7d8df392012-04-06 15:26:23 -0700774 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
775 if (TWO_PHASE_ANIMATION) {
776 if (mStartEnterAnimation != null) {
777 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
778 mStartEnterAnimation.cancel();
779 mStartEnterAnimation = null;
780 mStartEnterTransformation.clear();
781 }
782 if (mFinishEnterAnimation != null) {
783 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
784 mFinishEnterAnimation.cancel();
785 mFinishEnterAnimation = null;
786 mFinishEnterTransformation.clear();
787 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700788 }
789 if (mRotateEnterAnimation != null) {
790 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800791 mRotateEnterAnimation.cancel();
792 mRotateEnterAnimation = null;
793 mRotateEnterTransformation.clear();
794 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800795 }
796
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700797 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
798 if (mStartFrameAnimation != null) {
799 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
800 mStartFrameAnimation.cancel();
801 mStartFrameAnimation = null;
802 mStartFrameTransformation.clear();
803 }
804 if (mFinishFrameAnimation != null) {
805 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
806 mFinishFrameAnimation.cancel();
807 mFinishFrameAnimation = null;
808 mFinishFrameTransformation.clear();
809 }
810 if (mRotateFrameAnimation != null) {
811 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800812 mRotateFrameAnimation.cancel();
813 mRotateFrameAnimation = null;
814 mRotateFrameTransformation.clear();
815 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800816 }
817
818 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800819 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700820 if (TWO_PHASE_ANIMATION) {
821 mExitTransformation.compose(mStartExitTransformation);
822 mExitTransformation.compose(mFinishExitTransformation);
823
824 mEnterTransformation.compose(mStartEnterTransformation);
825 mEnterTransformation.compose(mFinishEnterTransformation);
826 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800827
828 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
829 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700830
831 if (USE_CUSTOM_BLACK_FRAME) {
832 //mFrameTransformation.set(mRotateExitTransformation);
833 //mFrameTransformation.compose(mStartExitTransformation);
834 //mFrameTransformation.compose(mFinishExitTransformation);
835 mFrameTransformation.set(mRotateFrameTransformation);
836 mFrameTransformation.compose(mStartFrameTransformation);
837 mFrameTransformation.compose(mFinishFrameTransformation);
838 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
839 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
840 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800841
Craig Mautner7d8df392012-04-06 15:26:23 -0700842 final boolean more = (TWO_PHASE_ANIMATION
843 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
844 || (USE_CUSTOM_BLACK_FRAME
845 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
846 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800847 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800848
849 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
850
851 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
852
853 return more;
854 }
855
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700856 void updateSurfacesInTransaction() {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700857 if (!mStarted) {
858 return;
859 }
860
Mathias Agopian29479eb2013-02-14 14:36:04 -0800861 if (mSurfaceControl != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700862 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800863 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800864 mSurfaceControl.hide();
Craig Mautnerdbb79912012-03-01 18:59:14 -0800865 }
866 }
867
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700868 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700869 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800870 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700871 mCustomBlackFrame.hide();
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700872 } else {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700873 mCustomBlackFrame.setMatrix(mFrameTransformation.getMatrix());
874 }
875 }
876
877 if (mExitingBlackFrame != null) {
878 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
879 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
880 mExitingBlackFrame.hide();
881 } else {
882 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
883 mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700884 }
885 }
886
887 if (mEnteringBlackFrame != null) {
888 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
889 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
890 mEnteringBlackFrame.hide();
891 } else {
892 mEnteringBlackFrame.setMatrix(mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800893 }
894 }
895
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700896 setSnapshotTransformInTransaction(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800897 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700898
Craig Mautnere32c3072012-03-12 15:25:35 -0700899 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700900 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800901 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800902 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800903 return false;
904 }
905
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800906 if (!mAnimRunning) {
907 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700908 if (TWO_PHASE_ANIMATION) {
909 if (mStartEnterAnimation != null) {
910 mStartEnterAnimation.setStartTime(now);
911 }
912 if (mStartExitAnimation != null) {
913 mStartExitAnimation.setStartTime(now);
914 }
915 if (mFinishEnterAnimation != null) {
916 mFinishEnterAnimation.setStartTime(0);
917 }
918 if (mFinishExitAnimation != null) {
919 mFinishExitAnimation.setStartTime(0);
920 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700921 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700922 if (USE_CUSTOM_BLACK_FRAME) {
923 if (mStartFrameAnimation != null) {
924 mStartFrameAnimation.setStartTime(now);
925 }
926 if (mFinishFrameAnimation != null) {
927 mFinishFrameAnimation.setStartTime(0);
928 }
929 if (mRotateFrameAnimation != null) {
930 mRotateFrameAnimation.setStartTime(now);
931 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800932 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800933 if (mRotateEnterAnimation != null) {
934 mRotateEnterAnimation.setStartTime(now);
935 }
936 if (mRotateExitAnimation != null) {
937 mRotateExitAnimation.setStartTime(now);
938 }
939 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -0700940 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800941 }
Craig Mautnere32c3072012-03-12 15:25:35 -0700942
943 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800944 }
945
946 public Transformation getEnterTransformation() {
947 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800948 }
949}