blob: 8e99be83d918b2d892bee285bc795ac843d96d15 [file] [log] [blame]
Dianne Hackborna1111872010-11-23 20:55:11 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080017package com.android.server.wm;
Dianne Hackborna1111872010-11-23 20:55:11 -080018
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080019import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
20import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
21import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
22import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
23import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Chong Zhang97782b42015-10-07 16:01:23 -070024import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
Chong Zhang97782b42015-10-07 16:01:23 -070025import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER;
Steven Timotiusf2d68892017-08-28 17:00:01 -070026import static com.android.server.wm.proto.ScreenRotationAnimationProto.ANIMATION_RUNNING;
27import static com.android.server.wm.proto.ScreenRotationAnimationProto.STARTED;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080028
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080029import android.content.Context;
Dianne Hackborna1111872010-11-23 20:55:11 -080030import android.graphics.Matrix;
Dianne Hackborna1111872010-11-23 20:55:11 -080031import android.graphics.PixelFormat;
32import android.graphics.Rect;
Dianne Hackborna1111872010-11-23 20:55:11 -080033import android.util.Slog;
Steven Timotiusf2d68892017-08-28 17:00:01 -070034import android.util.proto.ProtoOutputStream;
Craig Mautner6881a102012-07-27 13:04:51 -070035import android.view.Display;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070036import android.view.DisplayInfo;
Dianne Hackborna1111872010-11-23 20:55:11 -080037import android.view.Surface;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080038import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080039import android.view.SurfaceControl;
Dianne Hackborna1111872010-11-23 20:55:11 -080040import android.view.SurfaceSession;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080041import android.view.animation.Animation;
42import android.view.animation.AnimationUtils;
43import android.view.animation.Transformation;
Dianne Hackborna1111872010-11-23 20:55:11 -080044
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080045import java.io.PrintWriter;
46
Craig Mautnere32c3072012-03-12 15:25:35 -070047class ScreenRotationAnimation {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080048 static final String TAG = TAG_WITH_CLASS_NAME ? "ScreenRotationAnimation" : TAG_WM;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080049 static final boolean DEBUG_STATE = false;
50 static final boolean DEBUG_TRANSFORMS = false;
Dianne Hackborn187ae2102012-04-11 18:12:06 -070051 static final boolean TWO_PHASE_ANIMATION = false;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070052 static final boolean USE_CUSTOM_BLACK_FRAME = false;
Dianne Hackborna1111872010-11-23 20:55:11 -080053
Chong Zhang97782b42015-10-07 16:01:23 -070054 /*
55 * Layers for screen rotation animation. We put these layers above
56 * WINDOW_FREEZE_LAYER so that screen freeze will cover all windows.
57 */
58 static final int SCREEN_FREEZE_LAYER_BASE = WINDOW_FREEZE_LAYER + TYPE_LAYER_MULTIPLIER;
59 static final int SCREEN_FREEZE_LAYER_ENTER = SCREEN_FREEZE_LAYER_BASE;
60 static final int SCREEN_FREEZE_LAYER_SCREENSHOT = SCREEN_FREEZE_LAYER_BASE + 1;
61 static final int SCREEN_FREEZE_LAYER_EXIT = SCREEN_FREEZE_LAYER_BASE + 2;
62 static final int SCREEN_FREEZE_LAYER_CUSTOM = SCREEN_FREEZE_LAYER_BASE + 3;
Dianne Hackborn50660e22011-02-02 17:12:25 -080063
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080064 final Context mContext;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070065 final DisplayContent mDisplayContent;
Mathias Agopian29479eb2013-02-14 14:36:04 -080066 SurfaceControl mSurfaceControl;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070067 BlackFrame mCustomBlackFrame;
68 BlackFrame mExitingBlackFrame;
69 BlackFrame mEnteringBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080070 int mWidth, mHeight;
71
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080072 int mOriginalRotation;
73 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080074 int mCurRotation;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070075 Rect mOriginalDisplayRect = new Rect();
76 Rect mCurrentDisplayRect = new Rect();
Dianne Hackborna1111872010-11-23 20:55:11 -080077
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080078 // For all animations, "exit" is for the UI elements that are going
79 // away (that is the snapshot of the old screen), and "enter" is for
80 // the new UI elements that are appearing (that is the active windows
81 // in their final orientation).
82
83 // The starting animation for the exiting and entering elements. This
84 // animation applies a transformation while the rotation is in progress.
85 // It is started immediately, before the new entering UI is ready.
86 Animation mStartExitAnimation;
87 final Transformation mStartExitTransformation = new Transformation();
88 Animation mStartEnterAnimation;
89 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080090 Animation mStartFrameAnimation;
91 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080092
93 // The finishing animation for the exiting and entering elements. This
94 // animation needs to undo the transformation of the starting animation.
95 // It starts running once the new rotation UI elements are ready to be
96 // displayed.
97 Animation mFinishExitAnimation;
98 final Transformation mFinishExitTransformation = new Transformation();
99 Animation mFinishEnterAnimation;
100 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800101 Animation mFinishFrameAnimation;
102 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800103
104 // The current active animation to move from the old to the new rotated
105 // state. Which animation is run here will depend on the old and new
106 // rotations.
107 Animation mRotateExitAnimation;
108 final Transformation mRotateExitTransformation = new Transformation();
109 Animation mRotateEnterAnimation;
110 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800111 Animation mRotateFrameAnimation;
112 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800113
114 // A previously running rotate animation. This will be used if we need
115 // to switch to a new rotation before finishing the previous one.
116 Animation mLastRotateExitAnimation;
117 final Transformation mLastRotateExitTransformation = new Transformation();
118 Animation mLastRotateEnterAnimation;
119 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800120 Animation mLastRotateFrameAnimation;
121 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800122
123 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800124 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800125 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800126 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800127
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800128 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800129 boolean mAnimRunning;
130 boolean mFinishAnimReady;
131 long mFinishAnimStartTime;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700132 boolean mForceDefaultOrientation;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800133
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800134 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800135 final Matrix mSnapshotInitialMatrix = new Matrix();
136 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700137 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800138 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800139 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800140 private boolean mMoreRotateEnter;
141 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800142 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800143 private boolean mMoreFinishEnter;
144 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800145 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800146 private boolean mMoreStartEnter;
147 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800148 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700149 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800150
Robert Carr68e5c9e2016-09-14 10:50:09 -0700151 private final WindowManagerService mService;
152
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800153 public void printTo(String prefix, PrintWriter pw) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800154 pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800155 pw.print(" mWidth="); pw.print(mWidth);
156 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700157 if (USE_CUSTOM_BLACK_FRAME) {
158 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
159 if (mCustomBlackFrame != null) {
160 mCustomBlackFrame.printTo(prefix + " ", pw);
161 }
162 }
163 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
164 if (mExitingBlackFrame != null) {
165 mExitingBlackFrame.printTo(prefix + " ", pw);
166 }
167 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
168 if (mEnteringBlackFrame != null) {
169 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800170 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700171 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
172 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
173 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800174 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
175 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
176 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
177 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
178 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
179 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
180 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
181 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
182 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800183 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
184 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800185 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
186 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
187 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
188 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800189 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
190 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800191 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
192 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
193 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
194 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800195 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
196 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800197 pw.print(prefix); pw.print("mExitTransformation=");
198 mExitTransformation.printShortString(pw); pw.println();
199 pw.print(prefix); pw.print("mEnterTransformation=");
200 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800201 pw.print(prefix); pw.print("mFrameTransformation=");
Steven Timotius8304ef42017-08-28 16:59:14 -0700202 mFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800203 pw.print(prefix); pw.print("mFrameInitialMatrix=");
204 mFrameInitialMatrix.printShortString(pw);
205 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800206 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
207 mSnapshotInitialMatrix.printShortString(pw);
208 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
209 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700210 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
211 mExitFrameFinalMatrix.printShortString(pw);
212 pw.println();
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700213 pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
214 if (mForceDefaultOrientation) {
215 pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
216 pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString());
217 }
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800218 }
219
Steven Timotiusf2d68892017-08-28 17:00:01 -0700220 public void writeToProto(ProtoOutputStream proto, long fieldId) {
221 final long token = proto.start(fieldId);
222 proto.write(STARTED, mStarted);
223 proto.write(ANIMATION_RUNNING, mAnimRunning);
224 proto.end(token);
225 }
226
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700227 public ScreenRotationAnimation(Context context, DisplayContent displayContent,
Minoru Aoi2b74a242014-03-13 12:00:34 +0900228 SurfaceSession session, boolean inTransaction, boolean forceDefaultOrientation,
Robert Carr68e5c9e2016-09-14 10:50:09 -0700229 boolean isSecure, WindowManagerService service) {
230 mService = service;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800231 mContext = context;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700232 mDisplayContent = displayContent;
233 displayContent.getLogicalDisplayRect(mOriginalDisplayRect);
Dianne Hackborna1111872010-11-23 20:55:11 -0800234
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800235 // Screenshot does NOT include rotation!
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700236 final Display display = displayContent.getDisplay();
237 int originalRotation = display.getRotation();
238 final int originalWidth;
239 final int originalHeight;
240 DisplayInfo displayInfo = displayContent.getDisplayInfo();
241 if (forceDefaultOrientation) {
242 // Emulated orientation.
243 mForceDefaultOrientation = true;
244 originalWidth = displayContent.mBaseDisplayWidth;
245 originalHeight = displayContent.mBaseDisplayHeight;
246 } else {
247 // Normal situation
248 originalWidth = displayInfo.logicalWidth;
249 originalHeight = displayInfo.logicalHeight;
250 }
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700251 if (originalRotation == Surface.ROTATION_90
252 || originalRotation == Surface.ROTATION_270) {
253 mWidth = originalHeight;
254 mHeight = originalWidth;
255 } else {
256 mWidth = originalWidth;
257 mHeight = originalHeight;
258 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800259
Jeff Brownbc68a592011-07-25 12:58:12 -0700260 mOriginalRotation = originalRotation;
261 mOriginalWidth = originalWidth;
262 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800263
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800264 if (!inTransaction) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800265 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800266 ">>> OPEN TRANSACTION ScreenRotationAnimation");
Robert Carr68e5c9e2016-09-14 10:50:09 -0700267 mService.openSurfaceTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800268 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700269
Dianne Hackborna1111872010-11-23 20:55:11 -0800270 try {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800271 try {
Minoru Aoi2b74a242014-03-13 12:00:34 +0900272 int flags = SurfaceControl.HIDDEN;
273 if (isSecure) {
274 flags |= SurfaceControl.SECURE;
275 }
276
Robert Carre13b58e2017-08-31 14:50:44 -0700277 mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
278 mWidth, mHeight,
279 PixelFormat.OPAQUE, flags);
280
Mathias Agopian11e7d882013-03-05 14:14:55 -0800281 // capture a screenshot into the surface we just created
282 Surface sur = new Surface();
283 sur.copyFrom(mSurfaceControl);
David Stevens848cf822017-08-01 17:54:23 -0700284 // TODO(multidisplay): we should use the proper display
Mathias Agopian11e7d882013-03-05 14:14:55 -0800285 SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(
286 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), sur);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700287 mSurfaceControl.setLayerStack(display.getLayerStack());
Chong Zhang97782b42015-10-07 16:01:23 -0700288 mSurfaceControl.setLayer(SCREEN_FREEZE_LAYER_SCREENSHOT);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800289 mSurfaceControl.setAlpha(0);
290 mSurfaceControl.show();
Craig Mautnere50d7fc2013-03-18 10:06:21 -0700291 sur.destroy();
Igor Murashkina86ab6402013-08-30 12:58:36 -0700292 } catch (OutOfResourcesException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800293 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800294 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800295
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800296 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
297 " FREEZE " + mSurfaceControl + ": CREATE");
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700298
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700299 setRotationInTransaction(originalRotation);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800300 } finally {
301 if (!inTransaction) {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700302 mService.closeSurfaceTransaction();
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800303 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800304 "<<< CLOSE TRANSACTION ScreenRotationAnimation");
Dianne Hackborn352cc982011-01-04 11:34:18 -0800305 }
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800306 }
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
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700313 private void setSnapshotTransformInTransaction(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) {
319 mDisplayContent.getLogicalDisplayRect(mCurrentDisplayRect);
320 x -= mCurrentDisplayRect.left;
321 y -= mCurrentDisplayRect.top;
322 }
323 mSurfaceControl.setPosition(x, y);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800324 mSurfaceControl.setMatrix(
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]);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800327 mSurfaceControl.setAlpha(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
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800361 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700362 private void setRotationInTransaction(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);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700372 setSnapshotTransformInTransaction(mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800373 }
374
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800375 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700376 public boolean setRotationInTransaction(int rotation, SurfaceSession session,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800377 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700378 setRotationInTransaction(rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700379 if (TWO_PHASE_ANIMATION) {
380 return startAnimation(session, maxAnimationDuration, animationScale,
Craig Mautner3c174372013-02-21 17:54:37 -0800381 finalWidth, finalHeight, false, 0, 0);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700382 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700383
384 // Don't start animation yet.
385 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800386 }
387
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800388 /**
389 * Returns true if animating.
390 */
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800391 private boolean startAnimation(SurfaceSession session, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800392 float animationScale, int finalWidth, int finalHeight, boolean dismissing,
393 int exitAnim, int enterAnim) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800394 if (mSurfaceControl == null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800395 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800396 return false;
397 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800398 if (mStarted) {
399 return true;
400 }
401
402 mStarted = true;
403
404 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800405
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800406 // Figure out how the screen has moved from the original rotation.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800407 int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800408
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700409 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
410 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800411 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
412 firstStart = true;
413 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
414 com.android.internal.R.anim.screen_rotate_start_exit);
415 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
416 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700417 if (USE_CUSTOM_BLACK_FRAME) {
418 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
419 com.android.internal.R.anim.screen_rotate_start_frame);
420 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800421 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
422 com.android.internal.R.anim.screen_rotate_finish_exit);
423 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
424 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700425 if (USE_CUSTOM_BLACK_FRAME) {
426 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
427 com.android.internal.R.anim.screen_rotate_finish_frame);
428 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800429 }
430
431 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
432 + finalWidth + " finalHeight=" + finalHeight
433 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
434
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700435 final boolean customAnim;
Craig Mautner3c174372013-02-21 17:54:37 -0800436 if (exitAnim != 0 && enterAnim != 0) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700437 customAnim = true;
Craig Mautner3c174372013-02-21 17:54:37 -0800438 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
439 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700440 } else {
441 customAnim = false;
442 switch (delta) {
443 case Surface.ROTATION_0:
444 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
445 com.android.internal.R.anim.screen_rotate_0_exit);
446 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
447 com.android.internal.R.anim.screen_rotate_0_enter);
448 if (USE_CUSTOM_BLACK_FRAME) {
449 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
450 com.android.internal.R.anim.screen_rotate_0_frame);
451 }
452 break;
453 case Surface.ROTATION_90:
454 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
455 com.android.internal.R.anim.screen_rotate_plus_90_exit);
456 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
457 com.android.internal.R.anim.screen_rotate_plus_90_enter);
458 if (USE_CUSTOM_BLACK_FRAME) {
459 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
460 com.android.internal.R.anim.screen_rotate_plus_90_frame);
461 }
462 break;
463 case Surface.ROTATION_180:
464 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
465 com.android.internal.R.anim.screen_rotate_180_exit);
466 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
467 com.android.internal.R.anim.screen_rotate_180_enter);
468 if (USE_CUSTOM_BLACK_FRAME) {
469 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
470 com.android.internal.R.anim.screen_rotate_180_frame);
471 }
472 break;
473 case Surface.ROTATION_270:
474 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
475 com.android.internal.R.anim.screen_rotate_minus_90_exit);
476 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
477 com.android.internal.R.anim.screen_rotate_minus_90_enter);
478 if (USE_CUSTOM_BLACK_FRAME) {
479 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
480 com.android.internal.R.anim.screen_rotate_minus_90_frame);
481 }
482 break;
483 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800484 }
485
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800486 // Initialize the animations. This is a hack, redefining what "parent"
487 // means to allow supplying the last and next size. In this definition
488 // "%p" is the original (let's call it "previous") size, and "%" is the
489 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700490 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700491 // Compute partial steps between original and final sizes. These
492 // are used for the dimensions of the exiting and entering elements,
493 // so they are never stretched too significantly.
494 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
495 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
496
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800497 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
498 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800499 halfWidth, halfHeight);
500 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800501 mOriginalWidth, mOriginalHeight);
502 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800503 halfWidth, halfHeight);
504 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800505 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700506 if (USE_CUSTOM_BLACK_FRAME) {
507 mStartFrameAnimation.initialize(finalWidth, finalHeight,
508 mOriginalWidth, mOriginalHeight);
509 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
510 mOriginalWidth, mOriginalHeight);
511 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800512 }
513 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
514 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700515 if (USE_CUSTOM_BLACK_FRAME) {
516 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
517 mOriginalHeight);
518 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800519 mAnimRunning = false;
520 mFinishAnimReady = false;
521 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800522
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700523 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800524 mStartExitAnimation.restrictDuration(maxAnimationDuration);
525 mStartExitAnimation.scaleCurrentDuration(animationScale);
526 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
527 mStartEnterAnimation.scaleCurrentDuration(animationScale);
528 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
529 mFinishExitAnimation.scaleCurrentDuration(animationScale);
530 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
531 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700532 if (USE_CUSTOM_BLACK_FRAME) {
533 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
534 mStartFrameAnimation.scaleCurrentDuration(animationScale);
535 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
536 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
537 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800538 }
539 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
540 mRotateExitAnimation.scaleCurrentDuration(animationScale);
541 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
542 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700543 if (USE_CUSTOM_BLACK_FRAME) {
544 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
545 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
546 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800547
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700548 final int layerStack = mDisplayContent.getDisplay().getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700549 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800550 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
551 TAG_WM,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800552 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Robert Carr68e5c9e2016-09-14 10:50:09 -0700553 mService.openSurfaceTransaction();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800554
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800555 // Compute the transformation matrix that must be applied
556 // the the black frame to make it stay in the initial position
557 // before the new screen rotation. This is different than the
558 // snapshot transformation because the snapshot is always based
559 // of the native orientation of the screen, not the orientation
560 // we were last in.
561 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
562
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800563 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800564 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
565 mOriginalWidth*2, mOriginalHeight*2);
566 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Chong Zhang97782b42015-10-07 16:01:23 -0700567 mCustomBlackFrame = new BlackFrame(session, outer, inner,
568 SCREEN_FREEZE_LAYER_CUSTOM, layerStack, false);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700569 mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700570 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700571 Slog.w(TAG, "Unable to allocate black surface", e);
572 } finally {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700573 mService.closeSurfaceTransaction();
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800574 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
575 TAG_WM,
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700576 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
577 }
578 }
579
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700580 if (!customAnim && mExitingBlackFrame == null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800581 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
582 TAG_WM,
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700583 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Robert Carr68e5c9e2016-09-14 10:50:09 -0700584 mService.openSurfaceTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700585 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700586 // Compute the transformation matrix that must be applied
587 // the the black frame to make it stay in the initial position
588 // before the new screen rotation. This is different than the
589 // snapshot transformation because the snapshot is always based
590 // of the native orientation of the screen, not the orientation
591 // we were last in.
592 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
593
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700594 final Rect outer;
595 final Rect inner;
596 if (mForceDefaultOrientation) {
597 // Going from a smaller Display to a larger Display, add curtains to sides
598 // or top and bottom. Going from a larger to smaller display will result in
599 // no BlackSurfaces being constructed.
600 outer = mCurrentDisplayRect;
601 inner = mOriginalDisplayRect;
602 } else {
603 outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
604 mOriginalWidth*2, mOriginalHeight*2);
605 inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
606 }
Chong Zhang97782b42015-10-07 16:01:23 -0700607 mExitingBlackFrame = new BlackFrame(session, outer, inner,
608 SCREEN_FREEZE_LAYER_EXIT, layerStack, mForceDefaultOrientation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700609 mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700610 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700611 Slog.w(TAG, "Unable to allocate black surface", e);
612 } finally {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700613 mService.closeSurfaceTransaction();
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800614 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
615 TAG_WM,
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700616 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
617 }
618 }
619
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700620 if (customAnim && mEnteringBlackFrame == null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800621 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
622 TAG_WM,
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700623 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Robert Carr68e5c9e2016-09-14 10:50:09 -0700624 mService.openSurfaceTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700625
626 try {
627 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
628 finalWidth*2, finalHeight*2);
629 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Chong Zhang97782b42015-10-07 16:01:23 -0700630 mEnteringBlackFrame = new BlackFrame(session, outer, inner,
631 SCREEN_FREEZE_LAYER_ENTER, layerStack, false);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700632 } catch (OutOfResourcesException e) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800633 Slog.w(TAG, "Unable to allocate black surface", e);
634 } finally {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700635 mService.closeSurfaceTransaction();
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800636 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
637 TAG_WM,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800638 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
639 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800640 }
641
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800642 return true;
643 }
644
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800645 /**
646 * Returns true if animating.
647 */
648 public boolean dismiss(SurfaceSession session, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800649 float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800650 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800651 if (mSurfaceControl == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800652 // Can't do animation.
653 return false;
654 }
655 if (!mStarted) {
656 startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight,
Craig Mautner3c174372013-02-21 17:54:37 -0800657 true, exitAnim, enterAnim);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800658 }
659 if (!mStarted) {
660 return false;
661 }
662 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
663 mFinishAnimReady = true;
664 return true;
665 }
666
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800667 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800668 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800669 if (mSurfaceControl != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800670 if (SHOW_TRANSACTIONS ||
671 SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800672 " FREEZE " + mSurfaceControl + ": DESTROY");
673 mSurfaceControl.destroy();
674 mSurfaceControl = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800675 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700676 if (mCustomBlackFrame != null) {
677 mCustomBlackFrame.kill();
678 mCustomBlackFrame = null;
679 }
680 if (mExitingBlackFrame != null) {
681 mExitingBlackFrame.kill();
682 mExitingBlackFrame = null;
683 }
684 if (mEnteringBlackFrame != null) {
685 mEnteringBlackFrame.kill();
686 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800687 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700688 if (TWO_PHASE_ANIMATION) {
689 if (mStartExitAnimation != null) {
690 mStartExitAnimation.cancel();
691 mStartExitAnimation = null;
692 }
693 if (mStartEnterAnimation != null) {
694 mStartEnterAnimation.cancel();
695 mStartEnterAnimation = null;
696 }
697 if (mFinishExitAnimation != null) {
698 mFinishExitAnimation.cancel();
699 mFinishExitAnimation = null;
700 }
701 if (mFinishEnterAnimation != null) {
702 mFinishEnterAnimation.cancel();
703 mFinishEnterAnimation = null;
704 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800705 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700706 if (USE_CUSTOM_BLACK_FRAME) {
707 if (mStartFrameAnimation != null) {
708 mStartFrameAnimation.cancel();
709 mStartFrameAnimation = null;
710 }
711 if (mRotateFrameAnimation != null) {
712 mRotateFrameAnimation.cancel();
713 mRotateFrameAnimation = null;
714 }
715 if (mFinishFrameAnimation != null) {
716 mFinishFrameAnimation.cancel();
717 mFinishFrameAnimation = null;
718 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800719 }
720 if (mRotateExitAnimation != null) {
721 mRotateExitAnimation.cancel();
722 mRotateExitAnimation = null;
723 }
724 if (mRotateEnterAnimation != null) {
725 mRotateEnterAnimation.cancel();
726 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800727 }
728 }
729
730 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700731 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700732 }
733
Dianne Hackborn4b169692012-11-29 17:51:24 -0800734 public boolean isRotating() {
735 return mCurRotation != mOriginalRotation;
736 }
737
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700738 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700739 return (TWO_PHASE_ANIMATION &&
740 (mStartEnterAnimation != null || mStartExitAnimation != null
741 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
742 || (USE_CUSTOM_BLACK_FRAME &&
743 (mStartFrameAnimation != null || mRotateFrameAnimation != null
744 || mFinishFrameAnimation != null))
745 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800746 }
747
Craig Mautnere32c3072012-03-12 15:25:35 -0700748 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700749 if (now > mHalfwayPoint) {
750 mHalfwayPoint = Long.MAX_VALUE;
751 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800752 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
753 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
754 mFinishAnimStartTime = now;
755 }
756
Craig Mautner7d8df392012-04-06 15:26:23 -0700757 if (TWO_PHASE_ANIMATION) {
758 mMoreStartExit = false;
759 if (mStartExitAnimation != null) {
760 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
761 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
762 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800763
Craig Mautner7d8df392012-04-06 15:26:23 -0700764 mMoreStartEnter = false;
765 if (mStartEnterAnimation != null) {
766 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
767 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
768 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800769 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700770 if (USE_CUSTOM_BLACK_FRAME) {
771 mMoreStartFrame = false;
772 if (mStartFrameAnimation != null) {
773 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
774 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
775 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800776 }
777
Craig Mautnerdbb79912012-03-01 18:59:14 -0800778 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
779 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
780
Craig Mautner7d8df392012-04-06 15:26:23 -0700781 if (TWO_PHASE_ANIMATION) {
782 mMoreFinishExit = false;
783 if (mFinishExitAnimation != null) {
784 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
785 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
786 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800787
Craig Mautner7d8df392012-04-06 15:26:23 -0700788 mMoreFinishEnter = false;
789 if (mFinishEnterAnimation != null) {
790 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
791 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
792 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800793 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700794 if (USE_CUSTOM_BLACK_FRAME) {
795 mMoreFinishFrame = false;
796 if (mFinishFrameAnimation != null) {
797 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
798 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
799 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800800 }
801
Craig Mautnerdbb79912012-03-01 18:59:14 -0800802 mMoreRotateExit = false;
803 if (mRotateExitAnimation != null) {
804 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
805 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700806 }
807
808 mMoreRotateEnter = false;
809 if (mRotateEnterAnimation != null) {
810 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
811 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
812 }
813
Craig Mautner7d8df392012-04-06 15:26:23 -0700814 if (USE_CUSTOM_BLACK_FRAME) {
815 mMoreRotateFrame = false;
816 if (mRotateFrameAnimation != null) {
817 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
818 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
819 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700820 }
821
Craig Mautner7d8df392012-04-06 15:26:23 -0700822 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
823 if (TWO_PHASE_ANIMATION) {
824 if (mStartExitAnimation != null) {
825 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
826 mStartExitAnimation.cancel();
827 mStartExitAnimation = null;
828 mStartExitTransformation.clear();
829 }
830 if (mFinishExitAnimation != null) {
831 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
832 mFinishExitAnimation.cancel();
833 mFinishExitAnimation = null;
834 mFinishExitTransformation.clear();
835 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700836 }
837 if (mRotateExitAnimation != null) {
838 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800839 mRotateExitAnimation.cancel();
840 mRotateExitAnimation = null;
841 mRotateExitTransformation.clear();
842 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800843 }
844
Craig Mautner7d8df392012-04-06 15:26:23 -0700845 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
846 if (TWO_PHASE_ANIMATION) {
847 if (mStartEnterAnimation != null) {
848 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
849 mStartEnterAnimation.cancel();
850 mStartEnterAnimation = null;
851 mStartEnterTransformation.clear();
852 }
853 if (mFinishEnterAnimation != null) {
854 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
855 mFinishEnterAnimation.cancel();
856 mFinishEnterAnimation = null;
857 mFinishEnterTransformation.clear();
858 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700859 }
860 if (mRotateEnterAnimation != null) {
861 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800862 mRotateEnterAnimation.cancel();
863 mRotateEnterAnimation = null;
864 mRotateEnterTransformation.clear();
865 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800866 }
867
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700868 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
869 if (mStartFrameAnimation != null) {
870 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
871 mStartFrameAnimation.cancel();
872 mStartFrameAnimation = null;
873 mStartFrameTransformation.clear();
874 }
875 if (mFinishFrameAnimation != null) {
876 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
877 mFinishFrameAnimation.cancel();
878 mFinishFrameAnimation = null;
879 mFinishFrameTransformation.clear();
880 }
881 if (mRotateFrameAnimation != null) {
882 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800883 mRotateFrameAnimation.cancel();
884 mRotateFrameAnimation = null;
885 mRotateFrameTransformation.clear();
886 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800887 }
888
889 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800890 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700891 if (TWO_PHASE_ANIMATION) {
892 mExitTransformation.compose(mStartExitTransformation);
893 mExitTransformation.compose(mFinishExitTransformation);
894
895 mEnterTransformation.compose(mStartEnterTransformation);
896 mEnterTransformation.compose(mFinishEnterTransformation);
897 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800898
899 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
900 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700901
902 if (USE_CUSTOM_BLACK_FRAME) {
903 //mFrameTransformation.set(mRotateExitTransformation);
904 //mFrameTransformation.compose(mStartExitTransformation);
905 //mFrameTransformation.compose(mFinishExitTransformation);
906 mFrameTransformation.set(mRotateFrameTransformation);
907 mFrameTransformation.compose(mStartFrameTransformation);
908 mFrameTransformation.compose(mFinishFrameTransformation);
909 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
910 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
911 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800912
Craig Mautner7d8df392012-04-06 15:26:23 -0700913 final boolean more = (TWO_PHASE_ANIMATION
914 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
915 || (USE_CUSTOM_BLACK_FRAME
916 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
Igor Murashkina86ab6402013-08-30 12:58:36 -0700917 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800918 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800919
920 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
921
922 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
923
924 return more;
925 }
926
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700927 void updateSurfacesInTransaction() {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700928 if (!mStarted) {
929 return;
930 }
931
Mathias Agopian29479eb2013-02-14 14:36:04 -0800932 if (mSurfaceControl != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700933 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800934 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800935 mSurfaceControl.hide();
Craig Mautnerdbb79912012-03-01 18:59:14 -0800936 }
937 }
938
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700939 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700940 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800941 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700942 mCustomBlackFrame.hide();
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700943 } else {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700944 mCustomBlackFrame.setMatrix(mFrameTransformation.getMatrix());
945 }
946 }
947
948 if (mExitingBlackFrame != null) {
949 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
950 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
951 mExitingBlackFrame.hide();
952 } else {
953 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
954 mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700955 if (mForceDefaultOrientation) {
956 mExitingBlackFrame.setAlpha(mExitTransformation.getAlpha());
957 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700958 }
959 }
960
961 if (mEnteringBlackFrame != null) {
962 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
963 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
964 mEnteringBlackFrame.hide();
965 } else {
966 mEnteringBlackFrame.setMatrix(mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800967 }
968 }
969
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700970 setSnapshotTransformInTransaction(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800971 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700972
Craig Mautnere32c3072012-03-12 15:25:35 -0700973 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700974 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800975 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800976 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800977 return false;
978 }
979
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800980 if (!mAnimRunning) {
981 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700982 if (TWO_PHASE_ANIMATION) {
983 if (mStartEnterAnimation != null) {
984 mStartEnterAnimation.setStartTime(now);
985 }
986 if (mStartExitAnimation != null) {
987 mStartExitAnimation.setStartTime(now);
988 }
989 if (mFinishEnterAnimation != null) {
990 mFinishEnterAnimation.setStartTime(0);
991 }
992 if (mFinishExitAnimation != null) {
993 mFinishExitAnimation.setStartTime(0);
994 }
Dianne Hackborn89620282011-09-11 12:47:45 -0700995 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700996 if (USE_CUSTOM_BLACK_FRAME) {
997 if (mStartFrameAnimation != null) {
998 mStartFrameAnimation.setStartTime(now);
999 }
1000 if (mFinishFrameAnimation != null) {
1001 mFinishFrameAnimation.setStartTime(0);
1002 }
1003 if (mRotateFrameAnimation != null) {
1004 mRotateFrameAnimation.setStartTime(now);
1005 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -08001006 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08001007 if (mRotateEnterAnimation != null) {
1008 mRotateEnterAnimation.setStartTime(now);
1009 }
1010 if (mRotateExitAnimation != null) {
1011 mRotateExitAnimation.setStartTime(now);
1012 }
1013 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -07001014 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08001015 }
Craig Mautnere32c3072012-03-12 15:25:35 -07001016
1017 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08001018 }
1019
1020 public Transformation getEnterTransformation() {
1021 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -08001022 }
1023}