blob: ad2fabb7029946f863492a4b8de13150f8852f6a [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
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080019import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
20import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
21import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
22import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
23import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Chong Zhang97782b42015-10-07 16:01:23 -070024import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
Chong Zhang97782b42015-10-07 16:01:23 -070025import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER;
Steven Timotiusf2d68892017-08-28 17:00:01 -070026import static com.android.server.wm.proto.ScreenRotationAnimationProto.ANIMATION_RUNNING;
27import static com.android.server.wm.proto.ScreenRotationAnimationProto.STARTED;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080028
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080029import android.content.Context;
Dianne Hackborna1111872010-11-23 20:55:11 -080030import android.graphics.Matrix;
Dianne Hackborna1111872010-11-23 20:55:11 -080031import android.graphics.Rect;
Dianne Hackborna1111872010-11-23 20:55:11 -080032import android.util.Slog;
Steven Timotiusf2d68892017-08-28 17:00:01 -070033import android.util.proto.ProtoOutputStream;
Craig Mautner6881a102012-07-27 13:04:51 -070034import android.view.Display;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070035import android.view.DisplayInfo;
Dianne Hackborna1111872010-11-23 20:55:11 -080036import android.view.Surface;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080037import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080038import android.view.SurfaceControl;
Dianne Hackborna1111872010-11-23 20:55:11 -080039import android.view.SurfaceSession;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080040import android.view.animation.Animation;
41import android.view.animation.AnimationUtils;
42import android.view.animation.Transformation;
Dianne Hackborna1111872010-11-23 20:55:11 -080043
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080044import java.io.PrintWriter;
45
Craig Mautnere32c3072012-03-12 15:25:35 -070046class ScreenRotationAnimation {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080047 static final String TAG = TAG_WITH_CLASS_NAME ? "ScreenRotationAnimation" : TAG_WM;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080048 static final boolean DEBUG_STATE = false;
49 static final boolean DEBUG_TRANSFORMS = false;
Dianne Hackborn187ae2102012-04-11 18:12:06 -070050 static final boolean TWO_PHASE_ANIMATION = false;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070051 static final boolean USE_CUSTOM_BLACK_FRAME = false;
Dianne Hackborna1111872010-11-23 20:55:11 -080052
Chong Zhang97782b42015-10-07 16:01:23 -070053 /*
54 * Layers for screen rotation animation. We put these layers above
55 * WINDOW_FREEZE_LAYER so that screen freeze will cover all windows.
56 */
57 static final int SCREEN_FREEZE_LAYER_BASE = WINDOW_FREEZE_LAYER + TYPE_LAYER_MULTIPLIER;
58 static final int SCREEN_FREEZE_LAYER_ENTER = SCREEN_FREEZE_LAYER_BASE;
59 static final int SCREEN_FREEZE_LAYER_SCREENSHOT = SCREEN_FREEZE_LAYER_BASE + 1;
60 static final int SCREEN_FREEZE_LAYER_EXIT = SCREEN_FREEZE_LAYER_BASE + 2;
61 static final int SCREEN_FREEZE_LAYER_CUSTOM = SCREEN_FREEZE_LAYER_BASE + 3;
Dianne Hackborn50660e22011-02-02 17:12:25 -080062
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080063 final Context mContext;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070064 final DisplayContent mDisplayContent;
Mathias Agopian29479eb2013-02-14 14:36:04 -080065 SurfaceControl mSurfaceControl;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070066 BlackFrame mCustomBlackFrame;
67 BlackFrame mExitingBlackFrame;
68 BlackFrame mEnteringBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080069 int mWidth, mHeight;
70
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080071 int mOriginalRotation;
72 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080073 int mCurRotation;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070074 Rect mOriginalDisplayRect = new Rect();
75 Rect mCurrentDisplayRect = new Rect();
Dianne Hackborna1111872010-11-23 20:55:11 -080076
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080077 // For all animations, "exit" is for the UI elements that are going
78 // away (that is the snapshot of the old screen), and "enter" is for
79 // the new UI elements that are appearing (that is the active windows
80 // in their final orientation).
81
82 // The starting animation for the exiting and entering elements. This
83 // animation applies a transformation while the rotation is in progress.
84 // It is started immediately, before the new entering UI is ready.
85 Animation mStartExitAnimation;
86 final Transformation mStartExitTransformation = new Transformation();
87 Animation mStartEnterAnimation;
88 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080089 Animation mStartFrameAnimation;
90 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080091
92 // The finishing animation for the exiting and entering elements. This
93 // animation needs to undo the transformation of the starting animation.
94 // It starts running once the new rotation UI elements are ready to be
95 // displayed.
96 Animation mFinishExitAnimation;
97 final Transformation mFinishExitTransformation = new Transformation();
98 Animation mFinishEnterAnimation;
99 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800100 Animation mFinishFrameAnimation;
101 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800102
103 // The current active animation to move from the old to the new rotated
104 // state. Which animation is run here will depend on the old and new
105 // rotations.
106 Animation mRotateExitAnimation;
107 final Transformation mRotateExitTransformation = new Transformation();
108 Animation mRotateEnterAnimation;
109 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800110 Animation mRotateFrameAnimation;
111 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800112
113 // A previously running rotate animation. This will be used if we need
114 // to switch to a new rotation before finishing the previous one.
115 Animation mLastRotateExitAnimation;
116 final Transformation mLastRotateExitTransformation = new Transformation();
117 Animation mLastRotateEnterAnimation;
118 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800119 Animation mLastRotateFrameAnimation;
120 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800121
122 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800123 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800124 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800125 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800126
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800127 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800128 boolean mAnimRunning;
129 boolean mFinishAnimReady;
130 long mFinishAnimStartTime;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700131 boolean mForceDefaultOrientation;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800132
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800133 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800134 final Matrix mSnapshotInitialMatrix = new Matrix();
135 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700136 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800137 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800138 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800139 private boolean mMoreRotateEnter;
140 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800141 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800142 private boolean mMoreFinishEnter;
143 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800144 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800145 private boolean mMoreStartEnter;
146 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800147 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700148 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800149
Robert Carr68e5c9e2016-09-14 10:50:09 -0700150 private final WindowManagerService mService;
151
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800152 public void printTo(String prefix, PrintWriter pw) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800153 pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800154 pw.print(" mWidth="); pw.print(mWidth);
155 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700156 if (USE_CUSTOM_BLACK_FRAME) {
157 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
158 if (mCustomBlackFrame != null) {
159 mCustomBlackFrame.printTo(prefix + " ", pw);
160 }
161 }
162 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
163 if (mExitingBlackFrame != null) {
164 mExitingBlackFrame.printTo(prefix + " ", pw);
165 }
166 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
167 if (mEnteringBlackFrame != null) {
168 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800169 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700170 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
171 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
172 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800173 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
174 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
175 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
176 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
177 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
178 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
179 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
180 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
181 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800182 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
183 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800184 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
185 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
186 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
187 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800188 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
189 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800190 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
191 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
192 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
193 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800194 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
195 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800196 pw.print(prefix); pw.print("mExitTransformation=");
197 mExitTransformation.printShortString(pw); pw.println();
198 pw.print(prefix); pw.print("mEnterTransformation=");
199 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800200 pw.print(prefix); pw.print("mFrameTransformation=");
Steven Timotius8304ef42017-08-28 16:59:14 -0700201 mFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800202 pw.print(prefix); pw.print("mFrameInitialMatrix=");
203 mFrameInitialMatrix.printShortString(pw);
204 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800205 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
206 mSnapshotInitialMatrix.printShortString(pw);
207 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
208 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700209 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
210 mExitFrameFinalMatrix.printShortString(pw);
211 pw.println();
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700212 pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
213 if (mForceDefaultOrientation) {
214 pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
215 pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString());
216 }
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800217 }
218
Steven Timotiusf2d68892017-08-28 17:00:01 -0700219 public void writeToProto(ProtoOutputStream proto, long fieldId) {
220 final long token = proto.start(fieldId);
221 proto.write(STARTED, mStarted);
222 proto.write(ANIMATION_RUNNING, mAnimRunning);
223 proto.end(token);
224 }
225
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700226 public ScreenRotationAnimation(Context context, DisplayContent displayContent,
Robert Carrae606b42018-02-15 15:36:23 -0800227 boolean forceDefaultOrientation, boolean isSecure, WindowManagerService service) {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700228 mService = service;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800229 mContext = context;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700230 mDisplayContent = displayContent;
Bryce Leef3c6a472017-11-14 14:53:06 -0800231 displayContent.getBounds(mOriginalDisplayRect);
Dianne Hackborna1111872010-11-23 20:55:11 -0800232
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800233 // Screenshot does NOT include rotation!
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700234 final Display display = displayContent.getDisplay();
235 int originalRotation = display.getRotation();
236 final int originalWidth;
237 final int originalHeight;
238 DisplayInfo displayInfo = displayContent.getDisplayInfo();
239 if (forceDefaultOrientation) {
240 // Emulated orientation.
241 mForceDefaultOrientation = true;
242 originalWidth = displayContent.mBaseDisplayWidth;
243 originalHeight = displayContent.mBaseDisplayHeight;
244 } else {
245 // Normal situation
246 originalWidth = displayInfo.logicalWidth;
247 originalHeight = displayInfo.logicalHeight;
248 }
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700249 if (originalRotation == Surface.ROTATION_90
250 || originalRotation == Surface.ROTATION_270) {
251 mWidth = originalHeight;
252 mHeight = originalWidth;
253 } else {
254 mWidth = originalWidth;
255 mHeight = originalHeight;
256 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800257
Jeff Brownbc68a592011-07-25 12:58:12 -0700258 mOriginalRotation = originalRotation;
259 mOriginalWidth = originalWidth;
260 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800261
Robert Carrae606b42018-02-15 15:36:23 -0800262 final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
Dianne Hackborna1111872010-11-23 20:55:11 -0800263 try {
Robert Carrae606b42018-02-15 15:36:23 -0800264 mSurfaceControl = displayContent.makeOverlay()
265 .setName("ScreenshotSurface")
266 .setSize(mWidth, mHeight)
267 .setSecure(isSecure)
268 .build();
Robert Carre13b58e2017-08-31 14:50:44 -0700269
Robert Carrae606b42018-02-15 15:36:23 -0800270 // capture a screenshot into the surface we just created
271 Surface sur = new Surface();
272 sur.copyFrom(mSurfaceControl);
273 // TODO(multidisplay): we should use the proper display
274 SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(
275 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), sur);
276 t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT);
277 t.setAlpha(mSurfaceControl, 0);
278 t.show(mSurfaceControl);
279 sur.destroy();
280 } catch (OutOfResourcesException e) {
281 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800282 }
Robert Carrae606b42018-02-15 15:36:23 -0800283
284 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
285 " FREEZE " + mSurfaceControl + ": CREATE");
286 setRotation(t, originalRotation);
287 t.apply();
Dianne Hackborna1111872010-11-23 20:55:11 -0800288 }
289
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800290 boolean hasScreenshot() {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800291 return mSurfaceControl != null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800292 }
293
Robert Carrae606b42018-02-15 15:36:23 -0800294 private void setSnapshotTransform(SurfaceControl.Transaction t, 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) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800300 mDisplayContent.getBounds(mCurrentDisplayRect);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700301 x -= mCurrentDisplayRect.left;
302 y -= mCurrentDisplayRect.top;
303 }
Robert Carrae606b42018-02-15 15:36:23 -0800304 t.setPosition(mSurfaceControl, x, y);
305 t.setMatrix(mSurfaceControl,
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]);
Robert Carrae606b42018-02-15 15:36:23 -0800308 t.setAlpha(mSurfaceControl, 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
Robert Carrae606b42018-02-15 15:36:23 -0800342 private void setRotation(SurfaceControl.Transaction t, 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.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800348 int delta = DisplayContent.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);
Robert Carrae606b42018-02-15 15:36:23 -0800352 setSnapshotTransform(t, mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800353 }
354
Robert Carrae606b42018-02-15 15:36:23 -0800355 public boolean setRotation(SurfaceControl.Transaction t, int rotation,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800356 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Robert Carrae606b42018-02-15 15:36:23 -0800357 setRotation(t, rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700358 if (TWO_PHASE_ANIMATION) {
Robert Carrae606b42018-02-15 15:36:23 -0800359 return startAnimation(t, maxAnimationDuration, animationScale,
Craig Mautner3c174372013-02-21 17:54:37 -0800360 finalWidth, finalHeight, false, 0, 0);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700361 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700362
363 // Don't start animation yet.
364 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800365 }
366
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800367 /**
368 * Returns true if animating.
369 */
Robert Carrae606b42018-02-15 15:36:23 -0800370 private boolean startAnimation(SurfaceControl.Transaction t, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800371 float animationScale, int finalWidth, int finalHeight, boolean dismissing,
372 int exitAnim, int enterAnim) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800373 if (mSurfaceControl == null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800374 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800375 return false;
376 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800377 if (mStarted) {
378 return true;
379 }
380
381 mStarted = true;
382
383 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800384
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800385 // Figure out how the screen has moved from the original rotation.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800386 int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800387
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700388 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
389 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800390 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
391 firstStart = true;
392 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
393 com.android.internal.R.anim.screen_rotate_start_exit);
394 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
395 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700396 if (USE_CUSTOM_BLACK_FRAME) {
397 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
398 com.android.internal.R.anim.screen_rotate_start_frame);
399 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800400 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
401 com.android.internal.R.anim.screen_rotate_finish_exit);
402 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
403 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700404 if (USE_CUSTOM_BLACK_FRAME) {
405 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
406 com.android.internal.R.anim.screen_rotate_finish_frame);
407 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800408 }
409
410 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
411 + finalWidth + " finalHeight=" + finalHeight
412 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
413
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700414 final boolean customAnim;
Craig Mautner3c174372013-02-21 17:54:37 -0800415 if (exitAnim != 0 && enterAnim != 0) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700416 customAnim = true;
Craig Mautner3c174372013-02-21 17:54:37 -0800417 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
418 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700419 } else {
420 customAnim = false;
421 switch (delta) {
422 case Surface.ROTATION_0:
423 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
424 com.android.internal.R.anim.screen_rotate_0_exit);
425 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
426 com.android.internal.R.anim.screen_rotate_0_enter);
427 if (USE_CUSTOM_BLACK_FRAME) {
428 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
429 com.android.internal.R.anim.screen_rotate_0_frame);
430 }
431 break;
432 case Surface.ROTATION_90:
433 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
434 com.android.internal.R.anim.screen_rotate_plus_90_exit);
435 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
436 com.android.internal.R.anim.screen_rotate_plus_90_enter);
437 if (USE_CUSTOM_BLACK_FRAME) {
438 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
439 com.android.internal.R.anim.screen_rotate_plus_90_frame);
440 }
441 break;
442 case Surface.ROTATION_180:
443 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
444 com.android.internal.R.anim.screen_rotate_180_exit);
445 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
446 com.android.internal.R.anim.screen_rotate_180_enter);
447 if (USE_CUSTOM_BLACK_FRAME) {
448 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
449 com.android.internal.R.anim.screen_rotate_180_frame);
450 }
451 break;
452 case Surface.ROTATION_270:
453 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
454 com.android.internal.R.anim.screen_rotate_minus_90_exit);
455 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
456 com.android.internal.R.anim.screen_rotate_minus_90_enter);
457 if (USE_CUSTOM_BLACK_FRAME) {
458 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
459 com.android.internal.R.anim.screen_rotate_minus_90_frame);
460 }
461 break;
462 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800463 }
464
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800465 // Initialize the animations. This is a hack, redefining what "parent"
466 // means to allow supplying the last and next size. In this definition
467 // "%p" is the original (let's call it "previous") size, and "%" is the
468 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700469 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700470 // Compute partial steps between original and final sizes. These
471 // are used for the dimensions of the exiting and entering elements,
472 // so they are never stretched too significantly.
473 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
474 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
475
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800476 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
477 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800478 halfWidth, halfHeight);
479 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800480 mOriginalWidth, mOriginalHeight);
481 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800482 halfWidth, halfHeight);
483 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800484 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700485 if (USE_CUSTOM_BLACK_FRAME) {
486 mStartFrameAnimation.initialize(finalWidth, finalHeight,
487 mOriginalWidth, mOriginalHeight);
488 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
489 mOriginalWidth, mOriginalHeight);
490 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800491 }
492 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
493 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700494 if (USE_CUSTOM_BLACK_FRAME) {
495 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
496 mOriginalHeight);
497 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800498 mAnimRunning = false;
499 mFinishAnimReady = false;
500 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800501
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700502 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800503 mStartExitAnimation.restrictDuration(maxAnimationDuration);
504 mStartExitAnimation.scaleCurrentDuration(animationScale);
505 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
506 mStartEnterAnimation.scaleCurrentDuration(animationScale);
507 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
508 mFinishExitAnimation.scaleCurrentDuration(animationScale);
509 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
510 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700511 if (USE_CUSTOM_BLACK_FRAME) {
512 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
513 mStartFrameAnimation.scaleCurrentDuration(animationScale);
514 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
515 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
516 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800517 }
518 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
519 mRotateExitAnimation.scaleCurrentDuration(animationScale);
520 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
521 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700522 if (USE_CUSTOM_BLACK_FRAME) {
523 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
524 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
525 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800526
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700527 final int layerStack = mDisplayContent.getDisplay().getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700528 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800529 // Compute the transformation matrix that must be applied
530 // the the black frame to make it stay in the initial position
531 // before the new screen rotation. This is different than the
532 // snapshot transformation because the snapshot is always based
533 // of the native orientation of the screen, not the orientation
534 // we were last in.
535 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
536
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800537 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800538 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
539 mOriginalWidth*2, mOriginalHeight*2);
540 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Robert Carrae606b42018-02-15 15:36:23 -0800541 mCustomBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700542 SCREEN_FREEZE_LAYER_CUSTOM, mDisplayContent, false);
Robert Carrae606b42018-02-15 15:36:23 -0800543 mCustomBlackFrame.setMatrix(t, mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700544 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700545 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700546 }
547 }
548
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700549 if (!customAnim && mExitingBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700550 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700551 // Compute the transformation matrix that must be applied
552 // the the black frame to make it stay in the initial position
553 // before the new screen rotation. This is different than the
554 // snapshot transformation because the snapshot is always based
555 // of the native orientation of the screen, not the orientation
556 // we were last in.
557 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
558
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700559 final Rect outer;
560 final Rect inner;
561 if (mForceDefaultOrientation) {
562 // Going from a smaller Display to a larger Display, add curtains to sides
563 // or top and bottom. Going from a larger to smaller display will result in
564 // no BlackSurfaces being constructed.
565 outer = mCurrentDisplayRect;
566 inner = mOriginalDisplayRect;
567 } else {
568 outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
569 mOriginalWidth*2, mOriginalHeight*2);
570 inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
571 }
Robert Carrae606b42018-02-15 15:36:23 -0800572 mExitingBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700573 SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation);
Robert Carrae606b42018-02-15 15:36:23 -0800574 mExitingBlackFrame.setMatrix(t, mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700575 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700576 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700577 }
578 }
579
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700580 if (customAnim && mEnteringBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700581 try {
582 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
583 finalWidth*2, finalHeight*2);
584 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Robert Carrae606b42018-02-15 15:36:23 -0800585 mEnteringBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700586 SCREEN_FREEZE_LAYER_ENTER, mDisplayContent, false);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700587 } catch (OutOfResourcesException e) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800588 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800589 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800590 }
591
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800592 return true;
593 }
594
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800595 /**
596 * Returns true if animating.
597 */
Robert Carrae606b42018-02-15 15:36:23 -0800598 public boolean dismiss(SurfaceControl.Transaction t, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800599 float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800600 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800601 if (mSurfaceControl == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800602 // Can't do animation.
603 return false;
604 }
605 if (!mStarted) {
Robert Carrae606b42018-02-15 15:36:23 -0800606 startAnimation(t, maxAnimationDuration, animationScale, finalWidth, finalHeight,
Craig Mautner3c174372013-02-21 17:54:37 -0800607 true, exitAnim, enterAnim);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800608 }
609 if (!mStarted) {
610 return false;
611 }
612 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
613 mFinishAnimReady = true;
614 return true;
615 }
616
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800617 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800618 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800619 if (mSurfaceControl != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800620 if (SHOW_TRANSACTIONS ||
621 SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800622 " FREEZE " + mSurfaceControl + ": DESTROY");
623 mSurfaceControl.destroy();
624 mSurfaceControl = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800625 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700626 if (mCustomBlackFrame != null) {
627 mCustomBlackFrame.kill();
628 mCustomBlackFrame = null;
629 }
630 if (mExitingBlackFrame != null) {
631 mExitingBlackFrame.kill();
632 mExitingBlackFrame = null;
633 }
634 if (mEnteringBlackFrame != null) {
635 mEnteringBlackFrame.kill();
636 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800637 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700638 if (TWO_PHASE_ANIMATION) {
639 if (mStartExitAnimation != null) {
640 mStartExitAnimation.cancel();
641 mStartExitAnimation = null;
642 }
643 if (mStartEnterAnimation != null) {
644 mStartEnterAnimation.cancel();
645 mStartEnterAnimation = null;
646 }
647 if (mFinishExitAnimation != null) {
648 mFinishExitAnimation.cancel();
649 mFinishExitAnimation = null;
650 }
651 if (mFinishEnterAnimation != null) {
652 mFinishEnterAnimation.cancel();
653 mFinishEnterAnimation = null;
654 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800655 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700656 if (USE_CUSTOM_BLACK_FRAME) {
657 if (mStartFrameAnimation != null) {
658 mStartFrameAnimation.cancel();
659 mStartFrameAnimation = null;
660 }
661 if (mRotateFrameAnimation != null) {
662 mRotateFrameAnimation.cancel();
663 mRotateFrameAnimation = null;
664 }
665 if (mFinishFrameAnimation != null) {
666 mFinishFrameAnimation.cancel();
667 mFinishFrameAnimation = null;
668 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800669 }
670 if (mRotateExitAnimation != null) {
671 mRotateExitAnimation.cancel();
672 mRotateExitAnimation = null;
673 }
674 if (mRotateEnterAnimation != null) {
675 mRotateEnterAnimation.cancel();
676 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800677 }
678 }
679
680 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700681 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700682 }
683
Dianne Hackborn4b169692012-11-29 17:51:24 -0800684 public boolean isRotating() {
685 return mCurRotation != mOriginalRotation;
686 }
687
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700688 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700689 return (TWO_PHASE_ANIMATION &&
690 (mStartEnterAnimation != null || mStartExitAnimation != null
691 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
692 || (USE_CUSTOM_BLACK_FRAME &&
693 (mStartFrameAnimation != null || mRotateFrameAnimation != null
694 || mFinishFrameAnimation != null))
695 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800696 }
697
Craig Mautnere32c3072012-03-12 15:25:35 -0700698 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700699 if (now > mHalfwayPoint) {
700 mHalfwayPoint = Long.MAX_VALUE;
701 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800702 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
703 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
704 mFinishAnimStartTime = now;
705 }
706
Craig Mautner7d8df392012-04-06 15:26:23 -0700707 if (TWO_PHASE_ANIMATION) {
708 mMoreStartExit = false;
709 if (mStartExitAnimation != null) {
710 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
711 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
712 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800713
Craig Mautner7d8df392012-04-06 15:26:23 -0700714 mMoreStartEnter = false;
715 if (mStartEnterAnimation != null) {
716 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
717 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
718 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800719 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700720 if (USE_CUSTOM_BLACK_FRAME) {
721 mMoreStartFrame = false;
722 if (mStartFrameAnimation != null) {
723 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
724 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
725 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800726 }
727
Craig Mautnerdbb79912012-03-01 18:59:14 -0800728 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
729 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
730
Craig Mautner7d8df392012-04-06 15:26:23 -0700731 if (TWO_PHASE_ANIMATION) {
732 mMoreFinishExit = false;
733 if (mFinishExitAnimation != null) {
734 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
735 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
736 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800737
Craig Mautner7d8df392012-04-06 15:26:23 -0700738 mMoreFinishEnter = false;
739 if (mFinishEnterAnimation != null) {
740 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
741 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
742 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800743 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700744 if (USE_CUSTOM_BLACK_FRAME) {
745 mMoreFinishFrame = false;
746 if (mFinishFrameAnimation != null) {
747 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
748 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
749 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800750 }
751
Craig Mautnerdbb79912012-03-01 18:59:14 -0800752 mMoreRotateExit = false;
753 if (mRotateExitAnimation != null) {
754 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
755 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700756 }
757
758 mMoreRotateEnter = false;
759 if (mRotateEnterAnimation != null) {
760 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
761 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
762 }
763
Craig Mautner7d8df392012-04-06 15:26:23 -0700764 if (USE_CUSTOM_BLACK_FRAME) {
765 mMoreRotateFrame = false;
766 if (mRotateFrameAnimation != null) {
767 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
768 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
769 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700770 }
771
Craig Mautner7d8df392012-04-06 15:26:23 -0700772 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
773 if (TWO_PHASE_ANIMATION) {
774 if (mStartExitAnimation != null) {
775 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
776 mStartExitAnimation.cancel();
777 mStartExitAnimation = null;
778 mStartExitTransformation.clear();
779 }
780 if (mFinishExitAnimation != null) {
781 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
782 mFinishExitAnimation.cancel();
783 mFinishExitAnimation = null;
784 mFinishExitTransformation.clear();
785 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700786 }
787 if (mRotateExitAnimation != null) {
788 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800789 mRotateExitAnimation.cancel();
790 mRotateExitAnimation = null;
791 mRotateExitTransformation.clear();
792 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800793 }
794
Craig Mautner7d8df392012-04-06 15:26:23 -0700795 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
796 if (TWO_PHASE_ANIMATION) {
797 if (mStartEnterAnimation != null) {
798 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
799 mStartEnterAnimation.cancel();
800 mStartEnterAnimation = null;
801 mStartEnterTransformation.clear();
802 }
803 if (mFinishEnterAnimation != null) {
804 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
805 mFinishEnterAnimation.cancel();
806 mFinishEnterAnimation = null;
807 mFinishEnterTransformation.clear();
808 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700809 }
810 if (mRotateEnterAnimation != null) {
811 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800812 mRotateEnterAnimation.cancel();
813 mRotateEnterAnimation = null;
814 mRotateEnterTransformation.clear();
815 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800816 }
817
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700818 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
819 if (mStartFrameAnimation != null) {
820 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
821 mStartFrameAnimation.cancel();
822 mStartFrameAnimation = null;
823 mStartFrameTransformation.clear();
824 }
825 if (mFinishFrameAnimation != null) {
826 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
827 mFinishFrameAnimation.cancel();
828 mFinishFrameAnimation = null;
829 mFinishFrameTransformation.clear();
830 }
831 if (mRotateFrameAnimation != null) {
832 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800833 mRotateFrameAnimation.cancel();
834 mRotateFrameAnimation = null;
835 mRotateFrameTransformation.clear();
836 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800837 }
838
839 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800840 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700841 if (TWO_PHASE_ANIMATION) {
842 mExitTransformation.compose(mStartExitTransformation);
843 mExitTransformation.compose(mFinishExitTransformation);
844
845 mEnterTransformation.compose(mStartEnterTransformation);
846 mEnterTransformation.compose(mFinishEnterTransformation);
847 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800848
849 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
850 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700851
852 if (USE_CUSTOM_BLACK_FRAME) {
853 //mFrameTransformation.set(mRotateExitTransformation);
854 //mFrameTransformation.compose(mStartExitTransformation);
855 //mFrameTransformation.compose(mFinishExitTransformation);
856 mFrameTransformation.set(mRotateFrameTransformation);
857 mFrameTransformation.compose(mStartFrameTransformation);
858 mFrameTransformation.compose(mFinishFrameTransformation);
859 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
860 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
861 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800862
Craig Mautner7d8df392012-04-06 15:26:23 -0700863 final boolean more = (TWO_PHASE_ANIMATION
864 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
865 || (USE_CUSTOM_BLACK_FRAME
866 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
Igor Murashkina86ab6402013-08-30 12:58:36 -0700867 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800868 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800869
870 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
871
872 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
873
874 return more;
875 }
876
Robert Carrae606b42018-02-15 15:36:23 -0800877 void updateSurfaces(SurfaceControl.Transaction t) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700878 if (!mStarted) {
879 return;
880 }
881
Mathias Agopian29479eb2013-02-14 14:36:04 -0800882 if (mSurfaceControl != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700883 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800884 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
Robert Carrae606b42018-02-15 15:36:23 -0800885 t.hide(mSurfaceControl);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800886 }
887 }
888
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700889 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700890 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800891 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Robert Carrae606b42018-02-15 15:36:23 -0800892 mCustomBlackFrame.hide(t);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700893 } else {
Robert Carrae606b42018-02-15 15:36:23 -0800894 mCustomBlackFrame.setMatrix(t, mFrameTransformation.getMatrix());
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700895 }
896 }
897
898 if (mExitingBlackFrame != null) {
899 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
900 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
Robert Carrae606b42018-02-15 15:36:23 -0800901 mExitingBlackFrame.hide(t);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700902 } else {
903 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
Robert Carrae606b42018-02-15 15:36:23 -0800904 mExitingBlackFrame.setMatrix(t, mExitFrameFinalMatrix);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700905 if (mForceDefaultOrientation) {
Robert Carrae606b42018-02-15 15:36:23 -0800906 mExitingBlackFrame.setAlpha(t, mExitTransformation.getAlpha());
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700907 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700908 }
909 }
910
911 if (mEnteringBlackFrame != null) {
912 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
913 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
Robert Carrae606b42018-02-15 15:36:23 -0800914 mEnteringBlackFrame.hide(t);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700915 } else {
Robert Carrae606b42018-02-15 15:36:23 -0800916 mEnteringBlackFrame.setMatrix(t, mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800917 }
918 }
919
Robert Carrae606b42018-02-15 15:36:23 -0800920 setSnapshotTransform(t, mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800921 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700922
Craig Mautnere32c3072012-03-12 15:25:35 -0700923 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700924 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800925 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800926 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800927 return false;
928 }
929
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800930 if (!mAnimRunning) {
931 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700932 if (TWO_PHASE_ANIMATION) {
933 if (mStartEnterAnimation != null) {
934 mStartEnterAnimation.setStartTime(now);
935 }
936 if (mStartExitAnimation != null) {
937 mStartExitAnimation.setStartTime(now);
938 }
939 if (mFinishEnterAnimation != null) {
940 mFinishEnterAnimation.setStartTime(0);
941 }
942 if (mFinishExitAnimation != null) {
943 mFinishExitAnimation.setStartTime(0);
944 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700945 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700946 if (USE_CUSTOM_BLACK_FRAME) {
947 if (mStartFrameAnimation != null) {
948 mStartFrameAnimation.setStartTime(now);
949 }
950 if (mFinishFrameAnimation != null) {
951 mFinishFrameAnimation.setStartTime(0);
952 }
953 if (mRotateFrameAnimation != null) {
954 mRotateFrameAnimation.setStartTime(now);
955 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800956 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800957 if (mRotateEnterAnimation != null) {
958 mRotateEnterAnimation.setStartTime(now);
959 }
960 if (mRotateExitAnimation != null) {
961 mRotateExitAnimation.setStartTime(now);
962 }
963 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -0700964 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800965 }
Craig Mautnere32c3072012-03-12 15:25:35 -0700966
967 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800968 }
969
970 public Transformation getEnterTransformation() {
971 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800972 }
973}