blob: 0be9736e9d769bd7e4e28f01837a61c1925406dc [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 {
Peiyong Linccc06b62019-06-25 17:31:09 -0700282 surface.attachAndQueueBufferWithColorSpace(gb.getGraphicBuffer(),
283 gb.getColorSpace());
Robert Carr66b5664f2019-04-02 14:18:56 -0700284 } catch (RuntimeException e) {
285 Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage());
286 }
287 // If the screenshot contains secure layers, we have to make sure the
288 // screenshot surface we display it in also has FLAG_SECURE so that
289 // the user can not screenshot secure layers via the screenshot surface.
290 if (gb.containsSecureLayers()) {
291 t.setSecure(mSurfaceControl, true);
292 }
Garfield Tanf4ac3072018-03-16 13:03:52 -0700293 t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT);
294 t.setAlpha(mSurfaceControl, 0);
295 t.show(mSurfaceControl);
Garfield Tanf4ac3072018-03-16 13:03:52 -0700296 } else {
Riddle Hsu654a6f92018-07-13 22:59:36 +0800297 Slog.w(TAG, "Unable to take screenshot of display " + displayId);
Garfield Tanf4ac3072018-03-16 13:03:52 -0700298 }
Riddle Hsu654a6f92018-07-13 22:59:36 +0800299 surface.destroy();
Robert Carrae606b42018-02-15 15:36:23 -0800300 } catch (OutOfResourcesException e) {
301 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800302 }
Robert Carrae606b42018-02-15 15:36:23 -0800303
304 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
305 " FREEZE " + mSurfaceControl + ": CREATE");
306 setRotation(t, originalRotation);
307 t.apply();
Dianne Hackborna1111872010-11-23 20:55:11 -0800308 }
309
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800310 boolean hasScreenshot() {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800311 return mSurfaceControl != null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800312 }
313
Robert Carrae606b42018-02-15 15:36:23 -0800314 private void setSnapshotTransform(SurfaceControl.Transaction t, Matrix matrix, float alpha) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800315 if (mSurfaceControl != null) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800316 matrix.getValues(mTmpFloats);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700317 float x = mTmpFloats[Matrix.MTRANS_X];
318 float y = mTmpFloats[Matrix.MTRANS_Y];
319 if (mForceDefaultOrientation) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800320 mDisplayContent.getBounds(mCurrentDisplayRect);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700321 x -= mCurrentDisplayRect.left;
322 y -= mCurrentDisplayRect.top;
323 }
Robert Carrae606b42018-02-15 15:36:23 -0800324 t.setPosition(mSurfaceControl, x, y);
325 t.setMatrix(mSurfaceControl,
Dianne Hackborn352cc982011-01-04 11:34:18 -0800326 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
327 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
Robert Carrae606b42018-02-15 15:36:23 -0800328 t.setAlpha(mSurfaceControl, alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800329 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800330 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
331 float[] dstPnts = new float[4];
332 matrix.mapPoints(dstPnts, srcPnts);
333 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
334 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
335 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
336 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
337 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800338 }
339 }
340
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800341 public static void createRotationMatrix(int rotation, int width, int height,
342 Matrix outMatrix) {
343 switch (rotation) {
344 case Surface.ROTATION_0:
345 outMatrix.reset();
346 break;
347 case Surface.ROTATION_90:
348 outMatrix.setRotate(90, 0, 0);
349 outMatrix.postTranslate(height, 0);
350 break;
351 case Surface.ROTATION_180:
352 outMatrix.setRotate(180, 0, 0);
353 outMatrix.postTranslate(width, height);
354 break;
355 case Surface.ROTATION_270:
356 outMatrix.setRotate(270, 0, 0);
357 outMatrix.postTranslate(0, width);
358 break;
359 }
360 }
361
Robert Carrae606b42018-02-15 15:36:23 -0800362 private void setRotation(SurfaceControl.Transaction t, int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800363 mCurRotation = rotation;
364
365 // Compute the transformation matrix that must be applied
366 // to the snapshot to make it stay in the same original position
367 // with the current screen rotation.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800368 int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800369 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800370
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800371 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Robert Carrae606b42018-02-15 15:36:23 -0800372 setSnapshotTransform(t, mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800373 }
374
Robert Carrae606b42018-02-15 15:36:23 -0800375 public boolean setRotation(SurfaceControl.Transaction t, int rotation,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800376 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Robert Carrae606b42018-02-15 15:36:23 -0800377 setRotation(t, rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700378 if (TWO_PHASE_ANIMATION) {
Robert Carrae606b42018-02-15 15:36:23 -0800379 return startAnimation(t, maxAnimationDuration, animationScale,
Craig Mautner3c174372013-02-21 17:54:37 -0800380 finalWidth, finalHeight, false, 0, 0);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700381 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700382
383 // Don't start animation yet.
384 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800385 }
386
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800387 /**
388 * Returns true if animating.
389 */
Robert Carrae606b42018-02-15 15:36:23 -0800390 private boolean startAnimation(SurfaceControl.Transaction t, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800391 float animationScale, int finalWidth, int finalHeight, boolean dismissing,
392 int exitAnim, int enterAnim) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800393 if (mSurfaceControl == null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800394 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800395 return false;
396 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800397 if (mStarted) {
398 return true;
399 }
400
401 mStarted = true;
402
403 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800404
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800405 // Figure out how the screen has moved from the original rotation.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800406 int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800407
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700408 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
409 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800410 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
411 firstStart = true;
412 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
413 com.android.internal.R.anim.screen_rotate_start_exit);
414 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
415 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700416 if (USE_CUSTOM_BLACK_FRAME) {
417 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
418 com.android.internal.R.anim.screen_rotate_start_frame);
419 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800420 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
421 com.android.internal.R.anim.screen_rotate_finish_exit);
422 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
423 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700424 if (USE_CUSTOM_BLACK_FRAME) {
425 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
426 com.android.internal.R.anim.screen_rotate_finish_frame);
427 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800428 }
429
430 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
431 + finalWidth + " finalHeight=" + finalHeight
432 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
433
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700434 final boolean customAnim;
Craig Mautner3c174372013-02-21 17:54:37 -0800435 if (exitAnim != 0 && enterAnim != 0) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700436 customAnim = true;
Craig Mautner3c174372013-02-21 17:54:37 -0800437 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
438 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700439 } else {
440 customAnim = false;
441 switch (delta) {
442 case Surface.ROTATION_0:
443 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
444 com.android.internal.R.anim.screen_rotate_0_exit);
445 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
446 com.android.internal.R.anim.screen_rotate_0_enter);
447 if (USE_CUSTOM_BLACK_FRAME) {
448 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
449 com.android.internal.R.anim.screen_rotate_0_frame);
450 }
451 break;
452 case Surface.ROTATION_90:
453 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
454 com.android.internal.R.anim.screen_rotate_plus_90_exit);
455 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
456 com.android.internal.R.anim.screen_rotate_plus_90_enter);
457 if (USE_CUSTOM_BLACK_FRAME) {
458 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
459 com.android.internal.R.anim.screen_rotate_plus_90_frame);
460 }
461 break;
462 case Surface.ROTATION_180:
463 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
464 com.android.internal.R.anim.screen_rotate_180_exit);
465 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
466 com.android.internal.R.anim.screen_rotate_180_enter);
467 if (USE_CUSTOM_BLACK_FRAME) {
468 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
469 com.android.internal.R.anim.screen_rotate_180_frame);
470 }
471 break;
472 case Surface.ROTATION_270:
473 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
474 com.android.internal.R.anim.screen_rotate_minus_90_exit);
475 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
476 com.android.internal.R.anim.screen_rotate_minus_90_enter);
477 if (USE_CUSTOM_BLACK_FRAME) {
478 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
479 com.android.internal.R.anim.screen_rotate_minus_90_frame);
480 }
481 break;
482 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800483 }
484
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800485 // Initialize the animations. This is a hack, redefining what "parent"
486 // means to allow supplying the last and next size. In this definition
487 // "%p" is the original (let's call it "previous") size, and "%" is the
488 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700489 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700490 // Compute partial steps between original and final sizes. These
491 // are used for the dimensions of the exiting and entering elements,
492 // so they are never stretched too significantly.
493 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
494 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
495
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800496 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
497 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800498 halfWidth, halfHeight);
499 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800500 mOriginalWidth, mOriginalHeight);
501 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800502 halfWidth, halfHeight);
503 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800504 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700505 if (USE_CUSTOM_BLACK_FRAME) {
506 mStartFrameAnimation.initialize(finalWidth, finalHeight,
507 mOriginalWidth, mOriginalHeight);
508 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
509 mOriginalWidth, mOriginalHeight);
510 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800511 }
512 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
513 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700514 if (USE_CUSTOM_BLACK_FRAME) {
515 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
516 mOriginalHeight);
517 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800518 mAnimRunning = false;
519 mFinishAnimReady = false;
520 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800521
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700522 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800523 mStartExitAnimation.restrictDuration(maxAnimationDuration);
524 mStartExitAnimation.scaleCurrentDuration(animationScale);
525 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
526 mStartEnterAnimation.scaleCurrentDuration(animationScale);
527 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
528 mFinishExitAnimation.scaleCurrentDuration(animationScale);
529 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
530 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700531 if (USE_CUSTOM_BLACK_FRAME) {
532 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
533 mStartFrameAnimation.scaleCurrentDuration(animationScale);
534 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
535 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
536 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800537 }
538 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
539 mRotateExitAnimation.scaleCurrentDuration(animationScale);
540 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
541 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700542 if (USE_CUSTOM_BLACK_FRAME) {
543 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
544 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
545 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800546
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700547 final int layerStack = mDisplayContent.getDisplay().getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700548 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800549 // Compute the transformation matrix that must be applied
550 // the the black frame to make it stay in the initial position
551 // before the new screen rotation. This is different than the
552 // snapshot transformation because the snapshot is always based
553 // of the native orientation of the screen, not the orientation
554 // we were last in.
555 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
556
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800557 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800558 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
559 mOriginalWidth*2, mOriginalHeight*2);
560 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Robert Carrae606b42018-02-15 15:36:23 -0800561 mCustomBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700562 SCREEN_FREEZE_LAYER_CUSTOM, mDisplayContent, false);
Robert Carrae606b42018-02-15 15:36:23 -0800563 mCustomBlackFrame.setMatrix(t, mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700564 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700565 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700566 }
567 }
568
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700569 if (!customAnim && mExitingBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700570 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700571 // Compute the transformation matrix that must be applied
572 // the the black frame to make it stay in the initial position
573 // before the new screen rotation. This is different than the
574 // snapshot transformation because the snapshot is always based
575 // of the native orientation of the screen, not the orientation
576 // we were last in.
577 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
578
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700579 final Rect outer;
580 final Rect inner;
581 if (mForceDefaultOrientation) {
582 // Going from a smaller Display to a larger Display, add curtains to sides
583 // or top and bottom. Going from a larger to smaller display will result in
584 // no BlackSurfaces being constructed.
585 outer = mCurrentDisplayRect;
586 inner = mOriginalDisplayRect;
587 } else {
588 outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
589 mOriginalWidth*2, mOriginalHeight*2);
590 inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
591 }
Robert Carrae606b42018-02-15 15:36:23 -0800592 mExitingBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700593 SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation);
Robert Carrae606b42018-02-15 15:36:23 -0800594 mExitingBlackFrame.setMatrix(t, mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700595 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700596 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700597 }
598 }
599
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700600 if (customAnim && mEnteringBlackFrame == null) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700601 try {
602 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
603 finalWidth*2, finalHeight*2);
604 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Robert Carrae606b42018-02-15 15:36:23 -0800605 mEnteringBlackFrame = new BlackFrame(t, outer, inner,
Robert Carrb1579c82017-09-05 14:54:47 -0700606 SCREEN_FREEZE_LAYER_ENTER, mDisplayContent, false);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700607 } catch (OutOfResourcesException e) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800608 Slog.w(TAG, "Unable to allocate black surface", e);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800609 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800610 }
611
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800612 return true;
613 }
614
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800615 /**
616 * Returns true if animating.
617 */
Robert Carrae606b42018-02-15 15:36:23 -0800618 public boolean dismiss(SurfaceControl.Transaction t, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800619 float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800620 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800621 if (mSurfaceControl == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800622 // Can't do animation.
623 return false;
624 }
625 if (!mStarted) {
Robert Carrae606b42018-02-15 15:36:23 -0800626 startAnimation(t, maxAnimationDuration, animationScale, finalWidth, finalHeight,
Craig Mautner3c174372013-02-21 17:54:37 -0800627 true, exitAnim, enterAnim);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800628 }
629 if (!mStarted) {
630 return false;
631 }
632 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
633 mFinishAnimReady = true;
634 return true;
635 }
636
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800637 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800638 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800639 if (mSurfaceControl != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800640 if (SHOW_TRANSACTIONS ||
641 SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800642 " FREEZE " + mSurfaceControl + ": DESTROY");
Robert Carr5ea304d2019-02-04 16:04:55 -0800643 mSurfaceControl.remove();
Mathias Agopian29479eb2013-02-14 14:36:04 -0800644 mSurfaceControl = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800645 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700646 if (mCustomBlackFrame != null) {
647 mCustomBlackFrame.kill();
648 mCustomBlackFrame = null;
649 }
650 if (mExitingBlackFrame != null) {
651 mExitingBlackFrame.kill();
652 mExitingBlackFrame = null;
653 }
654 if (mEnteringBlackFrame != null) {
655 mEnteringBlackFrame.kill();
656 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800657 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700658 if (TWO_PHASE_ANIMATION) {
659 if (mStartExitAnimation != null) {
660 mStartExitAnimation.cancel();
661 mStartExitAnimation = null;
662 }
663 if (mStartEnterAnimation != null) {
664 mStartEnterAnimation.cancel();
665 mStartEnterAnimation = null;
666 }
667 if (mFinishExitAnimation != null) {
668 mFinishExitAnimation.cancel();
669 mFinishExitAnimation = null;
670 }
671 if (mFinishEnterAnimation != null) {
672 mFinishEnterAnimation.cancel();
673 mFinishEnterAnimation = null;
674 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800675 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700676 if (USE_CUSTOM_BLACK_FRAME) {
677 if (mStartFrameAnimation != null) {
678 mStartFrameAnimation.cancel();
679 mStartFrameAnimation = null;
680 }
681 if (mRotateFrameAnimation != null) {
682 mRotateFrameAnimation.cancel();
683 mRotateFrameAnimation = null;
684 }
685 if (mFinishFrameAnimation != null) {
686 mFinishFrameAnimation.cancel();
687 mFinishFrameAnimation = null;
688 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800689 }
690 if (mRotateExitAnimation != null) {
691 mRotateExitAnimation.cancel();
692 mRotateExitAnimation = null;
693 }
694 if (mRotateEnterAnimation != null) {
695 mRotateEnterAnimation.cancel();
696 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800697 }
698 }
699
700 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700701 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700702 }
703
Dianne Hackborn4b169692012-11-29 17:51:24 -0800704 public boolean isRotating() {
705 return mCurRotation != mOriginalRotation;
706 }
707
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700708 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700709 return (TWO_PHASE_ANIMATION &&
710 (mStartEnterAnimation != null || mStartExitAnimation != null
711 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
712 || (USE_CUSTOM_BLACK_FRAME &&
713 (mStartFrameAnimation != null || mRotateFrameAnimation != null
714 || mFinishFrameAnimation != null))
715 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800716 }
717
Craig Mautnere32c3072012-03-12 15:25:35 -0700718 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700719 if (now > mHalfwayPoint) {
720 mHalfwayPoint = Long.MAX_VALUE;
721 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800722 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
723 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
724 mFinishAnimStartTime = now;
725 }
726
Craig Mautner7d8df392012-04-06 15:26:23 -0700727 if (TWO_PHASE_ANIMATION) {
728 mMoreStartExit = false;
729 if (mStartExitAnimation != null) {
730 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
731 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
732 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800733
Craig Mautner7d8df392012-04-06 15:26:23 -0700734 mMoreStartEnter = false;
735 if (mStartEnterAnimation != null) {
736 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
737 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
738 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800739 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700740 if (USE_CUSTOM_BLACK_FRAME) {
741 mMoreStartFrame = false;
742 if (mStartFrameAnimation != null) {
743 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
744 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
745 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800746 }
747
Craig Mautnerdbb79912012-03-01 18:59:14 -0800748 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
749 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
750
Craig Mautner7d8df392012-04-06 15:26:23 -0700751 if (TWO_PHASE_ANIMATION) {
752 mMoreFinishExit = false;
753 if (mFinishExitAnimation != null) {
754 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
755 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
756 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800757
Craig Mautner7d8df392012-04-06 15:26:23 -0700758 mMoreFinishEnter = false;
759 if (mFinishEnterAnimation != null) {
760 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
761 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
762 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800763 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700764 if (USE_CUSTOM_BLACK_FRAME) {
765 mMoreFinishFrame = false;
766 if (mFinishFrameAnimation != null) {
767 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
768 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
769 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800770 }
771
Craig Mautnerdbb79912012-03-01 18:59:14 -0800772 mMoreRotateExit = false;
773 if (mRotateExitAnimation != null) {
774 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
775 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700776 }
777
778 mMoreRotateEnter = false;
779 if (mRotateEnterAnimation != null) {
780 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
781 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
782 }
783
Craig Mautner7d8df392012-04-06 15:26:23 -0700784 if (USE_CUSTOM_BLACK_FRAME) {
785 mMoreRotateFrame = false;
786 if (mRotateFrameAnimation != null) {
787 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
788 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
789 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700790 }
791
Craig Mautner7d8df392012-04-06 15:26:23 -0700792 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
793 if (TWO_PHASE_ANIMATION) {
794 if (mStartExitAnimation != null) {
795 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
796 mStartExitAnimation.cancel();
797 mStartExitAnimation = null;
798 mStartExitTransformation.clear();
799 }
800 if (mFinishExitAnimation != null) {
801 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
802 mFinishExitAnimation.cancel();
803 mFinishExitAnimation = null;
804 mFinishExitTransformation.clear();
805 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700806 }
807 if (mRotateExitAnimation != null) {
808 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800809 mRotateExitAnimation.cancel();
810 mRotateExitAnimation = null;
811 mRotateExitTransformation.clear();
812 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800813 }
814
Craig Mautner7d8df392012-04-06 15:26:23 -0700815 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
816 if (TWO_PHASE_ANIMATION) {
817 if (mStartEnterAnimation != null) {
818 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
819 mStartEnterAnimation.cancel();
820 mStartEnterAnimation = null;
821 mStartEnterTransformation.clear();
822 }
823 if (mFinishEnterAnimation != null) {
824 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
825 mFinishEnterAnimation.cancel();
826 mFinishEnterAnimation = null;
827 mFinishEnterTransformation.clear();
828 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700829 }
830 if (mRotateEnterAnimation != null) {
831 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800832 mRotateEnterAnimation.cancel();
833 mRotateEnterAnimation = null;
834 mRotateEnterTransformation.clear();
835 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800836 }
837
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700838 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
839 if (mStartFrameAnimation != null) {
840 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
841 mStartFrameAnimation.cancel();
842 mStartFrameAnimation = null;
843 mStartFrameTransformation.clear();
844 }
845 if (mFinishFrameAnimation != null) {
846 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
847 mFinishFrameAnimation.cancel();
848 mFinishFrameAnimation = null;
849 mFinishFrameTransformation.clear();
850 }
851 if (mRotateFrameAnimation != null) {
852 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800853 mRotateFrameAnimation.cancel();
854 mRotateFrameAnimation = null;
855 mRotateFrameTransformation.clear();
856 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800857 }
858
859 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800860 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700861 if (TWO_PHASE_ANIMATION) {
862 mExitTransformation.compose(mStartExitTransformation);
863 mExitTransformation.compose(mFinishExitTransformation);
864
865 mEnterTransformation.compose(mStartEnterTransformation);
866 mEnterTransformation.compose(mFinishEnterTransformation);
867 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800868
869 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
870 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700871
872 if (USE_CUSTOM_BLACK_FRAME) {
873 //mFrameTransformation.set(mRotateExitTransformation);
874 //mFrameTransformation.compose(mStartExitTransformation);
875 //mFrameTransformation.compose(mFinishExitTransformation);
876 mFrameTransformation.set(mRotateFrameTransformation);
877 mFrameTransformation.compose(mStartFrameTransformation);
878 mFrameTransformation.compose(mFinishFrameTransformation);
879 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
880 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
881 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800882
Craig Mautner7d8df392012-04-06 15:26:23 -0700883 final boolean more = (TWO_PHASE_ANIMATION
884 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
885 || (USE_CUSTOM_BLACK_FRAME
886 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
Igor Murashkina86ab6402013-08-30 12:58:36 -0700887 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800888 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800889
890 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
891
892 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
893
894 return more;
895 }
896
Robert Carrae606b42018-02-15 15:36:23 -0800897 void updateSurfaces(SurfaceControl.Transaction t) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700898 if (!mStarted) {
899 return;
900 }
901
Mathias Agopian29479eb2013-02-14 14:36:04 -0800902 if (mSurfaceControl != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700903 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800904 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
Robert Carrae606b42018-02-15 15:36:23 -0800905 t.hide(mSurfaceControl);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800906 }
907 }
908
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700909 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700910 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800911 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Robert Carrae606b42018-02-15 15:36:23 -0800912 mCustomBlackFrame.hide(t);
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700913 } else {
Robert Carrae606b42018-02-15 15:36:23 -0800914 mCustomBlackFrame.setMatrix(t, mFrameTransformation.getMatrix());
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700915 }
916 }
917
918 if (mExitingBlackFrame != null) {
919 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
920 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
Robert Carrae606b42018-02-15 15:36:23 -0800921 mExitingBlackFrame.hide(t);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700922 } else {
923 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
Robert Carrae606b42018-02-15 15:36:23 -0800924 mExitingBlackFrame.setMatrix(t, mExitFrameFinalMatrix);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700925 if (mForceDefaultOrientation) {
Robert Carrae606b42018-02-15 15:36:23 -0800926 mExitingBlackFrame.setAlpha(t, mExitTransformation.getAlpha());
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700927 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700928 }
929 }
930
931 if (mEnteringBlackFrame != null) {
932 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
933 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
Robert Carrae606b42018-02-15 15:36:23 -0800934 mEnteringBlackFrame.hide(t);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700935 } else {
Robert Carrae606b42018-02-15 15:36:23 -0800936 mEnteringBlackFrame.setMatrix(t, mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800937 }
938 }
939
Jorim Jaggi4e0300d2019-07-22 17:17:42 +0200940 t.setEarlyWakeup();
Robert Carrae606b42018-02-15 15:36:23 -0800941 setSnapshotTransform(t, mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800942 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700943
Craig Mautnere32c3072012-03-12 15:25:35 -0700944 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700945 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800946 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800947 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800948 return false;
949 }
950
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800951 if (!mAnimRunning) {
952 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700953 if (TWO_PHASE_ANIMATION) {
954 if (mStartEnterAnimation != null) {
955 mStartEnterAnimation.setStartTime(now);
956 }
957 if (mStartExitAnimation != null) {
958 mStartExitAnimation.setStartTime(now);
959 }
960 if (mFinishEnterAnimation != null) {
961 mFinishEnterAnimation.setStartTime(0);
962 }
963 if (mFinishExitAnimation != null) {
964 mFinishExitAnimation.setStartTime(0);
965 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700966 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700967 if (USE_CUSTOM_BLACK_FRAME) {
968 if (mStartFrameAnimation != null) {
969 mStartFrameAnimation.setStartTime(now);
970 }
971 if (mFinishFrameAnimation != null) {
972 mFinishFrameAnimation.setStartTime(0);
973 }
974 if (mRotateFrameAnimation != null) {
975 mRotateFrameAnimation.setStartTime(now);
976 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800977 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800978 if (mRotateEnterAnimation != null) {
979 mRotateEnterAnimation.setStartTime(now);
980 }
981 if (mRotateExitAnimation != null) {
982 mRotateExitAnimation.setStartTime(now);
983 }
984 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -0700985 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800986 }
Craig Mautnere32c3072012-03-12 15:25:35 -0700987
988 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800989 }
990
991 public Transformation getEnterTransformation() {
992 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -0800993 }
994}