blob: c0942c908f3b2e499a1fb50b81b5c5c062993f75 [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
Peiyong Lin67f3ba12018-08-23 10:26:45 -070019import static com.android.server.wm.ScreenRotationAnimationProto.ANIMATION_RUNNING;
20import static com.android.server.wm.ScreenRotationAnimationProto.STARTED;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080021import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
22import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
23import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
24import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Chong Zhang97782b42015-10-07 16:01:23 -070025import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
Chong Zhang97782b42015-10-07 16:01:23 -070026import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080027
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080028import android.content.Context;
Dianne Hackborna1111872010-11-23 20:55:11 -080029import android.graphics.Matrix;
Dianne Hackborna1111872010-11-23 20:55:11 -080030import android.graphics.Rect;
Dianne Hackborna1111872010-11-23 20:55:11 -080031import android.util.Slog;
Steven Timotiusf2d68892017-08-28 17:00:01 -070032import android.util.proto.ProtoOutputStream;
Craig Mautner6881a102012-07-27 13:04:51 -070033import android.view.Display;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070034import android.view.DisplayInfo;
Dianne Hackborna1111872010-11-23 20:55:11 -080035import android.view.Surface;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080036import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080037import android.view.SurfaceControl;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080038import android.view.animation.Animation;
39import android.view.animation.AnimationUtils;
40import android.view.animation.Transformation;
Dianne Hackborna1111872010-11-23 20:55:11 -080041
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080042import java.io.PrintWriter;
43
Craig Mautnere32c3072012-03-12 15:25:35 -070044class ScreenRotationAnimation {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080045 static final String TAG = TAG_WITH_CLASS_NAME ? "ScreenRotationAnimation" : TAG_WM;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080046 static final boolean DEBUG_STATE = false;
47 static final boolean DEBUG_TRANSFORMS = false;
Dianne Hackborn187ae2102012-04-11 18:12:06 -070048 static final boolean TWO_PHASE_ANIMATION = false;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070049 static final boolean USE_CUSTOM_BLACK_FRAME = false;
Dianne Hackborna1111872010-11-23 20:55:11 -080050
Chong Zhang97782b42015-10-07 16:01:23 -070051 /*
52 * Layers for screen rotation animation. We put these layers above
53 * WINDOW_FREEZE_LAYER so that screen freeze will cover all windows.
54 */
55 static final int SCREEN_FREEZE_LAYER_BASE = WINDOW_FREEZE_LAYER + TYPE_LAYER_MULTIPLIER;
56 static final int SCREEN_FREEZE_LAYER_ENTER = SCREEN_FREEZE_LAYER_BASE;
57 static final int SCREEN_FREEZE_LAYER_SCREENSHOT = SCREEN_FREEZE_LAYER_BASE + 1;
58 static final int SCREEN_FREEZE_LAYER_EXIT = SCREEN_FREEZE_LAYER_BASE + 2;
59 static final int SCREEN_FREEZE_LAYER_CUSTOM = SCREEN_FREEZE_LAYER_BASE + 3;
Dianne Hackborn50660e22011-02-02 17:12:25 -080060
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080061 final Context mContext;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070062 final DisplayContent mDisplayContent;
Mathias Agopian29479eb2013-02-14 14:36:04 -080063 SurfaceControl mSurfaceControl;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070064 BlackFrame mCustomBlackFrame;
65 BlackFrame mExitingBlackFrame;
66 BlackFrame mEnteringBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080067 int mWidth, mHeight;
68
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080069 int mOriginalRotation;
70 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080071 int mCurRotation;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070072 Rect mOriginalDisplayRect = new Rect();
73 Rect mCurrentDisplayRect = new Rect();
Dianne Hackborna1111872010-11-23 20:55:11 -080074
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080075 // For all animations, "exit" is for the UI elements that are going
76 // away (that is the snapshot of the old screen), and "enter" is for
77 // the new UI elements that are appearing (that is the active windows
78 // in their final orientation).
79
80 // The starting animation for the exiting and entering elements. This
81 // animation applies a transformation while the rotation is in progress.
82 // It is started immediately, before the new entering UI is ready.
83 Animation mStartExitAnimation;
84 final Transformation mStartExitTransformation = new Transformation();
85 Animation mStartEnterAnimation;
86 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080087 Animation mStartFrameAnimation;
88 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080089
90 // The finishing animation for the exiting and entering elements. This
91 // animation needs to undo the transformation of the starting animation.
92 // It starts running once the new rotation UI elements are ready to be
93 // displayed.
94 Animation mFinishExitAnimation;
95 final Transformation mFinishExitTransformation = new Transformation();
96 Animation mFinishEnterAnimation;
97 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080098 Animation mFinishFrameAnimation;
99 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800100
101 // The current active animation to move from the old to the new rotated
102 // state. Which animation is run here will depend on the old and new
103 // rotations.
104 Animation mRotateExitAnimation;
105 final Transformation mRotateExitTransformation = new Transformation();
106 Animation mRotateEnterAnimation;
107 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800108 Animation mRotateFrameAnimation;
109 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800110
111 // A previously running rotate animation. This will be used if we need
112 // to switch to a new rotation before finishing the previous one.
113 Animation mLastRotateExitAnimation;
114 final Transformation mLastRotateExitTransformation = new Transformation();
115 Animation mLastRotateEnterAnimation;
116 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800117 Animation mLastRotateFrameAnimation;
118 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800119
120 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800121 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800122 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800123 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800124
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800125 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800126 boolean mAnimRunning;
127 boolean mFinishAnimReady;
128 long mFinishAnimStartTime;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700129 boolean mForceDefaultOrientation;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800130
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800131 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800132 final Matrix mSnapshotInitialMatrix = new Matrix();
133 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700134 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800135 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800136 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800137 private boolean mMoreRotateEnter;
138 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800139 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800140 private boolean mMoreFinishEnter;
141 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800142 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800143 private boolean mMoreStartEnter;
144 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800145 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700146 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800147
Robert Carr68e5c9e2016-09-14 10:50:09 -0700148 private final WindowManagerService mService;
149
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800150 public void printTo(String prefix, PrintWriter pw) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800151 pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800152 pw.print(" mWidth="); pw.print(mWidth);
153 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700154 if (USE_CUSTOM_BLACK_FRAME) {
155 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
156 if (mCustomBlackFrame != null) {
157 mCustomBlackFrame.printTo(prefix + " ", pw);
158 }
159 }
160 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
161 if (mExitingBlackFrame != null) {
162 mExitingBlackFrame.printTo(prefix + " ", pw);
163 }
164 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
165 if (mEnteringBlackFrame != null) {
166 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800167 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700168 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
169 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
170 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800171 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
172 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
173 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
174 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
175 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
176 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
177 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
178 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
179 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800180 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
181 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800182 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
183 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
184 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
185 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800186 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
187 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800188 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
189 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
190 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
191 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800192 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
193 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800194 pw.print(prefix); pw.print("mExitTransformation=");
195 mExitTransformation.printShortString(pw); pw.println();
196 pw.print(prefix); pw.print("mEnterTransformation=");
197 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800198 pw.print(prefix); pw.print("mFrameTransformation=");
Steven Timotius8304ef42017-08-28 16:59:14 -0700199 mFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800200 pw.print(prefix); pw.print("mFrameInitialMatrix=");
201 mFrameInitialMatrix.printShortString(pw);
202 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800203 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
204 mSnapshotInitialMatrix.printShortString(pw);
205 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
206 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700207 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
208 mExitFrameFinalMatrix.printShortString(pw);
209 pw.println();
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700210 pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
211 if (mForceDefaultOrientation) {
212 pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
213 pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString());
214 }
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800215 }
216
Steven Timotiusf2d68892017-08-28 17:00:01 -0700217 public void writeToProto(ProtoOutputStream proto, long fieldId) {
218 final long token = proto.start(fieldId);
219 proto.write(STARTED, mStarted);
220 proto.write(ANIMATION_RUNNING, mAnimRunning);
221 proto.end(token);
222 }
223
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700224 public ScreenRotationAnimation(Context context, DisplayContent displayContent,
Garfield Tanff362222018-11-14 17:52:32 -0800225 boolean fixedToUserRotation, boolean isSecure, WindowManagerService service) {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700226 mService = service;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800227 mContext = context;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700228 mDisplayContent = displayContent;
Bryce Leef3c6a472017-11-14 14:53:06 -0800229 displayContent.getBounds(mOriginalDisplayRect);
Dianne Hackborna1111872010-11-23 20:55:11 -0800230
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800231 // Screenshot does NOT include rotation!
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700232 final Display display = displayContent.getDisplay();
233 int originalRotation = display.getRotation();
234 final int originalWidth;
235 final int originalHeight;
236 DisplayInfo displayInfo = displayContent.getDisplayInfo();
Garfield Tanff362222018-11-14 17:52:32 -0800237 if (fixedToUserRotation) {
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700238 // Emulated orientation.
239 mForceDefaultOrientation = true;
240 originalWidth = displayContent.mBaseDisplayWidth;
241 originalHeight = displayContent.mBaseDisplayHeight;
242 } else {
243 // Normal situation
244 originalWidth = displayInfo.logicalWidth;
245 originalHeight = displayInfo.logicalHeight;
246 }
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700247 if (originalRotation == Surface.ROTATION_90
248 || originalRotation == Surface.ROTATION_270) {
249 mWidth = originalHeight;
250 mHeight = originalWidth;
251 } else {
252 mWidth = originalWidth;
253 mHeight = originalHeight;
254 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800255
Jeff Brownbc68a592011-07-25 12:58:12 -0700256 mOriginalRotation = originalRotation;
257 mOriginalWidth = originalWidth;
258 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800259
Vishnu Naire6e2b0f2019-02-21 10:41:00 -0800260 final SurfaceControl.Transaction t = mService.mTransactionFactory.make();
Dianne Hackborna1111872010-11-23 20:55:11 -0800261 try {
Robert Carrae606b42018-02-15 15:36:23 -0800262 mSurfaceControl = displayContent.makeOverlay()
263 .setName("ScreenshotSurface")
Vishnu Naire86bd982018-11-28 13:23:17 -0800264 .setBufferSize(mWidth, mHeight)
Robert Carrae606b42018-02-15 15:36:23 -0800265 .setSecure(isSecure)
266 .build();
Robert Carre13b58e2017-08-31 14:50:44 -0700267
Peiyong Lin67f3ba12018-08-23 10:26:45 -0700268 // In case display bounds change, screenshot buffer and surface may mismatch so set a
269 // scaling mode.
Vishnu Naire6e2b0f2019-02-21 10:41:00 -0800270 SurfaceControl.Transaction t2 = mService.mTransactionFactory.make();
Peiyong Lin67f3ba12018-08-23 10:26:45 -0700271 t2.setOverrideScalingMode(mSurfaceControl, Surface.SCALING_MODE_SCALE_TO_WINDOW);
272 t2.apply(true /* sync */);
273
Riddle Hsu654a6f92018-07-13 22:59:36 +0800274 // Capture a screenshot into the surface we just created.
275 final int displayId = display.getDisplayId();
Vishnu Naire6e2b0f2019-02-21 10:41:00 -0800276 final Surface surface = mService.mSurfaceFactory.make();
Riddle Hsu654a6f92018-07-13 22:59:36 +0800277 surface.copyFrom(mSurfaceControl);
Robert Carr66b5664f2019-04-02 14:18:56 -0700278 SurfaceControl.ScreenshotGraphicBuffer gb =
279 mService.mDisplayManagerInternal.screenshot(displayId);
280 if (gb != null) {
281 try {
282 surface.attachAndQueueBuffer(gb.getGraphicBuffer());
283 } catch (RuntimeException e) {
284 Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage());
285 }
286 // If the screenshot contains secure layers, we have to make sure the
287 // screenshot surface we display it in also has FLAG_SECURE so that
288 // the user can not screenshot secure layers via the screenshot surface.
289 if (gb.containsSecureLayers()) {
290 t.setSecure(mSurfaceControl, true);
291 }
Garfield Tanf4ac3072018-03-16 13:03:52 -0700292 t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT);
293 t.setAlpha(mSurfaceControl, 0);
294 t.show(mSurfaceControl);
Garfield Tanf4ac3072018-03-16 13:03:52 -0700295 } else {
Riddle Hsu654a6f92018-07-13 22:59:36 +0800296 Slog.w(TAG, "Unable to take screenshot of display " + displayId);
Garfield Tanf4ac3072018-03-16 13:03:52 -0700297 }
Riddle Hsu654a6f92018-07-13 22:59:36 +0800298 surface.destroy();
Robert Carrae606b42018-02-15 15:36:23 -0800299 } catch (OutOfResourcesException e) {
300 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800301 }
Robert Carrae606b42018-02-15 15:36:23 -0800302
303 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
304 " FREEZE " + mSurfaceControl + ": CREATE");
305 setRotation(t, originalRotation);
306 t.apply();
Dianne Hackborna1111872010-11-23 20:55:11 -0800307 }
308
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800309 boolean hasScreenshot() {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800310 return mSurfaceControl != null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800311 }
312
Robert Carrae606b42018-02-15 15:36:23 -0800313 private void setSnapshotTransform(SurfaceControl.Transaction t, Matrix matrix, float alpha) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800314 if (mSurfaceControl != null) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800315 matrix.getValues(mTmpFloats);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700316 float x = mTmpFloats[Matrix.MTRANS_X];
317 float y = mTmpFloats[Matrix.MTRANS_Y];
318 if (mForceDefaultOrientation) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800319 mDisplayContent.getBounds(mCurrentDisplayRect);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700320 x -= mCurrentDisplayRect.left;
321 y -= mCurrentDisplayRect.top;
322 }
Robert Carrae606b42018-02-15 15:36:23 -0800323 t.setPosition(mSurfaceControl, x, y);
324 t.setMatrix(mSurfaceControl,
Dianne Hackborn352cc982011-01-04 11:34:18 -0800325 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
326 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
Robert Carrae606b42018-02-15 15:36:23 -0800327 t.setAlpha(mSurfaceControl, alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800328 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800329 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
330 float[] dstPnts = new float[4];
331 matrix.mapPoints(dstPnts, srcPnts);
332 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
333 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
334 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
335 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
336 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800337 }
338 }
339
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800340 public static void createRotationMatrix(int rotation, int width, int height,
341 Matrix outMatrix) {
342 switch (rotation) {
343 case Surface.ROTATION_0:
344 outMatrix.reset();
345 break;
346 case Surface.ROTATION_90:
347 outMatrix.setRotate(90, 0, 0);
348 outMatrix.postTranslate(height, 0);
349 break;
350 case Surface.ROTATION_180:
351 outMatrix.setRotate(180, 0, 0);
352 outMatrix.postTranslate(width, height);
353 break;
354 case Surface.ROTATION_270:
355 outMatrix.setRotate(270, 0, 0);
356 outMatrix.postTranslate(0, width);
357 break;
358 }
359 }
360
Robert Carrae606b42018-02-15 15:36:23 -0800361 private void setRotation(SurfaceControl.Transaction t, int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800362 mCurRotation = rotation;
363
364 // Compute the transformation matrix that must be applied
365 // to the snapshot to make it stay in the same original position
366 // with the current screen rotation.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800367 int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800368 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800369
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800370 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Robert Carrae606b42018-02-15 15:36:23 -0800371 setSnapshotTransform(t, mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800372 }
373
Robert Carrae606b42018-02-15 15:36:23 -0800374 public boolean setRotation(SurfaceControl.Transaction t, int rotation,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800375 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Robert Carrae606b42018-02-15 15:36:23 -0800376 setRotation(t, rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700377 if (TWO_PHASE_ANIMATION) {
Robert Carrae606b42018-02-15 15:36:23 -0800378 return startAnimation(t, maxAnimationDuration, animationScale,
Craig Mautner3c174372013-02-21 17:54:37 -0800379 finalWidth, finalHeight, false, 0, 0);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700380 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700381
382 // Don't start animation yet.
383 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800384 }
385
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800386 /**
387 * Returns true if animating.
388 */
Robert Carrae606b42018-02-15 15:36:23 -0800389 private boolean startAnimation(SurfaceControl.Transaction t, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800390 float animationScale, int finalWidth, int finalHeight, boolean dismissing,
391 int exitAnim, int enterAnim) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800392 if (mSurfaceControl == null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800393 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800394 return false;
395 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800396 if (mStarted) {
397 return true;
398 }
399
400 mStarted = true;
401
402 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800403
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800404 // Figure out how the screen has moved from the original rotation.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800405 int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800406
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700407 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
408 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800409 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
410 firstStart = true;
411 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
412 com.android.internal.R.anim.screen_rotate_start_exit);
413 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
414 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700415 if (USE_CUSTOM_BLACK_FRAME) {
416 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
417 com.android.internal.R.anim.screen_rotate_start_frame);
418 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800419 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
420 com.android.internal.R.anim.screen_rotate_finish_exit);
421 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
422 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700423 if (USE_CUSTOM_BLACK_FRAME) {
424 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
425 com.android.internal.R.anim.screen_rotate_finish_frame);
426 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800427 }
428
429 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
430 + finalWidth + " finalHeight=" + finalHeight
431 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
432
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700433 final boolean customAnim;
Craig Mautner3c174372013-02-21 17:54:37 -0800434 if (exitAnim != 0 && enterAnim != 0) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700435 customAnim = true;
Craig Mautner3c174372013-02-21 17:54:37 -0800436 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
437 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700438 } else {
439 customAnim = false;
440 switch (delta) {
441 case Surface.ROTATION_0:
442 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
443 com.android.internal.R.anim.screen_rotate_0_exit);
444 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
445 com.android.internal.R.anim.screen_rotate_0_enter);
446 if (USE_CUSTOM_BLACK_FRAME) {
447 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
448 com.android.internal.R.anim.screen_rotate_0_frame);
449 }
450 break;
451 case Surface.ROTATION_90:
452 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
453 com.android.internal.R.anim.screen_rotate_plus_90_exit);
454 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
455 com.android.internal.R.anim.screen_rotate_plus_90_enter);
456 if (USE_CUSTOM_BLACK_FRAME) {
457 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
458 com.android.internal.R.anim.screen_rotate_plus_90_frame);
459 }
460 break;
461 case Surface.ROTATION_180:
462 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
463 com.android.internal.R.anim.screen_rotate_180_exit);
464 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
465 com.android.internal.R.anim.screen_rotate_180_enter);
466 if (USE_CUSTOM_BLACK_FRAME) {
467 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
468 com.android.internal.R.anim.screen_rotate_180_frame);
469 }
470 break;
471 case Surface.ROTATION_270:
472 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
473 com.android.internal.R.anim.screen_rotate_minus_90_exit);
474 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
475 com.android.internal.R.anim.screen_rotate_minus_90_enter);
476 if (USE_CUSTOM_BLACK_FRAME) {
477 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
478 com.android.internal.R.anim.screen_rotate_minus_90_frame);
479 }
480 break;
481 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800482 }
483
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800484 // Initialize the animations. This is a hack, redefining what "parent"
485 // means to allow supplying the last and next size. In this definition
486 // "%p" is the original (let's call it "previous") size, and "%" is the
487 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700488 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700489 // Compute partial steps between original and final sizes. These
490 // are used for the dimensions of the exiting and entering elements,
491 // so they are never stretched too significantly.
492 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
493 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
494
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800495 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
496 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800497 halfWidth, halfHeight);
498 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800499 mOriginalWidth, mOriginalHeight);
500 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800501 halfWidth, halfHeight);
502 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800503 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700504 if (USE_CUSTOM_BLACK_FRAME) {
505 mStartFrameAnimation.initialize(finalWidth, finalHeight,
506 mOriginalWidth, mOriginalHeight);
507 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
508 mOriginalWidth, mOriginalHeight);
509 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800510 }
511 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
512 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700513 if (USE_CUSTOM_BLACK_FRAME) {
514 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
515 mOriginalHeight);
516 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800517 mAnimRunning = false;
518 mFinishAnimReady = false;
519 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800520
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700521 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800522 mStartExitAnimation.restrictDuration(maxAnimationDuration);
523 mStartExitAnimation.scaleCurrentDuration(animationScale);
524 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
525 mStartEnterAnimation.scaleCurrentDuration(animationScale);
526 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
527 mFinishExitAnimation.scaleCurrentDuration(animationScale);
528 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
529 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700530 if (USE_CUSTOM_BLACK_FRAME) {
531 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
532 mStartFrameAnimation.scaleCurrentDuration(animationScale);
533 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
534 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
535 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800536 }
537 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
538 mRotateExitAnimation.scaleCurrentDuration(animationScale);
539 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
540 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700541 if (USE_CUSTOM_BLACK_FRAME) {
542 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
543 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
544 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800545
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700546 final int layerStack = mDisplayContent.getDisplay().getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700547 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800548 // Compute the transformation matrix that must be applied
549 // the the black frame to make it stay in the initial position
550 // before the new screen rotation. This is different than the
551 // snapshot transformation because the snapshot is always based
552 // of the native orientation of the screen, not the orientation
553 // we were last in.
554 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
555
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800556 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800557 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
558 mOriginalWidth*2, mOriginalHeight*2);
559 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Robert Carrae606b42018-02-15 15:36:23 -0800560 mCustomBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700561 SCREEN_FREEZE_LAYER_CUSTOM, mDisplayContent, false);
Robert Carrae606b42018-02-15 15:36:23 -0800562 mCustomBlackFrame.setMatrix(t, mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700563 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700564 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700565 }
566 }
567
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700568 if (!customAnim && mExitingBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700569 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700570 // Compute the transformation matrix that must be applied
571 // the the black frame to make it stay in the initial position
572 // before the new screen rotation. This is different than the
573 // snapshot transformation because the snapshot is always based
574 // of the native orientation of the screen, not the orientation
575 // we were last in.
576 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
577
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700578 final Rect outer;
579 final Rect inner;
580 if (mForceDefaultOrientation) {
581 // Going from a smaller Display to a larger Display, add curtains to sides
582 // or top and bottom. Going from a larger to smaller display will result in
583 // no BlackSurfaces being constructed.
584 outer = mCurrentDisplayRect;
585 inner = mOriginalDisplayRect;
586 } else {
587 outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
588 mOriginalWidth*2, mOriginalHeight*2);
589 inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
590 }
Robert Carrae606b42018-02-15 15:36:23 -0800591 mExitingBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700592 SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation);
Robert Carrae606b42018-02-15 15:36:23 -0800593 mExitingBlackFrame.setMatrix(t, mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700594 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700595 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700596 }
597 }
598
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700599 if (customAnim && mEnteringBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700600 try {
601 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
602 finalWidth*2, finalHeight*2);
603 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Robert Carrae606b42018-02-15 15:36:23 -0800604 mEnteringBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700605 SCREEN_FREEZE_LAYER_ENTER, mDisplayContent, false);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700606 } catch (OutOfResourcesException e) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800607 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800608 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800609 }
610
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800611 return true;
612 }
613
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800614 /**
615 * Returns true if animating.
616 */
Robert Carrae606b42018-02-15 15:36:23 -0800617 public boolean dismiss(SurfaceControl.Transaction t, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800618 float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800619 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800620 if (mSurfaceControl == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800621 // Can't do animation.
622 return false;
623 }
624 if (!mStarted) {
Robert Carrae606b42018-02-15 15:36:23 -0800625 startAnimation(t, maxAnimationDuration, animationScale, finalWidth, finalHeight,
Craig Mautner3c174372013-02-21 17:54:37 -0800626 true, exitAnim, enterAnim);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800627 }
628 if (!mStarted) {
629 return false;
630 }
631 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
632 mFinishAnimReady = true;
633 return true;
634 }
635
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800636 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800637 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800638 if (mSurfaceControl != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800639 if (SHOW_TRANSACTIONS ||
640 SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800641 " FREEZE " + mSurfaceControl + ": DESTROY");
Robert Carr5ea304d2019-02-04 16:04:55 -0800642 mSurfaceControl.remove();
Mathias Agopian29479eb2013-02-14 14:36:04 -0800643 mSurfaceControl = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800644 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700645 if (mCustomBlackFrame != null) {
646 mCustomBlackFrame.kill();
647 mCustomBlackFrame = null;
648 }
649 if (mExitingBlackFrame != null) {
650 mExitingBlackFrame.kill();
651 mExitingBlackFrame = null;
652 }
653 if (mEnteringBlackFrame != null) {
654 mEnteringBlackFrame.kill();
655 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800656 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700657 if (TWO_PHASE_ANIMATION) {
658 if (mStartExitAnimation != null) {
659 mStartExitAnimation.cancel();
660 mStartExitAnimation = null;
661 }
662 if (mStartEnterAnimation != null) {
663 mStartEnterAnimation.cancel();
664 mStartEnterAnimation = null;
665 }
666 if (mFinishExitAnimation != null) {
667 mFinishExitAnimation.cancel();
668 mFinishExitAnimation = null;
669 }
670 if (mFinishEnterAnimation != null) {
671 mFinishEnterAnimation.cancel();
672 mFinishEnterAnimation = null;
673 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800674 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700675 if (USE_CUSTOM_BLACK_FRAME) {
676 if (mStartFrameAnimation != null) {
677 mStartFrameAnimation.cancel();
678 mStartFrameAnimation = null;
679 }
680 if (mRotateFrameAnimation != null) {
681 mRotateFrameAnimation.cancel();
682 mRotateFrameAnimation = null;
683 }
684 if (mFinishFrameAnimation != null) {
685 mFinishFrameAnimation.cancel();
686 mFinishFrameAnimation = null;
687 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800688 }
689 if (mRotateExitAnimation != null) {
690 mRotateExitAnimation.cancel();
691 mRotateExitAnimation = null;
692 }
693 if (mRotateEnterAnimation != null) {
694 mRotateEnterAnimation.cancel();
695 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800696 }
697 }
698
699 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700700 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700701 }
702
Dianne Hackborn4b169692012-11-29 17:51:24 -0800703 public boolean isRotating() {
704 return mCurRotation != mOriginalRotation;
705 }
706
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700707 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700708 return (TWO_PHASE_ANIMATION &&
709 (mStartEnterAnimation != null || mStartExitAnimation != null
710 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
711 || (USE_CUSTOM_BLACK_FRAME &&
712 (mStartFrameAnimation != null || mRotateFrameAnimation != null
713 || mFinishFrameAnimation != null))
714 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800715 }
716
Craig Mautnere32c3072012-03-12 15:25:35 -0700717 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700718 if (now > mHalfwayPoint) {
719 mHalfwayPoint = Long.MAX_VALUE;
720 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800721 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
722 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
723 mFinishAnimStartTime = now;
724 }
725
Craig Mautner7d8df392012-04-06 15:26:23 -0700726 if (TWO_PHASE_ANIMATION) {
727 mMoreStartExit = false;
728 if (mStartExitAnimation != null) {
729 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
730 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
731 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800732
Craig Mautner7d8df392012-04-06 15:26:23 -0700733 mMoreStartEnter = false;
734 if (mStartEnterAnimation != null) {
735 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
736 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
737 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800738 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700739 if (USE_CUSTOM_BLACK_FRAME) {
740 mMoreStartFrame = false;
741 if (mStartFrameAnimation != null) {
742 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
743 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
744 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800745 }
746
Craig Mautnerdbb79912012-03-01 18:59:14 -0800747 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
748 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
749
Craig Mautner7d8df392012-04-06 15:26:23 -0700750 if (TWO_PHASE_ANIMATION) {
751 mMoreFinishExit = false;
752 if (mFinishExitAnimation != null) {
753 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
754 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
755 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800756
Craig Mautner7d8df392012-04-06 15:26:23 -0700757 mMoreFinishEnter = false;
758 if (mFinishEnterAnimation != null) {
759 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
760 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
761 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800762 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700763 if (USE_CUSTOM_BLACK_FRAME) {
764 mMoreFinishFrame = false;
765 if (mFinishFrameAnimation != null) {
766 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
767 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
768 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800769 }
770
Craig Mautnerdbb79912012-03-01 18:59:14 -0800771 mMoreRotateExit = false;
772 if (mRotateExitAnimation != null) {
773 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
774 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700775 }
776
777 mMoreRotateEnter = false;
778 if (mRotateEnterAnimation != null) {
779 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
780 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
781 }
782
Craig Mautner7d8df392012-04-06 15:26:23 -0700783 if (USE_CUSTOM_BLACK_FRAME) {
784 mMoreRotateFrame = false;
785 if (mRotateFrameAnimation != null) {
786 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
787 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
788 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700789 }
790
Craig Mautner7d8df392012-04-06 15:26:23 -0700791 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
792 if (TWO_PHASE_ANIMATION) {
793 if (mStartExitAnimation != null) {
794 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
795 mStartExitAnimation.cancel();
796 mStartExitAnimation = null;
797 mStartExitTransformation.clear();
798 }
799 if (mFinishExitAnimation != null) {
800 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
801 mFinishExitAnimation.cancel();
802 mFinishExitAnimation = null;
803 mFinishExitTransformation.clear();
804 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700805 }
806 if (mRotateExitAnimation != null) {
807 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800808 mRotateExitAnimation.cancel();
809 mRotateExitAnimation = null;
810 mRotateExitTransformation.clear();
811 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800812 }
813
Craig Mautner7d8df392012-04-06 15:26:23 -0700814 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
815 if (TWO_PHASE_ANIMATION) {
816 if (mStartEnterAnimation != null) {
817 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
818 mStartEnterAnimation.cancel();
819 mStartEnterAnimation = null;
820 mStartEnterTransformation.clear();
821 }
822 if (mFinishEnterAnimation != null) {
823 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
824 mFinishEnterAnimation.cancel();
825 mFinishEnterAnimation = null;
826 mFinishEnterTransformation.clear();
827 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700828 }
829 if (mRotateEnterAnimation != null) {
830 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800831 mRotateEnterAnimation.cancel();
832 mRotateEnterAnimation = null;
833 mRotateEnterTransformation.clear();
834 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800835 }
836
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700837 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
838 if (mStartFrameAnimation != null) {
839 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
840 mStartFrameAnimation.cancel();
841 mStartFrameAnimation = null;
842 mStartFrameTransformation.clear();
843 }
844 if (mFinishFrameAnimation != null) {
845 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
846 mFinishFrameAnimation.cancel();
847 mFinishFrameAnimation = null;
848 mFinishFrameTransformation.clear();
849 }
850 if (mRotateFrameAnimation != null) {
851 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800852 mRotateFrameAnimation.cancel();
853 mRotateFrameAnimation = null;
854 mRotateFrameTransformation.clear();
855 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800856 }
857
858 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800859 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700860 if (TWO_PHASE_ANIMATION) {
861 mExitTransformation.compose(mStartExitTransformation);
862 mExitTransformation.compose(mFinishExitTransformation);
863
864 mEnterTransformation.compose(mStartEnterTransformation);
865 mEnterTransformation.compose(mFinishEnterTransformation);
866 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800867
868 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
869 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700870
871 if (USE_CUSTOM_BLACK_FRAME) {
872 //mFrameTransformation.set(mRotateExitTransformation);
873 //mFrameTransformation.compose(mStartExitTransformation);
874 //mFrameTransformation.compose(mFinishExitTransformation);
875 mFrameTransformation.set(mRotateFrameTransformation);
876 mFrameTransformation.compose(mStartFrameTransformation);
877 mFrameTransformation.compose(mFinishFrameTransformation);
878 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
879 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
880 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800881
Craig Mautner7d8df392012-04-06 15:26:23 -0700882 final boolean more = (TWO_PHASE_ANIMATION
883 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
884 || (USE_CUSTOM_BLACK_FRAME
885 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
Igor Murashkina86ab6402013-08-30 12:58:36 -0700886 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800887 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800888
889 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
890
891 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
892
893 return more;
894 }
895
Robert Carrae606b42018-02-15 15:36:23 -0800896 void updateSurfaces(SurfaceControl.Transaction t) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700897 if (!mStarted) {
898 return;
899 }
900
Mathias Agopian29479eb2013-02-14 14:36:04 -0800901 if (mSurfaceControl != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700902 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800903 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
Robert Carrae606b42018-02-15 15:36:23 -0800904 t.hide(mSurfaceControl);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800905 }
906 }
907
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700908 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700909 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800910 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Robert Carrae606b42018-02-15 15:36:23 -0800911 mCustomBlackFrame.hide(t);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700912 } else {
Robert Carrae606b42018-02-15 15:36:23 -0800913 mCustomBlackFrame.setMatrix(t, mFrameTransformation.getMatrix());
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700914 }
915 }
916
917 if (mExitingBlackFrame != null) {
918 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
919 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
Robert Carrae606b42018-02-15 15:36:23 -0800920 mExitingBlackFrame.hide(t);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700921 } else {
922 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
Robert Carrae606b42018-02-15 15:36:23 -0800923 mExitingBlackFrame.setMatrix(t, mExitFrameFinalMatrix);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700924 if (mForceDefaultOrientation) {
Robert Carrae606b42018-02-15 15:36:23 -0800925 mExitingBlackFrame.setAlpha(t, mExitTransformation.getAlpha());
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700926 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700927 }
928 }
929
930 if (mEnteringBlackFrame != null) {
931 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
932 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
Robert Carrae606b42018-02-15 15:36:23 -0800933 mEnteringBlackFrame.hide(t);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700934 } else {
Robert Carrae606b42018-02-15 15:36:23 -0800935 mEnteringBlackFrame.setMatrix(t, mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800936 }
937 }
938
Jorim Jaggi4e0300d2019-07-22 17:17:42 +0200939 t.setEarlyWakeup();
Robert Carrae606b42018-02-15 15:36:23 -0800940 setSnapshotTransform(t, mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800941 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700942
Craig Mautnere32c3072012-03-12 15:25:35 -0700943 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700944 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800945 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800946 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800947 return false;
948 }
949
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800950 if (!mAnimRunning) {
951 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700952 if (TWO_PHASE_ANIMATION) {
953 if (mStartEnterAnimation != null) {
954 mStartEnterAnimation.setStartTime(now);
955 }
956 if (mStartExitAnimation != null) {
957 mStartExitAnimation.setStartTime(now);
958 }
959 if (mFinishEnterAnimation != null) {
960 mFinishEnterAnimation.setStartTime(0);
961 }
962 if (mFinishExitAnimation != null) {
963 mFinishExitAnimation.setStartTime(0);
964 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700965 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700966 if (USE_CUSTOM_BLACK_FRAME) {
967 if (mStartFrameAnimation != null) {
968 mStartFrameAnimation.setStartTime(now);
969 }
970 if (mFinishFrameAnimation != null) {
971 mFinishFrameAnimation.setStartTime(0);
972 }
973 if (mRotateFrameAnimation != null) {
974 mRotateFrameAnimation.setStartTime(now);
975 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800976 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800977 if (mRotateEnterAnimation != null) {
978 mRotateEnterAnimation.setStartTime(now);
979 }
980 if (mRotateExitAnimation != null) {
981 mRotateExitAnimation.setStartTime(now);
982 }
983 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -0700984 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800985 }
Craig Mautnere32c3072012-03-12 15:25:35 -0700986
987 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800988 }
989
990 public Transformation getEnterTransformation() {
991 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800992 }
993}