blob: ab47f07262bd20249bf1ef56f94db7a3736fd826 [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;
26
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;
79 int thumbnailX;
80 int thumbnailY;
81 int thumbnailLayer;
Winson Chunga4ccb862014-08-22 15:26:27 -070082 int thumbnailForceAboveLayer;
Craig Mautner59431632012-04-04 11:56:44 -070083 Animation thumbnailAnimation;
84 final Transformation thumbnailTransformation = new Transformation();
Winson Chunga4ccb862014-08-22 15:26:27 -070085 // This flag indicates that the destruction of the thumbnail surface is synchronized with
Winson Chungab79fce2014-11-04 16:15:22 -080086 // another animation, so defer the destruction of this thumbnail surface for a single frame
87 // after the secondary animation completes.
Winson Chunga4ccb862014-08-22 15:26:27 -070088 boolean deferThumbnailDestruction;
Winson Chungab79fce2014-11-04 16:15:22 -080089 // This flag is set if the animator has deferThumbnailDestruction set and has reached the final
90 // frame of animation. It will extend the animation by one frame and then clean up afterwards.
91 boolean deferFinalFrameCleanup;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -080092 // If true when the animation hits the last frame, it will keep running on that last frame.
93 // This is used to synchronize animation with Recents and we wait for Recents to tell us to
94 // finish or for a new animation be set as fail-safe mechanism.
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -080095 private int mProlongAnimation;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -080096 // Whether the prolong animation can be removed when animation is set. The purpose of this is
97 // that if recents doesn't tell us to remove the prolonged animation, we will get rid of it
98 // when new animation is set.
99 private boolean mClearProlongedAnimation;
Craig Mautner59431632012-04-04 11:56:44 -0700100
Craig Mautner322e4032012-07-13 13:35:20 -0700101 /** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700102 ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<>();
103
104 /** True if the current animation was transferred from another AppWindowAnimator.
105 * See {@link #transferCurrentAnimation}*/
106 boolean usingTransferredAnimation = false;
Craig Mautner322e4032012-07-13 13:35:20 -0700107
Jorim Jaggic554b772015-06-04 16:07:57 -0700108 private boolean mSkipFirstFrame = false;
109
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 Jaggic554b772015-06-04 16:07:57 -0700118 public void setAnimation(Animation anim, int width, int height, boolean skipFirstFrame) {
Craig Mautner72669d12012-12-18 17:23:54 -0800119 if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting animation in " + mAppToken
120 + ": " + anim + " wxh=" + width + "x" + height
121 + " isVisible=" + mAppToken.isVisible());
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();
Craig Mautner72669d12012-12-18 17:23:54 -0800143 transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
Craig Mautner59431632012-04-04 11:56:44 -0700144 hasTransformation = true;
Craig Mautner1ad99152014-08-28 15:47:13 -0700145
Jorim Jaggic554b772015-06-04 16:07:57 -0700146 this.mSkipFirstFrame = skipFirstFrame;
147
Craig Mautner1ad99152014-08-28 15:47:13 -0700148 if (!mAppToken.appFullscreen) {
149 anim.setBackgroundColor(0);
150 }
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800151 if (mClearProlongedAnimation) {
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800152 mProlongAnimation = PROLONG_ANIMATION_DISABLED;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800153 } else {
154 mClearProlongedAnimation = true;
155 }
Craig Mautner59431632012-04-04 11:56:44 -0700156 }
157
158 public void setDummyAnimation() {
Craig Mautner72669d12012-12-18 17:23:54 -0800159 if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting dummy animation in " + mAppToken
160 + " isVisible=" + mAppToken.isVisible());
Craig Mautner1d961d42012-05-27 12:02:11 -0700161 animation = sDummyAnimation;
Craig Mautner94ef9df2012-05-02 17:08:39 -0700162 hasTransformation = true;
163 transformation.clear();
Craig Mautner72669d12012-12-18 17:23:54 -0800164 transformation.setAlpha(mAppToken.isVisible() ? 1 : 0);
Craig Mautner59431632012-04-04 11:56:44 -0700165 }
166
167 public void clearAnimation() {
168 if (animation != null) {
169 animation = null;
170 animating = true;
Craig Mautner59431632012-04-04 11:56:44 -0700171 }
Winson Chungab79fce2014-11-04 16:15:22 -0800172 clearThumbnail();
Craig Mautner7636dfb2012-11-16 15:24:11 -0800173 if (mAppToken.deferClearAllDrawn) {
174 mAppToken.allDrawn = false;
175 mAppToken.deferClearAllDrawn = false;
176 }
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700177 usingTransferredAnimation = false;
Craig Mautner59431632012-04-04 11:56:44 -0700178 }
179
Jorim Jaggi37875612015-02-19 21:05:31 +0100180 public boolean isAnimating() {
181 return animation != null || mAppToken.inPendingTransaction;
182 }
183
Craig Mautner59431632012-04-04 11:56:44 -0700184 public void clearThumbnail() {
185 if (thumbnail != null) {
186 thumbnail.destroy();
187 thumbnail = null;
188 }
Winson Chungab79fce2014-11-04 16:15:22 -0800189 deferThumbnailDestruction = false;
Winson Chunga4ccb862014-08-22 15:26:27 -0700190 }
191
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700192 void transferCurrentAnimation(
193 AppWindowAnimator toAppAnimator, WindowStateAnimator transferWinAnimator) {
194
195 if (animation != null) {
196 toAppAnimator.animation = animation;
197 animation = null;
198 toAppAnimator.animating = animating;
199 toAppAnimator.animLayerAdjustment = animLayerAdjustment;
200 animLayerAdjustment = 0;
201 toAppAnimator.updateLayers();
202 updateLayers();
203 toAppAnimator.usingTransferredAnimation = true;
204 }
205 if (transferWinAnimator != null) {
206 mAllAppWinAnimators.remove(transferWinAnimator);
207 toAppAnimator.mAllAppWinAnimators.add(transferWinAnimator);
208 transferWinAnimator.mAppAnimator = toAppAnimator;
209 }
210 }
211
Craig Mautner59431632012-04-04 11:56:44 -0700212 void updateLayers() {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700213 final int windowCount = mAppToken.allAppWindows.size();
Craig Mautner59431632012-04-04 11:56:44 -0700214 final int adj = animLayerAdjustment;
215 thumbnailLayer = -1;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700216 final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700217 for (int i = 0; i < windowCount; i++) {
Craig Mautner59431632012-04-04 11:56:44 -0700218 final WindowState w = mAppToken.allAppWindows.get(i);
219 final WindowStateAnimator winAnimator = w.mWinAnimator;
220 winAnimator.mAnimLayer = w.mLayer + adj;
221 if (winAnimator.mAnimLayer > thumbnailLayer) {
222 thumbnailLayer = winAnimator.mAnimLayer;
223 }
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700224 if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + winAnimator.mAnimLayer);
Craig Mautner59431632012-04-04 11:56:44 -0700225 if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
226 mService.setInputMethodAnimLayerAdjustment(adj);
227 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700228 wallpaperController.setAnimLayerAdjustment(w, adj);
Craig Mautner59431632012-04-04 11:56:44 -0700229 }
230 }
231
232 private void stepThumbnailAnimation(long currentTime) {
233 thumbnailTransformation.clear();
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800234 final long animationFrameTime = getAnimationFrameTime(thumbnailAnimation, currentTime);
235 thumbnailAnimation.getTransformation(animationFrameTime, thumbnailTransformation);
Craig Mautner59431632012-04-04 11:56:44 -0700236 thumbnailTransformation.getMatrix().preTranslate(thumbnailX, thumbnailY);
Craig Mautnera91f9e22012-09-14 16:22:08 -0700237
238 ScreenRotationAnimation screenRotationAnimation =
239 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
240 final boolean screenAnimation = screenRotationAnimation != null
241 && screenRotationAnimation.isAnimating();
Craig Mautner59431632012-04-04 11:56:44 -0700242 if (screenAnimation) {
Craig Mautnera91f9e22012-09-14 16:22:08 -0700243 thumbnailTransformation.postCompose(screenRotationAnimation.getEnterTransformation());
Craig Mautner59431632012-04-04 11:56:44 -0700244 }
245 // cache often used attributes locally
246 final float tmpFloats[] = mService.mTmpFloats;
247 thumbnailTransformation.getMatrix().getValues(tmpFloats);
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700248 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
Craig Mautner59431632012-04-04 11:56:44 -0700249 "thumbnail", "POS " + tmpFloats[Matrix.MTRANS_X]
250 + ", " + tmpFloats[Matrix.MTRANS_Y], null);
251 thumbnail.setPosition(tmpFloats[Matrix.MTRANS_X], tmpFloats[Matrix.MTRANS_Y]);
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700252 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
Craig Mautner59431632012-04-04 11:56:44 -0700253 "thumbnail", "alpha=" + thumbnailTransformation.getAlpha()
254 + " layer=" + thumbnailLayer
255 + " matrix=[" + tmpFloats[Matrix.MSCALE_X]
256 + "," + tmpFloats[Matrix.MSKEW_Y]
257 + "][" + tmpFloats[Matrix.MSKEW_X]
258 + "," + tmpFloats[Matrix.MSCALE_Y] + "]", null);
259 thumbnail.setAlpha(thumbnailTransformation.getAlpha());
Winson Chunga4ccb862014-08-22 15:26:27 -0700260 if (thumbnailForceAboveLayer > 0) {
261 thumbnail.setLayer(thumbnailForceAboveLayer + 1);
262 } else {
263 // The thumbnail is layered below the window immediately above this
264 // token's anim layer.
265 thumbnail.setLayer(thumbnailLayer + WindowManagerService.WINDOW_LAYER_MULTIPLIER
266 - WindowManagerService.LAYER_OFFSET_THUMBNAIL);
267 }
Craig Mautner59431632012-04-04 11:56:44 -0700268 thumbnail.setMatrix(tmpFloats[Matrix.MSCALE_X], tmpFloats[Matrix.MSKEW_Y],
269 tmpFloats[Matrix.MSKEW_X], tmpFloats[Matrix.MSCALE_Y]);
270 }
271
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800272 /**
273 * Sometimes we need to synchronize the first frame of animation with some external event, e.g.
274 * Recents hiding some of its content. To achieve this, we prolong the start of the animaiton
275 * and keep producing the first frame of the animation.
276 */
277 private long getAnimationFrameTime(Animation animation, long currentTime) {
278 if (mProlongAnimation == PROLONG_ANIMATION_AT_START) {
279 animation.setStartTime(currentTime);
280 return currentTime + 1;
281 }
282 return currentTime;
283 }
284
Craig Mautner59431632012-04-04 11:56:44 -0700285 private boolean stepAnimation(long currentTime) {
286 if (animation == null) {
287 return false;
288 }
289 transformation.clear();
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800290 final long animationFrameTime = getAnimationFrameTime(animation, currentTime);
291 boolean hasMoreFrames = animation.getTransformation(animationFrameTime, transformation);
Winson Chungab79fce2014-11-04 16:15:22 -0800292 if (!hasMoreFrames) {
293 if (deferThumbnailDestruction && !deferFinalFrameCleanup) {
294 // We are deferring the thumbnail destruction, so extend the animation for one more
295 // (dummy) frame before we clean up
296 deferFinalFrameCleanup = true;
297 hasMoreFrames = true;
298 } else {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700299 if (false && DEBUG_ANIM) Slog.v(TAG,
300 "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800301 ", xform=" + transformation + ", mProlongAnimation=" + mProlongAnimation);
Winson Chungab79fce2014-11-04 16:15:22 -0800302 deferFinalFrameCleanup = false;
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800303 if (mProlongAnimation == PROLONG_ANIMATION_AT_END) {
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800304 hasMoreFrames = true;
305 } else {
306 animation = null;
Filip Gruszczynski564a8f62015-11-20 11:25:23 -0800307 clearThumbnail();
308 if (DEBUG_ANIM) Slog.v(TAG, "Finished animation in " + mAppToken + " @ "
309 + currentTime);
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800310 }
Winson Chunga4ccb862014-08-22 15:26:27 -0700311 }
Craig Mautner59431632012-04-04 11:56:44 -0700312 }
Winson Chungab79fce2014-11-04 16:15:22 -0800313 hasTransformation = hasMoreFrames;
314 return hasMoreFrames;
Craig Mautner59431632012-04-04 11:56:44 -0700315 }
316
Jorim Jaggic554b772015-06-04 16:07:57 -0700317 private long getStartTimeCorrection() {
318 if (mSkipFirstFrame) {
319
320 // If the transition is an animation in which the first frame doesn't change the screen
321 // contents at all, we can just skip it and start at the second frame. So we shift the
322 // start time of the animation forward by minus the frame duration.
323 return -Choreographer.getInstance().getFrameIntervalNanos() / TimeUtils.NANOS_PER_MS;
324 } else {
325 return 0;
326 }
327 }
328
Craig Mautner59431632012-04-04 11:56:44 -0700329 // This must be called while inside a transaction.
Wale Ogunwalef16a2812015-04-01 11:23:15 -0700330 boolean stepAnimationLocked(long currentTime, final int displayId) {
Craig Mautner59431632012-04-04 11:56:44 -0700331 if (mService.okToDisplay()) {
332 // We will run animations as long as the display isn't frozen.
333
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700334 if (animation == sDummyAnimation) {
Craig Mautner59431632012-04-04 11:56:44 -0700335 // This guy is going to animate, but not yet. For now count
336 // it as not animating for purposes of scheduling transactions;
337 // when it is really time to animate, this will be set to
338 // a real animation and the next call will execute normally.
339 return false;
340 }
341
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700342 if ((mAppToken.allDrawn || mAppToken.mAnimatingWithSavedSurface
343 || animating || mAppToken.startingDisplayed)
Craig Mautner59431632012-04-04 11:56:44 -0700344 && animation != null) {
345 if (!animating) {
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700346 if (DEBUG_ANIM) Slog.v(TAG,
347 "Starting animation in " + mAppToken +
Dianne Hackborneb94fa72014-06-03 17:48:12 -0700348 " @ " + currentTime + " scale="
349 + mService.getTransitionAnimationScaleLocked()
Craig Mautner59431632012-04-04 11:56:44 -0700350 + " allDrawn=" + mAppToken.allDrawn + " animating=" + animating);
Jorim Jaggic554b772015-06-04 16:07:57 -0700351 long correction = getStartTimeCorrection();
352 animation.setStartTime(currentTime + correction);
Craig Mautner59431632012-04-04 11:56:44 -0700353 animating = true;
354 if (thumbnail != null) {
355 thumbnail.show();
Jorim Jaggic554b772015-06-04 16:07:57 -0700356 thumbnailAnimation.setStartTime(currentTime + correction);
Craig Mautner59431632012-04-04 11:56:44 -0700357 }
Jorim Jaggic554b772015-06-04 16:07:57 -0700358 mSkipFirstFrame = false;
Craig Mautner59431632012-04-04 11:56:44 -0700359 }
360 if (stepAnimation(currentTime)) {
361 // animation isn't over, step any thumbnail and that's
362 // it for now.
363 if (thumbnail != null) {
364 stepThumbnailAnimation(currentTime);
365 }
366 return true;
367 }
368 }
369 } else if (animation != null) {
370 // If the display is frozen, and there is a pending animation,
371 // clear it and make sure we run the cleanup code.
372 animating = true;
373 animation = null;
374 }
375
376 hasTransformation = false;
377
Craig Mautner3de422f2012-04-06 18:04:13 -0700378 if (!animating && animation == null) {
Craig Mautner59431632012-04-04 11:56:44 -0700379 return false;
380 }
381
Craig Mautner76a71652012-09-03 23:23:58 -0700382 mAnimator.setAppLayoutChanges(this, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM,
Wale Ogunwalef16a2812015-04-01 11:23:15 -0700383 "AppWindowToken", displayId);
Craig Mautner59431632012-04-04 11:56:44 -0700384
385 clearAnimation();
386 animating = false;
387 if (animLayerAdjustment != 0) {
388 animLayerAdjustment = 0;
389 updateLayers();
390 }
391 if (mService.mInputMethodTarget != null
392 && mService.mInputMethodTarget.mAppToken == mAppToken) {
393 mService.moveInputMethodWindowsIfNeededLocked(true);
394 }
395
Wale Ogunwale8ebc82a2015-05-13 15:27:12 -0700396 if (DEBUG_ANIM) Slog.v(TAG,
397 "Animation done in " + mAppToken
Craig Mautner59431632012-04-04 11:56:44 -0700398 + ": reportedVisible=" + mAppToken.reportedVisible);
399
400 transformation.clear();
401
Wale Ogunwaleec533f62014-12-05 09:03:48 -0800402 final int numAllAppWinAnimators = mAllAppWinAnimators.size();
403 for (int i = 0; i < numAllAppWinAnimators; i++) {
404 mAllAppWinAnimators.get(i).finishExit();
Craig Mautner59431632012-04-04 11:56:44 -0700405 }
Wale Ogunwalea48eadb2015-05-14 17:43:12 -0700406 mService.mAppTransition.notifyAppTransitionFinishedLocked(mAppToken.token);
Craig Mautner59431632012-04-04 11:56:44 -0700407 return false;
408 }
409
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700410 // This must be called while inside a transaction.
Craig Mautnerbec53f72012-04-05 11:49:05 -0700411 boolean showAllWindowsLocked() {
412 boolean isAnimating = false;
Craig Mautner322e4032012-07-13 13:35:20 -0700413 final int NW = mAllAppWinAnimators.size();
Craig Mautnerbec53f72012-04-05 11:49:05 -0700414 for (int i=0; i<NW; i++) {
Craig Mautner322e4032012-07-13 13:35:20 -0700415 WindowStateAnimator winAnimator = mAllAppWinAnimators.get(i);
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800416 if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + winAnimator);
Craig Mautnerbec53f72012-04-05 11:49:05 -0700417 winAnimator.performShowLocked();
418 isAnimating |= winAnimator.isAnimating();
419 }
420 return isAnimating;
421 }
422
Dianne Hackborn529e7442012-11-01 14:22:28 -0700423 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
424 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
425 pw.print(prefix); pw.print("mAnimator="); pw.println(mAnimator);
426 pw.print(prefix); pw.print("freezingScreen="); pw.print(freezingScreen);
427 pw.print(" allDrawn="); pw.print(allDrawn);
428 pw.print(" animLayerAdjustment="); pw.println(animLayerAdjustment);
Dianne Hackborna57c6952013-03-29 14:46:40 -0700429 if (lastFreezeDuration != 0) {
430 pw.print(prefix); pw.print("lastFreezeDuration=");
431 TimeUtils.formatDuration(lastFreezeDuration, pw); pw.println();
432 }
Craig Mautner59431632012-04-04 11:56:44 -0700433 if (animating || animation != null) {
Craig Mautner9339c402012-11-30 11:23:56 -0800434 pw.print(prefix); pw.print("animating="); pw.println(animating);
Dianne Hackborn529e7442012-11-01 14:22:28 -0700435 pw.print(prefix); pw.print("animation="); pw.println(animation);
Craig Mautner59431632012-04-04 11:56:44 -0700436 }
437 if (hasTransformation) {
438 pw.print(prefix); pw.print("XForm: ");
439 transformation.printShortString(pw);
440 pw.println();
441 }
Craig Mautner59431632012-04-04 11:56:44 -0700442 if (thumbnail != null) {
443 pw.print(prefix); pw.print("thumbnail="); pw.print(thumbnail);
444 pw.print(" x="); pw.print(thumbnailX);
445 pw.print(" y="); pw.print(thumbnailY);
446 pw.print(" layer="); pw.println(thumbnailLayer);
447 pw.print(prefix); pw.print("thumbnailAnimation="); pw.println(thumbnailAnimation);
448 pw.print(prefix); pw.print("thumbnailTransformation=");
449 pw.println(thumbnailTransformation.toShortString());
450 }
Dianne Hackborn529e7442012-11-01 14:22:28 -0700451 for (int i=0; i<mAllAppWinAnimators.size(); i++) {
452 WindowStateAnimator wanim = mAllAppWinAnimators.get(i);
453 pw.print(prefix); pw.print("App Win Anim #"); pw.print(i);
454 pw.print(": "); pw.println(wanim);
455 }
Craig Mautner59431632012-04-04 11:56:44 -0700456 }
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700457
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800458 void startProlongAnimation(int prolongType) {
459 mProlongAnimation = prolongType;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800460 mClearProlongedAnimation = false;
461 }
462
463 void endProlongedAnimation() {
Filip Gruszczynski1a4dfe52015-11-15 10:58:57 -0800464 mProlongAnimation = PROLONG_ANIMATION_DISABLED;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800465 }
466
Craig Mautnerfbf378c2012-04-23 17:24:21 -0700467 // This is an animation that does nothing: it just immediately finishes
468 // itself every time it is called. It is used as a stub animation in cases
469 // where we want to synchronize multiple things that may be animating.
470 static final class DummyAnimation extends Animation {
471 @Override
472 public boolean getTransformation(long currentTime, Transformation outTransformation) {
473 return false;
474 }
475 }
476
Craig Mautner59431632012-04-04 11:56:44 -0700477}