blob: e630737b40b7b0f9bc0893ea1bb35107a1f0f1bb [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;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070029import android.view.DisplayInfo;
Igor Murashkina86ab6402013-08-30 12:58:36 -070030import android.view.Surface.OutOfResourcesException;
Dianne Hackborna1111872010-11-23 20:55:11 -080031import android.view.Surface;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080032import android.view.SurfaceControl;
Dianne Hackborna1111872010-11-23 20:55:11 -080033import android.view.SurfaceSession;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080034import android.view.animation.Animation;
35import android.view.animation.AnimationUtils;
36import android.view.animation.Transformation;
Dianne Hackborna1111872010-11-23 20:55:11 -080037
Craig Mautnere32c3072012-03-12 15:25:35 -070038class ScreenRotationAnimation {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080039 static final String TAG = "ScreenRotationAnimation";
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080040 static final boolean DEBUG_STATE = false;
41 static final boolean DEBUG_TRANSFORMS = false;
Dianne Hackborn187ae2102012-04-11 18:12:06 -070042 static final boolean TWO_PHASE_ANIMATION = false;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070043 static final boolean USE_CUSTOM_BLACK_FRAME = false;
Dianne Hackborna1111872010-11-23 20:55:11 -080044
Dianne Hackborn50660e22011-02-02 17:12:25 -080045 static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200;
46
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080047 final Context mContext;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070048 final DisplayContent mDisplayContent;
Mathias Agopian29479eb2013-02-14 14:36:04 -080049 SurfaceControl mSurfaceControl;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070050 BlackFrame mCustomBlackFrame;
51 BlackFrame mExitingBlackFrame;
52 BlackFrame mEnteringBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080053 int mWidth, mHeight;
54
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080055 int mOriginalRotation;
56 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080057 int mCurRotation;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070058 Rect mOriginalDisplayRect = new Rect();
59 Rect mCurrentDisplayRect = new Rect();
Dianne Hackborna1111872010-11-23 20:55:11 -080060
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080061 // For all animations, "exit" is for the UI elements that are going
62 // away (that is the snapshot of the old screen), and "enter" is for
63 // the new UI elements that are appearing (that is the active windows
64 // in their final orientation).
65
66 // The starting animation for the exiting and entering elements. This
67 // animation applies a transformation while the rotation is in progress.
68 // It is started immediately, before the new entering UI is ready.
69 Animation mStartExitAnimation;
70 final Transformation mStartExitTransformation = new Transformation();
71 Animation mStartEnterAnimation;
72 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080073 Animation mStartFrameAnimation;
74 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080075
76 // The finishing animation for the exiting and entering elements. This
77 // animation needs to undo the transformation of the starting animation.
78 // It starts running once the new rotation UI elements are ready to be
79 // displayed.
80 Animation mFinishExitAnimation;
81 final Transformation mFinishExitTransformation = new Transformation();
82 Animation mFinishEnterAnimation;
83 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080084 Animation mFinishFrameAnimation;
85 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080086
87 // The current active animation to move from the old to the new rotated
88 // state. Which animation is run here will depend on the old and new
89 // rotations.
90 Animation mRotateExitAnimation;
91 final Transformation mRotateExitTransformation = new Transformation();
92 Animation mRotateEnterAnimation;
93 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080094 Animation mRotateFrameAnimation;
95 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080096
97 // A previously running rotate animation. This will be used if we need
98 // to switch to a new rotation before finishing the previous one.
99 Animation mLastRotateExitAnimation;
100 final Transformation mLastRotateExitTransformation = new Transformation();
101 Animation mLastRotateEnterAnimation;
102 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800103 Animation mLastRotateFrameAnimation;
104 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800105
106 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800107 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800108 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800109 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800110
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800111 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800112 boolean mAnimRunning;
113 boolean mFinishAnimReady;
114 long mFinishAnimStartTime;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700115 boolean mForceDefaultOrientation;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800116
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800117 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800118 final Matrix mSnapshotInitialMatrix = new Matrix();
119 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700120 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800121 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800122 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800123 private boolean mMoreRotateEnter;
124 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800125 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800126 private boolean mMoreFinishEnter;
127 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800128 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800129 private boolean mMoreStartEnter;
130 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800131 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700132 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800133
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800134 public void printTo(String prefix, PrintWriter pw) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800135 pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800136 pw.print(" mWidth="); pw.print(mWidth);
137 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700138 if (USE_CUSTOM_BLACK_FRAME) {
139 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
140 if (mCustomBlackFrame != null) {
141 mCustomBlackFrame.printTo(prefix + " ", pw);
142 }
143 }
144 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
145 if (mExitingBlackFrame != null) {
146 mExitingBlackFrame.printTo(prefix + " ", pw);
147 }
148 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
149 if (mEnteringBlackFrame != null) {
150 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800151 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700152 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
153 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
154 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800155 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
156 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
157 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
158 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
159 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
160 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
161 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
162 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
163 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800164 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
165 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800166 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
167 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
168 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
169 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800170 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
171 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800172 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
173 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
174 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
175 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800176 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
177 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800178 pw.print(prefix); pw.print("mExitTransformation=");
179 mExitTransformation.printShortString(pw); pw.println();
180 pw.print(prefix); pw.print("mEnterTransformation=");
181 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800182 pw.print(prefix); pw.print("mFrameTransformation=");
183 mEnterTransformation.printShortString(pw); pw.println();
184 pw.print(prefix); pw.print("mFrameInitialMatrix=");
185 mFrameInitialMatrix.printShortString(pw);
186 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800187 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
188 mSnapshotInitialMatrix.printShortString(pw);
189 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
190 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700191 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
192 mExitFrameFinalMatrix.printShortString(pw);
193 pw.println();
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700194 pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
195 if (mForceDefaultOrientation) {
196 pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
197 pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString());
198 }
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800199 }
200
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700201 public ScreenRotationAnimation(Context context, DisplayContent displayContent,
202 SurfaceSession session, boolean inTransaction, boolean forceDefaultOrientation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800203 mContext = context;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700204 mDisplayContent = displayContent;
205 displayContent.getLogicalDisplayRect(mOriginalDisplayRect);
Dianne Hackborna1111872010-11-23 20:55:11 -0800206
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800207 // Screenshot does NOT include rotation!
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700208 final Display display = displayContent.getDisplay();
209 int originalRotation = display.getRotation();
210 final int originalWidth;
211 final int originalHeight;
212 DisplayInfo displayInfo = displayContent.getDisplayInfo();
213 if (forceDefaultOrientation) {
214 // Emulated orientation.
215 mForceDefaultOrientation = true;
216 originalWidth = displayContent.mBaseDisplayWidth;
217 originalHeight = displayContent.mBaseDisplayHeight;
218 } else {
219 // Normal situation
220 originalWidth = displayInfo.logicalWidth;
221 originalHeight = displayInfo.logicalHeight;
222 }
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700223 if (originalRotation == Surface.ROTATION_90
224 || originalRotation == Surface.ROTATION_270) {
225 mWidth = originalHeight;
226 mHeight = originalWidth;
227 } else {
228 mWidth = originalWidth;
229 mHeight = originalHeight;
230 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800231
Jeff Brownbc68a592011-07-25 12:58:12 -0700232 mOriginalRotation = originalRotation;
233 mOriginalWidth = originalWidth;
234 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800235
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800236 if (!inTransaction) {
Dianne Hackborn36991742011-10-11 21:35:26 -0700237 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800238 ">>> OPEN TRANSACTION ScreenRotationAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800239 SurfaceControl.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800240 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700241
Dianne Hackborna1111872010-11-23 20:55:11 -0800242 try {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800243 try {
Craig Mautner7d8df392012-04-06 15:26:23 -0700244 if (WindowManagerService.DEBUG_SURFACE_TRACE) {
Mathias Agopian11e7d882013-03-05 14:14:55 -0800245 mSurfaceControl = new SurfaceTrace(session, "ScreenshotSurface",
Jeff Brown64a55af2012-08-26 02:47:39 -0700246 mWidth, mHeight,
Mathias Agopian11e7d882013-03-05 14:14:55 -0800247 PixelFormat.OPAQUE, SurfaceControl.HIDDEN);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700248 Slog.w(TAG, "ScreenRotationAnimation ctor: displayOffset="
249 + mOriginalDisplayRect.toShortString());
Craig Mautner7d8df392012-04-06 15:26:23 -0700250 } else {
Mathias Agopian11e7d882013-03-05 14:14:55 -0800251 mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
Jeff Brown64a55af2012-08-26 02:47:39 -0700252 mWidth, mHeight,
Mathias Agopian11e7d882013-03-05 14:14:55 -0800253 PixelFormat.OPAQUE, SurfaceControl.HIDDEN);
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700254 }
Mathias Agopian11e7d882013-03-05 14:14:55 -0800255 // capture a screenshot into the surface we just created
256 Surface sur = new Surface();
257 sur.copyFrom(mSurfaceControl);
258 // FIXME: we should use the proper display
259 SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(
260 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), sur);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700261 mSurfaceControl.setLayerStack(display.getLayerStack());
Mathias Agopian29479eb2013-02-14 14:36:04 -0800262 mSurfaceControl.setLayer(FREEZE_LAYER + 1);
263 mSurfaceControl.setAlpha(0);
264 mSurfaceControl.show();
Craig Mautnere50d7fc2013-03-18 10:06:21 -0700265 sur.destroy();
Igor Murashkina86ab6402013-08-30 12:58:36 -0700266 } catch (OutOfResourcesException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800267 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800268 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800269
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700270 if (WindowManagerService.SHOW_TRANSACTIONS ||
271 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800272 " FREEZE " + mSurfaceControl + ": CREATE");
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700273
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700274 setRotationInTransaction(originalRotation);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800275 } finally {
276 if (!inTransaction) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800277 SurfaceControl.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -0700278 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800279 "<<< CLOSE TRANSACTION ScreenRotationAnimation");
Dianne Hackborn352cc982011-01-04 11:34:18 -0800280 }
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800281 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800282 }
283
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800284 boolean hasScreenshot() {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800285 return mSurfaceControl != null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800286 }
287
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800288 static int deltaRotation(int oldRotation, int newRotation) {
289 int delta = newRotation - oldRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800290 if (delta < 0) delta += 4;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800291 return delta;
292 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800293
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700294 private void setSnapshotTransformInTransaction(Matrix matrix, float alpha) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800295 if (mSurfaceControl != null) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800296 matrix.getValues(mTmpFloats);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700297 float x = mTmpFloats[Matrix.MTRANS_X];
298 float y = mTmpFloats[Matrix.MTRANS_Y];
299 if (mForceDefaultOrientation) {
300 mDisplayContent.getLogicalDisplayRect(mCurrentDisplayRect);
301 x -= mCurrentDisplayRect.left;
302 y -= mCurrentDisplayRect.top;
303 }
304 mSurfaceControl.setPosition(x, y);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800305 mSurfaceControl.setMatrix(
Dianne Hackborn352cc982011-01-04 11:34:18 -0800306 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
307 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800308 mSurfaceControl.setAlpha(alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800309 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800310 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
311 float[] dstPnts = new float[4];
312 matrix.mapPoints(dstPnts, srcPnts);
313 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
314 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
315 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
316 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
317 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800318 }
319 }
320
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800321 public static void createRotationMatrix(int rotation, int width, int height,
322 Matrix outMatrix) {
323 switch (rotation) {
324 case Surface.ROTATION_0:
325 outMatrix.reset();
326 break;
327 case Surface.ROTATION_90:
328 outMatrix.setRotate(90, 0, 0);
329 outMatrix.postTranslate(height, 0);
330 break;
331 case Surface.ROTATION_180:
332 outMatrix.setRotate(180, 0, 0);
333 outMatrix.postTranslate(width, height);
334 break;
335 case Surface.ROTATION_270:
336 outMatrix.setRotate(270, 0, 0);
337 outMatrix.postTranslate(0, width);
338 break;
339 }
340 }
341
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800342 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700343 private void setRotationInTransaction(int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800344 mCurRotation = rotation;
345
346 // Compute the transformation matrix that must be applied
347 // to the snapshot to make it stay in the same original position
348 // with the current screen rotation.
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700349 int delta = deltaRotation(rotation, Surface.ROTATION_0);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800350 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800351
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800352 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700353 setSnapshotTransformInTransaction(mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800354 }
355
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800356 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700357 public boolean setRotationInTransaction(int rotation, SurfaceSession session,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800358 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700359 setRotationInTransaction(rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700360 if (TWO_PHASE_ANIMATION) {
361 return startAnimation(session, maxAnimationDuration, animationScale,
Craig Mautner3c174372013-02-21 17:54:37 -0800362 finalWidth, finalHeight, false, 0, 0);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700363 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700364
365 // Don't start animation yet.
366 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800367 }
368
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800369 /**
370 * Returns true if animating.
371 */
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800372 private boolean startAnimation(SurfaceSession session, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800373 float animationScale, int finalWidth, int finalHeight, boolean dismissing,
374 int exitAnim, int enterAnim) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800375 if (mSurfaceControl == null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800376 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800377 return false;
378 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800379 if (mStarted) {
380 return true;
381 }
382
383 mStarted = true;
384
385 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800386
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800387 // Figure out how the screen has moved from the original rotation.
388 int delta = deltaRotation(mCurRotation, mOriginalRotation);
389
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700390 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
391 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800392 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
393 firstStart = true;
394 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
395 com.android.internal.R.anim.screen_rotate_start_exit);
396 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
397 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700398 if (USE_CUSTOM_BLACK_FRAME) {
399 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
400 com.android.internal.R.anim.screen_rotate_start_frame);
401 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800402 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
403 com.android.internal.R.anim.screen_rotate_finish_exit);
404 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
405 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700406 if (USE_CUSTOM_BLACK_FRAME) {
407 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
408 com.android.internal.R.anim.screen_rotate_finish_frame);
409 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800410 }
411
412 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
413 + finalWidth + " finalHeight=" + finalHeight
414 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
415
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700416 final boolean customAnim;
Craig Mautner3c174372013-02-21 17:54:37 -0800417 if (exitAnim != 0 && enterAnim != 0) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700418 customAnim = true;
Craig Mautner3c174372013-02-21 17:54:37 -0800419 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
420 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700421 } else {
422 customAnim = false;
423 switch (delta) {
424 case Surface.ROTATION_0:
425 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
426 com.android.internal.R.anim.screen_rotate_0_exit);
427 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
428 com.android.internal.R.anim.screen_rotate_0_enter);
429 if (USE_CUSTOM_BLACK_FRAME) {
430 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
431 com.android.internal.R.anim.screen_rotate_0_frame);
432 }
433 break;
434 case Surface.ROTATION_90:
435 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
436 com.android.internal.R.anim.screen_rotate_plus_90_exit);
437 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
438 com.android.internal.R.anim.screen_rotate_plus_90_enter);
439 if (USE_CUSTOM_BLACK_FRAME) {
440 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
441 com.android.internal.R.anim.screen_rotate_plus_90_frame);
442 }
443 break;
444 case Surface.ROTATION_180:
445 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
446 com.android.internal.R.anim.screen_rotate_180_exit);
447 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
448 com.android.internal.R.anim.screen_rotate_180_enter);
449 if (USE_CUSTOM_BLACK_FRAME) {
450 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
451 com.android.internal.R.anim.screen_rotate_180_frame);
452 }
453 break;
454 case Surface.ROTATION_270:
455 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
456 com.android.internal.R.anim.screen_rotate_minus_90_exit);
457 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
458 com.android.internal.R.anim.screen_rotate_minus_90_enter);
459 if (USE_CUSTOM_BLACK_FRAME) {
460 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
461 com.android.internal.R.anim.screen_rotate_minus_90_frame);
462 }
463 break;
464 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800465 }
466
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800467 // Initialize the animations. This is a hack, redefining what "parent"
468 // means to allow supplying the last and next size. In this definition
469 // "%p" is the original (let's call it "previous") size, and "%" is the
470 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700471 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700472 // Compute partial steps between original and final sizes. These
473 // are used for the dimensions of the exiting and entering elements,
474 // so they are never stretched too significantly.
475 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
476 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
477
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800478 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
479 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800480 halfWidth, halfHeight);
481 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800482 mOriginalWidth, mOriginalHeight);
483 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800484 halfWidth, halfHeight);
485 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800486 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700487 if (USE_CUSTOM_BLACK_FRAME) {
488 mStartFrameAnimation.initialize(finalWidth, finalHeight,
489 mOriginalWidth, mOriginalHeight);
490 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
491 mOriginalWidth, mOriginalHeight);
492 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800493 }
494 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
495 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700496 if (USE_CUSTOM_BLACK_FRAME) {
497 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
498 mOriginalHeight);
499 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800500 mAnimRunning = false;
501 mFinishAnimReady = false;
502 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800503
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700504 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800505 mStartExitAnimation.restrictDuration(maxAnimationDuration);
506 mStartExitAnimation.scaleCurrentDuration(animationScale);
507 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
508 mStartEnterAnimation.scaleCurrentDuration(animationScale);
509 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
510 mFinishExitAnimation.scaleCurrentDuration(animationScale);
511 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
512 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700513 if (USE_CUSTOM_BLACK_FRAME) {
514 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
515 mStartFrameAnimation.scaleCurrentDuration(animationScale);
516 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
517 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
518 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800519 }
520 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
521 mRotateExitAnimation.scaleCurrentDuration(animationScale);
522 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
523 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700524 if (USE_CUSTOM_BLACK_FRAME) {
525 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
526 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
527 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800528
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700529 final int layerStack = mDisplayContent.getDisplay().getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700530 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800531 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
532 WindowManagerService.TAG,
533 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800534 SurfaceControl.openTransaction();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800535
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800536 // Compute the transformation matrix that must be applied
537 // the the black frame to make it stay in the initial position
538 // before the new screen rotation. This is different than the
539 // snapshot transformation because the snapshot is always based
540 // of the native orientation of the screen, not the orientation
541 // we were last in.
542 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
543
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800544 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800545 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
546 mOriginalWidth*2, mOriginalHeight*2);
547 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700548 mCustomBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 3,
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700549 layerStack, false);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700550 mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700551 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700552 Slog.w(TAG, "Unable to allocate black surface", e);
553 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800554 SurfaceControl.closeTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700555 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
556 WindowManagerService.TAG,
557 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
558 }
559 }
560
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700561 if (!customAnim && mExitingBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700562 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
563 WindowManagerService.TAG,
564 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800565 SurfaceControl.openTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700566 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700567 // Compute the transformation matrix that must be applied
568 // the the black frame to make it stay in the initial position
569 // before the new screen rotation. This is different than the
570 // snapshot transformation because the snapshot is always based
571 // of the native orientation of the screen, not the orientation
572 // we were last in.
573 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
574
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700575 final Rect outer;
576 final Rect inner;
577 if (mForceDefaultOrientation) {
578 // Going from a smaller Display to a larger Display, add curtains to sides
579 // or top and bottom. Going from a larger to smaller display will result in
580 // no BlackSurfaces being constructed.
581 outer = mCurrentDisplayRect;
582 inner = mOriginalDisplayRect;
583 } else {
584 outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
585 mOriginalWidth*2, mOriginalHeight*2);
586 inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
587 }
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700588 mExitingBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 2,
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700589 layerStack, mForceDefaultOrientation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700590 mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700591 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700592 Slog.w(TAG, "Unable to allocate black surface", e);
593 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800594 SurfaceControl.closeTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700595 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
596 WindowManagerService.TAG,
597 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
598 }
599 }
600
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700601 if (customAnim && mEnteringBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700602 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
603 WindowManagerService.TAG,
604 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800605 SurfaceControl.openTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700606
607 try {
608 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
609 finalWidth*2, finalHeight*2);
610 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700611 mEnteringBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER,
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700612 layerStack, false);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700613 } catch (OutOfResourcesException e) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800614 Slog.w(TAG, "Unable to allocate black surface", e);
615 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800616 SurfaceControl.closeTransaction();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800617 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
618 WindowManagerService.TAG,
619 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
620 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800621 }
622
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800623 return true;
624 }
625
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800626 /**
627 * Returns true if animating.
628 */
629 public boolean dismiss(SurfaceSession session, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800630 float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800631 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800632 if (mSurfaceControl == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800633 // Can't do animation.
634 return false;
635 }
636 if (!mStarted) {
637 startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight,
Craig Mautner3c174372013-02-21 17:54:37 -0800638 true, exitAnim, enterAnim);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800639 }
640 if (!mStarted) {
641 return false;
642 }
643 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
644 mFinishAnimReady = true;
645 return true;
646 }
647
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800648 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800649 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800650 if (mSurfaceControl != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700651 if (WindowManagerService.SHOW_TRANSACTIONS ||
652 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800653 " FREEZE " + mSurfaceControl + ": DESTROY");
654 mSurfaceControl.destroy();
655 mSurfaceControl = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800656 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700657 if (mCustomBlackFrame != null) {
658 mCustomBlackFrame.kill();
659 mCustomBlackFrame = null;
660 }
661 if (mExitingBlackFrame != null) {
662 mExitingBlackFrame.kill();
663 mExitingBlackFrame = null;
664 }
665 if (mEnteringBlackFrame != null) {
666 mEnteringBlackFrame.kill();
667 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800668 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700669 if (TWO_PHASE_ANIMATION) {
670 if (mStartExitAnimation != null) {
671 mStartExitAnimation.cancel();
672 mStartExitAnimation = null;
673 }
674 if (mStartEnterAnimation != null) {
675 mStartEnterAnimation.cancel();
676 mStartEnterAnimation = null;
677 }
678 if (mFinishExitAnimation != null) {
679 mFinishExitAnimation.cancel();
680 mFinishExitAnimation = null;
681 }
682 if (mFinishEnterAnimation != null) {
683 mFinishEnterAnimation.cancel();
684 mFinishEnterAnimation = null;
685 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800686 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700687 if (USE_CUSTOM_BLACK_FRAME) {
688 if (mStartFrameAnimation != null) {
689 mStartFrameAnimation.cancel();
690 mStartFrameAnimation = null;
691 }
692 if (mRotateFrameAnimation != null) {
693 mRotateFrameAnimation.cancel();
694 mRotateFrameAnimation = null;
695 }
696 if (mFinishFrameAnimation != null) {
697 mFinishFrameAnimation.cancel();
698 mFinishFrameAnimation = null;
699 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800700 }
701 if (mRotateExitAnimation != null) {
702 mRotateExitAnimation.cancel();
703 mRotateExitAnimation = null;
704 }
705 if (mRotateEnterAnimation != null) {
706 mRotateEnterAnimation.cancel();
707 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800708 }
709 }
710
711 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700712 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700713 }
714
Dianne Hackborn4b169692012-11-29 17:51:24 -0800715 public boolean isRotating() {
716 return mCurRotation != mOriginalRotation;
717 }
718
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700719 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700720 return (TWO_PHASE_ANIMATION &&
721 (mStartEnterAnimation != null || mStartExitAnimation != null
722 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
723 || (USE_CUSTOM_BLACK_FRAME &&
724 (mStartFrameAnimation != null || mRotateFrameAnimation != null
725 || mFinishFrameAnimation != null))
726 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800727 }
728
Craig Mautnere32c3072012-03-12 15:25:35 -0700729 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700730 if (now > mHalfwayPoint) {
731 mHalfwayPoint = Long.MAX_VALUE;
732 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800733 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
734 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
735 mFinishAnimStartTime = now;
736 }
737
Craig Mautner7d8df392012-04-06 15:26:23 -0700738 if (TWO_PHASE_ANIMATION) {
739 mMoreStartExit = false;
740 if (mStartExitAnimation != null) {
741 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
742 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
743 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800744
Craig Mautner7d8df392012-04-06 15:26:23 -0700745 mMoreStartEnter = false;
746 if (mStartEnterAnimation != null) {
747 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
748 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
749 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800750 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700751 if (USE_CUSTOM_BLACK_FRAME) {
752 mMoreStartFrame = false;
753 if (mStartFrameAnimation != null) {
754 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
755 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
756 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800757 }
758
Craig Mautnerdbb79912012-03-01 18:59:14 -0800759 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
760 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
761
Craig Mautner7d8df392012-04-06 15:26:23 -0700762 if (TWO_PHASE_ANIMATION) {
763 mMoreFinishExit = false;
764 if (mFinishExitAnimation != null) {
765 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
766 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
767 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800768
Craig Mautner7d8df392012-04-06 15:26:23 -0700769 mMoreFinishEnter = false;
770 if (mFinishEnterAnimation != null) {
771 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
772 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
773 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800774 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700775 if (USE_CUSTOM_BLACK_FRAME) {
776 mMoreFinishFrame = false;
777 if (mFinishFrameAnimation != null) {
778 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
779 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
780 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800781 }
782
Craig Mautnerdbb79912012-03-01 18:59:14 -0800783 mMoreRotateExit = false;
784 if (mRotateExitAnimation != null) {
785 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
786 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700787 }
788
789 mMoreRotateEnter = false;
790 if (mRotateEnterAnimation != null) {
791 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
792 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
793 }
794
Craig Mautner7d8df392012-04-06 15:26:23 -0700795 if (USE_CUSTOM_BLACK_FRAME) {
796 mMoreRotateFrame = false;
797 if (mRotateFrameAnimation != null) {
798 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
799 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
800 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700801 }
802
Craig Mautner7d8df392012-04-06 15:26:23 -0700803 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
804 if (TWO_PHASE_ANIMATION) {
805 if (mStartExitAnimation != null) {
806 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
807 mStartExitAnimation.cancel();
808 mStartExitAnimation = null;
809 mStartExitTransformation.clear();
810 }
811 if (mFinishExitAnimation != null) {
812 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
813 mFinishExitAnimation.cancel();
814 mFinishExitAnimation = null;
815 mFinishExitTransformation.clear();
816 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700817 }
818 if (mRotateExitAnimation != null) {
819 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800820 mRotateExitAnimation.cancel();
821 mRotateExitAnimation = null;
822 mRotateExitTransformation.clear();
823 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800824 }
825
Craig Mautner7d8df392012-04-06 15:26:23 -0700826 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
827 if (TWO_PHASE_ANIMATION) {
828 if (mStartEnterAnimation != null) {
829 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
830 mStartEnterAnimation.cancel();
831 mStartEnterAnimation = null;
832 mStartEnterTransformation.clear();
833 }
834 if (mFinishEnterAnimation != null) {
835 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
836 mFinishEnterAnimation.cancel();
837 mFinishEnterAnimation = null;
838 mFinishEnterTransformation.clear();
839 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700840 }
841 if (mRotateEnterAnimation != null) {
842 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800843 mRotateEnterAnimation.cancel();
844 mRotateEnterAnimation = null;
845 mRotateEnterTransformation.clear();
846 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800847 }
848
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700849 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
850 if (mStartFrameAnimation != null) {
851 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
852 mStartFrameAnimation.cancel();
853 mStartFrameAnimation = null;
854 mStartFrameTransformation.clear();
855 }
856 if (mFinishFrameAnimation != null) {
857 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
858 mFinishFrameAnimation.cancel();
859 mFinishFrameAnimation = null;
860 mFinishFrameTransformation.clear();
861 }
862 if (mRotateFrameAnimation != null) {
863 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800864 mRotateFrameAnimation.cancel();
865 mRotateFrameAnimation = null;
866 mRotateFrameTransformation.clear();
867 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800868 }
869
870 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800871 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700872 if (TWO_PHASE_ANIMATION) {
873 mExitTransformation.compose(mStartExitTransformation);
874 mExitTransformation.compose(mFinishExitTransformation);
875
876 mEnterTransformation.compose(mStartEnterTransformation);
877 mEnterTransformation.compose(mFinishEnterTransformation);
878 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800879
880 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
881 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700882
883 if (USE_CUSTOM_BLACK_FRAME) {
884 //mFrameTransformation.set(mRotateExitTransformation);
885 //mFrameTransformation.compose(mStartExitTransformation);
886 //mFrameTransformation.compose(mFinishExitTransformation);
887 mFrameTransformation.set(mRotateFrameTransformation);
888 mFrameTransformation.compose(mStartFrameTransformation);
889 mFrameTransformation.compose(mFinishFrameTransformation);
890 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
891 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
892 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800893
Craig Mautner7d8df392012-04-06 15:26:23 -0700894 final boolean more = (TWO_PHASE_ANIMATION
895 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
896 || (USE_CUSTOM_BLACK_FRAME
897 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
Igor Murashkina86ab6402013-08-30 12:58:36 -0700898 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800899 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800900
901 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
902
903 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
904
905 return more;
906 }
907
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700908 void updateSurfacesInTransaction() {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700909 if (!mStarted) {
910 return;
911 }
912
Mathias Agopian29479eb2013-02-14 14:36:04 -0800913 if (mSurfaceControl != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700914 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800915 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800916 mSurfaceControl.hide();
Craig Mautnerdbb79912012-03-01 18:59:14 -0800917 }
918 }
919
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700920 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700921 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800922 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700923 mCustomBlackFrame.hide();
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700924 } else {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700925 mCustomBlackFrame.setMatrix(mFrameTransformation.getMatrix());
926 }
927 }
928
929 if (mExitingBlackFrame != null) {
930 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
931 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
932 mExitingBlackFrame.hide();
933 } else {
934 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
935 mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700936 if (mForceDefaultOrientation) {
937 mExitingBlackFrame.setAlpha(mExitTransformation.getAlpha());
938 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700939 }
940 }
941
942 if (mEnteringBlackFrame != null) {
943 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
944 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
945 mEnteringBlackFrame.hide();
946 } else {
947 mEnteringBlackFrame.setMatrix(mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800948 }
949 }
950
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700951 setSnapshotTransformInTransaction(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800952 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700953
Craig Mautnere32c3072012-03-12 15:25:35 -0700954 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700955 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800956 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800957 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800958 return false;
959 }
960
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800961 if (!mAnimRunning) {
962 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700963 if (TWO_PHASE_ANIMATION) {
964 if (mStartEnterAnimation != null) {
965 mStartEnterAnimation.setStartTime(now);
966 }
967 if (mStartExitAnimation != null) {
968 mStartExitAnimation.setStartTime(now);
969 }
970 if (mFinishEnterAnimation != null) {
971 mFinishEnterAnimation.setStartTime(0);
972 }
973 if (mFinishExitAnimation != null) {
974 mFinishExitAnimation.setStartTime(0);
975 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700976 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700977 if (USE_CUSTOM_BLACK_FRAME) {
978 if (mStartFrameAnimation != null) {
979 mStartFrameAnimation.setStartTime(now);
980 }
981 if (mFinishFrameAnimation != null) {
982 mFinishFrameAnimation.setStartTime(0);
983 }
984 if (mRotateFrameAnimation != null) {
985 mRotateFrameAnimation.setStartTime(now);
986 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800987 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800988 if (mRotateEnterAnimation != null) {
989 mRotateEnterAnimation.setStartTime(now);
990 }
991 if (mRotateExitAnimation != null) {
992 mRotateExitAnimation.setStartTime(now);
993 }
994 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -0700995 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800996 }
Craig Mautnere32c3072012-03-12 15:25:35 -0700997
998 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800999 }
1000
1001 public Transformation getEnterTransformation() {
1002 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -08001003 }
1004}