blob: fa8a5c66aeea880e9758ff68f834a847d8b0bf5a [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;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070026import static com.android.server.wm.ScreenRotationAnimationProto.ANIMATION_RUNNING;
27import static com.android.server.wm.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;
Garfield Tanf4ac3072018-03-16 13:03:52 -070032import android.os.IBinder;
Dianne Hackborna1111872010-11-23 20:55:11 -080033import android.util.Slog;
Steven Timotiusf2d68892017-08-28 17:00:01 -070034import android.util.proto.ProtoOutputStream;
Craig Mautner6881a102012-07-27 13:04:51 -070035import android.view.Display;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070036import android.view.DisplayInfo;
Dianne Hackborna1111872010-11-23 20:55:11 -080037import android.view.Surface;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080038import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080039import android.view.SurfaceControl;
Dianne Hackborna1111872010-11-23 20:55:11 -080040import android.view.SurfaceSession;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080041import android.view.animation.Animation;
42import android.view.animation.AnimationUtils;
43import android.view.animation.Transformation;
Dianne Hackborna1111872010-11-23 20:55:11 -080044
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080045import java.io.PrintWriter;
46
Craig Mautnere32c3072012-03-12 15:25:35 -070047class ScreenRotationAnimation {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080048 static final String TAG = TAG_WITH_CLASS_NAME ? "ScreenRotationAnimation" : TAG_WM;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080049 static final boolean DEBUG_STATE = false;
50 static final boolean DEBUG_TRANSFORMS = false;
Dianne Hackborn187ae2102012-04-11 18:12:06 -070051 static final boolean TWO_PHASE_ANIMATION = false;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070052 static final boolean USE_CUSTOM_BLACK_FRAME = false;
Dianne Hackborna1111872010-11-23 20:55:11 -080053
Chong Zhang97782b42015-10-07 16:01:23 -070054 /*
55 * Layers for screen rotation animation. We put these layers above
56 * WINDOW_FREEZE_LAYER so that screen freeze will cover all windows.
57 */
58 static final int SCREEN_FREEZE_LAYER_BASE = WINDOW_FREEZE_LAYER + TYPE_LAYER_MULTIPLIER;
59 static final int SCREEN_FREEZE_LAYER_ENTER = SCREEN_FREEZE_LAYER_BASE;
60 static final int SCREEN_FREEZE_LAYER_SCREENSHOT = SCREEN_FREEZE_LAYER_BASE + 1;
61 static final int SCREEN_FREEZE_LAYER_EXIT = SCREEN_FREEZE_LAYER_BASE + 2;
62 static final int SCREEN_FREEZE_LAYER_CUSTOM = SCREEN_FREEZE_LAYER_BASE + 3;
Dianne Hackborn50660e22011-02-02 17:12:25 -080063
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080064 final Context mContext;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070065 final DisplayContent mDisplayContent;
Mathias Agopian29479eb2013-02-14 14:36:04 -080066 SurfaceControl mSurfaceControl;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070067 BlackFrame mCustomBlackFrame;
68 BlackFrame mExitingBlackFrame;
69 BlackFrame mEnteringBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080070 int mWidth, mHeight;
71
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080072 int mOriginalRotation;
73 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080074 int mCurRotation;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070075 Rect mOriginalDisplayRect = new Rect();
76 Rect mCurrentDisplayRect = new Rect();
Dianne Hackborna1111872010-11-23 20:55:11 -080077
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080078 // For all animations, "exit" is for the UI elements that are going
79 // away (that is the snapshot of the old screen), and "enter" is for
80 // the new UI elements that are appearing (that is the active windows
81 // in their final orientation).
82
83 // The starting animation for the exiting and entering elements. This
84 // animation applies a transformation while the rotation is in progress.
85 // It is started immediately, before the new entering UI is ready.
86 Animation mStartExitAnimation;
87 final Transformation mStartExitTransformation = new Transformation();
88 Animation mStartEnterAnimation;
89 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080090 Animation mStartFrameAnimation;
91 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080092
93 // The finishing animation for the exiting and entering elements. This
94 // animation needs to undo the transformation of the starting animation.
95 // It starts running once the new rotation UI elements are ready to be
96 // displayed.
97 Animation mFinishExitAnimation;
98 final Transformation mFinishExitTransformation = new Transformation();
99 Animation mFinishEnterAnimation;
100 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800101 Animation mFinishFrameAnimation;
102 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800103
104 // The current active animation to move from the old to the new rotated
105 // state. Which animation is run here will depend on the old and new
106 // rotations.
107 Animation mRotateExitAnimation;
108 final Transformation mRotateExitTransformation = new Transformation();
109 Animation mRotateEnterAnimation;
110 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800111 Animation mRotateFrameAnimation;
112 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800113
114 // A previously running rotate animation. This will be used if we need
115 // to switch to a new rotation before finishing the previous one.
116 Animation mLastRotateExitAnimation;
117 final Transformation mLastRotateExitTransformation = new Transformation();
118 Animation mLastRotateEnterAnimation;
119 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800120 Animation mLastRotateFrameAnimation;
121 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800122
123 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800124 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800125 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800126 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800127
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800128 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800129 boolean mAnimRunning;
130 boolean mFinishAnimReady;
131 long mFinishAnimStartTime;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700132 boolean mForceDefaultOrientation;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800133
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800134 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800135 final Matrix mSnapshotInitialMatrix = new Matrix();
136 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700137 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800138 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800139 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800140 private boolean mMoreRotateEnter;
141 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800142 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800143 private boolean mMoreFinishEnter;
144 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800145 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800146 private boolean mMoreStartEnter;
147 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800148 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700149 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800150
Robert Carr68e5c9e2016-09-14 10:50:09 -0700151 private final WindowManagerService mService;
152
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800153 public void printTo(String prefix, PrintWriter pw) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800154 pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800155 pw.print(" mWidth="); pw.print(mWidth);
156 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700157 if (USE_CUSTOM_BLACK_FRAME) {
158 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
159 if (mCustomBlackFrame != null) {
160 mCustomBlackFrame.printTo(prefix + " ", pw);
161 }
162 }
163 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
164 if (mExitingBlackFrame != null) {
165 mExitingBlackFrame.printTo(prefix + " ", pw);
166 }
167 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
168 if (mEnteringBlackFrame != null) {
169 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800170 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700171 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
172 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
173 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800174 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
175 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
176 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
177 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
178 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
179 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
180 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
181 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
182 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800183 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
184 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800185 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
186 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
187 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
188 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800189 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
190 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800191 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
192 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
193 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
194 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800195 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
196 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800197 pw.print(prefix); pw.print("mExitTransformation=");
198 mExitTransformation.printShortString(pw); pw.println();
199 pw.print(prefix); pw.print("mEnterTransformation=");
200 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800201 pw.print(prefix); pw.print("mFrameTransformation=");
Steven Timotius8304ef42017-08-28 16:59:14 -0700202 mFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800203 pw.print(prefix); pw.print("mFrameInitialMatrix=");
204 mFrameInitialMatrix.printShortString(pw);
205 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800206 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
207 mSnapshotInitialMatrix.printShortString(pw);
208 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
209 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700210 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
211 mExitFrameFinalMatrix.printShortString(pw);
212 pw.println();
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700213 pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
214 if (mForceDefaultOrientation) {
215 pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
216 pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString());
217 }
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800218 }
219
Steven Timotiusf2d68892017-08-28 17:00:01 -0700220 public void writeToProto(ProtoOutputStream proto, long fieldId) {
221 final long token = proto.start(fieldId);
222 proto.write(STARTED, mStarted);
223 proto.write(ANIMATION_RUNNING, mAnimRunning);
224 proto.end(token);
225 }
226
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700227 public ScreenRotationAnimation(Context context, DisplayContent displayContent,
Robert Carrae606b42018-02-15 15:36:23 -0800228 boolean forceDefaultOrientation, boolean isSecure, WindowManagerService service) {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700229 mService = service;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800230 mContext = context;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700231 mDisplayContent = displayContent;
Bryce Leef3c6a472017-11-14 14:53:06 -0800232 displayContent.getBounds(mOriginalDisplayRect);
Dianne Hackborna1111872010-11-23 20:55:11 -0800233
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800234 // Screenshot does NOT include rotation!
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700235 final Display display = displayContent.getDisplay();
236 int originalRotation = display.getRotation();
237 final int originalWidth;
238 final int originalHeight;
239 DisplayInfo displayInfo = displayContent.getDisplayInfo();
240 if (forceDefaultOrientation) {
241 // Emulated orientation.
242 mForceDefaultOrientation = true;
243 originalWidth = displayContent.mBaseDisplayWidth;
244 originalHeight = displayContent.mBaseDisplayHeight;
245 } else {
246 // Normal situation
247 originalWidth = displayInfo.logicalWidth;
248 originalHeight = displayInfo.logicalHeight;
249 }
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700250 if (originalRotation == Surface.ROTATION_90
251 || originalRotation == Surface.ROTATION_270) {
252 mWidth = originalHeight;
253 mHeight = originalWidth;
254 } else {
255 mWidth = originalWidth;
256 mHeight = originalHeight;
257 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800258
Jeff Brownbc68a592011-07-25 12:58:12 -0700259 mOriginalRotation = originalRotation;
260 mOriginalWidth = originalWidth;
261 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800262
Robert Carrae606b42018-02-15 15:36:23 -0800263 final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
Dianne Hackborna1111872010-11-23 20:55:11 -0800264 try {
Robert Carrae606b42018-02-15 15:36:23 -0800265 mSurfaceControl = displayContent.makeOverlay()
266 .setName("ScreenshotSurface")
267 .setSize(mWidth, mHeight)
268 .setSecure(isSecure)
269 .build();
Robert Carre13b58e2017-08-31 14:50:44 -0700270
Robert Carrae606b42018-02-15 15:36:23 -0800271 // capture a screenshot into the surface we just created
Robert Carrae606b42018-02-15 15:36:23 -0800272 // TODO(multidisplay): we should use the proper display
Garfield Tanf4ac3072018-03-16 13:03:52 -0700273 final int displayId = SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN;
274 final IBinder displayHandle = SurfaceControl.getBuiltInDisplay(displayId);
275 // This null check below is to guard a race condition where WMS didn't have a chance to
276 // respond to display disconnection before handling rotation , that surfaceflinger may
277 // return a null handle here because it doesn't think that display is valid anymore.
278 if (displayHandle != null) {
279 Surface sur = new Surface();
280 sur.copyFrom(mSurfaceControl);
281 SurfaceControl.screenshot(displayHandle, sur);
282 t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT);
283 t.setAlpha(mSurfaceControl, 0);
284 t.show(mSurfaceControl);
285 sur.destroy();
286 } else {
287 Slog.w(TAG, "Built-in display " + displayId + " is null.");
288 }
Robert Carrae606b42018-02-15 15:36:23 -0800289 } catch (OutOfResourcesException e) {
290 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800291 }
Robert Carrae606b42018-02-15 15:36:23 -0800292
293 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
294 " FREEZE " + mSurfaceControl + ": CREATE");
295 setRotation(t, originalRotation);
296 t.apply();
Dianne Hackborna1111872010-11-23 20:55:11 -0800297 }
298
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800299 boolean hasScreenshot() {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800300 return mSurfaceControl != null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800301 }
302
Robert Carrae606b42018-02-15 15:36:23 -0800303 private void setSnapshotTransform(SurfaceControl.Transaction t, Matrix matrix, float alpha) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800304 if (mSurfaceControl != null) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800305 matrix.getValues(mTmpFloats);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700306 float x = mTmpFloats[Matrix.MTRANS_X];
307 float y = mTmpFloats[Matrix.MTRANS_Y];
308 if (mForceDefaultOrientation) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800309 mDisplayContent.getBounds(mCurrentDisplayRect);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700310 x -= mCurrentDisplayRect.left;
311 y -= mCurrentDisplayRect.top;
312 }
Robert Carrae606b42018-02-15 15:36:23 -0800313 t.setPosition(mSurfaceControl, x, y);
314 t.setMatrix(mSurfaceControl,
Dianne Hackborn352cc982011-01-04 11:34:18 -0800315 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
316 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
Robert Carrae606b42018-02-15 15:36:23 -0800317 t.setAlpha(mSurfaceControl, alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800318 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800319 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
320 float[] dstPnts = new float[4];
321 matrix.mapPoints(dstPnts, srcPnts);
322 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
323 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
324 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
325 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
326 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800327 }
328 }
329
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800330 public static void createRotationMatrix(int rotation, int width, int height,
331 Matrix outMatrix) {
332 switch (rotation) {
333 case Surface.ROTATION_0:
334 outMatrix.reset();
335 break;
336 case Surface.ROTATION_90:
337 outMatrix.setRotate(90, 0, 0);
338 outMatrix.postTranslate(height, 0);
339 break;
340 case Surface.ROTATION_180:
341 outMatrix.setRotate(180, 0, 0);
342 outMatrix.postTranslate(width, height);
343 break;
344 case Surface.ROTATION_270:
345 outMatrix.setRotate(270, 0, 0);
346 outMatrix.postTranslate(0, width);
347 break;
348 }
349 }
350
Robert Carrae606b42018-02-15 15:36:23 -0800351 private void setRotation(SurfaceControl.Transaction t, int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800352 mCurRotation = rotation;
353
354 // Compute the transformation matrix that must be applied
355 // to the snapshot to make it stay in the same original position
356 // with the current screen rotation.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800357 int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800358 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800359
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800360 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Robert Carrae606b42018-02-15 15:36:23 -0800361 setSnapshotTransform(t, mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800362 }
363
Robert Carrae606b42018-02-15 15:36:23 -0800364 public boolean setRotation(SurfaceControl.Transaction t, int rotation,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800365 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Robert Carrae606b42018-02-15 15:36:23 -0800366 setRotation(t, rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700367 if (TWO_PHASE_ANIMATION) {
Robert Carrae606b42018-02-15 15:36:23 -0800368 return startAnimation(t, maxAnimationDuration, animationScale,
Craig Mautner3c174372013-02-21 17:54:37 -0800369 finalWidth, finalHeight, false, 0, 0);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700370 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700371
372 // Don't start animation yet.
373 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800374 }
375
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800376 /**
377 * Returns true if animating.
378 */
Robert Carrae606b42018-02-15 15:36:23 -0800379 private boolean startAnimation(SurfaceControl.Transaction t, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800380 float animationScale, int finalWidth, int finalHeight, boolean dismissing,
381 int exitAnim, int enterAnim) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800382 if (mSurfaceControl == null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800383 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800384 return false;
385 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800386 if (mStarted) {
387 return true;
388 }
389
390 mStarted = true;
391
392 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800393
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800394 // Figure out how the screen has moved from the original rotation.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800395 int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800396
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700397 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
398 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800399 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
400 firstStart = true;
401 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
402 com.android.internal.R.anim.screen_rotate_start_exit);
403 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
404 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700405 if (USE_CUSTOM_BLACK_FRAME) {
406 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
407 com.android.internal.R.anim.screen_rotate_start_frame);
408 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800409 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
410 com.android.internal.R.anim.screen_rotate_finish_exit);
411 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
412 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700413 if (USE_CUSTOM_BLACK_FRAME) {
414 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
415 com.android.internal.R.anim.screen_rotate_finish_frame);
416 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800417 }
418
419 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
420 + finalWidth + " finalHeight=" + finalHeight
421 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
422
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700423 final boolean customAnim;
Craig Mautner3c174372013-02-21 17:54:37 -0800424 if (exitAnim != 0 && enterAnim != 0) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700425 customAnim = true;
Craig Mautner3c174372013-02-21 17:54:37 -0800426 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
427 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700428 } else {
429 customAnim = false;
430 switch (delta) {
431 case Surface.ROTATION_0:
432 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
433 com.android.internal.R.anim.screen_rotate_0_exit);
434 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
435 com.android.internal.R.anim.screen_rotate_0_enter);
436 if (USE_CUSTOM_BLACK_FRAME) {
437 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
438 com.android.internal.R.anim.screen_rotate_0_frame);
439 }
440 break;
441 case Surface.ROTATION_90:
442 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
443 com.android.internal.R.anim.screen_rotate_plus_90_exit);
444 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
445 com.android.internal.R.anim.screen_rotate_plus_90_enter);
446 if (USE_CUSTOM_BLACK_FRAME) {
447 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
448 com.android.internal.R.anim.screen_rotate_plus_90_frame);
449 }
450 break;
451 case Surface.ROTATION_180:
452 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
453 com.android.internal.R.anim.screen_rotate_180_exit);
454 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
455 com.android.internal.R.anim.screen_rotate_180_enter);
456 if (USE_CUSTOM_BLACK_FRAME) {
457 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
458 com.android.internal.R.anim.screen_rotate_180_frame);
459 }
460 break;
461 case Surface.ROTATION_270:
462 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
463 com.android.internal.R.anim.screen_rotate_minus_90_exit);
464 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
465 com.android.internal.R.anim.screen_rotate_minus_90_enter);
466 if (USE_CUSTOM_BLACK_FRAME) {
467 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
468 com.android.internal.R.anim.screen_rotate_minus_90_frame);
469 }
470 break;
471 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800472 }
473
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800474 // Initialize the animations. This is a hack, redefining what "parent"
475 // means to allow supplying the last and next size. In this definition
476 // "%p" is the original (let's call it "previous") size, and "%" is the
477 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700478 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700479 // Compute partial steps between original and final sizes. These
480 // are used for the dimensions of the exiting and entering elements,
481 // so they are never stretched too significantly.
482 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
483 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
484
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800485 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
486 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800487 halfWidth, halfHeight);
488 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800489 mOriginalWidth, mOriginalHeight);
490 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800491 halfWidth, halfHeight);
492 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800493 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700494 if (USE_CUSTOM_BLACK_FRAME) {
495 mStartFrameAnimation.initialize(finalWidth, finalHeight,
496 mOriginalWidth, mOriginalHeight);
497 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
498 mOriginalWidth, mOriginalHeight);
499 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800500 }
501 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
502 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700503 if (USE_CUSTOM_BLACK_FRAME) {
504 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
505 mOriginalHeight);
506 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800507 mAnimRunning = false;
508 mFinishAnimReady = false;
509 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800510
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700511 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800512 mStartExitAnimation.restrictDuration(maxAnimationDuration);
513 mStartExitAnimation.scaleCurrentDuration(animationScale);
514 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
515 mStartEnterAnimation.scaleCurrentDuration(animationScale);
516 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
517 mFinishExitAnimation.scaleCurrentDuration(animationScale);
518 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
519 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700520 if (USE_CUSTOM_BLACK_FRAME) {
521 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
522 mStartFrameAnimation.scaleCurrentDuration(animationScale);
523 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
524 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
525 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800526 }
527 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
528 mRotateExitAnimation.scaleCurrentDuration(animationScale);
529 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
530 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700531 if (USE_CUSTOM_BLACK_FRAME) {
532 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
533 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
534 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800535
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700536 final int layerStack = mDisplayContent.getDisplay().getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700537 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800538 // Compute the transformation matrix that must be applied
539 // the the black frame to make it stay in the initial position
540 // before the new screen rotation. This is different than the
541 // snapshot transformation because the snapshot is always based
542 // of the native orientation of the screen, not the orientation
543 // we were last in.
544 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
545
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800546 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800547 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
548 mOriginalWidth*2, mOriginalHeight*2);
549 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Robert Carrae606b42018-02-15 15:36:23 -0800550 mCustomBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700551 SCREEN_FREEZE_LAYER_CUSTOM, mDisplayContent, false);
Robert Carrae606b42018-02-15 15:36:23 -0800552 mCustomBlackFrame.setMatrix(t, mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700553 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700554 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700555 }
556 }
557
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700558 if (!customAnim && mExitingBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700559 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700560 // Compute the transformation matrix that must be applied
561 // the the black frame to make it stay in the initial position
562 // before the new screen rotation. This is different than the
563 // snapshot transformation because the snapshot is always based
564 // of the native orientation of the screen, not the orientation
565 // we were last in.
566 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
567
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700568 final Rect outer;
569 final Rect inner;
570 if (mForceDefaultOrientation) {
571 // Going from a smaller Display to a larger Display, add curtains to sides
572 // or top and bottom. Going from a larger to smaller display will result in
573 // no BlackSurfaces being constructed.
574 outer = mCurrentDisplayRect;
575 inner = mOriginalDisplayRect;
576 } else {
577 outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
578 mOriginalWidth*2, mOriginalHeight*2);
579 inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
580 }
Robert Carrae606b42018-02-15 15:36:23 -0800581 mExitingBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700582 SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation);
Robert Carrae606b42018-02-15 15:36:23 -0800583 mExitingBlackFrame.setMatrix(t, mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700584 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700585 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700586 }
587 }
588
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700589 if (customAnim && mEnteringBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700590 try {
591 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
592 finalWidth*2, finalHeight*2);
593 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Robert Carrae606b42018-02-15 15:36:23 -0800594 mEnteringBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700595 SCREEN_FREEZE_LAYER_ENTER, mDisplayContent, false);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700596 } catch (OutOfResourcesException e) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800597 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800598 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800599 }
600
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800601 return true;
602 }
603
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800604 /**
605 * Returns true if animating.
606 */
Robert Carrae606b42018-02-15 15:36:23 -0800607 public boolean dismiss(SurfaceControl.Transaction t, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800608 float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800609 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800610 if (mSurfaceControl == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800611 // Can't do animation.
612 return false;
613 }
614 if (!mStarted) {
Robert Carrae606b42018-02-15 15:36:23 -0800615 startAnimation(t, maxAnimationDuration, animationScale, finalWidth, finalHeight,
Craig Mautner3c174372013-02-21 17:54:37 -0800616 true, exitAnim, enterAnim);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800617 }
618 if (!mStarted) {
619 return false;
620 }
621 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
622 mFinishAnimReady = true;
623 return true;
624 }
625
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800626 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800627 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800628 if (mSurfaceControl != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800629 if (SHOW_TRANSACTIONS ||
630 SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800631 " FREEZE " + mSurfaceControl + ": DESTROY");
632 mSurfaceControl.destroy();
633 mSurfaceControl = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800634 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700635 if (mCustomBlackFrame != null) {
636 mCustomBlackFrame.kill();
637 mCustomBlackFrame = null;
638 }
639 if (mExitingBlackFrame != null) {
640 mExitingBlackFrame.kill();
641 mExitingBlackFrame = null;
642 }
643 if (mEnteringBlackFrame != null) {
644 mEnteringBlackFrame.kill();
645 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800646 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700647 if (TWO_PHASE_ANIMATION) {
648 if (mStartExitAnimation != null) {
649 mStartExitAnimation.cancel();
650 mStartExitAnimation = null;
651 }
652 if (mStartEnterAnimation != null) {
653 mStartEnterAnimation.cancel();
654 mStartEnterAnimation = null;
655 }
656 if (mFinishExitAnimation != null) {
657 mFinishExitAnimation.cancel();
658 mFinishExitAnimation = null;
659 }
660 if (mFinishEnterAnimation != null) {
661 mFinishEnterAnimation.cancel();
662 mFinishEnterAnimation = null;
663 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800664 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700665 if (USE_CUSTOM_BLACK_FRAME) {
666 if (mStartFrameAnimation != null) {
667 mStartFrameAnimation.cancel();
668 mStartFrameAnimation = null;
669 }
670 if (mRotateFrameAnimation != null) {
671 mRotateFrameAnimation.cancel();
672 mRotateFrameAnimation = null;
673 }
674 if (mFinishFrameAnimation != null) {
675 mFinishFrameAnimation.cancel();
676 mFinishFrameAnimation = null;
677 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800678 }
679 if (mRotateExitAnimation != null) {
680 mRotateExitAnimation.cancel();
681 mRotateExitAnimation = null;
682 }
683 if (mRotateEnterAnimation != null) {
684 mRotateEnterAnimation.cancel();
685 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800686 }
687 }
688
689 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700690 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700691 }
692
Dianne Hackborn4b169692012-11-29 17:51:24 -0800693 public boolean isRotating() {
694 return mCurRotation != mOriginalRotation;
695 }
696
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700697 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700698 return (TWO_PHASE_ANIMATION &&
699 (mStartEnterAnimation != null || mStartExitAnimation != null
700 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
701 || (USE_CUSTOM_BLACK_FRAME &&
702 (mStartFrameAnimation != null || mRotateFrameAnimation != null
703 || mFinishFrameAnimation != null))
704 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800705 }
706
Craig Mautnere32c3072012-03-12 15:25:35 -0700707 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700708 if (now > mHalfwayPoint) {
709 mHalfwayPoint = Long.MAX_VALUE;
710 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800711 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
712 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
713 mFinishAnimStartTime = now;
714 }
715
Craig Mautner7d8df392012-04-06 15:26:23 -0700716 if (TWO_PHASE_ANIMATION) {
717 mMoreStartExit = false;
718 if (mStartExitAnimation != null) {
719 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
720 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
721 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800722
Craig Mautner7d8df392012-04-06 15:26:23 -0700723 mMoreStartEnter = false;
724 if (mStartEnterAnimation != null) {
725 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
726 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
727 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800728 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700729 if (USE_CUSTOM_BLACK_FRAME) {
730 mMoreStartFrame = false;
731 if (mStartFrameAnimation != null) {
732 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
733 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
734 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800735 }
736
Craig Mautnerdbb79912012-03-01 18:59:14 -0800737 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
738 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
739
Craig Mautner7d8df392012-04-06 15:26:23 -0700740 if (TWO_PHASE_ANIMATION) {
741 mMoreFinishExit = false;
742 if (mFinishExitAnimation != null) {
743 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
744 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
745 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800746
Craig Mautner7d8df392012-04-06 15:26:23 -0700747 mMoreFinishEnter = false;
748 if (mFinishEnterAnimation != null) {
749 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
750 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
751 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800752 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700753 if (USE_CUSTOM_BLACK_FRAME) {
754 mMoreFinishFrame = false;
755 if (mFinishFrameAnimation != null) {
756 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
757 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
758 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800759 }
760
Craig Mautnerdbb79912012-03-01 18:59:14 -0800761 mMoreRotateExit = false;
762 if (mRotateExitAnimation != null) {
763 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
764 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700765 }
766
767 mMoreRotateEnter = false;
768 if (mRotateEnterAnimation != null) {
769 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
770 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
771 }
772
Craig Mautner7d8df392012-04-06 15:26:23 -0700773 if (USE_CUSTOM_BLACK_FRAME) {
774 mMoreRotateFrame = false;
775 if (mRotateFrameAnimation != null) {
776 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
777 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
778 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700779 }
780
Craig Mautner7d8df392012-04-06 15:26:23 -0700781 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
782 if (TWO_PHASE_ANIMATION) {
783 if (mStartExitAnimation != null) {
784 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
785 mStartExitAnimation.cancel();
786 mStartExitAnimation = null;
787 mStartExitTransformation.clear();
788 }
789 if (mFinishExitAnimation != null) {
790 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
791 mFinishExitAnimation.cancel();
792 mFinishExitAnimation = null;
793 mFinishExitTransformation.clear();
794 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700795 }
796 if (mRotateExitAnimation != null) {
797 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800798 mRotateExitAnimation.cancel();
799 mRotateExitAnimation = null;
800 mRotateExitTransformation.clear();
801 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800802 }
803
Craig Mautner7d8df392012-04-06 15:26:23 -0700804 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
805 if (TWO_PHASE_ANIMATION) {
806 if (mStartEnterAnimation != null) {
807 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
808 mStartEnterAnimation.cancel();
809 mStartEnterAnimation = null;
810 mStartEnterTransformation.clear();
811 }
812 if (mFinishEnterAnimation != null) {
813 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
814 mFinishEnterAnimation.cancel();
815 mFinishEnterAnimation = null;
816 mFinishEnterTransformation.clear();
817 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700818 }
819 if (mRotateEnterAnimation != null) {
820 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800821 mRotateEnterAnimation.cancel();
822 mRotateEnterAnimation = null;
823 mRotateEnterTransformation.clear();
824 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800825 }
826
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700827 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
828 if (mStartFrameAnimation != null) {
829 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
830 mStartFrameAnimation.cancel();
831 mStartFrameAnimation = null;
832 mStartFrameTransformation.clear();
833 }
834 if (mFinishFrameAnimation != null) {
835 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
836 mFinishFrameAnimation.cancel();
837 mFinishFrameAnimation = null;
838 mFinishFrameTransformation.clear();
839 }
840 if (mRotateFrameAnimation != null) {
841 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800842 mRotateFrameAnimation.cancel();
843 mRotateFrameAnimation = null;
844 mRotateFrameTransformation.clear();
845 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800846 }
847
848 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800849 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700850 if (TWO_PHASE_ANIMATION) {
851 mExitTransformation.compose(mStartExitTransformation);
852 mExitTransformation.compose(mFinishExitTransformation);
853
854 mEnterTransformation.compose(mStartEnterTransformation);
855 mEnterTransformation.compose(mFinishEnterTransformation);
856 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800857
858 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
859 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700860
861 if (USE_CUSTOM_BLACK_FRAME) {
862 //mFrameTransformation.set(mRotateExitTransformation);
863 //mFrameTransformation.compose(mStartExitTransformation);
864 //mFrameTransformation.compose(mFinishExitTransformation);
865 mFrameTransformation.set(mRotateFrameTransformation);
866 mFrameTransformation.compose(mStartFrameTransformation);
867 mFrameTransformation.compose(mFinishFrameTransformation);
868 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
869 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
870 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800871
Craig Mautner7d8df392012-04-06 15:26:23 -0700872 final boolean more = (TWO_PHASE_ANIMATION
873 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
874 || (USE_CUSTOM_BLACK_FRAME
875 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
Igor Murashkina86ab6402013-08-30 12:58:36 -0700876 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800877 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800878
879 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
880
881 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
882
883 return more;
884 }
885
Robert Carrae606b42018-02-15 15:36:23 -0800886 void updateSurfaces(SurfaceControl.Transaction t) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700887 if (!mStarted) {
888 return;
889 }
890
Mathias Agopian29479eb2013-02-14 14:36:04 -0800891 if (mSurfaceControl != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700892 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800893 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
Robert Carrae606b42018-02-15 15:36:23 -0800894 t.hide(mSurfaceControl);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800895 }
896 }
897
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700898 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700899 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800900 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Robert Carrae606b42018-02-15 15:36:23 -0800901 mCustomBlackFrame.hide(t);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700902 } else {
Robert Carrae606b42018-02-15 15:36:23 -0800903 mCustomBlackFrame.setMatrix(t, mFrameTransformation.getMatrix());
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700904 }
905 }
906
907 if (mExitingBlackFrame != null) {
908 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
909 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
Robert Carrae606b42018-02-15 15:36:23 -0800910 mExitingBlackFrame.hide(t);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700911 } else {
912 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
Robert Carrae606b42018-02-15 15:36:23 -0800913 mExitingBlackFrame.setMatrix(t, mExitFrameFinalMatrix);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700914 if (mForceDefaultOrientation) {
Robert Carrae606b42018-02-15 15:36:23 -0800915 mExitingBlackFrame.setAlpha(t, mExitTransformation.getAlpha());
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700916 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700917 }
918 }
919
920 if (mEnteringBlackFrame != null) {
921 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
922 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
Robert Carrae606b42018-02-15 15:36:23 -0800923 mEnteringBlackFrame.hide(t);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700924 } else {
Robert Carrae606b42018-02-15 15:36:23 -0800925 mEnteringBlackFrame.setMatrix(t, mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800926 }
927 }
928
Robert Carrae606b42018-02-15 15:36:23 -0800929 setSnapshotTransform(t, mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800930 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700931
Craig Mautnere32c3072012-03-12 15:25:35 -0700932 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700933 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800934 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800935 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800936 return false;
937 }
938
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800939 if (!mAnimRunning) {
940 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700941 if (TWO_PHASE_ANIMATION) {
942 if (mStartEnterAnimation != null) {
943 mStartEnterAnimation.setStartTime(now);
944 }
945 if (mStartExitAnimation != null) {
946 mStartExitAnimation.setStartTime(now);
947 }
948 if (mFinishEnterAnimation != null) {
949 mFinishEnterAnimation.setStartTime(0);
950 }
951 if (mFinishExitAnimation != null) {
952 mFinishExitAnimation.setStartTime(0);
953 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700954 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700955 if (USE_CUSTOM_BLACK_FRAME) {
956 if (mStartFrameAnimation != null) {
957 mStartFrameAnimation.setStartTime(now);
958 }
959 if (mFinishFrameAnimation != null) {
960 mFinishFrameAnimation.setStartTime(0);
961 }
962 if (mRotateFrameAnimation != null) {
963 mRotateFrameAnimation.setStartTime(now);
964 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800965 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800966 if (mRotateEnterAnimation != null) {
967 mRotateEnterAnimation.setStartTime(now);
968 }
969 if (mRotateExitAnimation != null) {
970 mRotateExitAnimation.setStartTime(now);
971 }
972 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -0700973 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800974 }
Craig Mautnere32c3072012-03-12 15:25:35 -0700975
976 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800977 }
978
979 public Transformation getEnterTransformation() {
980 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800981 }
982}