blob: d5b6d24631e6358e171a924db1c4c2e2c174be85 [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.DEBUG_SURFACE_TRACE;
20import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
21import 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 -080027import static com.android.server.wm.WindowSurfaceController.SurfaceTrace;
Steven Timotiusf2d68892017-08-28 17:00:01 -070028import static com.android.server.wm.proto.ScreenRotationAnimationProto.ANIMATION_RUNNING;
29import static com.android.server.wm.proto.ScreenRotationAnimationProto.STARTED;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080030
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080031import android.content.Context;
Dianne Hackborna1111872010-11-23 20:55:11 -080032import android.graphics.Matrix;
Dianne Hackborna1111872010-11-23 20:55:11 -080033import android.graphics.PixelFormat;
34import android.graphics.Rect;
Dianne Hackborna1111872010-11-23 20:55:11 -080035import android.util.Slog;
Steven Timotiusf2d68892017-08-28 17:00:01 -070036import android.util.proto.ProtoOutputStream;
Craig Mautner6881a102012-07-27 13:04:51 -070037import android.view.Display;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070038import android.view.DisplayInfo;
Dianne Hackborna1111872010-11-23 20:55:11 -080039import android.view.Surface;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080040import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080041import android.view.SurfaceControl;
Dianne Hackborna1111872010-11-23 20:55:11 -080042import android.view.SurfaceSession;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080043import android.view.animation.Animation;
44import android.view.animation.AnimationUtils;
45import android.view.animation.Transformation;
Dianne Hackborna1111872010-11-23 20:55:11 -080046
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080047import java.io.PrintWriter;
48
Craig Mautnere32c3072012-03-12 15:25:35 -070049class ScreenRotationAnimation {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080050 static final String TAG = TAG_WITH_CLASS_NAME ? "ScreenRotationAnimation" : TAG_WM;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080051 static final boolean DEBUG_STATE = false;
52 static final boolean DEBUG_TRANSFORMS = false;
Dianne Hackborn187ae2102012-04-11 18:12:06 -070053 static final boolean TWO_PHASE_ANIMATION = false;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070054 static final boolean USE_CUSTOM_BLACK_FRAME = false;
Dianne Hackborna1111872010-11-23 20:55:11 -080055
Chong Zhang97782b42015-10-07 16:01:23 -070056 /*
57 * Layers for screen rotation animation. We put these layers above
58 * WINDOW_FREEZE_LAYER so that screen freeze will cover all windows.
59 */
60 static final int SCREEN_FREEZE_LAYER_BASE = WINDOW_FREEZE_LAYER + TYPE_LAYER_MULTIPLIER;
61 static final int SCREEN_FREEZE_LAYER_ENTER = SCREEN_FREEZE_LAYER_BASE;
62 static final int SCREEN_FREEZE_LAYER_SCREENSHOT = SCREEN_FREEZE_LAYER_BASE + 1;
63 static final int SCREEN_FREEZE_LAYER_EXIT = SCREEN_FREEZE_LAYER_BASE + 2;
64 static final int SCREEN_FREEZE_LAYER_CUSTOM = SCREEN_FREEZE_LAYER_BASE + 3;
Dianne Hackborn50660e22011-02-02 17:12:25 -080065
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080066 final Context mContext;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070067 final DisplayContent mDisplayContent;
Mathias Agopian29479eb2013-02-14 14:36:04 -080068 SurfaceControl mSurfaceControl;
Dianne Hackbornd6b32b62012-03-16 11:54:51 -070069 BlackFrame mCustomBlackFrame;
70 BlackFrame mExitingBlackFrame;
71 BlackFrame mEnteringBlackFrame;
Dianne Hackborna1111872010-11-23 20:55:11 -080072 int mWidth, mHeight;
73
Dianne Hackbornf9d0be92010-11-24 12:35:25 -080074 int mOriginalRotation;
75 int mOriginalWidth, mOriginalHeight;
Dianne Hackborna1111872010-11-23 20:55:11 -080076 int mCurRotation;
Craig Mautner46ac6fa2013-08-01 10:06:34 -070077 Rect mOriginalDisplayRect = new Rect();
78 Rect mCurrentDisplayRect = new Rect();
Dianne Hackborna1111872010-11-23 20:55:11 -080079
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080080 // For all animations, "exit" is for the UI elements that are going
81 // away (that is the snapshot of the old screen), and "enter" is for
82 // the new UI elements that are appearing (that is the active windows
83 // in their final orientation).
84
85 // The starting animation for the exiting and entering elements. This
86 // animation applies a transformation while the rotation is in progress.
87 // It is started immediately, before the new entering UI is ready.
88 Animation mStartExitAnimation;
89 final Transformation mStartExitTransformation = new Transformation();
90 Animation mStartEnterAnimation;
91 final Transformation mStartEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -080092 Animation mStartFrameAnimation;
93 final Transformation mStartFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -080094
95 // The finishing animation for the exiting and entering elements. This
96 // animation needs to undo the transformation of the starting animation.
97 // It starts running once the new rotation UI elements are ready to be
98 // displayed.
99 Animation mFinishExitAnimation;
100 final Transformation mFinishExitTransformation = new Transformation();
101 Animation mFinishEnterAnimation;
102 final Transformation mFinishEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800103 Animation mFinishFrameAnimation;
104 final Transformation mFinishFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800105
106 // The current active animation to move from the old to the new rotated
107 // state. Which animation is run here will depend on the old and new
108 // rotations.
109 Animation mRotateExitAnimation;
110 final Transformation mRotateExitTransformation = new Transformation();
111 Animation mRotateEnterAnimation;
112 final Transformation mRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800113 Animation mRotateFrameAnimation;
114 final Transformation mRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800115
116 // A previously running rotate animation. This will be used if we need
117 // to switch to a new rotation before finishing the previous one.
118 Animation mLastRotateExitAnimation;
119 final Transformation mLastRotateExitTransformation = new Transformation();
120 Animation mLastRotateEnterAnimation;
121 final Transformation mLastRotateEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800122 Animation mLastRotateFrameAnimation;
123 final Transformation mLastRotateFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800124
125 // Complete transformations being applied.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800126 final Transformation mExitTransformation = new Transformation();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800127 final Transformation mEnterTransformation = new Transformation();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800128 final Transformation mFrameTransformation = new Transformation();
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800129
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800130 boolean mStarted;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800131 boolean mAnimRunning;
132 boolean mFinishAnimReady;
133 long mFinishAnimStartTime;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700134 boolean mForceDefaultOrientation;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800135
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800136 final Matrix mFrameInitialMatrix = new Matrix();
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800137 final Matrix mSnapshotInitialMatrix = new Matrix();
138 final Matrix mSnapshotFinalMatrix = new Matrix();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700139 final Matrix mExitFrameFinalMatrix = new Matrix();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800140 final Matrix mTmpMatrix = new Matrix();
Dianne Hackborna1111872010-11-23 20:55:11 -0800141 final float[] mTmpFloats = new float[9];
Craig Mautnerdbb79912012-03-01 18:59:14 -0800142 private boolean mMoreRotateEnter;
143 private boolean mMoreRotateExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800144 private boolean mMoreRotateFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800145 private boolean mMoreFinishEnter;
146 private boolean mMoreFinishExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800147 private boolean mMoreFinishFrame;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800148 private boolean mMoreStartEnter;
149 private boolean mMoreStartExit;
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800150 private boolean mMoreStartFrame;
Craig Mautner3255a282012-04-16 15:42:47 -0700151 long mHalfwayPoint;
Dianne Hackborna1111872010-11-23 20:55:11 -0800152
Robert Carr68e5c9e2016-09-14 10:50:09 -0700153 private final WindowManagerService mService;
154
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800155 public void printTo(String prefix, PrintWriter pw) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800156 pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800157 pw.print(" mWidth="); pw.print(mWidth);
158 pw.print(" mHeight="); pw.println(mHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700159 if (USE_CUSTOM_BLACK_FRAME) {
160 pw.print(prefix); pw.print("mCustomBlackFrame="); pw.println(mCustomBlackFrame);
161 if (mCustomBlackFrame != null) {
162 mCustomBlackFrame.printTo(prefix + " ", pw);
163 }
164 }
165 pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame);
166 if (mExitingBlackFrame != null) {
167 mExitingBlackFrame.printTo(prefix + " ", pw);
168 }
169 pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame);
170 if (mEnteringBlackFrame != null) {
171 mEnteringBlackFrame.printTo(prefix + " ", pw);
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800172 }
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700173 pw.print(prefix); pw.print("mCurRotation="); pw.print(mCurRotation);
174 pw.print(" mOriginalRotation="); pw.println(mOriginalRotation);
175 pw.print(prefix); pw.print("mOriginalWidth="); pw.print(mOriginalWidth);
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800176 pw.print(" mOriginalHeight="); pw.println(mOriginalHeight);
177 pw.print(prefix); pw.print("mStarted="); pw.print(mStarted);
178 pw.print(" mAnimRunning="); pw.print(mAnimRunning);
179 pw.print(" mFinishAnimReady="); pw.print(mFinishAnimReady);
180 pw.print(" mFinishAnimStartTime="); pw.println(mFinishAnimStartTime);
181 pw.print(prefix); pw.print("mStartExitAnimation="); pw.print(mStartExitAnimation);
182 pw.print(" "); mStartExitTransformation.printShortString(pw); pw.println();
183 pw.print(prefix); pw.print("mStartEnterAnimation="); pw.print(mStartEnterAnimation);
184 pw.print(" "); mStartEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800185 pw.print(prefix); pw.print("mStartFrameAnimation="); pw.print(mStartFrameAnimation);
186 pw.print(" "); mStartFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800187 pw.print(prefix); pw.print("mFinishExitAnimation="); pw.print(mFinishExitAnimation);
188 pw.print(" "); mFinishExitTransformation.printShortString(pw); pw.println();
189 pw.print(prefix); pw.print("mFinishEnterAnimation="); pw.print(mFinishEnterAnimation);
190 pw.print(" "); mFinishEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800191 pw.print(prefix); pw.print("mFinishFrameAnimation="); pw.print(mFinishFrameAnimation);
192 pw.print(" "); mFinishFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800193 pw.print(prefix); pw.print("mRotateExitAnimation="); pw.print(mRotateExitAnimation);
194 pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println();
195 pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation);
196 pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800197 pw.print(prefix); pw.print("mRotateFrameAnimation="); pw.print(mRotateFrameAnimation);
198 pw.print(" "); mRotateFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800199 pw.print(prefix); pw.print("mExitTransformation=");
200 mExitTransformation.printShortString(pw); pw.println();
201 pw.print(prefix); pw.print("mEnterTransformation=");
202 mEnterTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800203 pw.print(prefix); pw.print("mFrameTransformation=");
Steven Timotius8304ef42017-08-28 16:59:14 -0700204 mFrameTransformation.printShortString(pw); pw.println();
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800205 pw.print(prefix); pw.print("mFrameInitialMatrix=");
206 mFrameInitialMatrix.printShortString(pw);
207 pw.println();
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800208 pw.print(prefix); pw.print("mSnapshotInitialMatrix=");
209 mSnapshotInitialMatrix.printShortString(pw);
210 pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw);
211 pw.println();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700212 pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
213 mExitFrameFinalMatrix.printShortString(pw);
214 pw.println();
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700215 pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
216 if (mForceDefaultOrientation) {
217 pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
218 pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString());
219 }
Dianne Hackborn4dcece82012-02-10 14:50:32 -0800220 }
221
Steven Timotiusf2d68892017-08-28 17:00:01 -0700222 public void writeToProto(ProtoOutputStream proto, long fieldId) {
223 final long token = proto.start(fieldId);
224 proto.write(STARTED, mStarted);
225 proto.write(ANIMATION_RUNNING, mAnimRunning);
226 proto.end(token);
227 }
228
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700229 public ScreenRotationAnimation(Context context, DisplayContent displayContent,
Minoru Aoi2b74a242014-03-13 12:00:34 +0900230 SurfaceSession session, boolean inTransaction, boolean forceDefaultOrientation,
Robert Carr68e5c9e2016-09-14 10:50:09 -0700231 boolean isSecure, WindowManagerService service) {
232 mService = service;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800233 mContext = context;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700234 mDisplayContent = displayContent;
235 displayContent.getLogicalDisplayRect(mOriginalDisplayRect);
Dianne Hackborna1111872010-11-23 20:55:11 -0800236
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800237 // Screenshot does NOT include rotation!
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700238 final Display display = displayContent.getDisplay();
239 int originalRotation = display.getRotation();
240 final int originalWidth;
241 final int originalHeight;
242 DisplayInfo displayInfo = displayContent.getDisplayInfo();
243 if (forceDefaultOrientation) {
244 // Emulated orientation.
245 mForceDefaultOrientation = true;
246 originalWidth = displayContent.mBaseDisplayWidth;
247 originalHeight = displayContent.mBaseDisplayHeight;
248 } else {
249 // Normal situation
250 originalWidth = displayInfo.logicalWidth;
251 originalHeight = displayInfo.logicalHeight;
252 }
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700253 if (originalRotation == Surface.ROTATION_90
254 || originalRotation == Surface.ROTATION_270) {
255 mWidth = originalHeight;
256 mHeight = originalWidth;
257 } else {
258 mWidth = originalWidth;
259 mHeight = originalHeight;
260 }
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800261
Jeff Brownbc68a592011-07-25 12:58:12 -0700262 mOriginalRotation = originalRotation;
263 mOriginalWidth = originalWidth;
264 mOriginalHeight = originalHeight;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800265
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800266 if (!inTransaction) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800267 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800268 ">>> OPEN TRANSACTION ScreenRotationAnimation");
Robert Carr68e5c9e2016-09-14 10:50:09 -0700269 mService.openSurfaceTransaction();
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800270 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700271
Dianne Hackborna1111872010-11-23 20:55:11 -0800272 try {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800273 try {
Minoru Aoi2b74a242014-03-13 12:00:34 +0900274 int flags = SurfaceControl.HIDDEN;
275 if (isSecure) {
276 flags |= SurfaceControl.SECURE;
277 }
278
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800279 if (DEBUG_SURFACE_TRACE) {
Mathias Agopian11e7d882013-03-05 14:14:55 -0800280 mSurfaceControl = new SurfaceTrace(session, "ScreenshotSurface",
Jeff Brown64a55af2012-08-26 02:47:39 -0700281 mWidth, mHeight,
Minoru Aoi2b74a242014-03-13 12:00:34 +0900282 PixelFormat.OPAQUE, flags);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700283 Slog.w(TAG, "ScreenRotationAnimation ctor: displayOffset="
284 + mOriginalDisplayRect.toShortString());
Craig Mautner7d8df392012-04-06 15:26:23 -0700285 } else {
Mathias Agopian11e7d882013-03-05 14:14:55 -0800286 mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
Jeff Brown64a55af2012-08-26 02:47:39 -0700287 mWidth, mHeight,
Minoru Aoi2b74a242014-03-13 12:00:34 +0900288 PixelFormat.OPAQUE, flags);
Mathias Agopian0ab84ef2011-10-13 16:02:48 -0700289 }
Mathias Agopian11e7d882013-03-05 14:14:55 -0800290 // capture a screenshot into the surface we just created
291 Surface sur = new Surface();
292 sur.copyFrom(mSurfaceControl);
David Stevens848cf822017-08-01 17:54:23 -0700293 // TODO(multidisplay): we should use the proper display
Mathias Agopian11e7d882013-03-05 14:14:55 -0800294 SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(
295 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), sur);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700296 mSurfaceControl.setLayerStack(display.getLayerStack());
Chong Zhang97782b42015-10-07 16:01:23 -0700297 mSurfaceControl.setLayer(SCREEN_FREEZE_LAYER_SCREENSHOT);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800298 mSurfaceControl.setAlpha(0);
299 mSurfaceControl.show();
Craig Mautnere50d7fc2013-03-18 10:06:21 -0700300 sur.destroy();
Igor Murashkina86ab6402013-08-30 12:58:36 -0700301 } catch (OutOfResourcesException e) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800302 Slog.w(TAG, "Unable to allocate freeze surface", e);
Dianne Hackborn352cc982011-01-04 11:34:18 -0800303 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800304
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800305 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
306 " FREEZE " + mSurfaceControl + ": CREATE");
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700307
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700308 setRotationInTransaction(originalRotation);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800309 } finally {
310 if (!inTransaction) {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700311 mService.closeSurfaceTransaction();
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800312 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -0800313 "<<< CLOSE TRANSACTION ScreenRotationAnimation");
Dianne Hackborn352cc982011-01-04 11:34:18 -0800314 }
Dianne Hackborn0f761d62010-11-30 22:06:10 -0800315 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800316 }
317
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800318 boolean hasScreenshot() {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800319 return mSurfaceControl != null;
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800320 }
321
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700322 private void setSnapshotTransformInTransaction(Matrix matrix, float alpha) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800323 if (mSurfaceControl != null) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800324 matrix.getValues(mTmpFloats);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700325 float x = mTmpFloats[Matrix.MTRANS_X];
326 float y = mTmpFloats[Matrix.MTRANS_Y];
327 if (mForceDefaultOrientation) {
328 mDisplayContent.getLogicalDisplayRect(mCurrentDisplayRect);
329 x -= mCurrentDisplayRect.left;
330 y -= mCurrentDisplayRect.top;
331 }
332 mSurfaceControl.setPosition(x, y);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800333 mSurfaceControl.setMatrix(
Dianne Hackborn352cc982011-01-04 11:34:18 -0800334 mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
335 mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
Mathias Agopian29479eb2013-02-14 14:36:04 -0800336 mSurfaceControl.setAlpha(alpha);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800337 if (DEBUG_TRANSFORMS) {
Dianne Hackborn352cc982011-01-04 11:34:18 -0800338 float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
339 float[] dstPnts = new float[4];
340 matrix.mapPoints(dstPnts, srcPnts);
341 Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
342 + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
343 Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
344 + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
345 }
Dianne Hackborna1111872010-11-23 20:55:11 -0800346 }
347 }
348
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800349 public static void createRotationMatrix(int rotation, int width, int height,
350 Matrix outMatrix) {
351 switch (rotation) {
352 case Surface.ROTATION_0:
353 outMatrix.reset();
354 break;
355 case Surface.ROTATION_90:
356 outMatrix.setRotate(90, 0, 0);
357 outMatrix.postTranslate(height, 0);
358 break;
359 case Surface.ROTATION_180:
360 outMatrix.setRotate(180, 0, 0);
361 outMatrix.postTranslate(width, height);
362 break;
363 case Surface.ROTATION_270:
364 outMatrix.setRotate(270, 0, 0);
365 outMatrix.postTranslate(0, width);
366 break;
367 }
368 }
369
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800370 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700371 private void setRotationInTransaction(int rotation) {
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800372 mCurRotation = rotation;
373
374 // Compute the transformation matrix that must be applied
375 // to the snapshot to make it stay in the same original position
376 // with the current screen rotation.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800377 int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800378 createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800379
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800380 if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700381 setSnapshotTransformInTransaction(mSnapshotInitialMatrix, 1.0f);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800382 }
383
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800384 // Must be called while in a transaction.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700385 public boolean setRotationInTransaction(int rotation, SurfaceSession session,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800386 long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700387 setRotationInTransaction(rotation);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700388 if (TWO_PHASE_ANIMATION) {
389 return startAnimation(session, maxAnimationDuration, animationScale,
Craig Mautner3c174372013-02-21 17:54:37 -0800390 finalWidth, finalHeight, false, 0, 0);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700391 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700392
393 // Don't start animation yet.
394 return false;
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800395 }
396
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800397 /**
398 * Returns true if animating.
399 */
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800400 private boolean startAnimation(SurfaceSession session, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800401 float animationScale, int finalWidth, int finalHeight, boolean dismissing,
402 int exitAnim, int enterAnim) {
Mathias Agopian29479eb2013-02-14 14:36:04 -0800403 if (mSurfaceControl == null) {
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800404 // Can't do animation.
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800405 return false;
406 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800407 if (mStarted) {
408 return true;
409 }
410
411 mStarted = true;
412
413 boolean firstStart = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800414
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800415 // Figure out how the screen has moved from the original rotation.
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800416 int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
Dianne Hackbornde75cb42011-03-02 17:11:21 -0800417
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700418 if (TWO_PHASE_ANIMATION && mFinishExitAnimation == null
419 && (!dismissing || delta != Surface.ROTATION_0)) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800420 if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations");
421 firstStart = true;
422 mStartExitAnimation = AnimationUtils.loadAnimation(mContext,
423 com.android.internal.R.anim.screen_rotate_start_exit);
424 mStartEnterAnimation = AnimationUtils.loadAnimation(mContext,
425 com.android.internal.R.anim.screen_rotate_start_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700426 if (USE_CUSTOM_BLACK_FRAME) {
427 mStartFrameAnimation = AnimationUtils.loadAnimation(mContext,
428 com.android.internal.R.anim.screen_rotate_start_frame);
429 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800430 mFinishExitAnimation = AnimationUtils.loadAnimation(mContext,
431 com.android.internal.R.anim.screen_rotate_finish_exit);
432 mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext,
433 com.android.internal.R.anim.screen_rotate_finish_enter);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700434 if (USE_CUSTOM_BLACK_FRAME) {
435 mFinishFrameAnimation = AnimationUtils.loadAnimation(mContext,
436 com.android.internal.R.anim.screen_rotate_finish_frame);
437 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800438 }
439
440 if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth="
441 + finalWidth + " finalHeight=" + finalHeight
442 + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
443
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700444 final boolean customAnim;
Craig Mautner3c174372013-02-21 17:54:37 -0800445 if (exitAnim != 0 && enterAnim != 0) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700446 customAnim = true;
Craig Mautner3c174372013-02-21 17:54:37 -0800447 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim);
448 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim);
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700449 } else {
450 customAnim = false;
451 switch (delta) {
452 case Surface.ROTATION_0:
453 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
454 com.android.internal.R.anim.screen_rotate_0_exit);
455 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
456 com.android.internal.R.anim.screen_rotate_0_enter);
457 if (USE_CUSTOM_BLACK_FRAME) {
458 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
459 com.android.internal.R.anim.screen_rotate_0_frame);
460 }
461 break;
462 case Surface.ROTATION_90:
463 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
464 com.android.internal.R.anim.screen_rotate_plus_90_exit);
465 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
466 com.android.internal.R.anim.screen_rotate_plus_90_enter);
467 if (USE_CUSTOM_BLACK_FRAME) {
468 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
469 com.android.internal.R.anim.screen_rotate_plus_90_frame);
470 }
471 break;
472 case Surface.ROTATION_180:
473 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
474 com.android.internal.R.anim.screen_rotate_180_exit);
475 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
476 com.android.internal.R.anim.screen_rotate_180_enter);
477 if (USE_CUSTOM_BLACK_FRAME) {
478 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
479 com.android.internal.R.anim.screen_rotate_180_frame);
480 }
481 break;
482 case Surface.ROTATION_270:
483 mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
484 com.android.internal.R.anim.screen_rotate_minus_90_exit);
485 mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
486 com.android.internal.R.anim.screen_rotate_minus_90_enter);
487 if (USE_CUSTOM_BLACK_FRAME) {
488 mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
489 com.android.internal.R.anim.screen_rotate_minus_90_frame);
490 }
491 break;
492 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800493 }
494
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800495 // Initialize the animations. This is a hack, redefining what "parent"
496 // means to allow supplying the last and next size. In this definition
497 // "%p" is the original (let's call it "previous") size, and "%" is the
498 // screen's current/new size.
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700499 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700500 // Compute partial steps between original and final sizes. These
501 // are used for the dimensions of the exiting and entering elements,
502 // so they are never stretched too significantly.
503 final int halfWidth = (finalWidth + mOriginalWidth) / 2;
504 final int halfHeight = (finalHeight + mOriginalHeight) / 2;
505
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800506 if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
507 mStartEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800508 halfWidth, halfHeight);
509 mStartExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800510 mOriginalWidth, mOriginalHeight);
511 mFinishEnterAnimation.initialize(finalWidth, finalHeight,
Dianne Hackborn191874e32012-03-09 11:03:36 -0800512 halfWidth, halfHeight);
513 mFinishExitAnimation.initialize(halfWidth, halfHeight,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800514 mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700515 if (USE_CUSTOM_BLACK_FRAME) {
516 mStartFrameAnimation.initialize(finalWidth, finalHeight,
517 mOriginalWidth, mOriginalHeight);
518 mFinishFrameAnimation.initialize(finalWidth, finalHeight,
519 mOriginalWidth, mOriginalHeight);
520 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800521 }
522 mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
523 mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700524 if (USE_CUSTOM_BLACK_FRAME) {
525 mRotateFrameAnimation.initialize(finalWidth, finalHeight, mOriginalWidth,
526 mOriginalHeight);
527 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800528 mAnimRunning = false;
529 mFinishAnimReady = false;
530 mFinishAnimStartTime = -1;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800531
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700532 if (TWO_PHASE_ANIMATION && firstStart) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800533 mStartExitAnimation.restrictDuration(maxAnimationDuration);
534 mStartExitAnimation.scaleCurrentDuration(animationScale);
535 mStartEnterAnimation.restrictDuration(maxAnimationDuration);
536 mStartEnterAnimation.scaleCurrentDuration(animationScale);
537 mFinishExitAnimation.restrictDuration(maxAnimationDuration);
538 mFinishExitAnimation.scaleCurrentDuration(animationScale);
539 mFinishEnterAnimation.restrictDuration(maxAnimationDuration);
540 mFinishEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700541 if (USE_CUSTOM_BLACK_FRAME) {
542 mStartFrameAnimation.restrictDuration(maxAnimationDuration);
543 mStartFrameAnimation.scaleCurrentDuration(animationScale);
544 mFinishFrameAnimation.restrictDuration(maxAnimationDuration);
545 mFinishFrameAnimation.scaleCurrentDuration(animationScale);
546 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800547 }
548 mRotateExitAnimation.restrictDuration(maxAnimationDuration);
549 mRotateExitAnimation.scaleCurrentDuration(animationScale);
550 mRotateEnterAnimation.restrictDuration(maxAnimationDuration);
551 mRotateEnterAnimation.scaleCurrentDuration(animationScale);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700552 if (USE_CUSTOM_BLACK_FRAME) {
553 mRotateFrameAnimation.restrictDuration(maxAnimationDuration);
554 mRotateFrameAnimation.scaleCurrentDuration(animationScale);
555 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800556
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700557 final int layerStack = mDisplayContent.getDisplay().getLayerStack();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700558 if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800559 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
560 TAG_WM,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800561 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Robert Carr68e5c9e2016-09-14 10:50:09 -0700562 mService.openSurfaceTransaction();
Dianne Hackborn50660e22011-02-02 17:12:25 -0800563
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800564 // Compute the transformation matrix that must be applied
565 // the the black frame to make it stay in the initial position
566 // before the new screen rotation. This is different than the
567 // snapshot transformation because the snapshot is always based
568 // of the native orientation of the screen, not the orientation
569 // we were last in.
570 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
571
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800572 try {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800573 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
574 mOriginalWidth*2, mOriginalHeight*2);
575 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
Chong Zhang97782b42015-10-07 16:01:23 -0700576 mCustomBlackFrame = new BlackFrame(session, outer, inner,
577 SCREEN_FREEZE_LAYER_CUSTOM, layerStack, false);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700578 mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700579 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700580 Slog.w(TAG, "Unable to allocate black surface", e);
581 } finally {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700582 mService.closeSurfaceTransaction();
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800583 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
584 TAG_WM,
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700585 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
586 }
587 }
588
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700589 if (!customAnim && mExitingBlackFrame == null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800590 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
591 TAG_WM,
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700592 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Robert Carr68e5c9e2016-09-14 10:50:09 -0700593 mService.openSurfaceTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700594 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700595 // Compute the transformation matrix that must be applied
596 // the the black frame to make it stay in the initial position
597 // before the new screen rotation. This is different than the
598 // snapshot transformation because the snapshot is always based
599 // of the native orientation of the screen, not the orientation
600 // we were last in.
601 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
602
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700603 final Rect outer;
604 final Rect inner;
605 if (mForceDefaultOrientation) {
606 // Going from a smaller Display to a larger Display, add curtains to sides
607 // or top and bottom. Going from a larger to smaller display will result in
608 // no BlackSurfaces being constructed.
609 outer = mCurrentDisplayRect;
610 inner = mOriginalDisplayRect;
611 } else {
612 outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
613 mOriginalWidth*2, mOriginalHeight*2);
614 inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
615 }
Chong Zhang97782b42015-10-07 16:01:23 -0700616 mExitingBlackFrame = new BlackFrame(session, outer, inner,
617 SCREEN_FREEZE_LAYER_EXIT, layerStack, mForceDefaultOrientation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700618 mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700619 } catch (OutOfResourcesException e) {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700620 Slog.w(TAG, "Unable to allocate black surface", e);
621 } finally {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700622 mService.closeSurfaceTransaction();
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800623 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
624 TAG_WM,
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700625 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
626 }
627 }
628
Dianne Hackborn9d9ece32012-09-10 15:33:52 -0700629 if (customAnim && mEnteringBlackFrame == null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800630 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
631 TAG_WM,
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700632 ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
Robert Carr68e5c9e2016-09-14 10:50:09 -0700633 mService.openSurfaceTransaction();
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700634
635 try {
636 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
637 finalWidth*2, finalHeight*2);
638 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
Chong Zhang97782b42015-10-07 16:01:23 -0700639 mEnteringBlackFrame = new BlackFrame(session, outer, inner,
640 SCREEN_FREEZE_LAYER_ENTER, layerStack, false);
Igor Murashkina86ab6402013-08-30 12:58:36 -0700641 } catch (OutOfResourcesException e) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800642 Slog.w(TAG, "Unable to allocate black surface", e);
643 } finally {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700644 mService.closeSurfaceTransaction();
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800645 if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
646 TAG_WM,
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800647 "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
648 }
Dianne Hackborn50660e22011-02-02 17:12:25 -0800649 }
650
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800651 return true;
652 }
653
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800654 /**
655 * Returns true if animating.
656 */
657 public boolean dismiss(SurfaceSession session, long maxAnimationDuration,
Craig Mautner3c174372013-02-21 17:54:37 -0800658 float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800659 if (DEBUG_STATE) Slog.v(TAG, "Dismiss!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800660 if (mSurfaceControl == null) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800661 // Can't do animation.
662 return false;
663 }
664 if (!mStarted) {
665 startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight,
Craig Mautner3c174372013-02-21 17:54:37 -0800666 true, exitAnim, enterAnim);
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800667 }
668 if (!mStarted) {
669 return false;
670 }
671 if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true");
672 mFinishAnimReady = true;
673 return true;
674 }
675
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800676 public void kill() {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800677 if (DEBUG_STATE) Slog.v(TAG, "Kill!");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800678 if (mSurfaceControl != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800679 if (SHOW_TRANSACTIONS ||
680 SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
Mathias Agopian29479eb2013-02-14 14:36:04 -0800681 " FREEZE " + mSurfaceControl + ": DESTROY");
682 mSurfaceControl.destroy();
683 mSurfaceControl = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800684 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700685 if (mCustomBlackFrame != null) {
686 mCustomBlackFrame.kill();
687 mCustomBlackFrame = null;
688 }
689 if (mExitingBlackFrame != null) {
690 mExitingBlackFrame.kill();
691 mExitingBlackFrame = null;
692 }
693 if (mEnteringBlackFrame != null) {
694 mEnteringBlackFrame.kill();
695 mEnteringBlackFrame = null;
Dianne Hackborn352cc982011-01-04 11:34:18 -0800696 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700697 if (TWO_PHASE_ANIMATION) {
698 if (mStartExitAnimation != null) {
699 mStartExitAnimation.cancel();
700 mStartExitAnimation = null;
701 }
702 if (mStartEnterAnimation != null) {
703 mStartEnterAnimation.cancel();
704 mStartEnterAnimation = null;
705 }
706 if (mFinishExitAnimation != null) {
707 mFinishExitAnimation.cancel();
708 mFinishExitAnimation = null;
709 }
710 if (mFinishEnterAnimation != null) {
711 mFinishEnterAnimation.cancel();
712 mFinishEnterAnimation = null;
713 }
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800714 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700715 if (USE_CUSTOM_BLACK_FRAME) {
716 if (mStartFrameAnimation != null) {
717 mStartFrameAnimation.cancel();
718 mStartFrameAnimation = null;
719 }
720 if (mRotateFrameAnimation != null) {
721 mRotateFrameAnimation.cancel();
722 mRotateFrameAnimation = null;
723 }
724 if (mFinishFrameAnimation != null) {
725 mFinishFrameAnimation.cancel();
726 mFinishFrameAnimation = null;
727 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800728 }
729 if (mRotateExitAnimation != null) {
730 mRotateExitAnimation.cancel();
731 mRotateExitAnimation = null;
732 }
733 if (mRotateEnterAnimation != null) {
734 mRotateEnterAnimation.cancel();
735 mRotateEnterAnimation = null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800736 }
737 }
738
739 public boolean isAnimating() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700740 return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700741 }
742
Dianne Hackborn4b169692012-11-29 17:51:24 -0800743 public boolean isRotating() {
744 return mCurRotation != mOriginalRotation;
745 }
746
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700747 private boolean hasAnimations() {
Craig Mautner7d8df392012-04-06 15:26:23 -0700748 return (TWO_PHASE_ANIMATION &&
749 (mStartEnterAnimation != null || mStartExitAnimation != null
750 || mFinishEnterAnimation != null || mFinishExitAnimation != null))
751 || (USE_CUSTOM_BLACK_FRAME &&
752 (mStartFrameAnimation != null || mRotateFrameAnimation != null
753 || mFinishFrameAnimation != null))
754 || mRotateEnterAnimation != null || mRotateExitAnimation != null;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800755 }
756
Craig Mautnere32c3072012-03-12 15:25:35 -0700757 private boolean stepAnimation(long now) {
Craig Mautner3255a282012-04-16 15:42:47 -0700758 if (now > mHalfwayPoint) {
759 mHalfwayPoint = Long.MAX_VALUE;
760 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800761 if (mFinishAnimReady && mFinishAnimStartTime < 0) {
762 if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready");
763 mFinishAnimStartTime = now;
764 }
765
Craig Mautner7d8df392012-04-06 15:26:23 -0700766 if (TWO_PHASE_ANIMATION) {
767 mMoreStartExit = false;
768 if (mStartExitAnimation != null) {
769 mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
770 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
771 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800772
Craig Mautner7d8df392012-04-06 15:26:23 -0700773 mMoreStartEnter = false;
774 if (mStartEnterAnimation != null) {
775 mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
776 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
777 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800778 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700779 if (USE_CUSTOM_BLACK_FRAME) {
780 mMoreStartFrame = false;
781 if (mStartFrameAnimation != null) {
782 mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
783 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
784 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800785 }
786
Craig Mautnerdbb79912012-03-01 18:59:14 -0800787 long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
788 if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
789
Craig Mautner7d8df392012-04-06 15:26:23 -0700790 if (TWO_PHASE_ANIMATION) {
791 mMoreFinishExit = false;
792 if (mFinishExitAnimation != null) {
793 mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
794 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
795 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800796
Craig Mautner7d8df392012-04-06 15:26:23 -0700797 mMoreFinishEnter = false;
798 if (mFinishEnterAnimation != null) {
799 mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
800 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
801 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800802 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700803 if (USE_CUSTOM_BLACK_FRAME) {
804 mMoreFinishFrame = false;
805 if (mFinishFrameAnimation != null) {
806 mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
807 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
808 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800809 }
810
Craig Mautnerdbb79912012-03-01 18:59:14 -0800811 mMoreRotateExit = false;
812 if (mRotateExitAnimation != null) {
813 mMoreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation);
814 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700815 }
816
817 mMoreRotateEnter = false;
818 if (mRotateEnterAnimation != null) {
819 mMoreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation);
820 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
821 }
822
Craig Mautner7d8df392012-04-06 15:26:23 -0700823 if (USE_CUSTOM_BLACK_FRAME) {
824 mMoreRotateFrame = false;
825 if (mRotateFrameAnimation != null) {
826 mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
827 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
828 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700829 }
830
Craig Mautner7d8df392012-04-06 15:26:23 -0700831 if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
832 if (TWO_PHASE_ANIMATION) {
833 if (mStartExitAnimation != null) {
834 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
835 mStartExitAnimation.cancel();
836 mStartExitAnimation = null;
837 mStartExitTransformation.clear();
838 }
839 if (mFinishExitAnimation != null) {
840 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
841 mFinishExitAnimation.cancel();
842 mFinishExitAnimation = null;
843 mFinishExitTransformation.clear();
844 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700845 }
846 if (mRotateExitAnimation != null) {
847 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800848 mRotateExitAnimation.cancel();
849 mRotateExitAnimation = null;
850 mRotateExitTransformation.clear();
851 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800852 }
853
Craig Mautner7d8df392012-04-06 15:26:23 -0700854 if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
855 if (TWO_PHASE_ANIMATION) {
856 if (mStartEnterAnimation != null) {
857 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
858 mStartEnterAnimation.cancel();
859 mStartEnterAnimation = null;
860 mStartEnterTransformation.clear();
861 }
862 if (mFinishEnterAnimation != null) {
863 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
864 mFinishEnterAnimation.cancel();
865 mFinishEnterAnimation = null;
866 mFinishEnterTransformation.clear();
867 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700868 }
869 if (mRotateEnterAnimation != null) {
870 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800871 mRotateEnterAnimation.cancel();
872 mRotateEnterAnimation = null;
873 mRotateEnterTransformation.clear();
874 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800875 }
876
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700877 if (USE_CUSTOM_BLACK_FRAME && !mMoreStartFrame && !mMoreRotateFrame && !mMoreFinishFrame) {
878 if (mStartFrameAnimation != null) {
879 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing start frame anim!");
880 mStartFrameAnimation.cancel();
881 mStartFrameAnimation = null;
882 mStartFrameTransformation.clear();
883 }
884 if (mFinishFrameAnimation != null) {
885 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing finish frame anim!");
886 mFinishFrameAnimation.cancel();
887 mFinishFrameAnimation = null;
888 mFinishFrameTransformation.clear();
889 }
890 if (mRotateFrameAnimation != null) {
891 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, clearing rotate frame anim!");
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800892 mRotateFrameAnimation.cancel();
893 mRotateFrameAnimation = null;
894 mRotateFrameTransformation.clear();
895 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800896 }
897
898 mExitTransformation.set(mRotateExitTransformation);
Craig Mautnerdbb79912012-03-01 18:59:14 -0800899 mEnterTransformation.set(mRotateEnterTransformation);
Craig Mautner7d8df392012-04-06 15:26:23 -0700900 if (TWO_PHASE_ANIMATION) {
901 mExitTransformation.compose(mStartExitTransformation);
902 mExitTransformation.compose(mFinishExitTransformation);
903
904 mEnterTransformation.compose(mStartEnterTransformation);
905 mEnterTransformation.compose(mFinishEnterTransformation);
906 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800907
908 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
909 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700910
911 if (USE_CUSTOM_BLACK_FRAME) {
912 //mFrameTransformation.set(mRotateExitTransformation);
913 //mFrameTransformation.compose(mStartExitTransformation);
914 //mFrameTransformation.compose(mFinishExitTransformation);
915 mFrameTransformation.set(mRotateFrameTransformation);
916 mFrameTransformation.compose(mStartFrameTransformation);
917 mFrameTransformation.compose(mFinishFrameTransformation);
918 mFrameTransformation.getMatrix().preConcat(mFrameInitialMatrix);
919 if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
920 }
Craig Mautnerdbb79912012-03-01 18:59:14 -0800921
Craig Mautner7d8df392012-04-06 15:26:23 -0700922 final boolean more = (TWO_PHASE_ANIMATION
923 && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
924 || (USE_CUSTOM_BLACK_FRAME
925 && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
Igor Murashkina86ab6402013-08-30 12:58:36 -0700926 || mMoreRotateEnter || mMoreRotateExit
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800927 || !mFinishAnimReady;
Craig Mautnerdbb79912012-03-01 18:59:14 -0800928
929 mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
930
931 if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more);
932
933 return more;
934 }
935
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700936 void updateSurfacesInTransaction() {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700937 if (!mStarted) {
938 return;
939 }
940
Mathias Agopian29479eb2013-02-14 14:36:04 -0800941 if (mSurfaceControl != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700942 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
Craig Mautnerdbb79912012-03-01 18:59:14 -0800943 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface");
Mathias Agopian29479eb2013-02-14 14:36:04 -0800944 mSurfaceControl.hide();
Craig Mautnerdbb79912012-03-01 18:59:14 -0800945 }
946 }
947
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700948 if (mCustomBlackFrame != null) {
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700949 if (!mMoreStartFrame && !mMoreFinishFrame && !mMoreRotateFrame) {
Dianne Hackborn9fd74802012-03-01 19:26:31 -0800950 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding black frame");
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700951 mCustomBlackFrame.hide();
Craig Mautnerbf90eaa2012-03-15 11:28:53 -0700952 } else {
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700953 mCustomBlackFrame.setMatrix(mFrameTransformation.getMatrix());
954 }
955 }
956
957 if (mExitingBlackFrame != null) {
958 if (!mMoreStartExit && !mMoreFinishExit && !mMoreRotateExit) {
959 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding exiting frame");
960 mExitingBlackFrame.hide();
961 } else {
962 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
963 mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix);
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700964 if (mForceDefaultOrientation) {
965 mExitingBlackFrame.setAlpha(mExitTransformation.getAlpha());
966 }
Dianne Hackbornd6b32b62012-03-16 11:54:51 -0700967 }
968 }
969
970 if (mEnteringBlackFrame != null) {
971 if (!mMoreStartEnter && !mMoreFinishEnter && !mMoreRotateEnter) {
972 if (DEBUG_STATE) Slog.v(TAG, "Frame animations done, hiding entering frame");
973 mEnteringBlackFrame.hide();
974 } else {
975 mEnteringBlackFrame.setMatrix(mEnterTransformation.getMatrix());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800976 }
977 }
978
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700979 setSnapshotTransformInTransaction(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
Craig Mautnerdbb79912012-03-01 18:59:14 -0800980 }
Craig Mautner7d8df392012-04-06 15:26:23 -0700981
Craig Mautnere32c3072012-03-12 15:25:35 -0700982 public boolean stepAnimationLocked(long now) {
Dianne Hackborn187ae2102012-04-11 18:12:06 -0700983 if (!hasAnimations()) {
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800984 if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
Craig Mautnera731cd32012-03-02 15:23:55 -0800985 mFinishAnimReady = false;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -0800986 return false;
987 }
988
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -0800989 if (!mAnimRunning) {
990 if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
Craig Mautner7d8df392012-04-06 15:26:23 -0700991 if (TWO_PHASE_ANIMATION) {
992 if (mStartEnterAnimation != null) {
993 mStartEnterAnimation.setStartTime(now);
994 }
995 if (mStartExitAnimation != null) {
996 mStartExitAnimation.setStartTime(now);
997 }
998 if (mFinishEnterAnimation != null) {
999 mFinishEnterAnimation.setStartTime(0);
1000 }
1001 if (mFinishExitAnimation != null) {
1002 mFinishExitAnimation.setStartTime(0);
1003 }
Dianne Hackborn89620282011-09-11 12:47:45 -07001004 }
Craig Mautner7d8df392012-04-06 15:26:23 -07001005 if (USE_CUSTOM_BLACK_FRAME) {
1006 if (mStartFrameAnimation != null) {
1007 mStartFrameAnimation.setStartTime(now);
1008 }
1009 if (mFinishFrameAnimation != null) {
1010 mFinishFrameAnimation.setStartTime(0);
1011 }
1012 if (mRotateFrameAnimation != null) {
1013 mRotateFrameAnimation.setStartTime(now);
1014 }
Dianne Hackborn9fd74802012-03-01 19:26:31 -08001015 }
Dianne Hackbornfd1c5ed2012-01-13 13:09:16 -08001016 if (mRotateEnterAnimation != null) {
1017 mRotateEnterAnimation.setStartTime(now);
1018 }
1019 if (mRotateExitAnimation != null) {
1020 mRotateExitAnimation.setStartTime(now);
1021 }
1022 mAnimRunning = true;
Craig Mautner3255a282012-04-16 15:42:47 -07001023 mHalfwayPoint = now + mRotateEnterAnimation.getDuration() / 2;
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08001024 }
Craig Mautnere32c3072012-03-12 15:25:35 -07001025
1026 return stepAnimation(now);
Dianne Hackbornf9d0be92010-11-24 12:35:25 -08001027 }
1028
1029 public Transformation getEnterTransformation() {
1030 return mEnterTransformation;
Dianne Hackborna1111872010-11-23 20:55:11 -08001031 }
1032}