blob: 305e47fbe0213b4f6b641e798141bdf340571737 [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;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080020import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
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;
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -070024import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +010025import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -070026
Craig Mautner59431632012-04-04 11:56:44 -070027import android.graphics.Matrix;
28import android.util.Slog;
Dianne Hackborna57c6952013-03-29 14:46:40 -070029import android.util.TimeUtils;
Jorim Jaggic554b772015-06-04 16:07:57 -070030import android.view.Choreographer;
Craig Mautnera91f9e22012-09-14 16:22:08 -070031import android.view.Display;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080032import android.view.SurfaceControl;
Craig Mautner59431632012-04-04 11:56:44 -070033import android.view.WindowManagerPolicy;
34import android.view.animation.Animation;
35import android.view.animation.Transformation;
36
37import java.io.PrintWriter;
Craig Mautner322e4032012-07-13 13:35:20 -070038import java.util.ArrayList;
Craig Mautner59431632012-04-04 11:56:44 -070039
Craig Mautner59431632012-04-04 11:56:44 -070040public class AppWindowAnimator {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080041 static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowAnimator" : TAG_WM;
Craig Mautner59431632012-04-04 11:56:44 -070042
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -080043 private static final int PROLONG_ANIMATION_DISABLED = 0;
44 static final int PROLONG_ANIMATION_AT_END = 1;
45 static final int PROLONG_ANIMATION_AT_START = 2;
46
Craig Mautner59431632012-04-04 11:56:44 -070047 final AppWindowToken mAppToken;
48 final WindowManagerService mService;
49 final WindowAnimator mAnimator;
50
51 boolean animating;
Jorim Jaggi827e0fa2015-05-07 11:41:41 -070052 boolean wasAnimating;
Craig Mautner59431632012-04-04 11:56:44 -070053 Animation animation;
Craig Mautner59431632012-04-04 11:56:44 -070054 boolean hasTransformation;
55 final Transformation transformation = new Transformation();
56
57 // Have we been asked to have this token keep the screen frozen?
58 // Protect with mAnimator.
59 boolean freezingScreen;
60
Dianne Hackborna57c6952013-03-29 14:46:40 -070061 /**
62 * How long we last kept the screen frozen.
63 */
64 int lastFreezeDuration;
65
Craig Mautner59431632012-04-04 11:56:44 -070066 // Offset to the window of all layers in the token, for use by
67 // AppWindowToken animations.
68 int animLayerAdjustment;
69
Craig Mautner6fbda632012-07-03 09:26:39 -070070 // Propagated from AppWindowToken.allDrawn, to determine when
71 // the state changes.
72 boolean allDrawn;
73
Winson Chungab79fce2014-11-04 16:15:22 -080074 // Special surface for thumbnail animation. If deferThumbnailDestruction is enabled, then we
75 // will make sure that the thumbnail is destroyed after the other surface is completed. This
76 // requires that the duration of the two animations are the same.
Mathias Agopian3866f0d2013-02-11 22:08:48 -080077 SurfaceControl thumbnail;
Craig Mautner59431632012-04-04 11:56:44 -070078 int thumbnailTransactionSeq;
Craig Mautner59431632012-04-04 11:56:44 -070079 int thumbnailLayer;
Winson Chunga4ccb862014-08-22 15:26:27 -070080 int thumbnailForceAboveLayer;
Craig Mautner59431632012-04-04 11:56:44 -070081 Animation thumbnailAnimation;
82 final Transformation thumbnailTransformation = new Transformation();
Winson Chunga4ccb862014-08-22 15:26:27 -070083 // This flag indicates that the destruction of the thumbnail surface is synchronized with
Winson Chungab79fce2014-11-04 16:15:22 -080084 // another animation, so defer the destruction of this thumbnail surface for a single frame
85 // after the secondary animation completes.
Winson Chunga4ccb862014-08-22 15:26:27 -070086 boolean deferThumbnailDestruction;
Winson Chungab79fce2014-11-04 16:15:22 -080087 // This flag is set if the animator has deferThumbnailDestruction set and has reached the final
88 // frame of animation. It will extend the animation by one frame and then clean up afterwards.
89 boolean deferFinalFrameCleanup;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -080090 // If true when the animation hits the last frame, it will keep running on that last frame.
91 // This is used to synchronize animation with Recents and we wait for Recents to tell us to
92 // finish or for a new animation be set as fail-safe mechanism.
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -080093 private int mProlongAnimation;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -080094 // Whether the prolong animation can be removed when animation is set. The purpose of this is
95 // that if recents doesn't tell us to remove the prolonged animation, we will get rid of it
96 // when new animation is set.
97 private boolean mClearProlongedAnimation;
Craig Mautner59431632012-04-04 11:56:44 -070098
Craig Mautner322e4032012-07-13 13:35:20 -070099 /** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700100 ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<>();
101
102 /** True if the current animation was transferred from another AppWindowAnimator.
103 * See {@link #transferCurrentAnimation}*/
104 boolean usingTransferredAnimation = false;
Craig Mautner322e4032012-07-13 13:35:20 -0700105
Jorim Jaggic554b772015-06-04 16:07:57 -0700106 private boolean mSkipFirstFrame = false;
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100107 private int mStackClip = STACK_CLIP_BEFORE_ANIM;
Jorim Jaggic554b772015-06-04 16:07:57 -0700108
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700109 static final Animation sDummyAnimation = new DummyAnimation();
110
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700111 public AppWindowAnimator(final AppWindowToken atoken, WindowManagerService service) {
Craig Mautner59431632012-04-04 11:56:44 -0700112 mAppToken = atoken;
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700113 mService = service;
Filip Gruszczynskia590c992015-11-25 16:45:26 -0800114 mAnimator = mService.mAnimator;
Craig Mautner59431632012-04-04 11:56:44 -0700115 }
116
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100117 public void setAnimation(Animation anim, int width, int height, boolean skipFirstFrame,
118 int stackClip) {
Craig Mautner72669d12012-12-18 17:23:54 -0800119 if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting animation in " + mAppToken
120 + ": " + anim + " wxh=" + width + "x" + height
Wale Ogunwale44f21802016-09-02 12:49:48 -0700121 + " hasContentToDisplay=" + mAppToken.hasContentToDisplay());
Craig Mautner59431632012-04-04 11:56:44 -0700122 animation = anim;
123 animating = false;
Craig Mautner9339c402012-11-30 11:23:56 -0800124 if (!anim.isInitialized()) {
125 anim.initialize(width, height, width, height);
126 }
Craig Mautner59431632012-04-04 11:56:44 -0700127 anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
Dianne Hackborneb94fa72014-06-03 17:48:12 -0700128 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
Craig Mautner59431632012-04-04 11:56:44 -0700129 int zorder = anim.getZAdjustment();
130 int adj = 0;
131 if (zorder == Animation.ZORDER_TOP) {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700132 adj = TYPE_LAYER_OFFSET;
Craig Mautner59431632012-04-04 11:56:44 -0700133 } else if (zorder == Animation.ZORDER_BOTTOM) {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700134 adj = -TYPE_LAYER_OFFSET;
Craig Mautner59431632012-04-04 11:56:44 -0700135 }
136
137 if (animLayerAdjustment != adj) {
138 animLayerAdjustment = adj;
139 updateLayers();
140 }
141 // Start out animation gone if window is gone, or visible if window is visible.
142 transformation.clear();
Wale Ogunwale44f21802016-09-02 12:49:48 -0700143 transformation.setAlpha(mAppToken.hasContentToDisplay() ? 1 : 0);
Craig Mautner59431632012-04-04 11:56:44 -0700144 hasTransformation = true;
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100145 mStackClip = stackClip;
Craig Mautner1ad99152014-08-28 15:47:13 -0700146
Jorim Jaggic554b772015-06-04 16:07:57 -0700147 this.mSkipFirstFrame = skipFirstFrame;
148
Wale Ogunwale51362492016-09-08 17:49:17 -0700149 if (!mAppToken.fillsParent()) {
Craig Mautner1ad99152014-08-28 15:47:13 -0700150 anim.setBackgroundColor(0);
151 }
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800152 if (mClearProlongedAnimation) {
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800153 mProlongAnimation = PROLONG_ANIMATION_DISABLED;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800154 } else {
155 mClearProlongedAnimation = true;
156 }
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800157
158 // Since we are finally starting our animation, we don't need the logic anymore to prevent
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700159 // the app from showing again if we just moved between stacks.
160 // See {@link WindowState#notifyMovedInStack}.
161 mAppToken.resetJustMovedInStack();
Craig Mautner59431632012-04-04 11:56:44 -0700162 }
163
164 public void setDummyAnimation() {
Craig Mautner72669d12012-12-18 17:23:54 -0800165 if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting dummy animation in " + mAppToken
Wale Ogunwale44f21802016-09-02 12:49:48 -0700166 + " hasContentToDisplay=" + mAppToken.hasContentToDisplay());
Craig Mautner1d961d42012-05-27 12:02:11 -0700167 animation = sDummyAnimation;
Craig Mautner94ef9df2012-05-02 17:08:39 -0700168 hasTransformation = true;
169 transformation.clear();
Wale Ogunwale44f21802016-09-02 12:49:48 -0700170 transformation.setAlpha(mAppToken.hasContentToDisplay() ? 1 : 0);
Craig Mautner59431632012-04-04 11:56:44 -0700171 }
172
Chong Zhang65d15d02016-03-14 13:59:32 -0700173 void setNullAnimation() {
174 animation = null;
175 usingTransferredAnimation = false;
176 }
177
Craig Mautner59431632012-04-04 11:56:44 -0700178 public void clearAnimation() {
179 if (animation != null) {
Craig Mautner59431632012-04-04 11:56:44 -0700180 animating = true;
Craig Mautner59431632012-04-04 11:56:44 -0700181 }
Winson Chungab79fce2014-11-04 16:15:22 -0800182 clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -0700183 setNullAnimation();
Craig Mautner7636dfb2012-11-16 15:24:11 -0800184 if (mAppToken.deferClearAllDrawn) {
Chong Zhang92147042016-05-09 12:47:11 -0700185 mAppToken.clearAllDrawn();
Craig Mautner7636dfb2012-11-16 15:24:11 -0800186 }
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100187 mStackClip = STACK_CLIP_BEFORE_ANIM;
Craig Mautner59431632012-04-04 11:56:44 -0700188 }
189
Jorim Jaggi37875612015-02-19 21:05:31 +0100190 public boolean isAnimating() {
191 return animation != null || mAppToken.inPendingTransaction;
192 }
193
Craig Mautner59431632012-04-04 11:56:44 -0700194 public void clearThumbnail() {
195 if (thumbnail != null) {
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100196 thumbnail.hide();
197 mService.mWindowPlacerLocked.destroyAfterTransaction(thumbnail);
Craig Mautner59431632012-04-04 11:56:44 -0700198 thumbnail = null;
199 }
Winson Chungab79fce2014-11-04 16:15:22 -0800200 deferThumbnailDestruction = false;
Winson Chunga4ccb862014-08-22 15:26:27 -0700201 }
202
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100203 int getStackClip() {
204 return mStackClip;
205 }
206
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700207 void transferCurrentAnimation(
208 AppWindowAnimator toAppAnimator, WindowStateAnimator transferWinAnimator) {
209
210 if (animation != null) {
211 toAppAnimator.animation = animation;
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700212 toAppAnimator.animating = animating;
213 toAppAnimator.animLayerAdjustment = animLayerAdjustment;
Chong Zhang65d15d02016-03-14 13:59:32 -0700214 setNullAnimation();
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700215 animLayerAdjustment = 0;
216 toAppAnimator.updateLayers();
217 updateLayers();
218 toAppAnimator.usingTransferredAnimation = true;
219 }
220 if (transferWinAnimator != null) {
221 mAllAppWinAnimators.remove(transferWinAnimator);
222 toAppAnimator.mAllAppWinAnimators.add(transferWinAnimator);
Chong Zhang8e062652016-04-29 15:58:45 -0700223 toAppAnimator.hasTransformation = transferWinAnimator.mAppAnimator.hasTransformation;
224 if (toAppAnimator.hasTransformation) {
225 toAppAnimator.transformation.set(transferWinAnimator.mAppAnimator.transformation);
226 } else {
227 toAppAnimator.transformation.clear();
228 }
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700229 transferWinAnimator.mAppAnimator = toAppAnimator;
230 }
231 }
232
Craig Mautner59431632012-04-04 11:56:44 -0700233 void updateLayers() {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700234 thumbnailLayer = mAppToken.adjustAnimLayer(animLayerAdjustment);
Craig Mautner59431632012-04-04 11:56:44 -0700235 }
236
237 private void stepThumbnailAnimation(long currentTime) {
238 thumbnailTransformation.clear();
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800239 final long animationFrameTime = getAnimationFrameTime(thumbnailAnimation, currentTime);
240 thumbnailAnimation.getTransformation(animationFrameTime, thumbnailTransformation);
Craig Mautnera91f9e22012-09-14 16:22:08 -0700241
242 ScreenRotationAnimation screenRotationAnimation =
243 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
244 final boolean screenAnimation = screenRotationAnimation != null
245 && screenRotationAnimation.isAnimating();
Craig Mautner59431632012-04-04 11:56:44 -0700246 if (screenAnimation) {
Craig Mautnera91f9e22012-09-14 16:22:08 -0700247 thumbnailTransformation.postCompose(screenRotationAnimation.getEnterTransformation());
Craig Mautner59431632012-04-04 11:56:44 -0700248 }
249 // cache often used attributes locally
250 final float tmpFloats[] = mService.mTmpFloats;
251 thumbnailTransformation.getMatrix().getValues(tmpFloats);
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700252 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
Craig Mautner59431632012-04-04 11:56:44 -0700253 "thumbnail", "POS " + tmpFloats[Matrix.MTRANS_X]
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -0800254 + ", " + tmpFloats[Matrix.MTRANS_Y]);
Craig Mautner59431632012-04-04 11:56:44 -0700255 thumbnail.setPosition(tmpFloats[Matrix.MTRANS_X], tmpFloats[Matrix.MTRANS_Y]);
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700256 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
Craig Mautner59431632012-04-04 11:56:44 -0700257 "thumbnail", "alpha=" + thumbnailTransformation.getAlpha()
258 + " layer=" + thumbnailLayer
259 + " matrix=[" + tmpFloats[Matrix.MSCALE_X]
260 + "," + tmpFloats[Matrix.MSKEW_Y]
261 + "][" + tmpFloats[Matrix.MSKEW_X]
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -0800262 + "," + tmpFloats[Matrix.MSCALE_Y] + "]");
Craig Mautner59431632012-04-04 11:56:44 -0700263 thumbnail.setAlpha(thumbnailTransformation.getAlpha());
Winson Chunga4ccb862014-08-22 15:26:27 -0700264 if (thumbnailForceAboveLayer > 0) {
265 thumbnail.setLayer(thumbnailForceAboveLayer + 1);
266 } else {
267 // The thumbnail is layered below the window immediately above this
268 // token's anim layer.
269 thumbnail.setLayer(thumbnailLayer + WindowManagerService.WINDOW_LAYER_MULTIPLIER
270 - WindowManagerService.LAYER_OFFSET_THUMBNAIL);
271 }
Craig Mautner59431632012-04-04 11:56:44 -0700272 thumbnail.setMatrix(tmpFloats[Matrix.MSCALE_X], tmpFloats[Matrix.MSKEW_Y],
273 tmpFloats[Matrix.MSKEW_X], tmpFloats[Matrix.MSCALE_Y]);
Jorim Jaggide63d442016-03-14 14:56:56 +0100274 thumbnail.setWindowCrop(thumbnailTransformation.getClipRect());
Craig Mautner59431632012-04-04 11:56:44 -0700275 }
276
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800277 /**
278 * Sometimes we need to synchronize the first frame of animation with some external event, e.g.
279 * Recents hiding some of its content. To achieve this, we prolong the start of the animaiton
280 * and keep producing the first frame of the animation.
281 */
282 private long getAnimationFrameTime(Animation animation, long currentTime) {
283 if (mProlongAnimation == PROLONG_ANIMATION_AT_START) {
284 animation.setStartTime(currentTime);
285 return currentTime + 1;
286 }
287 return currentTime;
288 }
289
Craig Mautner59431632012-04-04 11:56:44 -0700290 private boolean stepAnimation(long currentTime) {
291 if (animation == null) {
292 return false;
293 }
294 transformation.clear();
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800295 final long animationFrameTime = getAnimationFrameTime(animation, currentTime);
296 boolean hasMoreFrames = animation.getTransformation(animationFrameTime, transformation);
Winson Chungab79fce2014-11-04 16:15:22 -0800297 if (!hasMoreFrames) {
298 if (deferThumbnailDestruction && !deferFinalFrameCleanup) {
299 // We are deferring the thumbnail destruction, so extend the animation for one more
300 // (dummy) frame before we clean up
301 deferFinalFrameCleanup = true;
302 hasMoreFrames = true;
303 } else {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700304 if (false && DEBUG_ANIM) Slog.v(TAG,
305 "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800306 ", xform=" + transformation + ", mProlongAnimation=" + mProlongAnimation);
Winson Chungab79fce2014-11-04 16:15:22 -0800307 deferFinalFrameCleanup = false;
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800308 if (mProlongAnimation == PROLONG_ANIMATION_AT_END) {
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800309 hasMoreFrames = true;
310 } else {
Chong Zhang65d15d02016-03-14 13:59:32 -0700311 setNullAnimation();
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800312 clearThumbnail();
313 if (DEBUG_ANIM) Slog.v(TAG, "Finished animation in " + mAppToken + " @ "
314 + currentTime);
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800315 }
Winson Chunga4ccb862014-08-22 15:26:27 -0700316 }
Craig Mautner59431632012-04-04 11:56:44 -0700317 }
Winson Chungab79fce2014-11-04 16:15:22 -0800318 hasTransformation = hasMoreFrames;
319 return hasMoreFrames;
Craig Mautner59431632012-04-04 11:56:44 -0700320 }
321
Jorim Jaggic554b772015-06-04 16:07:57 -0700322 private long getStartTimeCorrection() {
323 if (mSkipFirstFrame) {
324
325 // If the transition is an animation in which the first frame doesn't change the screen
326 // contents at all, we can just skip it and start at the second frame. So we shift the
327 // start time of the animation forward by minus the frame duration.
328 return -Choreographer.getInstance().getFrameIntervalNanos() / TimeUtils.NANOS_PER_MS;
329 } else {
330 return 0;
331 }
332 }
333
Craig Mautner59431632012-04-04 11:56:44 -0700334 // This must be called while inside a transaction.
Wale Ogunwalef16a2812015-04-01 11:23:15 -0700335 boolean stepAnimationLocked(long currentTime, final int displayId) {
Craig Mautner59431632012-04-04 11:56:44 -0700336 if (mService.okToDisplay()) {
337 // We will run animations as long as the display isn't frozen.
338
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700339 if (animation == sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -0700340 // This guy is going to animate, but not yet. For now count
341 // it as not animating for purposes of scheduling transactions;
342 // when it is really time to animate, this will be set to
343 // a real animation and the next call will execute normally.
344 return false;
345 }
346
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800347 if ((mAppToken.allDrawn || animating || mAppToken.startingDisplayed)
Craig Mautner59431632012-04-04 11:56:44 -0700348 && animation != null) {
349 if (!animating) {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700350 if (DEBUG_ANIM) Slog.v(TAG,
351 "Starting animation in " + mAppToken +
Dianne Hackborneb94fa72014-06-03 17:48:12 -0700352 " @ " + currentTime + " scale="
353 + mService.getTransitionAnimationScaleLocked()
Craig Mautner59431632012-04-04 11:56:44 -0700354 + " allDrawn=" + mAppToken.allDrawn + " animating=" + animating);
Jorim Jaggic554b772015-06-04 16:07:57 -0700355 long correction = getStartTimeCorrection();
356 animation.setStartTime(currentTime + correction);
Craig Mautner59431632012-04-04 11:56:44 -0700357 animating = true;
358 if (thumbnail != null) {
359 thumbnail.show();
Jorim Jaggic554b772015-06-04 16:07:57 -0700360 thumbnailAnimation.setStartTime(currentTime + correction);
Craig Mautner59431632012-04-04 11:56:44 -0700361 }
Jorim Jaggic554b772015-06-04 16:07:57 -0700362 mSkipFirstFrame = false;
Craig Mautner59431632012-04-04 11:56:44 -0700363 }
364 if (stepAnimation(currentTime)) {
365 // animation isn't over, step any thumbnail and that's
366 // it for now.
367 if (thumbnail != null) {
368 stepThumbnailAnimation(currentTime);
369 }
370 return true;
371 }
372 }
373 } else if (animation != null) {
374 // If the display is frozen, and there is a pending animation,
375 // clear it and make sure we run the cleanup code.
376 animating = true;
377 animation = null;
378 }
379
380 hasTransformation = false;
381
Craig Mautner3de422f2012-04-06 18:04:13 -0700382 if (!animating && animation == null) {
Craig Mautner59431632012-04-04 11:56:44 -0700383 return false;
384 }
385
Wale Ogunwale15ead902016-09-02 14:30:11 -0700386 mAppToken.setAppLayoutChanges(
387 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM, "AppWindowToken", displayId);
Craig Mautner59431632012-04-04 11:56:44 -0700388
389 clearAnimation();
390 animating = false;
391 if (animLayerAdjustment != 0) {
392 animLayerAdjustment = 0;
393 updateLayers();
394 }
395 if (mService.mInputMethodTarget != null
396 && mService.mInputMethodTarget.mAppToken == mAppToken) {
397 mService.moveInputMethodWindowsIfNeededLocked(true);
398 }
399
Wale Ogunwale15ead902016-09-02 14:30:11 -0700400 if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + mAppToken
Craig Mautner59431632012-04-04 11:56:44 -0700401 + ": reportedVisible=" + mAppToken.reportedVisible);
402
403 transformation.clear();
404
Wale Ogunwaleec533f62014-12-05 09:03:48 -0800405 final int numAllAppWinAnimators = mAllAppWinAnimators.size();
406 for (int i = 0; i < numAllAppWinAnimators; i++) {
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700407 mAllAppWinAnimators.get(i).mWin.onExitAnimationDone();
Craig Mautner59431632012-04-04 11:56:44 -0700408 }
Wale Ogunwalea48eadb2015-05-14 17:43:12 -0700409 mService.mAppTransition.notifyAppTransitionFinishedLocked(mAppToken.token);
Craig Mautner59431632012-04-04 11:56:44 -0700410 return false;
411 }
412
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700413 // This must be called while inside a transaction.
Craig Mautnerbec53f72012-04-05 11:49:05 -0700414 boolean showAllWindowsLocked() {
415 boolean isAnimating = false;
Craig Mautner322e4032012-07-13 13:35:20 -0700416 final int NW = mAllAppWinAnimators.size();
Craig Mautnerbec53f72012-04-05 11:49:05 -0700417 for (int i=0; i<NW; i++) {
Craig Mautner322e4032012-07-13 13:35:20 -0700418 WindowStateAnimator winAnimator = mAllAppWinAnimators.get(i);
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800419 if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + winAnimator);
Wale Ogunwale9d147902016-07-16 11:58:55 -0700420 winAnimator.mWin.performShowLocked();
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700421 isAnimating |= winAnimator.isAnimationSet();
Craig Mautnerbec53f72012-04-05 11:49:05 -0700422 }
423 return isAnimating;
424 }
425
Dianne Hackborn529e7442012-11-01 14:22:28 -0700426 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
427 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
428 pw.print(prefix); pw.print("mAnimator="); pw.println(mAnimator);
429 pw.print(prefix); pw.print("freezingScreen="); pw.print(freezingScreen);
430 pw.print(" allDrawn="); pw.print(allDrawn);
431 pw.print(" animLayerAdjustment="); pw.println(animLayerAdjustment);
Dianne Hackborna57c6952013-03-29 14:46:40 -0700432 if (lastFreezeDuration != 0) {
433 pw.print(prefix); pw.print("lastFreezeDuration=");
434 TimeUtils.formatDuration(lastFreezeDuration, pw); pw.println();
435 }
Craig Mautner59431632012-04-04 11:56:44 -0700436 if (animating || animation != null) {
Craig Mautner9339c402012-11-30 11:23:56 -0800437 pw.print(prefix); pw.print("animating="); pw.println(animating);
Dianne Hackborn529e7442012-11-01 14:22:28 -0700438 pw.print(prefix); pw.print("animation="); pw.println(animation);
Craig Mautner59431632012-04-04 11:56:44 -0700439 }
440 if (hasTransformation) {
441 pw.print(prefix); pw.print("XForm: ");
442 transformation.printShortString(pw);
443 pw.println();
444 }
Craig Mautner59431632012-04-04 11:56:44 -0700445 if (thumbnail != null) {
446 pw.print(prefix); pw.print("thumbnail="); pw.print(thumbnail);
Craig Mautner59431632012-04-04 11:56:44 -0700447 pw.print(" layer="); pw.println(thumbnailLayer);
448 pw.print(prefix); pw.print("thumbnailAnimation="); pw.println(thumbnailAnimation);
449 pw.print(prefix); pw.print("thumbnailTransformation=");
450 pw.println(thumbnailTransformation.toShortString());
451 }
Dianne Hackborn529e7442012-11-01 14:22:28 -0700452 for (int i=0; i<mAllAppWinAnimators.size(); i++) {
453 WindowStateAnimator wanim = mAllAppWinAnimators.get(i);
454 pw.print(prefix); pw.print("App Win Anim #"); pw.print(i);
455 pw.print(": "); pw.println(wanim);
456 }
Craig Mautner59431632012-04-04 11:56:44 -0700457 }
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700458
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800459 void startProlongAnimation(int prolongType) {
460 mProlongAnimation = prolongType;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800461 mClearProlongedAnimation = false;
462 }
463
464 void endProlongedAnimation() {
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800465 mProlongAnimation = PROLONG_ANIMATION_DISABLED;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800466 }
467
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700468 // This is an animation that does nothing: it just immediately finishes
469 // itself every time it is called. It is used as a stub animation in cases
470 // where we want to synchronize multiple things that may be animating.
471 static final class DummyAnimation extends Animation {
472 @Override
473 public boolean getTransformation(long currentTime, Transformation outTransformation) {
474 return false;
475 }
476 }
477
Craig Mautner59431632012-04-04 11:56:44 -0700478}