blob: aae52e847e79ebd6b2a04ac1ff1f21ef08e236bd [file] [log] [blame]
Craig Mautnerc2c0a612014-02-20 20:25:41 -08001/*
2 * Copyright (C) 2014 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 */
Craig Mautner59431632012-04-04 11:56:44 -070016
17package com.android.server.wm;
18
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080019import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
20import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
21import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
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;
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -070025import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +010026import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -070027
Craig Mautner59431632012-04-04 11:56:44 -070028import android.graphics.Matrix;
29import android.util.Slog;
Dianne Hackborna57c6952013-03-29 14:46:40 -070030import android.util.TimeUtils;
Jorim Jaggic554b772015-06-04 16:07:57 -070031import android.view.Choreographer;
Craig Mautnera91f9e22012-09-14 16:22:08 -070032import android.view.Display;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080033import android.view.SurfaceControl;
Craig Mautner59431632012-04-04 11:56:44 -070034import android.view.WindowManagerPolicy;
35import android.view.animation.Animation;
36import android.view.animation.Transformation;
37
38import java.io.PrintWriter;
Craig Mautner322e4032012-07-13 13:35:20 -070039import java.util.ArrayList;
Craig Mautner59431632012-04-04 11:56:44 -070040
Craig Mautner59431632012-04-04 11:56:44 -070041public class AppWindowAnimator {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080042 static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowAnimator" : TAG_WM;
Craig Mautner59431632012-04-04 11:56:44 -070043
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -080044 private static final int PROLONG_ANIMATION_DISABLED = 0;
45 static final int PROLONG_ANIMATION_AT_END = 1;
46 static final int PROLONG_ANIMATION_AT_START = 2;
47
Craig Mautner59431632012-04-04 11:56:44 -070048 final AppWindowToken mAppToken;
49 final WindowManagerService mService;
50 final WindowAnimator mAnimator;
51
52 boolean animating;
Jorim Jaggi827e0fa2015-05-07 11:41:41 -070053 boolean wasAnimating;
Craig Mautner59431632012-04-04 11:56:44 -070054 Animation animation;
Craig Mautner59431632012-04-04 11:56:44 -070055 boolean hasTransformation;
56 final Transformation transformation = new Transformation();
57
58 // Have we been asked to have this token keep the screen frozen?
59 // Protect with mAnimator.
60 boolean freezingScreen;
61
Dianne Hackborna57c6952013-03-29 14:46:40 -070062 /**
63 * How long we last kept the screen frozen.
64 */
65 int lastFreezeDuration;
66
Craig Mautner59431632012-04-04 11:56:44 -070067 // Offset to the window of all layers in the token, for use by
68 // AppWindowToken animations.
69 int animLayerAdjustment;
70
Craig Mautner6fbda632012-07-03 09:26:39 -070071 // Propagated from AppWindowToken.allDrawn, to determine when
72 // the state changes.
73 boolean allDrawn;
74
Winson Chungab79fce2014-11-04 16:15:22 -080075 // Special surface for thumbnail animation. If deferThumbnailDestruction is enabled, then we
76 // will make sure that the thumbnail is destroyed after the other surface is completed. This
77 // requires that the duration of the two animations are the same.
Mathias Agopian3866f0d2013-02-11 22:08:48 -080078 SurfaceControl thumbnail;
Craig Mautner59431632012-04-04 11:56:44 -070079 int thumbnailTransactionSeq;
Craig Mautner59431632012-04-04 11:56:44 -070080 int thumbnailLayer;
Winson Chunga4ccb862014-08-22 15:26:27 -070081 int thumbnailForceAboveLayer;
Craig Mautner59431632012-04-04 11:56:44 -070082 Animation thumbnailAnimation;
83 final Transformation thumbnailTransformation = new Transformation();
Winson Chunga4ccb862014-08-22 15:26:27 -070084 // This flag indicates that the destruction of the thumbnail surface is synchronized with
Winson Chungab79fce2014-11-04 16:15:22 -080085 // another animation, so defer the destruction of this thumbnail surface for a single frame
86 // after the secondary animation completes.
Winson Chunga4ccb862014-08-22 15:26:27 -070087 boolean deferThumbnailDestruction;
Winson Chungab79fce2014-11-04 16:15:22 -080088 // This flag is set if the animator has deferThumbnailDestruction set and has reached the final
89 // frame of animation. It will extend the animation by one frame and then clean up afterwards.
90 boolean deferFinalFrameCleanup;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -080091 // If true when the animation hits the last frame, it will keep running on that last frame.
92 // This is used to synchronize animation with Recents and we wait for Recents to tell us to
93 // finish or for a new animation be set as fail-safe mechanism.
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -080094 private int mProlongAnimation;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -080095 // Whether the prolong animation can be removed when animation is set. The purpose of this is
96 // that if recents doesn't tell us to remove the prolonged animation, we will get rid of it
97 // when new animation is set.
98 private boolean mClearProlongedAnimation;
Craig Mautner59431632012-04-04 11:56:44 -070099
Craig Mautner322e4032012-07-13 13:35:20 -0700100 /** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700101 ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<>();
102
103 /** True if the current animation was transferred from another AppWindowAnimator.
104 * See {@link #transferCurrentAnimation}*/
105 boolean usingTransferredAnimation = false;
Craig Mautner322e4032012-07-13 13:35:20 -0700106
Jorim Jaggic554b772015-06-04 16:07:57 -0700107 private boolean mSkipFirstFrame = false;
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100108 private int mStackClip = STACK_CLIP_BEFORE_ANIM;
Jorim Jaggic554b772015-06-04 16:07:57 -0700109
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700110 static final Animation sDummyAnimation = new DummyAnimation();
111
Craig Mautner322e4032012-07-13 13:35:20 -0700112 public AppWindowAnimator(final AppWindowToken atoken) {
Craig Mautner59431632012-04-04 11:56:44 -0700113 mAppToken = atoken;
Craig Mautner322e4032012-07-13 13:35:20 -0700114 mService = atoken.service;
Filip Gruszczynskia590c992015-11-25 16:45:26 -0800115 mAnimator = mService.mAnimator;
Craig Mautner59431632012-04-04 11:56:44 -0700116 }
117
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100118 public void setAnimation(Animation anim, int width, int height, boolean skipFirstFrame,
119 int stackClip) {
Craig Mautner72669d12012-12-18 17:23:54 -0800120 if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting animation in " + mAppToken
121 + ": " + anim + " wxh=" + width + "x" + height
122 + " isVisible=" + mAppToken.isVisible());
Craig Mautner59431632012-04-04 11:56:44 -0700123 animation = anim;
124 animating = false;
Craig Mautner9339c402012-11-30 11:23:56 -0800125 if (!anim.isInitialized()) {
126 anim.initialize(width, height, width, height);
127 }
Craig Mautner59431632012-04-04 11:56:44 -0700128 anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
Dianne Hackborneb94fa72014-06-03 17:48:12 -0700129 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
Craig Mautner59431632012-04-04 11:56:44 -0700130 int zorder = anim.getZAdjustment();
131 int adj = 0;
132 if (zorder == Animation.ZORDER_TOP) {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700133 adj = TYPE_LAYER_OFFSET;
Craig Mautner59431632012-04-04 11:56:44 -0700134 } else if (zorder == Animation.ZORDER_BOTTOM) {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700135 adj = -TYPE_LAYER_OFFSET;
Craig Mautner59431632012-04-04 11:56:44 -0700136 }
137
138 if (animLayerAdjustment != adj) {
139 animLayerAdjustment = adj;
140 updateLayers();
141 }
142 // Start out animation gone if window is gone, or visible if window is visible.
143 transformation.clear();
Craig Mautner72669d12012-12-18 17:23:54 -0800144 transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
Craig Mautner59431632012-04-04 11:56:44 -0700145 hasTransformation = true;
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100146 mStackClip = stackClip;
Craig Mautner1ad99152014-08-28 15:47:13 -0700147
Jorim Jaggic554b772015-06-04 16:07:57 -0700148 this.mSkipFirstFrame = skipFirstFrame;
149
Craig Mautner1ad99152014-08-28 15:47:13 -0700150 if (!mAppToken.appFullscreen) {
151 anim.setBackgroundColor(0);
152 }
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800153 if (mClearProlongedAnimation) {
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800154 mProlongAnimation = PROLONG_ANIMATION_DISABLED;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800155 } else {
156 mClearProlongedAnimation = true;
157 }
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800158
159 // Since we are finally starting our animation, we don't need the logic anymore to prevent
160 // the app from showing again if we just moved between stacks. See
161 // {@link WindowState#notifyMovedInStack}.
162 for (int i = mAppToken.allAppWindows.size() - 1; i >= 0; i--) {
163 mAppToken.allAppWindows.get(i).resetJustMovedInStack();
164 }
Craig Mautner59431632012-04-04 11:56:44 -0700165 }
166
167 public void setDummyAnimation() {
Craig Mautner72669d12012-12-18 17:23:54 -0800168 if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting dummy animation in " + mAppToken
169 + " isVisible=" + mAppToken.isVisible());
Craig Mautner1d961d42012-05-27 12:02:11 -0700170 animation = sDummyAnimation;
Craig Mautner94ef9df2012-05-02 17:08:39 -0700171 hasTransformation = true;
172 transformation.clear();
Craig Mautner72669d12012-12-18 17:23:54 -0800173 transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
Craig Mautner59431632012-04-04 11:56:44 -0700174 }
175
Chong Zhang65d15d02016-03-14 13:59:32 -0700176 void setNullAnimation() {
177 animation = null;
178 usingTransferredAnimation = false;
179 }
180
Craig Mautner59431632012-04-04 11:56:44 -0700181 public void clearAnimation() {
182 if (animation != null) {
Craig Mautner59431632012-04-04 11:56:44 -0700183 animating = true;
Craig Mautner59431632012-04-04 11:56:44 -0700184 }
Winson Chungab79fce2014-11-04 16:15:22 -0800185 clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -0700186 setNullAnimation();
Craig Mautner7636dfb2012-11-16 15:24:11 -0800187 if (mAppToken.deferClearAllDrawn) {
188 mAppToken.allDrawn = false;
189 mAppToken.deferClearAllDrawn = false;
190 }
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100191 mStackClip = STACK_CLIP_BEFORE_ANIM;
Craig Mautner59431632012-04-04 11:56:44 -0700192 }
193
Jorim Jaggi37875612015-02-19 21:05:31 +0100194 public boolean isAnimating() {
195 return animation != null || mAppToken.inPendingTransaction;
196 }
197
Craig Mautner59431632012-04-04 11:56:44 -0700198 public void clearThumbnail() {
199 if (thumbnail != null) {
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100200 thumbnail.hide();
201 mService.mWindowPlacerLocked.destroyAfterTransaction(thumbnail);
Craig Mautner59431632012-04-04 11:56:44 -0700202 thumbnail = null;
203 }
Winson Chungab79fce2014-11-04 16:15:22 -0800204 deferThumbnailDestruction = false;
Winson Chunga4ccb862014-08-22 15:26:27 -0700205 }
206
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100207 int getStackClip() {
208 return mStackClip;
209 }
210
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700211 void transferCurrentAnimation(
212 AppWindowAnimator toAppAnimator, WindowStateAnimator transferWinAnimator) {
213
214 if (animation != null) {
215 toAppAnimator.animation = animation;
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700216 toAppAnimator.animating = animating;
217 toAppAnimator.animLayerAdjustment = animLayerAdjustment;
Chong Zhang65d15d02016-03-14 13:59:32 -0700218 setNullAnimation();
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700219 animLayerAdjustment = 0;
220 toAppAnimator.updateLayers();
221 updateLayers();
222 toAppAnimator.usingTransferredAnimation = true;
223 }
224 if (transferWinAnimator != null) {
225 mAllAppWinAnimators.remove(transferWinAnimator);
226 toAppAnimator.mAllAppWinAnimators.add(transferWinAnimator);
227 transferWinAnimator.mAppAnimator = toAppAnimator;
228 }
229 }
230
Craig Mautner59431632012-04-04 11:56:44 -0700231 void updateLayers() {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700232 final int windowCount = mAppToken.allAppWindows.size();
Craig Mautner59431632012-04-04 11:56:44 -0700233 final int adj = animLayerAdjustment;
234 thumbnailLayer = -1;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700235 final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700236 for (int i = 0; i < windowCount; i++) {
Craig Mautner59431632012-04-04 11:56:44 -0700237 final WindowState w = mAppToken.allAppWindows.get(i);
238 final WindowStateAnimator winAnimator = w.mWinAnimator;
239 winAnimator.mAnimLayer = w.mLayer + adj;
240 if (winAnimator.mAnimLayer > thumbnailLayer) {
241 thumbnailLayer = winAnimator.mAnimLayer;
242 }
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700243 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + winAnimator.mAnimLayer);
Craig Mautner59431632012-04-04 11:56:44 -0700244 if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800245 mService.mLayersController.setInputMethodAnimLayerAdjustment(adj);
Craig Mautner59431632012-04-04 11:56:44 -0700246 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700247 wallpaperController.setAnimLayerAdjustment(w, adj);
Craig Mautner59431632012-04-04 11:56:44 -0700248 }
249 }
250
251 private void stepThumbnailAnimation(long currentTime) {
252 thumbnailTransformation.clear();
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800253 final long animationFrameTime = getAnimationFrameTime(thumbnailAnimation, currentTime);
254 thumbnailAnimation.getTransformation(animationFrameTime, thumbnailTransformation);
Craig Mautnera91f9e22012-09-14 16:22:08 -0700255
256 ScreenRotationAnimation screenRotationAnimation =
257 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
258 final boolean screenAnimation = screenRotationAnimation != null
259 && screenRotationAnimation.isAnimating();
Craig Mautner59431632012-04-04 11:56:44 -0700260 if (screenAnimation) {
Craig Mautnera91f9e22012-09-14 16:22:08 -0700261 thumbnailTransformation.postCompose(screenRotationAnimation.getEnterTransformation());
Craig Mautner59431632012-04-04 11:56:44 -0700262 }
263 // cache often used attributes locally
264 final float tmpFloats[] = mService.mTmpFloats;
265 thumbnailTransformation.getMatrix().getValues(tmpFloats);
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700266 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
Craig Mautner59431632012-04-04 11:56:44 -0700267 "thumbnail", "POS " + tmpFloats[Matrix.MTRANS_X]
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -0800268 + ", " + tmpFloats[Matrix.MTRANS_Y]);
Craig Mautner59431632012-04-04 11:56:44 -0700269 thumbnail.setPosition(tmpFloats[Matrix.MTRANS_X], tmpFloats[Matrix.MTRANS_Y]);
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700270 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
Craig Mautner59431632012-04-04 11:56:44 -0700271 "thumbnail", "alpha=" + thumbnailTransformation.getAlpha()
272 + " layer=" + thumbnailLayer
273 + " matrix=[" + tmpFloats[Matrix.MSCALE_X]
274 + "," + tmpFloats[Matrix.MSKEW_Y]
275 + "][" + tmpFloats[Matrix.MSKEW_X]
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -0800276 + "," + tmpFloats[Matrix.MSCALE_Y] + "]");
Craig Mautner59431632012-04-04 11:56:44 -0700277 thumbnail.setAlpha(thumbnailTransformation.getAlpha());
Winson Chunga4ccb862014-08-22 15:26:27 -0700278 if (thumbnailForceAboveLayer > 0) {
279 thumbnail.setLayer(thumbnailForceAboveLayer + 1);
280 } else {
281 // The thumbnail is layered below the window immediately above this
282 // token's anim layer.
283 thumbnail.setLayer(thumbnailLayer + WindowManagerService.WINDOW_LAYER_MULTIPLIER
284 - WindowManagerService.LAYER_OFFSET_THUMBNAIL);
285 }
Craig Mautner59431632012-04-04 11:56:44 -0700286 thumbnail.setMatrix(tmpFloats[Matrix.MSCALE_X], tmpFloats[Matrix.MSKEW_Y],
287 tmpFloats[Matrix.MSKEW_X], tmpFloats[Matrix.MSCALE_Y]);
Jorim Jaggide63d442016-03-14 14:56:56 +0100288 thumbnail.setWindowCrop(thumbnailTransformation.getClipRect());
Craig Mautner59431632012-04-04 11:56:44 -0700289 }
290
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800291 /**
292 * Sometimes we need to synchronize the first frame of animation with some external event, e.g.
293 * Recents hiding some of its content. To achieve this, we prolong the start of the animaiton
294 * and keep producing the first frame of the animation.
295 */
296 private long getAnimationFrameTime(Animation animation, long currentTime) {
297 if (mProlongAnimation == PROLONG_ANIMATION_AT_START) {
298 animation.setStartTime(currentTime);
299 return currentTime + 1;
300 }
301 return currentTime;
302 }
303
Craig Mautner59431632012-04-04 11:56:44 -0700304 private boolean stepAnimation(long currentTime) {
305 if (animation == null) {
306 return false;
307 }
308 transformation.clear();
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800309 final long animationFrameTime = getAnimationFrameTime(animation, currentTime);
310 boolean hasMoreFrames = animation.getTransformation(animationFrameTime, transformation);
Winson Chungab79fce2014-11-04 16:15:22 -0800311 if (!hasMoreFrames) {
312 if (deferThumbnailDestruction && !deferFinalFrameCleanup) {
313 // We are deferring the thumbnail destruction, so extend the animation for one more
314 // (dummy) frame before we clean up
315 deferFinalFrameCleanup = true;
316 hasMoreFrames = true;
317 } else {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700318 if (false && DEBUG_ANIM) Slog.v(TAG,
319 "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800320 ", xform=" + transformation + ", mProlongAnimation=" + mProlongAnimation);
Winson Chungab79fce2014-11-04 16:15:22 -0800321 deferFinalFrameCleanup = false;
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800322 if (mProlongAnimation == PROLONG_ANIMATION_AT_END) {
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800323 hasMoreFrames = true;
324 } else {
Chong Zhang65d15d02016-03-14 13:59:32 -0700325 setNullAnimation();
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800326 clearThumbnail();
327 if (DEBUG_ANIM) Slog.v(TAG, "Finished animation in " + mAppToken + " @ "
328 + currentTime);
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800329 }
Winson Chunga4ccb862014-08-22 15:26:27 -0700330 }
Craig Mautner59431632012-04-04 11:56:44 -0700331 }
Winson Chungab79fce2014-11-04 16:15:22 -0800332 hasTransformation = hasMoreFrames;
333 return hasMoreFrames;
Craig Mautner59431632012-04-04 11:56:44 -0700334 }
335
Jorim Jaggic554b772015-06-04 16:07:57 -0700336 private long getStartTimeCorrection() {
337 if (mSkipFirstFrame) {
338
339 // If the transition is an animation in which the first frame doesn't change the screen
340 // contents at all, we can just skip it and start at the second frame. So we shift the
341 // start time of the animation forward by minus the frame duration.
342 return -Choreographer.getInstance().getFrameIntervalNanos() / TimeUtils.NANOS_PER_MS;
343 } else {
344 return 0;
345 }
346 }
347
Craig Mautner59431632012-04-04 11:56:44 -0700348 // This must be called while inside a transaction.
Wale Ogunwalef16a2812015-04-01 11:23:15 -0700349 boolean stepAnimationLocked(long currentTime, final int displayId) {
Craig Mautner59431632012-04-04 11:56:44 -0700350 if (mService.okToDisplay()) {
351 // We will run animations as long as the display isn't frozen.
352
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700353 if (animation == sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -0700354 // This guy is going to animate, but not yet. For now count
355 // it as not animating for purposes of scheduling transactions;
356 // when it is really time to animate, this will be set to
357 // a real animation and the next call will execute normally.
358 return false;
359 }
360
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800361 if ((mAppToken.allDrawn || animating || mAppToken.startingDisplayed)
Craig Mautner59431632012-04-04 11:56:44 -0700362 && animation != null) {
363 if (!animating) {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700364 if (DEBUG_ANIM) Slog.v(TAG,
365 "Starting animation in " + mAppToken +
Dianne Hackborneb94fa72014-06-03 17:48:12 -0700366 " @ " + currentTime + " scale="
367 + mService.getTransitionAnimationScaleLocked()
Craig Mautner59431632012-04-04 11:56:44 -0700368 + " allDrawn=" + mAppToken.allDrawn + " animating=" + animating);
Jorim Jaggic554b772015-06-04 16:07:57 -0700369 long correction = getStartTimeCorrection();
370 animation.setStartTime(currentTime + correction);
Craig Mautner59431632012-04-04 11:56:44 -0700371 animating = true;
372 if (thumbnail != null) {
373 thumbnail.show();
Jorim Jaggic554b772015-06-04 16:07:57 -0700374 thumbnailAnimation.setStartTime(currentTime + correction);
Craig Mautner59431632012-04-04 11:56:44 -0700375 }
Jorim Jaggic554b772015-06-04 16:07:57 -0700376 mSkipFirstFrame = false;
Craig Mautner59431632012-04-04 11:56:44 -0700377 }
378 if (stepAnimation(currentTime)) {
379 // animation isn't over, step any thumbnail and that's
380 // it for now.
381 if (thumbnail != null) {
382 stepThumbnailAnimation(currentTime);
383 }
384 return true;
385 }
386 }
387 } else if (animation != null) {
388 // If the display is frozen, and there is a pending animation,
389 // clear it and make sure we run the cleanup code.
390 animating = true;
391 animation = null;
392 }
393
394 hasTransformation = false;
395
Craig Mautner3de422f2012-04-06 18:04:13 -0700396 if (!animating && animation == null) {
Craig Mautner59431632012-04-04 11:56:44 -0700397 return false;
398 }
399
Craig Mautner76a71652012-09-03 23:23:58 -0700400 mAnimator.setAppLayoutChanges(this, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM,
Wale Ogunwalef16a2812015-04-01 11:23:15 -0700401 "AppWindowToken", displayId);
Craig Mautner59431632012-04-04 11:56:44 -0700402
403 clearAnimation();
404 animating = false;
405 if (animLayerAdjustment != 0) {
406 animLayerAdjustment = 0;
407 updateLayers();
408 }
409 if (mService.mInputMethodTarget != null
410 && mService.mInputMethodTarget.mAppToken == mAppToken) {
411 mService.moveInputMethodWindowsIfNeededLocked(true);
412 }
413
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700414 if (DEBUG_ANIM) Slog.v(TAG,
415 "Animation done in " + mAppToken
Craig Mautner59431632012-04-04 11:56:44 -0700416 + ": reportedVisible=" + mAppToken.reportedVisible);
417
418 transformation.clear();
419
Wale Ogunwaleec533f62014-12-05 09:03:48 -0800420 final int numAllAppWinAnimators = mAllAppWinAnimators.size();
421 for (int i = 0; i < numAllAppWinAnimators; i++) {
422 mAllAppWinAnimators.get(i).finishExit();
Craig Mautner59431632012-04-04 11:56:44 -0700423 }
Wale Ogunwalea48eadb2015-05-14 17:43:12 -0700424 mService.mAppTransition.notifyAppTransitionFinishedLocked(mAppToken.token);
Craig Mautner59431632012-04-04 11:56:44 -0700425 return false;
426 }
427
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700428 // This must be called while inside a transaction.
Craig Mautnerbec53f72012-04-05 11:49:05 -0700429 boolean showAllWindowsLocked() {
430 boolean isAnimating = false;
Craig Mautner322e4032012-07-13 13:35:20 -0700431 final int NW = mAllAppWinAnimators.size();
Craig Mautnerbec53f72012-04-05 11:49:05 -0700432 for (int i=0; i<NW; i++) {
Craig Mautner322e4032012-07-13 13:35:20 -0700433 WindowStateAnimator winAnimator = mAllAppWinAnimators.get(i);
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800434 if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + winAnimator);
Craig Mautnerbec53f72012-04-05 11:49:05 -0700435 winAnimator.performShowLocked();
436 isAnimating |= winAnimator.isAnimating();
437 }
438 return isAnimating;
439 }
440
Dianne Hackborn529e7442012-11-01 14:22:28 -0700441 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
442 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
443 pw.print(prefix); pw.print("mAnimator="); pw.println(mAnimator);
444 pw.print(prefix); pw.print("freezingScreen="); pw.print(freezingScreen);
445 pw.print(" allDrawn="); pw.print(allDrawn);
446 pw.print(" animLayerAdjustment="); pw.println(animLayerAdjustment);
Dianne Hackborna57c6952013-03-29 14:46:40 -0700447 if (lastFreezeDuration != 0) {
448 pw.print(prefix); pw.print("lastFreezeDuration=");
449 TimeUtils.formatDuration(lastFreezeDuration, pw); pw.println();
450 }
Craig Mautner59431632012-04-04 11:56:44 -0700451 if (animating || animation != null) {
Craig Mautner9339c402012-11-30 11:23:56 -0800452 pw.print(prefix); pw.print("animating="); pw.println(animating);
Dianne Hackborn529e7442012-11-01 14:22:28 -0700453 pw.print(prefix); pw.print("animation="); pw.println(animation);
Craig Mautner59431632012-04-04 11:56:44 -0700454 }
455 if (hasTransformation) {
456 pw.print(prefix); pw.print("XForm: ");
457 transformation.printShortString(pw);
458 pw.println();
459 }
Craig Mautner59431632012-04-04 11:56:44 -0700460 if (thumbnail != null) {
461 pw.print(prefix); pw.print("thumbnail="); pw.print(thumbnail);
Craig Mautner59431632012-04-04 11:56:44 -0700462 pw.print(" layer="); pw.println(thumbnailLayer);
463 pw.print(prefix); pw.print("thumbnailAnimation="); pw.println(thumbnailAnimation);
464 pw.print(prefix); pw.print("thumbnailTransformation=");
465 pw.println(thumbnailTransformation.toShortString());
466 }
Dianne Hackborn529e7442012-11-01 14:22:28 -0700467 for (int i=0; i<mAllAppWinAnimators.size(); i++) {
468 WindowStateAnimator wanim = mAllAppWinAnimators.get(i);
469 pw.print(prefix); pw.print("App Win Anim #"); pw.print(i);
470 pw.print(": "); pw.println(wanim);
471 }
Craig Mautner59431632012-04-04 11:56:44 -0700472 }
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700473
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800474 void startProlongAnimation(int prolongType) {
475 mProlongAnimation = prolongType;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800476 mClearProlongedAnimation = false;
477 }
478
479 void endProlongedAnimation() {
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800480 mProlongAnimation = PROLONG_ANIMATION_DISABLED;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800481 }
482
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700483 // This is an animation that does nothing: it just immediately finishes
484 // itself every time it is called. It is used as a stub animation in cases
485 // where we want to synchronize multiple things that may be animating.
486 static final class DummyAnimation extends Animation {
487 @Override
488 public boolean getTransformation(long currentTime, Transformation outTransformation) {
489 return false;
490 }
491 }
492
Craig Mautner59431632012-04-04 11:56:44 -0700493}