blob: 7d9085888ef2e707cb501fef62e52db9f210be9c [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;
Dianne Hackborna1111872010-11-23 20:55:11 -080030import android.view.Surface;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080031import android.view.SurfaceControl;
Dianne Hackborna1111872010-11-23 20:55:11 -080032import android.view.SurfaceSession;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080033import android.view.animation.Animation;
34import android.view.animation.AnimationUtils;
35import android.view.animation.Transformation;
Dianne Hackborna1111872010-11-23 20:55:11 -080036
Craig Mautnere32c3072012-03-12 15:25:35 -070037class ScreenRotationAnimation {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080038 static final String TAG = "ScreenRotationAnimation";
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080039 static final boolean DEBUG_STATE = false;
40 static final boolean DEBUG_TRANSFORMS = false;
Dianne Hackborn187ae2102012-04-11 18:12:06 -070041 static final boolean TWO_PHASE_ANIMATION = false;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070042 static final boolean USE_CUSTOM_BLACK_FRAME = false;
Dianne Hackborna1111872010-11-23 20:55:11 -080043
Dianne Hackborn50660e22011-02-02 17:12:25 -080044 static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200;
45
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080046 final Context mContext;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070047 final DisplayContent mDisplayContent;
Mathias Agopian29479eb2013-02-14 14:36:04 -080048 SurfaceControl mSurfaceControl;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070049 BlackFrame mCustomBlackFrame;
50 BlackFrame mExitingBlackFrame;
51 BlackFrame mEnteringBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080052 int mWidth, mHeight;
53
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080054 int mOriginalRotation;
55 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080056 int mCurRotation;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070057 Rect mOriginalDisplayRect = new Rect();
58 Rect mCurrentDisplayRect = new Rect();
Dianne Hackborna1111872010-11-23 20:55:11 -080059
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080060 // For all animations, "exit" is for the UI elements that are going
61 // away (that is the snapshot of the old screen), and "enter" is for
62 // the new UI elements that are appearing (that is the active windows
63 // in their final orientation).
64
65 // The starting animation for the exiting and entering elements. This
66 // animation applies a transformation while the rotation is in progress.
67 // It is started immediately, before the new entering UI is ready.
68 Animation mStartExitAnimation;
69 final Transformation mStartExitTransformation = new Transformation();
70 Animation mStartEnterAnimation;
71 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080072 Animation mStartFrameAnimation;
73 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080074
75 // The finishing animation for the exiting and entering elements. This
76 // animation needs to undo the transformation of the starting animation.
77 // It starts running once the new rotation UI elements are ready to be
78 // displayed.
79 Animation mFinishExitAnimation;
80 final Transformation mFinishExitTransformation = new Transformation();
81 Animation mFinishEnterAnimation;
82 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080083 Animation mFinishFrameAnimation;
84 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080085
86 // The current active animation to move from the old to the new rotated
87 // state. Which animation is run here will depend on the old and new
88 // rotations.
89 Animation mRotateExitAnimation;
90 final Transformation mRotateExitTransformation = new Transformation();
91 Animation mRotateEnterAnimation;
92 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080093 Animation mRotateFrameAnimation;
94 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080095
96 // A previously running rotate animation. This will be used if we need
97 // to switch to a new rotation before finishing the previous one.
98 Animation mLastRotateExitAnimation;
99 final Transformation mLastRotateExitTransformation = new Transformation();
100 Animation mLastRotateEnterAnimation;
101 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800102 Animation mLastRotateFrameAnimation;
103 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800104
105 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800106 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800107 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800108 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800109
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800110 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800111 boolean mAnimRunning;
112 boolean mFinishAnimReady;
113 long mFinishAnimStartTime;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700114 boolean mForceDefaultOrientation;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800115
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800116 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800117 final Matrix mSnapshotInitialMatrix = new Matrix();
118 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700119 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800120 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800121 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800122 private boolean mMoreRotateEnter;
123 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800124 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800125 private boolean mMoreFinishEnter;
126 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800127 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800128 private boolean mMoreStartEnter;
129 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800130 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700131 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800132
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800133 public void printTo(String prefix, PrintWriter pw) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800134 pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800135 pw.print(" mWidth="); pw.print(mWidth);
136 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700137 if (USE_CUSTOM_BLACK_FRAME) {
138 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
139 if (mCustomBlackFrame != null) {
140 mCustomBlackFrame.printTo(prefix + " ", pw);
141 }
142 }
143 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
144 if (mExitingBlackFrame != null) {
145 mExitingBlackFrame.printTo(prefix + " ", pw);
146 }
147 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
148 if (mEnteringBlackFrame != null) {
149 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800150 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700151 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
152 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
153 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800154 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
155 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
156 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
157 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
158 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
159 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
160 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
161 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
162 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800163 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
164 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800165 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
166 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
167 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
168 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800169 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
170 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800171 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
172 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
173 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
174 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800175 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
176 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800177 pw.print(prefix); pw.print("mExitTransformation=");
178 mExitTransformation.printShortString(pw); pw.println();
179 pw.print(prefix); pw.print("mEnterTransformation=");
180 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800181 pw.print(prefix); pw.print("mFrameTransformation=");
182 mEnterTransformation.printShortString(pw); pw.println();
183 pw.print(prefix); pw.print("mFrameInitialMatrix=");
184 mFrameInitialMatrix.printShortString(pw);
185 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800186 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
187 mSnapshotInitialMatrix.printShortString(pw);
188 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
189 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700190 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
191 mExitFrameFinalMatrix.printShortString(pw);
192 pw.println();
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700193 pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
194 if (mForceDefaultOrientation) {
195 pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
196 pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString());
197 }
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800198 }
199
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700200 public ScreenRotationAnimation(Context context, DisplayContent displayContent,
201 SurfaceSession session, boolean inTransaction, boolean forceDefaultOrientation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800202 mContext = context;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700203 mDisplayContent = displayContent;
204 displayContent.getLogicalDisplayRect(mOriginalDisplayRect);
Dianne Hackborna1111872010-11-23 20:55:11 -0800205
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800206 // Screenshot does NOT include rotation!
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700207 final Display display = displayContent.getDisplay();
208 int originalRotation = display.getRotation();
209 final int originalWidth;
210 final int originalHeight;
211 DisplayInfo displayInfo = displayContent.getDisplayInfo();
212 if (forceDefaultOrientation) {
213 // Emulated orientation.
214 mForceDefaultOrientation = true;
215 originalWidth = displayContent.mBaseDisplayWidth;
216 originalHeight = displayContent.mBaseDisplayHeight;
217 } else {
218 // Normal situation
219 originalWidth = displayInfo.logicalWidth;
220 originalHeight = displayInfo.logicalHeight;
221 }
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700222 if (originalRotation == Surface.ROTATION_90
223 || originalRotation == Surface.ROTATION_270) {
224 mWidth = originalHeight;
225 mHeight = originalWidth;
226 } else {
227 mWidth = originalWidth;
228 mHeight = originalHeight;
229 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800230
Jeff Brownbc68a592011-07-25 12:58:12 -0700231 mOriginalRotation = originalRotation;
232 mOriginalWidth = originalWidth;
233 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800234
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800235 if (!inTransaction) {
Dianne Hackborn36991742011-10-11 21:35:26 -0700236 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800237 ">>> OPEN TRANSACTION ScreenRotationAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800238 SurfaceControl.openTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800239 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700240
Dianne Hackborna1111872010-11-23 20:55:11 -0800241 try {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800242 try {
Craig Mautner7d8df392012-04-06 15:26:23 -0700243 if (WindowManagerService.DEBUG_SURFACE_TRACE) {
Mathias Agopian11e7d882013-03-05 14:14:55 -0800244 mSurfaceControl = new SurfaceTrace(session, "ScreenshotSurface",
Jeff Brown64a55af2012-08-26 02:47:39 -0700245 mWidth, mHeight,
Mathias Agopian11e7d882013-03-05 14:14:55 -0800246 PixelFormat.OPAQUE, SurfaceControl.HIDDEN);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700247 Slog.w(TAG, "ScreenRotationAnimation ctor: displayOffset="
248 + mOriginalDisplayRect.toShortString());
Craig Mautner7d8df392012-04-06 15:26:23 -0700249 } else {
Mathias Agopian11e7d882013-03-05 14:14:55 -0800250 mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
Jeff Brown64a55af2012-08-26 02:47:39 -0700251 mWidth, mHeight,
Mathias Agopian11e7d882013-03-05 14:14:55 -0800252 PixelFormat.OPAQUE, SurfaceControl.HIDDEN);
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700253 }
Mathias Agopian11e7d882013-03-05 14:14:55 -0800254 // capture a screenshot into the surface we just created
255 Surface sur = new Surface();
256 sur.copyFrom(mSurfaceControl);
257 // FIXME: we should use the proper display
258 SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(
259 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), sur);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700260 mSurfaceControl.setLayerStack(display.getLayerStack());
Mathias Agopian29479eb2013-02-14 14:36:04 -0800261 mSurfaceControl.setLayer(FREEZE_LAYER + 1);
262 mSurfaceControl.setAlpha(0);
263 mSurfaceControl.show();
Craig Mautnere50d7fc2013-03-18 10:06:21 -0700264 sur.destroy();
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800265 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800266 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800267 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800268
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700269 if (WindowManagerService.SHOW_TRANSACTIONS ||
270 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800271 " FREEZE " + mSurfaceControl + ": CREATE");
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700272
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700273 setRotationInTransaction(originalRotation);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800274 } finally {
275 if (!inTransaction) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800276 SurfaceControl.closeTransaction();
Dianne Hackborn36991742011-10-11 21:35:26 -0700277 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800278 "<<< CLOSE TRANSACTION ScreenRotationAnimation");
Dianne Hackborn352cc982011-01-04 11:34:18 -0800279 }
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800280 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800281 }
282
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800283 boolean hasScreenshot() {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800284 return mSurfaceControl != null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800285 }
286
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800287 static int deltaRotation(int oldRotation, int newRotation) {
288 int delta = newRotation - oldRotation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800289 if (delta < 0) delta += 4;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800290 return delta;
291 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800292
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700293 private void setSnapshotTransformInTransaction(Matrix matrix, float alpha) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800294 if (mSurfaceControl != null) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800295 matrix.getValues(mTmpFloats);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700296 float x = mTmpFloats[Matrix.MTRANS_X];
297 float y = mTmpFloats[Matrix.MTRANS_Y];
298 if (mForceDefaultOrientation) {
299 mDisplayContent.getLogicalDisplayRect(mCurrentDisplayRect);
300 x -= mCurrentDisplayRect.left;
301 y -= mCurrentDisplayRect.top;
302 }
303 mSurfaceControl.setPosition(x, y);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800304 mSurfaceControl.setMatrix(
Dianne Hackborn352cc982011-01-04 11:34:18 -0800305 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
306 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800307 mSurfaceControl.setAlpha(alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800308 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800309 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
310 float[] dstPnts = new float[4];
311 matrix.mapPoints(dstPnts, srcPnts);
312 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
313 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
314 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
315 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
316 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800317 }
318 }
319
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800320 public static void createRotationMatrix(int rotation, int width, int height,
321 Matrix outMatrix) {
322 switch (rotation) {
323 case Surface.ROTATION_0:
324 outMatrix.reset();
325 break;
326 case Surface.ROTATION_90:
327 outMatrix.setRotate(90, 0, 0);
328 outMatrix.postTranslate(height, 0);
329 break;
330 case Surface.ROTATION_180:
331 outMatrix.setRotate(180, 0, 0);
332 outMatrix.postTranslate(width, height);
333 break;
334 case Surface.ROTATION_270:
335 outMatrix.setRotate(270, 0, 0);
336 outMatrix.postTranslate(0, width);
337 break;
338 }
339 }
340
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800341 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700342 private void setRotationInTransaction(int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800343 mCurRotation = rotation;
344
345 // Compute the transformation matrix that must be applied
346 // to the snapshot to make it stay in the same original position
347 // with the current screen rotation.
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700348 int delta = deltaRotation(rotation, Surface.ROTATION_0);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800349 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800350
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800351 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700352 setSnapshotTransformInTransaction(mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800353 }
354
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800355 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700356 public boolean setRotationInTransaction(int rotation, SurfaceSession session,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800357 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700358 setRotationInTransaction(rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700359 if (TWO_PHASE_ANIMATION) {
360 return startAnimation(session, maxAnimationDuration, animationScale,
Craig Mautner3c174372013-02-21 17:54:37 -0800361 finalWidth, finalHeight, false, 0, 0);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700362 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700363
364 // Don't start animation yet.
365 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800366 }
367
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800368 /**
369 * Returns true if animating.
370 */
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800371 private boolean startAnimation(SurfaceSession session, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800372 float animationScale, int finalWidth, int finalHeight, boolean dismissing,
373 int exitAnim, int enterAnim) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800374 if (mSurfaceControl == null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800375 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800376 return false;
377 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800378 if (mStarted) {
379 return true;
380 }
381
382 mStarted = true;
383
384 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800385
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800386 // Figure out how the screen has moved from the original rotation.
387 int delta = deltaRotation(mCurRotation, mOriginalRotation);
388
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700389 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
390 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800391 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
392 firstStart = true;
393 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
394 com.android.internal.R.anim.screen_rotate_start_exit);
395 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
396 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700397 if (USE_CUSTOM_BLACK_FRAME) {
398 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
399 com.android.internal.R.anim.screen_rotate_start_frame);
400 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800401 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
402 com.android.internal.R.anim.screen_rotate_finish_exit);
403 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
404 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700405 if (USE_CUSTOM_BLACK_FRAME) {
406 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
407 com.android.internal.R.anim.screen_rotate_finish_frame);
408 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800409 }
410
411 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
412 + finalWidth + " finalHeight=" + finalHeight
413 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
414
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700415 final boolean customAnim;
Craig Mautner3c174372013-02-21 17:54:37 -0800416 if (exitAnim != 0 && enterAnim != 0) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700417 customAnim = true;
Craig Mautner3c174372013-02-21 17:54:37 -0800418 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
419 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700420 } else {
421 customAnim = false;
422 switch (delta) {
423 case Surface.ROTATION_0:
424 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
425 com.android.internal.R.anim.screen_rotate_0_exit);
426 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
427 com.android.internal.R.anim.screen_rotate_0_enter);
428 if (USE_CUSTOM_BLACK_FRAME) {
429 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
430 com.android.internal.R.anim.screen_rotate_0_frame);
431 }
432 break;
433 case Surface.ROTATION_90:
434 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
435 com.android.internal.R.anim.screen_rotate_plus_90_exit);
436 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
437 com.android.internal.R.anim.screen_rotate_plus_90_enter);
438 if (USE_CUSTOM_BLACK_FRAME) {
439 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
440 com.android.internal.R.anim.screen_rotate_plus_90_frame);
441 }
442 break;
443 case Surface.ROTATION_180:
444 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
445 com.android.internal.R.anim.screen_rotate_180_exit);
446 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
447 com.android.internal.R.anim.screen_rotate_180_enter);
448 if (USE_CUSTOM_BLACK_FRAME) {
449 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
450 com.android.internal.R.anim.screen_rotate_180_frame);
451 }
452 break;
453 case Surface.ROTATION_270:
454 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
455 com.android.internal.R.anim.screen_rotate_minus_90_exit);
456 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
457 com.android.internal.R.anim.screen_rotate_minus_90_enter);
458 if (USE_CUSTOM_BLACK_FRAME) {
459 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
460 com.android.internal.R.anim.screen_rotate_minus_90_frame);
461 }
462 break;
463 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800464 }
465
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800466 // Initialize the animations. This is a hack, redefining what "parent"
467 // means to allow supplying the last and next size. In this definition
468 // "%p" is the original (let's call it "previous") size, and "%" is the
469 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700470 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700471 // Compute partial steps between original and final sizes. These
472 // are used for the dimensions of the exiting and entering elements,
473 // so they are never stretched too significantly.
474 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
475 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
476
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800477 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
478 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800479 halfWidth, halfHeight);
480 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800481 mOriginalWidth, mOriginalHeight);
482 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800483 halfWidth, halfHeight);
484 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800485 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700486 if (USE_CUSTOM_BLACK_FRAME) {
487 mStartFrameAnimation.initialize(finalWidth, finalHeight,
488 mOriginalWidth, mOriginalHeight);
489 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
490 mOriginalWidth, mOriginalHeight);
491 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800492 }
493 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
494 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700495 if (USE_CUSTOM_BLACK_FRAME) {
496 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
497 mOriginalHeight);
498 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800499 mAnimRunning = false;
500 mFinishAnimReady = false;
501 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800502
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700503 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800504 mStartExitAnimation.restrictDuration(maxAnimationDuration);
505 mStartExitAnimation.scaleCurrentDuration(animationScale);
506 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
507 mStartEnterAnimation.scaleCurrentDuration(animationScale);
508 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
509 mFinishExitAnimation.scaleCurrentDuration(animationScale);
510 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
511 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700512 if (USE_CUSTOM_BLACK_FRAME) {
513 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
514 mStartFrameAnimation.scaleCurrentDuration(animationScale);
515 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
516 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
517 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800518 }
519 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
520 mRotateExitAnimation.scaleCurrentDuration(animationScale);
521 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
522 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700523 if (USE_CUSTOM_BLACK_FRAME) {
524 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
525 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
526 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800527
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700528 final int layerStack = mDisplayContent.getDisplay().getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700529 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800530 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
531 WindowManagerService.TAG,
532 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800533 SurfaceControl.openTransaction();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800534
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800535 // Compute the transformation matrix that must be applied
536 // the the black frame to make it stay in the initial position
537 // before the new screen rotation. This is different than the
538 // snapshot transformation because the snapshot is always based
539 // of the native orientation of the screen, not the orientation
540 // we were last in.
541 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
542
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800543 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800544 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
545 mOriginalWidth*2, mOriginalHeight*2);
546 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700547 mCustomBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 3,
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700548 layerStack, false);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700549 mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800550 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700551 Slog.w(TAG, "Unable to allocate black surface", e);
552 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800553 SurfaceControl.closeTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700554 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
555 WindowManagerService.TAG,
556 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
557 }
558 }
559
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700560 if (!customAnim && mExitingBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700561 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
562 WindowManagerService.TAG,
563 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800564 SurfaceControl.openTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700565 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700566 // Compute the transformation matrix that must be applied
567 // the the black frame to make it stay in the initial position
568 // before the new screen rotation. This is different than the
569 // snapshot transformation because the snapshot is always based
570 // of the native orientation of the screen, not the orientation
571 // we were last in.
572 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
573
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700574 final Rect outer;
575 final Rect inner;
576 if (mForceDefaultOrientation) {
577 // Going from a smaller Display to a larger Display, add curtains to sides
578 // or top and bottom. Going from a larger to smaller display will result in
579 // no BlackSurfaces being constructed.
580 outer = mCurrentDisplayRect;
581 inner = mOriginalDisplayRect;
582 } else {
583 outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
584 mOriginalWidth*2, mOriginalHeight*2);
585 inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
586 }
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700587 mExitingBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 2,
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700588 layerStack, mForceDefaultOrientation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700589 mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800590 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700591 Slog.w(TAG, "Unable to allocate black surface", e);
592 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800593 SurfaceControl.closeTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700594 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
595 WindowManagerService.TAG,
596 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
597 }
598 }
599
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700600 if (customAnim && mEnteringBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700601 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
602 WindowManagerService.TAG,
603 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800604 SurfaceControl.openTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700605
606 try {
607 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
608 finalWidth*2, finalHeight*2);
609 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700610 mEnteringBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER,
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700611 layerStack, false);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800612 } catch (SurfaceControl.OutOfResourcesException e) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800613 Slog.w(TAG, "Unable to allocate black surface", e);
614 } finally {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800615 SurfaceControl.closeTransaction();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800616 if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
617 WindowManagerService.TAG,
618 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
619 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800620 }
621
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800622 return true;
623 }
624
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800625 /**
626 * Returns true if animating.
627 */
628 public boolean dismiss(SurfaceSession session, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800629 float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800630 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800631 if (mSurfaceControl == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800632 // Can't do animation.
633 return false;
634 }
635 if (!mStarted) {
636 startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight,
Craig Mautner3c174372013-02-21 17:54:37 -0800637 true, exitAnim, enterAnim);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800638 }
639 if (!mStarted) {
640 return false;
641 }
642 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
643 mFinishAnimReady = true;
644 return true;
645 }
646
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800647 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800648 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800649 if (mSurfaceControl != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700650 if (WindowManagerService.SHOW_TRANSACTIONS ||
651 WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800652 " FREEZE " + mSurfaceControl + ": DESTROY");
653 mSurfaceControl.destroy();
654 mSurfaceControl = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800655 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700656 if (mCustomBlackFrame != null) {
657 mCustomBlackFrame.kill();
658 mCustomBlackFrame = null;
659 }
660 if (mExitingBlackFrame != null) {
661 mExitingBlackFrame.kill();
662 mExitingBlackFrame = null;
663 }
664 if (mEnteringBlackFrame != null) {
665 mEnteringBlackFrame.kill();
666 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800667 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700668 if (TWO_PHASE_ANIMATION) {
669 if (mStartExitAnimation != null) {
670 mStartExitAnimation.cancel();
671 mStartExitAnimation = null;
672 }
673 if (mStartEnterAnimation != null) {
674 mStartEnterAnimation.cancel();
675 mStartEnterAnimation = null;
676 }
677 if (mFinishExitAnimation != null) {
678 mFinishExitAnimation.cancel();
679 mFinishExitAnimation = null;
680 }
681 if (mFinishEnterAnimation != null) {
682 mFinishEnterAnimation.cancel();
683 mFinishEnterAnimation = null;
684 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800685 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700686 if (USE_CUSTOM_BLACK_FRAME) {
687 if (mStartFrameAnimation != null) {
688 mStartFrameAnimation.cancel();
689 mStartFrameAnimation = null;
690 }
691 if (mRotateFrameAnimation != null) {
692 mRotateFrameAnimation.cancel();
693 mRotateFrameAnimation = null;
694 }
695 if (mFinishFrameAnimation != null) {
696 mFinishFrameAnimation.cancel();
697 mFinishFrameAnimation = null;
698 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800699 }
700 if (mRotateExitAnimation != null) {
701 mRotateExitAnimation.cancel();
702 mRotateExitAnimation = null;
703 }
704 if (mRotateEnterAnimation != null) {
705 mRotateEnterAnimation.cancel();
706 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800707 }
708 }
709
710 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700711 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700712 }
713
Dianne Hackborn4b169692012-11-29 17:51:24 -0800714 public boolean isRotating() {
715 return mCurRotation != mOriginalRotation;
716 }
717
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700718 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700719 return (TWO_PHASE_ANIMATION &&
720 (mStartEnterAnimation != null || mStartExitAnimation != null
721 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
722 || (USE_CUSTOM_BLACK_FRAME &&
723 (mStartFrameAnimation != null || mRotateFrameAnimation != null
724 || mFinishFrameAnimation != null))
725 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800726 }
727
Craig Mautnere32c3072012-03-12 15:25:35 -0700728 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700729 if (now > mHalfwayPoint) {
730 mHalfwayPoint = Long.MAX_VALUE;
731 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800732 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
733 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
734 mFinishAnimStartTime = now;
735 }
736
Craig Mautner7d8df392012-04-06 15:26:23 -0700737 if (TWO_PHASE_ANIMATION) {
738 mMoreStartExit = false;
739 if (mStartExitAnimation != null) {
740 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
741 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
742 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800743
Craig Mautner7d8df392012-04-06 15:26:23 -0700744 mMoreStartEnter = false;
745 if (mStartEnterAnimation != null) {
746 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
747 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
748 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800749 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700750 if (USE_CUSTOM_BLACK_FRAME) {
751 mMoreStartFrame = false;
752 if (mStartFrameAnimation != null) {
753 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
754 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
755 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800756 }
757
Craig Mautnerdbb79912012-03-01 18:59:14 -0800758 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
759 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
760
Craig Mautner7d8df392012-04-06 15:26:23 -0700761 if (TWO_PHASE_ANIMATION) {
762 mMoreFinishExit = false;
763 if (mFinishExitAnimation != null) {
764 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
765 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
766 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800767
Craig Mautner7d8df392012-04-06 15:26:23 -0700768 mMoreFinishEnter = false;
769 if (mFinishEnterAnimation != null) {
770 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
771 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
772 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800773 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700774 if (USE_CUSTOM_BLACK_FRAME) {
775 mMoreFinishFrame = false;
776 if (mFinishFrameAnimation != null) {
777 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
778 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
779 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800780 }
781
Craig Mautnerdbb79912012-03-01 18:59:14 -0800782 mMoreRotateExit = false;
783 if (mRotateExitAnimation != null) {
784 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
785 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700786 }
787
788 mMoreRotateEnter = false;
789 if (mRotateEnterAnimation != null) {
790 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
791 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
792 }
793
Craig Mautner7d8df392012-04-06 15:26:23 -0700794 if (USE_CUSTOM_BLACK_FRAME) {
795 mMoreRotateFrame = false;
796 if (mRotateFrameAnimation != null) {
797 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
798 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
799 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700800 }
801
Craig Mautner7d8df392012-04-06 15:26:23 -0700802 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
803 if (TWO_PHASE_ANIMATION) {
804 if (mStartExitAnimation != null) {
805 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
806 mStartExitAnimation.cancel();
807 mStartExitAnimation = null;
808 mStartExitTransformation.clear();
809 }
810 if (mFinishExitAnimation != null) {
811 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
812 mFinishExitAnimation.cancel();
813 mFinishExitAnimation = null;
814 mFinishExitTransformation.clear();
815 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700816 }
817 if (mRotateExitAnimation != null) {
818 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800819 mRotateExitAnimation.cancel();
820 mRotateExitAnimation = null;
821 mRotateExitTransformation.clear();
822 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800823 }
824
Craig Mautner7d8df392012-04-06 15:26:23 -0700825 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
826 if (TWO_PHASE_ANIMATION) {
827 if (mStartEnterAnimation != null) {
828 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
829 mStartEnterAnimation.cancel();
830 mStartEnterAnimation = null;
831 mStartEnterTransformation.clear();
832 }
833 if (mFinishEnterAnimation != null) {
834 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
835 mFinishEnterAnimation.cancel();
836 mFinishEnterAnimation = null;
837 mFinishEnterTransformation.clear();
838 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700839 }
840 if (mRotateEnterAnimation != null) {
841 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800842 mRotateEnterAnimation.cancel();
843 mRotateEnterAnimation = null;
844 mRotateEnterTransformation.clear();
845 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800846 }
847
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700848 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
849 if (mStartFrameAnimation != null) {
850 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
851 mStartFrameAnimation.cancel();
852 mStartFrameAnimation = null;
853 mStartFrameTransformation.clear();
854 }
855 if (mFinishFrameAnimation != null) {
856 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
857 mFinishFrameAnimation.cancel();
858 mFinishFrameAnimation = null;
859 mFinishFrameTransformation.clear();
860 }
861 if (mRotateFrameAnimation != null) {
862 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800863 mRotateFrameAnimation.cancel();
864 mRotateFrameAnimation = null;
865 mRotateFrameTransformation.clear();
866 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800867 }
868
869 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800870 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700871 if (TWO_PHASE_ANIMATION) {
872 mExitTransformation.compose(mStartExitTransformation);
873 mExitTransformation.compose(mFinishExitTransformation);
874
875 mEnterTransformation.compose(mStartEnterTransformation);
876 mEnterTransformation.compose(mFinishEnterTransformation);
877 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800878
879 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
880 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700881
882 if (USE_CUSTOM_BLACK_FRAME) {
883 //mFrameTransformation.set(mRotateExitTransformation);
884 //mFrameTransformation.compose(mStartExitTransformation);
885 //mFrameTransformation.compose(mFinishExitTransformation);
886 mFrameTransformation.set(mRotateFrameTransformation);
887 mFrameTransformation.compose(mStartFrameTransformation);
888 mFrameTransformation.compose(mFinishFrameTransformation);
889 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
890 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
891 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800892
Craig Mautner7d8df392012-04-06 15:26:23 -0700893 final boolean more = (TWO_PHASE_ANIMATION
894 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
895 || (USE_CUSTOM_BLACK_FRAME
896 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
897 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800898 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800899
900 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
901
902 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
903
904 return more;
905 }
906
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700907 void updateSurfacesInTransaction() {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700908 if (!mStarted) {
909 return;
910 }
911
Mathias Agopian29479eb2013-02-14 14:36:04 -0800912 if (mSurfaceControl != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700913 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800914 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800915 mSurfaceControl.hide();
Craig Mautnerdbb79912012-03-01 18:59:14 -0800916 }
917 }
918
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700919 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700920 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800921 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700922 mCustomBlackFrame.hide();
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700923 } else {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700924 mCustomBlackFrame.setMatrix(mFrameTransformation.getMatrix());
925 }
926 }
927
928 if (mExitingBlackFrame != null) {
929 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
930 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
931 mExitingBlackFrame.hide();
932 } else {
933 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
934 mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700935 if (mForceDefaultOrientation) {
936 mExitingBlackFrame.setAlpha(mExitTransformation.getAlpha());
937 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700938 }
939 }
940
941 if (mEnteringBlackFrame != null) {
942 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
943 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
944 mEnteringBlackFrame.hide();
945 } else {
946 mEnteringBlackFrame.setMatrix(mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800947 }
948 }
949
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700950 setSnapshotTransformInTransaction(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800951 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700952
Craig Mautnere32c3072012-03-12 15:25:35 -0700953 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700954 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800955 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800956 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800957 return false;
958 }
959
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800960 if (!mAnimRunning) {
961 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700962 if (TWO_PHASE_ANIMATION) {
963 if (mStartEnterAnimation != null) {
964 mStartEnterAnimation.setStartTime(now);
965 }
966 if (mStartExitAnimation != null) {
967 mStartExitAnimation.setStartTime(now);
968 }
969 if (mFinishEnterAnimation != null) {
970 mFinishEnterAnimation.setStartTime(0);
971 }
972 if (mFinishExitAnimation != null) {
973 mFinishExitAnimation.setStartTime(0);
974 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700975 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700976 if (USE_CUSTOM_BLACK_FRAME) {
977 if (mStartFrameAnimation != null) {
978 mStartFrameAnimation.setStartTime(now);
979 }
980 if (mFinishFrameAnimation != null) {
981 mFinishFrameAnimation.setStartTime(0);
982 }
983 if (mRotateFrameAnimation != null) {
984 mRotateFrameAnimation.setStartTime(now);
985 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800986 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800987 if (mRotateEnterAnimation != null) {
988 mRotateEnterAnimation.setStartTime(now);
989 }
990 if (mRotateExitAnimation != null) {
991 mRotateExitAnimation.setStartTime(now);
992 }
993 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -0700994 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800995 }
Craig Mautnere32c3072012-03-12 15:25:35 -0700996
997 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800998 }
999
1000 public Transformation getEnterTransformation() {
1001 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -08001002 }
1003}