blob: 54c84ea5afed61feabfc361152d6b615e0dafa29 [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 Mautnera2c77052012-03-26 12:14:43 -070016
17package com.android.server.wm;
18
Filip Gruszczynski69cbc352015-11-11 13:46:04 -080019import static android.view.Display.DEFAULT_DISPLAY;
Wale Ogunwalee7bf46b2015-09-30 09:19:28 -070020import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Filip Gruszczynski69cbc352015-11-11 13:46:04 -080021import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
Robert Carr132c9f52017-07-31 17:02:30 -070022import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070023import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Jorim Jaggieb88d832016-04-13 20:17:43 -070024import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
Robert Carrfbbde852016-10-18 11:02:28 -070025import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Jorim Jaggiff71d202016-04-14 13:12:36 -070026import static com.android.server.wm.AppWindowAnimator.sDummyAnimation;
Jorim Jaggi0b46f3c2016-03-14 12:21:37 +010027import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080028import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
29import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
30import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
31import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
32import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
Jorim Jaggie4b0f282017-05-17 15:10:29 +020033import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080034import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
35import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -080036import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080037import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
38import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
39import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
40import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
41import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Chong Zhang97782b42015-10-07 16:01:23 -070042import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
Filip Gruszczynski69cbc352015-11-11 13:46:04 -080043import static com.android.server.wm.WindowManagerService.localLOGV;
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -080044import static com.android.server.wm.WindowManagerService.logWithStack;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070045import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
46import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN;
Steven Timotiusaf03df62017-07-18 16:56:43 -070047import static com.android.server.wm.proto.WindowStateAnimatorProto.LAST_CLIP_RECT;
48import static com.android.server.wm.proto.WindowStateAnimatorProto.SURFACE;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070049
Wale Ogunwale3382ab12017-07-27 08:55:03 -070050import android.app.WindowConfiguration;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070051import android.content.Context;
52import android.graphics.Matrix;
53import android.graphics.PixelFormat;
Craig Mautner7358fbf2012-04-12 21:06:33 -070054import android.graphics.Point;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070055import android.graphics.Rect;
Robert Carr6da3cc02016-06-16 15:17:07 -070056import android.graphics.RectF;
Craig Mautner48ba1e72012-04-02 13:18:16 -070057import android.graphics.Region;
Craig Mautnera51a9562012-04-17 17:05:26 -070058import android.os.Debug;
Chong Zhang8784be62016-06-28 15:25:07 -070059import android.os.Trace;
Craig Mautnera2c77052012-03-26 12:14:43 -070060import android.util.Slog;
Steven Timotiusaf03df62017-07-18 16:56:43 -070061import android.util.proto.ProtoOutputStream;
Craig Mautner59c00972012-07-30 12:10:24 -070062import android.view.DisplayInfo;
Igor Murashkina86ab6402013-08-30 12:58:36 -070063import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080064import android.view.SurfaceControl;
Craig Mautnera2c77052012-03-26 12:14:43 -070065import android.view.WindowManager;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070066import android.view.WindowManager.LayoutParams;
Craig Mautnera2c77052012-03-26 12:14:43 -070067import android.view.animation.Animation;
Jorim Jaggif8d77da2014-11-11 16:59:12 +010068import android.view.animation.AnimationSet;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070069import android.view.animation.AnimationUtils;
Craig Mautnera2c77052012-03-26 12:14:43 -070070import android.view.animation.Transformation;
71
Adrian Roose99bc052017-11-20 17:55:31 +010072import com.android.server.policy.WindowManagerPolicy;
73
Craig Mautnera2c77052012-03-26 12:14:43 -070074import java.io.PrintWriter;
Robert Carr3b716242016-08-16 16:02:21 -070075import java.io.FileDescriptor;
Craig Mautnera2c77052012-03-26 12:14:43 -070076
77/**
Craig Mautnerc2f9be02012-03-27 17:32:29 -070078 * Keep track of animations and surface operations for a single WindowState.
79 **/
Craig Mautnera2c77052012-03-26 12:14:43 -070080class WindowStateAnimator {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080081 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowStateAnimator" : TAG_WM;
Chong Zhang97782b42015-10-07 16:01:23 -070082 static final int WINDOW_FREEZE_LAYER = TYPE_LAYER_MULTIPLIER * 200;
Craig Mautnera2c77052012-03-26 12:14:43 -070083
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +010084 /**
85 * Mode how the window gets clipped by the stack bounds during an animation: The clipping should
86 * be applied after applying the animation transformation, i.e. the stack bounds don't move
87 * during the animation.
88 */
89 static final int STACK_CLIP_AFTER_ANIM = 0;
90
91 /**
92 * Mode how the window gets clipped by the stack bounds: The clipping should be applied before
93 * applying the animation transformation, i.e. the stack bounds move with the window.
94 */
95 static final int STACK_CLIP_BEFORE_ANIM = 1;
96
97 /**
98 * Mode how window gets clipped by the stack bounds during an animation: Don't clip the window
99 * by the stack bounds.
100 */
101 static final int STACK_CLIP_NONE = 2;
102
Craig Mautner918b53b2012-07-09 14:15:54 -0700103 // Unchanging local convenience fields.
Craig Mautnera2c77052012-03-26 12:14:43 -0700104 final WindowManagerService mService;
105 final WindowState mWin;
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700106 private final WindowStateAnimator mParentWinAnimator;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700107 final WindowAnimator mAnimator;
Craig Mautner8863cca2012-09-18 15:04:34 -0700108 AppWindowAnimator mAppAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700109 final Session mSession;
110 final WindowManagerPolicy mPolicy;
111 final Context mContext;
Craig Mautner918b53b2012-07-09 14:15:54 -0700112 final boolean mIsWallpaper;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700113 private final WallpaperController mWallpaperControllerLocked;
Craig Mautnera2c77052012-03-26 12:14:43 -0700114
115 // Currently running animation.
116 boolean mAnimating;
117 boolean mLocalAnimating;
118 Animation mAnimation;
119 boolean mAnimationIsEntrance;
120 boolean mHasTransformation;
121 boolean mHasLocalTransformation;
122 final Transformation mTransformation = new Transformation();
123 boolean mWasAnimating; // Were we animating going into the most recent animation step?
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700124 int mAnimLayer;
125 int mLastLayer;
Jorim Jaggi44f60cc2014-11-07 20:33:51 +0100126 long mAnimationStartTime;
Jorim Jaggif8d77da2014-11-11 16:59:12 +0100127 long mLastAnimationTime;
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100128 int mStackClip = STACK_CLIP_BEFORE_ANIM;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700129
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700130 /**
131 * Set when we have changed the size of the surface, to know that
132 * we must tell them application to resize (and thus redraw itself).
133 */
134 boolean mSurfaceResized;
Chong Zhang5b2f1992015-11-13 15:40:36 -0800135 /**
136 * Whether we should inform the client on next relayoutWindow that
137 * the surface has been resized since last time.
138 */
139 boolean mReportSurfaceResized;
Robert Carre6a83512015-11-03 16:09:21 -0800140 WindowSurfaceController mSurfaceController;
Filip Gruszczynski10a80e02015-11-06 09:21:17 -0800141 private WindowSurfaceController mPendingDestroySurface;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700142
143 /**
144 * Set if the client has asked that the destroy of its surface be delayed
145 * until it explicitly says it is okay.
146 */
147 boolean mSurfaceDestroyDeferred;
148
Filip Gruszczynski10a80e02015-11-06 09:21:17 -0800149 private boolean mDestroyPreservedSurfaceUponRedraw;
Craig Mautner7d8df392012-04-06 15:26:23 -0700150 float mShownAlpha = 0;
151 float mAlpha = 0;
152 float mLastAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700153
Winson Chung399f6202014-03-19 10:47:20 -0700154 boolean mHasClipRect;
155 Rect mClipRect = new Rect();
156 Rect mTmpClipRect = new Rect();
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100157 Rect mTmpFinalClipRect = new Rect();
Winson Chung399f6202014-03-19 10:47:20 -0700158 Rect mLastClipRect = new Rect();
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100159 Rect mLastFinalClipRect = new Rect();
Filip Gruszczynski4b8eea72015-09-14 18:16:19 -0700160 Rect mTmpStackBounds = new Rect();
Winson Chung08f81892017-03-02 15:40:51 -0800161 private Rect mTmpAnimatingBounds = new Rect();
162 private Rect mTmpSourceBounds = new Rect();
Winson Chung399f6202014-03-19 10:47:20 -0700163
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -0800164 /**
165 * This is rectangle of the window's surface that is not covered by
166 * system decorations.
167 */
168 private final Rect mSystemDecorRect = new Rect();
169 private final Rect mLastSystemDecorRect = new Rect();
170
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800171 // Used to save animation distances between the time they are calculated and when they are used.
172 private int mAnimDx;
173 private int mAnimDy;
Jorim Jaggic5af4f82015-07-01 17:16:27 -0700174
175 /** Is the next animation to be started a window move animation? */
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800176 private boolean mAnimateMove = false;
Jorim Jaggic5af4f82015-07-01 17:16:27 -0700177
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700178 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
Robert Carr0edf18f2017-02-21 20:01:47 -0800179 private float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700180
181 boolean mHaveMatrix;
182
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700183 // Set to true if, when the window gets displayed, it should perform
184 // an enter animation.
185 boolean mEnterAnimationPending;
Craig Mautnera2c77052012-03-26 12:14:43 -0700186
Craig Mautner9c795042014-10-28 19:59:59 -0700187 /** Used to indicate that this window is undergoing an enter animation. Used for system
188 * windows to make the callback to View.dispatchOnWindowShownCallback(). Set when the
189 * window is first added or shown, cleared when the callback has been made. */
190 boolean mEnteringAnimation;
191
Jorim Jaggiff71d202016-04-14 13:12:36 -0700192 private boolean mAnimationStartDelayed;
193
John Reck80181b92015-05-19 11:09:32 -0700194 /** The pixel format of the underlying SurfaceControl */
195 int mSurfaceFormat;
196
Craig Mautner749a7bb2012-04-02 13:49:53 -0700197 /** This is set when there is no Surface */
198 static final int NO_SURFACE = 0;
199 /** This is set after the Surface has been created but before the window has been drawn. During
200 * this time the surface is hidden. */
201 static final int DRAW_PENDING = 1;
202 /** This is set after the window has finished drawing for the first time but before its surface
203 * is shown. The surface will be displayed when the next layout is run. */
204 static final int COMMIT_DRAW_PENDING = 2;
205 /** This is set during the time after the window's drawing has been committed, and before its
206 * surface is actually shown. It is used to delay showing the surface until all windows in a
207 * token are ready to be shown. */
208 static final int READY_TO_SHOW = 3;
209 /** Set when the window has been shown in the screen the first time. */
210 static final int HAS_DRAWN = 4;
Adrian Roos3eeb4e62014-05-19 12:43:26 +0200211
Craig Mautner276a6eb2014-11-04 15:32:57 -0800212 String drawStateToString() {
213 switch (mDrawState) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700214 case NO_SURFACE: return "NO_SURFACE";
215 case DRAW_PENDING: return "DRAW_PENDING";
216 case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
217 case READY_TO_SHOW: return "READY_TO_SHOW";
218 case HAS_DRAWN: return "HAS_DRAWN";
Craig Mautner276a6eb2014-11-04 15:32:57 -0800219 default: return Integer.toString(mDrawState);
Craig Mautner6fbda632012-07-03 09:26:39 -0700220 }
221 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700222 int mDrawState;
Craig Mautnera608b882012-03-30 13:03:49 -0700223
Craig Mautner749a7bb2012-04-02 13:49:53 -0700224 /** Was this window last hidden? */
225 boolean mLastHidden;
Craig Mautnera608b882012-03-30 13:03:49 -0700226
Craig Mautnerbec53f72012-04-05 11:49:05 -0700227 int mAttrType;
228
Robert Carr679c8072016-04-07 15:51:48 -0700229 static final long PENDING_TRANSACTION_FINISH_WAIT_TIME = 100;
Robert Carr679c8072016-04-07 15:51:48 -0700230
Robert Carrc7294602016-05-13 11:32:05 -0700231 boolean mForceScaleUntilResize;
232
Robert Carr04092112016-06-02 12:56:12 -0700233 // WindowState.mHScale and WindowState.mVScale contain the
234 // scale according to client specified layout parameters (e.g.
235 // one layout size, with another surface size, creates such scaling).
236 // Here we track an additional scaling factor used to follow stack
237 // scaling (as in the case of the Pinned stack animation).
238 float mExtraHScale = (float) 1.0;
239 float mExtraVScale = (float) 1.0;
240
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800241 private final Rect mTmpSize = new Rect();
242
Craig Mautnerc431e892015-02-11 13:14:26 -0800243 WindowStateAnimator(final WindowState win) {
Craig Mautner918b53b2012-07-09 14:15:54 -0700244 final WindowManagerService service = win.mService;
245
Craig Mautnera2c77052012-03-26 12:14:43 -0700246 mService = service;
Craig Mautner918b53b2012-07-09 14:15:54 -0700247 mAnimator = service.mAnimator;
248 mPolicy = service.mPolicy;
249 mContext = service.mContext;
Craig Mautnerd3849f52014-03-27 13:19:29 -0700250 final DisplayContent displayContent = win.getDisplayContent();
251 if (displayContent != null) {
252 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800253 mAnimDx = displayInfo.appWidth;
254 mAnimDy = displayInfo.appHeight;
Craig Mautnerd3849f52014-03-27 13:19:29 -0700255 } else {
256 Slog.w(TAG, "WindowStateAnimator ctor: Display has been removed");
257 // This is checked on return and dealt with.
258 }
Craig Mautner918b53b2012-07-09 14:15:54 -0700259
260 mWin = win;
Wale Ogunwalecaa53af2016-07-17 14:50:26 -0700261 mParentWinAnimator = !win.isChildWindow() ? null : win.getParentWindow().mWinAnimator;
Craig Mautner322e4032012-07-13 13:35:20 -0700262 mAppAnimator = win.mAppToken == null ? null : win.mAppToken.mAppAnimator;
Craig Mautner918b53b2012-07-09 14:15:54 -0700263 mSession = win.mSession;
Craig Mautner918b53b2012-07-09 14:15:54 -0700264 mAttrType = win.mAttrs.type;
265 mIsWallpaper = win.mIsWallpaper;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700266 mWallpaperControllerLocked = mService.mRoot.mWallpaperController;
Craig Mautnera2c77052012-03-26 12:14:43 -0700267 }
268
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100269 public void setAnimation(Animation anim, long startTime, int stackClip) {
Craig Mautnerbec53f72012-04-05 11:49:05 -0700270 if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim);
Craig Mautnera2c77052012-03-26 12:14:43 -0700271 mAnimating = false;
272 mLocalAnimating = false;
273 mAnimation = anim;
274 mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
Dianne Hackborneb94fa72014-06-03 17:48:12 -0700275 mAnimation.scaleCurrentDuration(mService.getWindowAnimationScaleLocked());
Craig Mautnera2c77052012-03-26 12:14:43 -0700276 // Start out animation gone if window is gone, or visible if window is visible.
277 mTransformation.clear();
Craig Mautner749a7bb2012-04-02 13:49:53 -0700278 mTransformation.setAlpha(mLastHidden ? 0 : 1);
Craig Mautnera2c77052012-03-26 12:14:43 -0700279 mHasLocalTransformation = true;
Jorim Jaggi44f60cc2014-11-07 20:33:51 +0100280 mAnimationStartTime = startTime;
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100281 mStackClip = stackClip;
282 }
283
284 public void setAnimation(Animation anim, int stackClip) {
285 setAnimation(anim, -1, stackClip);
Jorim Jaggi44f60cc2014-11-07 20:33:51 +0100286 }
287
288 public void setAnimation(Animation anim) {
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100289 setAnimation(anim, -1, STACK_CLIP_AFTER_ANIM);
Craig Mautnera2c77052012-03-26 12:14:43 -0700290 }
291
292 public void clearAnimation() {
293 if (mAnimation != null) {
294 mAnimating = true;
295 mLocalAnimating = false;
296 mAnimation.cancel();
297 mAnimation = null;
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100298 mStackClip = STACK_CLIP_BEFORE_ANIM;
Craig Mautnera2c77052012-03-26 12:14:43 -0700299 }
300 }
301
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700302 /**
303 * Is the window or its container currently set to animate or currently animating?
304 */
305 boolean isAnimationSet() {
Craig Mautnera2c77052012-03-26 12:14:43 -0700306 return mAnimation != null
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700307 || (mParentWinAnimator != null && mParentWinAnimator.mAnimation != null)
Jorim Jaggi37875612015-02-19 21:05:31 +0100308 || (mAppAnimator != null && mAppAnimator.isAnimating());
Craig Mautnera2c77052012-03-26 12:14:43 -0700309 }
310
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700311 /**
312 * @return whether an animation is about to start, i.e. the animation is set already but we
313 * haven't processed the first frame yet.
314 */
315 boolean isAnimationStarting() {
316 return isAnimationSet() && !mAnimating;
317 }
318
Craig Mautner0afddcb2012-05-08 15:38:00 -0700319 /** Is the window animating the DummyAnimation? */
320 boolean isDummyAnimation() {
Craig Mautner322e4032012-07-13 13:35:20 -0700321 return mAppAnimator != null
Jorim Jaggiff71d202016-04-14 13:12:36 -0700322 && mAppAnimator.animation == sDummyAnimation;
Craig Mautner0afddcb2012-05-08 15:38:00 -0700323 }
324
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700325 /**
326 * Is this window currently set to animate or currently animating?
327 */
328 boolean isWindowAnimationSet() {
Craig Mautnera2c77052012-03-26 12:14:43 -0700329 return mAnimation != null;
330 }
331
Chong Zhange22006d2016-05-09 10:59:59 -0700332 /**
333 * Is this window currently waiting to run an opening animation?
334 */
335 boolean isWaitingForOpening() {
336 return mService.mAppTransition.isTransitionSet() && isDummyAnimation()
337 && mService.mOpeningApps.contains(mWin.mAppToken);
338 }
339
Craig Mautnera2c77052012-03-26 12:14:43 -0700340 void cancelExitAnimationForNextAnimationLocked() {
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800341 if (DEBUG_ANIM) Slog.d(TAG,
342 "cancelExitAnimationForNextAnimationLocked: " + mWin);
343
Craig Mautnera2c77052012-03-26 12:14:43 -0700344 if (mAnimation != null) {
345 mAnimation.cancel();
346 mAnimation = null;
Craig Mautner4d7349b2012-04-20 14:52:47 -0700347 mLocalAnimating = false;
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200348 mWin.destroySurfaceUnchecked();
Craig Mautnera2c77052012-03-26 12:14:43 -0700349 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700350 }
351
352 private boolean stepAnimation(long currentTime) {
353 if ((mAnimation == null) || !mLocalAnimating) {
354 return false;
355 }
Jorim Jaggiff71d202016-04-14 13:12:36 -0700356 currentTime = getAnimationFrameTime(mAnimation, currentTime);
Craig Mautnera2c77052012-03-26 12:14:43 -0700357 mTransformation.clear();
358 final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
Jorim Jaggiff71d202016-04-14 13:12:36 -0700359 if (mAnimationStartDelayed && mAnimationIsEntrance) {
360 mTransformation.setAlpha(0f);
361 }
Filip Gruszczynski1a5203d2015-10-29 17:43:49 -0700362 if (false && DEBUG_ANIM) Slog.v(TAG, "Stepped animation in " + this + ": more=" + more
363 + ", xform=" + mTransformation);
Craig Mautnera2c77052012-03-26 12:14:43 -0700364 return more;
365 }
366
367 // This must be called while inside a transaction. Returns true if
368 // there is more animation to run.
369 boolean stepAnimationLocked(long currentTime) {
Chet Haase9c450412015-10-01 13:25:58 -0700370 // Save the animation state as it was before this step so WindowManagerService can tell if
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700371 // we just started or just stopped animating by comparing mWasAnimating with isAnimationSet().
Chet Haase9c450412015-10-01 13:25:58 -0700372 mWasAnimating = mAnimating;
Craig Mautnerdf88d732014-01-27 09:21:32 -0800373 final DisplayContent displayContent = mWin.getDisplayContent();
David Stevens9440dc82017-03-16 19:00:20 -0700374 if (mWin.mToken.okToAnimate()) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700375 // We will run animations as long as the display isn't frozen.
376
377 if (mWin.isDrawnLw() && mAnimation != null) {
378 mHasTransformation = true;
379 mHasLocalTransformation = true;
380 if (!mLocalAnimating) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700381 if (DEBUG_ANIM) Slog.v(
382 TAG, "Starting animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700383 " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
384 " wh=" + mWin.mFrame.height() +
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800385 " dx=" + mAnimDx + " dy=" + mAnimDy +
Dianne Hackborneb94fa72014-06-03 17:48:12 -0700386 " scale=" + mService.getWindowAnimationScaleLocked());
Craig Mautnerdf88d732014-01-27 09:21:32 -0800387 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
tiger_huangb7f3f922015-04-27 20:36:46 +0800388 if (mAnimateMove) {
389 mAnimateMove = false;
390 mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800391 mAnimDx, mAnimDy);
tiger_huangb7f3f922015-04-27 20:36:46 +0800392 } else {
393 mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
394 displayInfo.appWidth, displayInfo.appHeight);
395 }
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800396 mAnimDx = displayInfo.appWidth;
397 mAnimDy = displayInfo.appHeight;
Jorim Jaggi44f60cc2014-11-07 20:33:51 +0100398 mAnimation.setStartTime(mAnimationStartTime != -1
399 ? mAnimationStartTime
400 : currentTime);
Craig Mautnera2c77052012-03-26 12:14:43 -0700401 mLocalAnimating = true;
402 mAnimating = true;
403 }
404 if ((mAnimation != null) && mLocalAnimating) {
Jorim Jaggif8d77da2014-11-11 16:59:12 +0100405 mLastAnimationTime = currentTime;
Craig Mautnera2c77052012-03-26 12:14:43 -0700406 if (stepAnimation(currentTime)) {
407 return true;
408 }
409 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700410 if (DEBUG_ANIM) Slog.v(
411 TAG, "Finished animation in " + this +
Craig Mautnera2c77052012-03-26 12:14:43 -0700412 " @ " + currentTime);
413 //WindowManagerService.this.dump();
414 }
415 mHasLocalTransformation = false;
Craig Mautner322e4032012-07-13 13:35:20 -0700416 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppAnimator != null
417 && mAppAnimator.animation != null) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700418 // When our app token is animating, we kind-of pretend like
419 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
420 // part of this check means that we will only do this if
421 // our window is not currently exiting, or it is not
422 // locally animating itself. The idea being that one that
423 // is exiting and doing a local animation should be removed
424 // once that animation is done.
425 mAnimating = true;
426 mHasTransformation = true;
427 mTransformation.clear();
428 return false;
429 } else if (mHasTransformation) {
430 // Little trick to get through the path below to act like
431 // we have finished an animation.
432 mAnimating = true;
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700433 } else if (isAnimationSet()) {
Craig Mautnera2c77052012-03-26 12:14:43 -0700434 mAnimating = true;
435 }
436 } else if (mAnimation != null) {
437 // If the display is frozen, and there is a pending animation,
438 // clear it and make sure we run the cleanup code.
439 mAnimating = true;
Craig Mautnera2c77052012-03-26 12:14:43 -0700440 }
441
442 if (!mAnimating && !mLocalAnimating) {
443 return false;
444 }
445
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700446 // Done animating, clean up.
447 if (DEBUG_ANIM) Slog.v(
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800448 TAG, "Animation done in " + this + ": exiting=" + mWin.mAnimatingExit
Craig Mautnera2c77052012-03-26 12:14:43 -0700449 + ", reportedVisible="
450 + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
451
452 mAnimating = false;
453 mLocalAnimating = false;
454 if (mAnimation != null) {
455 mAnimation.cancel();
456 mAnimation = null;
457 }
Craig Mautnere7ae2502012-03-26 17:11:19 -0700458 if (mAnimator.mWindowDetachedWallpaper == mWin) {
459 mAnimator.mWindowDetachedWallpaper = null;
Craig Mautnera2c77052012-03-26 12:14:43 -0700460 }
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700461 mAnimLayer = mWin.getSpecialWindowAnimLayerAdjustment();
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800462 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this + " anim layer: " + mAnimLayer);
Craig Mautnera2c77052012-03-26 12:14:43 -0700463 mHasTransformation = false;
464 mHasLocalTransformation = false;
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100465 mStackClip = STACK_CLIP_BEFORE_ANIM;
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800466 mWin.checkPolicyVisibilityChange();
Craig Mautnera2c77052012-03-26 12:14:43 -0700467 mTransformation.clear();
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800468 if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.mPolicyVisibility) {
Craig Mautner81defc72013-10-29 11:10:42 -0700469 // Upon completion of a not-visible to visible status bar animation a relayout is
470 // required.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800471 if (displayContent != null) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700472 displayContent.setLayoutNeeded();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800473 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700474 }
475
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700476 mWin.onExitAnimationDone();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800477 final int displayId = mWin.getDisplayId();
Craig Mautner76a71652012-09-03 23:23:58 -0700478 mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800479 if (DEBUG_LAYOUT_REPEATS)
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700480 mService.mWindowPlacerLocked.debugLayoutRepeats(
481 "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
Craig Mautnera2c77052012-03-26 12:14:43 -0700482
483 if (mWin.mAppToken != null) {
484 mWin.mAppToken.updateReportedVisibilityLocked();
485 }
486
487 return false;
488 }
489
Filip Gruszczynski63a35e22015-11-05 15:38:59 -0800490 void hide(String reason) {
Craig Mautner0afddcb2012-05-08 15:38:00 -0700491 if (!mLastHidden) {
492 //dump();
493 mLastHidden = true;
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800494 if (mSurfaceController != null) {
495 mSurfaceController.hideInTransaction(reason);
496 }
Craig Mautner0afddcb2012-05-08 15:38:00 -0700497 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700498 }
499
Craig Mautnera608b882012-03-30 13:03:49 -0700500 boolean finishDrawingLocked() {
Craig Mautner42d04db2014-11-06 12:13:23 -0800501 final boolean startingWindow =
502 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
503 if (DEBUG_STARTING_WINDOW && startingWindow) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700504 Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
Craig Mautner276a6eb2014-11-04 15:32:57 -0800505 + drawStateToString());
Craig Mautner6fbda632012-07-03 09:26:39 -0700506 }
Robert Carr1ca6a332016-04-11 18:00:43 -0700507
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200508 boolean layoutNeeded = false;
Chong Zhang92147042016-05-09 12:47:11 -0700509
Craig Mautner749a7bb2012-04-02 13:49:53 -0700510 if (mDrawState == DRAW_PENDING) {
Robert Carre13b58e2017-08-31 14:50:44 -0700511 if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
Chong Zhang5b2f1992015-11-13 15:40:36 -0800512 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
Robert Carre6a83512015-11-03 16:09:21 -0800513 + mSurfaceController);
Craig Mautner42d04db2014-11-06 12:13:23 -0800514 if (DEBUG_STARTING_WINDOW && startingWindow) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700515 Slog.v(TAG, "Draw state now committed in " + mWin);
516 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700517 mDrawState = COMMIT_DRAW_PENDING;
Chong Zhangcbbcc0f2016-05-17 20:46:58 -0700518 layoutNeeded = true;
Craig Mautnera608b882012-03-30 13:03:49 -0700519 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700520
Chong Zhangcbbcc0f2016-05-17 20:46:58 -0700521 return layoutNeeded;
Craig Mautnera608b882012-03-30 13:03:49 -0700522 }
523
524 // This must be called while inside a transaction.
Craig Mautnerc431e892015-02-11 13:14:26 -0800525 boolean commitFinishDrawingLocked() {
Jorim Jaggie4b0f282017-05-17 15:10:29 +0200526 if (DEBUG_STARTING_WINDOW_VERBOSE &&
Craig Mautner6fbda632012-07-03 09:26:39 -0700527 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
528 Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
Craig Mautner276a6eb2014-11-04 15:32:57 -0800529 + drawStateToString());
Craig Mautner6fbda632012-07-03 09:26:39 -0700530 }
Craig Mautner276a6eb2014-11-04 15:32:57 -0800531 if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
Craig Mautnera608b882012-03-30 13:03:49 -0700532 return false;
533 }
Robert Carre13b58e2017-08-31 14:50:44 -0700534 if (DEBUG_ANIM) {
Robert Carre6a83512015-11-03 16:09:21 -0800535 Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceController);
Craig Mautner6fbda632012-07-03 09:26:39 -0700536 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700537 mDrawState = READY_TO_SHOW;
Chong Zhang0275e392015-09-17 10:41:44 -0700538 boolean result = false;
Craig Mautnera608b882012-03-30 13:03:49 -0700539 final AppWindowToken atoken = mWin.mAppToken;
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800540 if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
Wale Ogunwale9d147902016-07-16 11:58:55 -0700541 result = mWin.performShowLocked();
Chong Zhang0275e392015-09-17 10:41:44 -0700542 }
Chong Zhang97782b42015-10-07 16:01:23 -0700543 return result;
Craig Mautnera608b882012-03-30 13:03:49 -0700544 }
545
Chong Zhang97782b42015-10-07 16:01:23 -0700546 void preserveSurfaceLocked() {
547 if (mDestroyPreservedSurfaceUponRedraw) {
Chong Zhangb9b0fec2016-02-11 18:51:51 -0800548 // This could happen when switching the surface mode very fast. For example,
549 // we preserved a surface when dragResizing changed to true. Then before the
550 // preserved surface is removed, dragResizing changed to false again.
551 // In this case, we need to leave the preserved surface alone, and destroy
552 // the actual surface, so that the createSurface call could create a surface
553 // of the proper size. The preserved surface will still be removed when client
554 // finishes drawing to the new surface.
555 mSurfaceDestroyDeferred = false;
556 destroySurfaceLocked();
557 mSurfaceDestroyDeferred = true;
Chong Zhang97782b42015-10-07 16:01:23 -0700558 return;
559 }
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -0800560 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "SET FREEZE LAYER", false);
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800561 if (mSurfaceController != null) {
Robert Carrb1579c82017-09-05 14:54:47 -0700562 // Our SurfaceControl is always at layer 0 within the parent Surface managed by
563 // window-state. We want this old Surface to stay on top of the new one
564 // until we do the swap, so we place it at layer 1.
565 mSurfaceController.mSurfaceControl.setLayer(1);
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800566 }
Chong Zhang97782b42015-10-07 16:01:23 -0700567 mDestroyPreservedSurfaceUponRedraw = true;
568 mSurfaceDestroyDeferred = true;
569 destroySurfaceLocked();
570 }
571
572 void destroyPreservedSurfaceLocked() {
573 if (!mDestroyPreservedSurfaceUponRedraw) {
574 return;
575 }
Robert Carrd5c7dd62017-03-08 10:39:30 -0800576 if (mSurfaceController != null) {
577 if (mPendingDestroySurface != null) {
578 // If we are preserving a surface but we aren't relaunching that means
579 // we are just doing an in-place switch. In that case any SurfaceFlinger side
580 // child layers need to be reparented to the new surface to make this
581 // transparent to the app.
582 if (mWin.mAppToken == null || mWin.mAppToken.isRelaunching() == false) {
583 SurfaceControl.openTransaction();
584 mPendingDestroySurface.reparentChildrenInTransaction(mSurfaceController);
585 SurfaceControl.closeTransaction();
586 }
587 }
588 }
589
Chong Zhang97782b42015-10-07 16:01:23 -0700590 destroyDeferredSurfaceLocked();
591 mDestroyPreservedSurfaceUponRedraw = false;
592 }
593
Chong Zhangeb665572016-05-09 18:28:27 -0700594 void markPreservedSurfaceForDestroy() {
595 if (mDestroyPreservedSurfaceUponRedraw
596 && !mService.mDestroyPreservedSurface.contains(mWin)) {
597 mService.mDestroyPreservedSurface.add(mWin);
598 }
599 }
600
Robert Carrda61ba92017-03-29 15:52:23 -0700601 private int getLayerStack() {
602 return mWin.getDisplayContent().getDisplay().getLayerStack();
603 }
604
Robert Carrecc06b32017-04-18 14:25:10 -0700605 void resetDrawState() {
606 mDrawState = DRAW_PENDING;
607
608 if (mWin.mAppToken == null) {
609 return;
610 }
611
612 if (mWin.mAppToken.mAppAnimator.animation == null) {
613 mWin.mAppToken.clearAllDrawn();
614 } else {
615 // Currently animating, persist current state of allDrawn until animation
616 // is complete.
617 mWin.mAppToken.deferClearAllDrawn = true;
618 }
619 }
620
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500621 WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
Alan Viveretteccb11e12014-07-08 16:04:02 -0700622 final WindowState w = mWin;
Chong Zhanga8975bd2016-01-28 17:13:47 -0800623
Wale Ogunwale722ff892016-02-18 13:37:55 -0800624 if (mSurfaceController != null) {
625 return mSurfaceController;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700626 }
Wale Ogunwale722ff892016-02-18 13:37:55 -0800627
Robert Carr132c9f52017-07-31 17:02:30 -0700628 if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
629 windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT;
630 }
631
Wale Ogunwale722ff892016-02-18 13:37:55 -0800632 w.setHasSurface(false);
633
634 if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
635 "createSurface " + this + ": mDrawState=DRAW_PENDING");
636
Robert Carrecc06b32017-04-18 14:25:10 -0700637 resetDrawState();
Wale Ogunwale722ff892016-02-18 13:37:55 -0800638
639 mService.makeWindowFreezingScreenIfNeededLocked(w);
640
641 int flags = SurfaceControl.HIDDEN;
642 final WindowManager.LayoutParams attrs = w.mAttrs;
643
644 if (mService.isSecureLocked(w)) {
645 flags |= SurfaceControl.SECURE;
646 }
647
648 mTmpSize.set(w.mFrame.left + w.mXOffset, w.mFrame.top + w.mYOffset, 0, 0);
649 calculateSurfaceBounds(w, attrs);
650 final int width = mTmpSize.width();
651 final int height = mTmpSize.height();
652
653 if (DEBUG_VISIBILITY) {
654 Slog.v(TAG, "Creating surface in session "
655 + mSession.mSurfaceSession + " window " + this
656 + " w=" + width + " h=" + height
657 + " x=" + mTmpSize.left + " y=" + mTmpSize.top
658 + " format=" + attrs.format + " flags=" + flags);
659 }
660
661 // We may abort, so initialize to defaults.
662 mLastSystemDecorRect.set(0, 0, 0, 0);
663 mHasClipRect = false;
664 mClipRect.set(0, 0, 0, 0);
665 mLastClipRect.set(0, 0, 0, 0);
666
667 // Set up surface control with initial size.
668 try {
669
670 final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
671 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
672 if (!PixelFormat.formatHasAlpha(attrs.format)
673 // Don't make surface with surfaceInsets opaque as they display a
674 // translucent shadow.
675 && attrs.surfaceInsets.left == 0
676 && attrs.surfaceInsets.top == 0
677 && attrs.surfaceInsets.right == 0
678 && attrs.surfaceInsets.bottom == 0
679 // Don't make surface opaque when resizing to reduce the amount of
680 // artifacts shown in areas the app isn't drawing content to.
681 && !w.isDragResizing()) {
682 flags |= SurfaceControl.OPAQUE;
683 }
684
685 mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
686 attrs.getTitle().toString(),
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500687 width, height, format, flags, this, windowType, ownerUid);
Robert Carr486bbb72017-05-30 11:25:22 -0700688 mSurfaceFormat = format;
Wale Ogunwale722ff892016-02-18 13:37:55 -0800689
690 w.setHasSurface(true);
691
692 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
693 Slog.i(TAG, " CREATE SURFACE "
694 + mSurfaceController + " IN SESSION "
695 + mSession.mSurfaceSession
696 + ": pid=" + mSession.mPid + " format="
697 + attrs.format + " flags=0x"
698 + Integer.toHexString(flags)
699 + " / " + this);
700 }
701 } catch (OutOfResourcesException e) {
702 Slog.w(TAG, "OutOfResourcesException creating surface");
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700703 mService.mRoot.reclaimSomeSurfaceMemory(this, "create", true);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800704 mDrawState = NO_SURFACE;
705 return null;
706 } catch (Exception e) {
707 Slog.e(TAG, "Exception creating surface", e);
708 mDrawState = NO_SURFACE;
709 return null;
710 }
711
712 if (WindowManagerService.localLOGV) Slog.v(TAG, "Got surface: " + mSurfaceController
713 + ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
714 + ", animLayer=" + mAnimLayer);
715
716 if (SHOW_LIGHT_TRANSACTIONS) {
717 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
718 WindowManagerService.logSurface(w, "CREATE pos=("
719 + w.mFrame.left + "," + w.mFrame.top + ") ("
720 + width + "x" + height + "), layer=" + mAnimLayer + " HIDE", false);
721 }
722
Wale Ogunwale722ff892016-02-18 13:37:55 -0800723 mLastHidden = true;
724
725 if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this);
Robert Carre6a83512015-11-03 16:09:21 -0800726 return mSurfaceController;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700727 }
728
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800729 private void calculateSurfaceBounds(WindowState w, LayoutParams attrs) {
730 if ((attrs.flags & FLAG_SCALED) != 0) {
731 // For a scaled surface, we always want the requested size.
732 mTmpSize.right = mTmpSize.left + w.mRequestedWidth;
733 mTmpSize.bottom = mTmpSize.top + w.mRequestedHeight;
734 } else {
735 // When we're doing a drag-resizing, request a surface that's fullscreen size,
736 // so that we don't need to reallocate during the process. This also prevents
737 // buffer drops due to size mismatch.
738 if (w.isDragResizing()) {
739 if (w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM) {
740 mTmpSize.left = 0;
741 mTmpSize.top = 0;
742 }
743 final DisplayInfo displayInfo = w.getDisplayInfo();
744 mTmpSize.right = mTmpSize.left + displayInfo.logicalWidth;
745 mTmpSize.bottom = mTmpSize.top + displayInfo.logicalHeight;
746 } else {
747 mTmpSize.right = mTmpSize.left + w.mCompatFrame.width();
748 mTmpSize.bottom = mTmpSize.top + w.mCompatFrame.height();
749 }
750 }
751
752 // Something is wrong and SurfaceFlinger will not like this, try to revert to sane values.
Filip Gruszczynskie6ed1952015-12-21 09:34:16 -0800753 // This doesn't necessarily mean that there is an error in the system. The sizes might be
754 // incorrect, because it is before the first layout or draw.
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800755 if (mTmpSize.width() < 1) {
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800756 mTmpSize.right = mTmpSize.left + 1;
757 }
758 if (mTmpSize.height() < 1) {
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800759 mTmpSize.bottom = mTmpSize.top + 1;
760 }
761
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800762 // Adjust for surface insets.
Phil Weavera4b32b92016-06-02 13:55:39 -0700763 mTmpSize.left -= attrs.surfaceInsets.left;
764 mTmpSize.top -= attrs.surfaceInsets.top;
765 mTmpSize.right += attrs.surfaceInsets.right;
766 mTmpSize.bottom += attrs.surfaceInsets.bottom;
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800767 }
768
Chong Zhangeb22e8e2016-01-20 19:52:22 -0800769 boolean hasSurface() {
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200770 return mSurfaceController != null && mSurfaceController.hasSurface();
Chong Zhangeb22e8e2016-01-20 19:52:22 -0800771 }
772
Craig Mautner96868332012-12-04 14:29:11 -0800773 void destroySurfaceLocked() {
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700774 final AppWindowToken wtoken = mWin.mAppToken;
775 if (wtoken != null) {
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700776 if (mWin == wtoken.startingWindow) {
777 wtoken.startingDisplayed = false;
778 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700779 }
780
Wale Ogunwale722ff892016-02-18 13:37:55 -0800781 if (mSurfaceController == null) {
782 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700783 }
Wale Ogunwale722ff892016-02-18 13:37:55 -0800784
Wale Ogunwale722ff892016-02-18 13:37:55 -0800785 // When destroying a surface we want to make sure child windows are hidden. If we are
786 // preserving the surface until redraw though we intend to swap it out with another surface
787 // for resizing. In this case the window always remains visible to the user and the child
788 // windows should likewise remain visible.
Wale Ogunwale9d147902016-07-16 11:58:55 -0700789 if (!mDestroyPreservedSurfaceUponRedraw) {
790 mWin.mHidden = true;
Wale Ogunwale722ff892016-02-18 13:37:55 -0800791 }
792
793 try {
794 if (DEBUG_VISIBILITY) logWithStack(TAG, "Window " + this + " destroying surface "
795 + mSurfaceController + ", session " + mSession);
796 if (mSurfaceDestroyDeferred) {
797 if (mSurfaceController != null && mPendingDestroySurface != mSurfaceController) {
798 if (mPendingDestroySurface != null) {
799 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
800 WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
801 }
802 mPendingDestroySurface.destroyInTransaction();
803 }
804 mPendingDestroySurface = mSurfaceController;
805 }
806 } else {
807 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
808 WindowManagerService.logSurface(mWin, "DESTROY", true);
809 }
810 destroySurface();
811 }
812 // Don't hide wallpaper if we're deferring the surface destroy
813 // because of a surface change.
814 if (!mDestroyPreservedSurfaceUponRedraw) {
815 mWallpaperControllerLocked.hideWallpapers(mWin);
816 }
817 } catch (RuntimeException e) {
818 Slog.w(TAG, "Exception thrown when destroying Window " + this
819 + " surface " + mSurfaceController + " session " + mSession + ": " + e.toString());
820 }
821
822 // Whether the surface was preserved (and copied to mPendingDestroySurface) or not, it
823 // needs to be cleared to match the WindowState.mHasSurface state. It is also necessary
824 // so it can be recreated successfully in mPendingDestroySurface case.
825 mWin.setHasSurface(false);
826 if (mSurfaceController != null) {
827 mSurfaceController.setShown(false);
828 }
829 mSurfaceController = null;
830 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700831 }
832
Craig Mautner96868332012-12-04 14:29:11 -0800833 void destroyDeferredSurfaceLocked() {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700834 try {
835 if (mPendingDestroySurface != null) {
836 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -0800837 WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700838 }
Robert Carre6a83512015-11-03 16:09:21 -0800839 mPendingDestroySurface.destroyInTransaction();
Chong Zhang6e21cf42015-11-09 14:41:42 -0800840 // Don't hide wallpaper if we're destroying a deferred surface
841 // after a surface mode change.
842 if (!mDestroyPreservedSurfaceUponRedraw) {
843 mWallpaperControllerLocked.hideWallpapers(mWin);
844 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700845 }
846 } catch (RuntimeException e) {
Craig Mautnerd87946b2012-03-29 18:00:19 -0700847 Slog.w(TAG, "Exception thrown when destroying Window "
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700848 + this + " surface " + mPendingDestroySurface
849 + " session " + mSession + ": " + e.toString());
850 }
851 mSurfaceDestroyDeferred = false;
852 mPendingDestroySurface = null;
853 }
854
855 void computeShownFrameLocked() {
856 final boolean selfTransformation = mHasLocalTransformation;
Craig Mautner322e4032012-07-13 13:35:20 -0700857 Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation)
858 ? mAppAnimator.transformation : null;
Robert Carr29d196f2017-11-28 12:39:46 -0800859 Transformation wallpaperTargetTransformation = null;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700860
861 // Wallpapers are animated based on the "real" window they
862 // are currently targeting.
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700863 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
Craig Mautner798adef2013-10-22 14:29:01 -0700864 if (mIsWallpaper && wallpaperTarget != null && mService.mAnimateWallpaperWithTarget) {
865 final WindowStateAnimator wallpaperAnimator = wallpaperTarget.mWinAnimator;
Craig Mautner918b53b2012-07-09 14:15:54 -0700866 if (wallpaperAnimator.mHasLocalTransformation &&
867 wallpaperAnimator.mAnimation != null &&
868 !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
Robert Carr29d196f2017-11-28 12:39:46 -0800869 wallpaperTargetTransformation = wallpaperAnimator.mTransformation;
870 if (DEBUG_WALLPAPER && wallpaperTargetTransformation != null) {
871 Slog.v(TAG, "WP target attached xform: " + wallpaperTargetTransformation);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700872 }
873 }
Craig Mautner798adef2013-10-22 14:29:01 -0700874 final AppWindowAnimator wpAppAnimator = wallpaperTarget.mAppToken == null ?
875 null : wallpaperTarget.mAppToken.mAppAnimator;
876 if (wpAppAnimator != null && wpAppAnimator.hasTransformation
Craig Mautner918b53b2012-07-09 14:15:54 -0700877 && wpAppAnimator.animation != null
878 && !wpAppAnimator.animation.getDetachWallpaper()) {
Craig Mautner59431632012-04-04 11:56:44 -0700879 appTransformation = wpAppAnimator.transformation;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800880 if (DEBUG_WALLPAPER && appTransformation != null) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700881 Slog.v(TAG, "WP target app xform: " + appTransformation);
882 }
883 }
884 }
885
Craig Mautnera91f9e22012-09-14 16:22:08 -0700886 final int displayId = mWin.getDisplayId();
887 final ScreenRotationAnimation screenRotationAnimation =
888 mAnimator.getScreenRotationAnimationLocked(displayId);
889 final boolean screenAnimation =
890 screenRotationAnimation != null && screenRotationAnimation.isAnimating();
Robert Carr2f0fe622015-09-25 14:56:38 -0700891
892 mHasClipRect = false;
Robert Carr29d196f2017-11-28 12:39:46 -0800893 if (selfTransformation || wallpaperTargetTransformation != null
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700894 || appTransformation != null || screenAnimation) {
895 // cache often used attributes locally
896 final Rect frame = mWin.mFrame;
897 final float tmpFloats[] = mService.mTmpFloats;
898 final Matrix tmpMatrix = mWin.mTmpMatrix;
899
900 // Compute the desired transformation.
Dianne Hackborn4b169692012-11-29 17:51:24 -0800901 if (screenAnimation && screenRotationAnimation.isRotating()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700902 // If we are doing a screen animation, the global rotation
903 // applied to windows can result in windows that are carefully
904 // aligned with each other to slightly separate, allowing you
905 // to see what is behind them. An unsightly mess. This...
906 // thing... magically makes it call good: scale each window
907 // slightly (two pixels larger in each dimension, from the
908 // window's center).
909 final float w = frame.width();
910 final float h = frame.height();
911 if (w>=1 && h>=1) {
912 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
913 } else {
914 tmpMatrix.reset();
915 }
916 } else {
917 tmpMatrix.reset();
918 }
919 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
920 if (selfTransformation) {
921 tmpMatrix.postConcat(mTransformation.getMatrix());
922 }
Robert Carr29d196f2017-11-28 12:39:46 -0800923
924 if (wallpaperTargetTransformation != null) {
925 tmpMatrix.postConcat(wallpaperTargetTransformation.getMatrix());
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700926 }
927 if (appTransformation != null) {
928 tmpMatrix.postConcat(appTransformation.getMatrix());
929 }
Matthew Ng34a06d12017-02-03 11:56:08 -0800930
Robert Carr29d196f2017-11-28 12:39:46 -0800931 int left = frame.left;
932 int top = frame.top;
933 if (mWin.isChildWindow()) {
934 WindowState parent = mWin.getParentWindow();
935 left -= parent.mFrame.left;
936 top -= parent.mFrame.top;
937 }
938
Matthew Ng34a06d12017-02-03 11:56:08 -0800939 // The translation that applies the position of the window needs to be applied at the
940 // end in case that other translations include scaling. Otherwise the scaling will
941 // affect this translation. But it needs to be set before the screen rotation animation
942 // so the pivot point is at the center of the screen for all windows.
Robert Carr29d196f2017-11-28 12:39:46 -0800943 tmpMatrix.postTranslate(left + mWin.mXOffset, top + mWin.mYOffset);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700944 if (screenAnimation) {
Craig Mautnera91f9e22012-09-14 16:22:08 -0700945 tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700946 }
Winson Chung399f6202014-03-19 10:47:20 -0700947
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700948 // "convert" it into SurfaceFlinger's format
949 // (a 2x2 matrix + an offset)
950 // Here we must not transform the position of the surface
951 // since it is already included in the transformation.
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800952 //Slog.i(TAG_WM, "Transform: " + matrix);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700953
954 mHaveMatrix = true;
955 tmpMatrix.getValues(tmpFloats);
956 mDsDx = tmpFloats[Matrix.MSCALE_X];
957 mDtDx = tmpFloats[Matrix.MSKEW_Y];
Robert Carr0edf18f2017-02-21 20:01:47 -0800958 mDtDy = tmpFloats[Matrix.MSKEW_X];
959 mDsDy = tmpFloats[Matrix.MSCALE_Y];
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700960 float x = tmpFloats[Matrix.MTRANS_X];
961 float y = tmpFloats[Matrix.MTRANS_Y];
Qiushi Han32fed962016-10-01 17:06:49 +0800962 mWin.mShownPosition.set(Math.round(x), Math.round(y));
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700963
964 // Now set the alpha... but because our current hardware
965 // can't do alpha transformation on a non-opaque surface,
966 // turn it off if we are running an animation that is also
967 // transforming since it is more important to have that
968 // animation be smooth.
969 mShownAlpha = mAlpha;
970 if (!mService.mLimitedAlphaCompositing
971 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
Robert Carr0edf18f2017-02-21 20:01:47 -0800972 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700973 && x == frame.left && y == frame.top))) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800974 //Slog.i(TAG_WM, "Applying alpha transform");
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700975 if (selfTransformation) {
976 mShownAlpha *= mTransformation.getAlpha();
977 }
Robert Carr29d196f2017-11-28 12:39:46 -0800978 if (wallpaperTargetTransformation != null) {
979 mShownAlpha *= wallpaperTargetTransformation.getAlpha();
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700980 }
981 if (appTransformation != null) {
982 mShownAlpha *= appTransformation.getAlpha();
Winson Chung399f6202014-03-19 10:47:20 -0700983 if (appTransformation.hasClipRect()) {
984 mClipRect.set(appTransformation.getClipRect());
985 mHasClipRect = true;
Robert Carrf3b72c72016-03-21 18:16:39 -0700986 // The app transformation clip will be in the coordinate space of the main
987 // activity window, which the animation correctly assumes will be placed at
988 // (0,0)+(insets) relative to the containing frame. This isn't necessarily
989 // true for child windows though which can have an arbitrary frame position
990 // relative to their containing frame. We need to offset the difference
991 // between the containing frame as used to calculate the crop and our
992 // bounds to compensate for this.
Wale Ogunwale246c2092016-04-07 14:12:44 -0700993 if (mWin.layoutInParentFrame()) {
Robert Carrf3b72c72016-03-21 18:16:39 -0700994 mClipRect.offset( (mWin.mContainingFrame.left - mWin.mFrame.left),
995 mWin.mContainingFrame.top - mWin.mFrame.top );
996 }
Winson Chung399f6202014-03-19 10:47:20 -0700997 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700998 }
999 if (screenAnimation) {
Craig Mautnera91f9e22012-09-14 16:22:08 -07001000 mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001001 }
1002 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001003 //Slog.i(TAG_WM, "Not applying alpha transform");
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001004 }
1005
Robert Carre13b58e2017-08-31 14:50:44 -07001006 if ((DEBUG_ANIM || WindowManagerService.localLOGV)
Craig Mautnera91f9e22012-09-14 16:22:08 -07001007 && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
1008 TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
1009 + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null")
Robert Carr29d196f2017-11-28 12:39:46 -08001010 + " attached=" + (wallpaperTargetTransformation == null ?
1011 "null" : wallpaperTargetTransformation.getAlpha())
Craig Mautnera91f9e22012-09-14 16:22:08 -07001012 + " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha())
1013 + " screen=" + (screenAnimation ?
1014 screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001015 return;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001016 } else if (mIsWallpaper && mService.mRoot.mWallpaperActionPending) {
Craig Mautner4d7349b2012-04-20 14:52:47 -07001017 return;
Chong Zhang3005e752015-09-18 18:46:28 -07001018 } else if (mWin.isDragResizeChanged()) {
1019 // This window is awaiting a relayout because user just started (or ended)
1020 // drag-resizing. The shown frame (which affects surface size and pos)
1021 // should not be updated until we get next finished draw with the new surface.
1022 // Otherwise one or two frames rendered with old settings would be displayed
1023 // with new geometry.
1024 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001025 }
1026
Filip Gruszczynski19723a42015-11-25 15:01:48 -08001027 if (WindowManagerService.localLOGV) Slog.v(
Craig Mautner4d7349b2012-04-20 14:52:47 -07001028 TAG, "computeShownFrameLocked: " + this +
1029 " not attached, mAlpha=" + mAlpha);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -07001030
Robert Carrb1579c82017-09-05 14:54:47 -07001031 mWin.mShownPosition.set(mWin.mFrame.left, mWin.mFrame.top);
1032 if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
1033 mWin.mShownPosition.offset(mWin.mXOffset, mWin.mYOffset);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001034 }
Robert Carrb1579c82017-09-05 14:54:47 -07001035 mShownAlpha = mAlpha;
1036 mHaveMatrix = false;
1037 mDsDx = mWin.mGlobalScale;
1038 mDtDx = 0;
1039 mDtDy = 0;
1040 mDsDy = mWin.mGlobalScale;
Robert Carref090ac2017-05-15 16:45:50 -07001041 }
1042
Robert Carrfbbde852016-10-18 11:02:28 -07001043 /**
1044 * In some scenarios we use a screen space clip rect (so called, final clip rect)
1045 * to crop to stack bounds. Generally because it's easier to deal with while
1046 * animating.
1047 *
1048 * @return True in scenarios where we use the final clip rect for stack clipping.
1049 */
1050 private boolean useFinalClipRect() {
1051 return (isAnimationSet() && resolveStackClip() == STACK_CLIP_AFTER_ANIM)
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001052 || mDestroyPreservedSurfaceUponRedraw || mWin.inPinnedWindowingMode();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001053 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07001054
Robert Carrfbbde852016-10-18 11:02:28 -07001055 /**
1056 * Calculate the screen-space crop rect and fill finalClipRect.
1057 * @return true if finalClipRect has been filled, otherwise,
1058 * no screen space crop should be applied.
1059 */
1060 private boolean calculateFinalCrop(Rect finalClipRect) {
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001061 final WindowState w = mWin;
Craig Mautnerdf88d732014-01-27 09:21:32 -08001062 final DisplayContent displayContent = w.getDisplayContent();
Robert Carrfbbde852016-10-18 11:02:28 -07001063 finalClipRect.setEmpty();
1064
Craig Mautnerdf88d732014-01-27 09:21:32 -08001065 if (displayContent == null) {
Robert Carrfbbde852016-10-18 11:02:28 -07001066 return false;
Craig Mautnerdf88d732014-01-27 09:21:32 -08001067 }
Robert Carrfbbde852016-10-18 11:02:28 -07001068
1069 if (!shouldCropToStackBounds() || !useFinalClipRect()) {
1070 return false;
1071 }
1072
1073 // Task is non-null per shouldCropToStackBounds
1074 final TaskStack stack = w.getTask().mStack;
1075 stack.getDimBounds(finalClipRect);
Robert Carr002c8e12017-04-27 15:32:22 -07001076
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001077 if (stack.getWindowConfiguration().tasksAreFloating()) {
Robert Carr002c8e12017-04-27 15:32:22 -07001078 w.expandForSurfaceInsets(finalClipRect);
1079 }
Robert Carref090ac2017-05-15 16:45:50 -07001080
Robert Carrfbbde852016-10-18 11:02:28 -07001081 return true;
1082 }
1083
1084 /**
1085 * Calculate the window-space crop rect and fill clipRect.
Wale Ogunwaleca9e0612016-12-02 07:45:59 -08001086 * @return true if clipRect has been filled otherwise, no window space crop should be applied.
Robert Carrfbbde852016-10-18 11:02:28 -07001087 */
Wale Ogunwaleca9e0612016-12-02 07:45:59 -08001088 private boolean calculateCrop(Rect clipRect) {
Robert Carrfbbde852016-10-18 11:02:28 -07001089 final WindowState w = mWin;
1090 final DisplayContent displayContent = w.getDisplayContent();
1091 clipRect.setEmpty();
1092
1093 if (displayContent == null) {
1094 return false;
1095 }
1096
Wale Ogunwale44f036f2017-09-29 05:09:09 -07001097 if (w.inPinnedWindowingMode()) {
Robert Carrfbbde852016-10-18 11:02:28 -07001098 return false;
1099 }
1100
1101 // If we're animating, the wallpaper should only
1102 // be updated at the end of the animation.
1103 if (w.mAttrs.type == TYPE_WALLPAPER) {
1104 return false;
1105 }
1106
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001107 if (DEBUG_WINDOW_CROP) Slog.d(TAG,
1108 "Updating crop win=" + w + " mLastCrop=" + mLastClipRect);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001109
Robert Carrfbbde852016-10-18 11:02:28 -07001110 w.calculatePolicyCrop(mSystemDecorRect);
1111
1112 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
1113 + w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001114
Andrii Kulian283acd22017-08-03 04:03:51 -07001115 final Task task = w.getTask();
1116 final boolean fullscreen = w.fillsDisplay() || (task != null && task.isFullscreen());
Jorim Jaggi253a20f2015-11-03 12:38:42 +01001117 final boolean isFreeformResizing =
Jorim Jaggidcf467c2015-11-05 13:59:32 +01001118 w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
Robert Carr51a1b872015-12-08 14:03:13 -08001119
1120 // We use the clip rect as provided by the tranformation for non-fullscreen windows to
1121 // avoid premature clipping with the system decor rect.
1122 clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : mSystemDecorRect);
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001123 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect
1124 + " mHasClipRect=" + mHasClipRect + " fullscreen=" + fullscreen);
Robert Carr51a1b872015-12-08 14:03:13 -08001125
1126 if (isFreeformResizing && !w.isChildWindow()) {
1127 // For freeform resizing non child windows, we are using the big surface positioned
1128 // at 0,0. Thus we must express the crop in that coordinate space.
1129 clipRect.offset(w.mShownPosition.x, w.mShownPosition.y);
Chong Zhang09b21ef2015-09-14 10:20:21 -07001130 }
Robert Carr51a1b872015-12-08 14:03:13 -08001131
Robert Carrfbbde852016-10-18 11:02:28 -07001132 w.expandForSurfaceInsets(clipRect);
Alan Viverette49a22e82014-07-12 20:01:27 -07001133
Wale Ogunwaleb3eba812015-07-30 20:20:16 -07001134 if (mHasClipRect && fullscreen) {
1135 // We intersect the clip rect specified by the transformation with the expanded system
1136 // decor rect to prevent artifacts from drawing during animation if the transformation
1137 // clip rect extends outside the system decor rect.
1138 clipRect.intersect(mClipRect);
1139 }
Alan Viverette49a22e82014-07-12 20:01:27 -07001140 // The clip rect was generated assuming (0,0) as the window origin,
1141 // so we need to translate to match the actual surface coordinates.
Robert Carrfbbde852016-10-18 11:02:28 -07001142 clipRect.offset(w.mAttrs.surfaceInsets.left, w.mAttrs.surfaceInsets.top);
Robert Carr58f29132015-10-29 14:19:05 -07001143
Robert Carrfbbde852016-10-18 11:02:28 -07001144 if (!useFinalClipRect()) {
1145 adjustCropToStackBounds(clipRect, isFreeformResizing);
1146 }
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001147 if (DEBUG_WINDOW_CROP) Slog.d(TAG,
1148 "win=" + w + " Clip rect after stack adjustment=" + clipRect);
Robert Carr58f29132015-10-29 14:19:05 -07001149
Chia-I Wue6bcaf12016-05-27 10:58:48 +08001150 w.transformClipRectFromScreenToSurfaceSpace(clipRect);
Robert Carr58f29132015-10-29 14:19:05 -07001151
Robert Carrfbbde852016-10-18 11:02:28 -07001152 return true;
Robert Carr0d00c2e2016-02-29 17:45:02 -08001153 }
1154
Robert Carrfbbde852016-10-18 11:02:28 -07001155 private void applyCrop(Rect clipRect, Rect finalClipRect, boolean recoveringMemory) {
1156 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "applyCrop: win=" + mWin
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001157 + " clipRect=" + clipRect + " finalClipRect=" + finalClipRect);
Robert Carr4320d332016-06-10 15:13:32 -07001158 if (clipRect != null) {
1159 if (!clipRect.equals(mLastClipRect)) {
1160 mLastClipRect.set(clipRect);
1161 mSurfaceController.setCropInTransaction(clipRect, recoveringMemory);
1162 }
1163 } else {
1164 mSurfaceController.clearCropInTransaction(recoveringMemory);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001165 }
Robert Carrfbbde852016-10-18 11:02:28 -07001166
1167 if (finalClipRect == null) {
1168 finalClipRect = mService.mTmpRect;
1169 finalClipRect.setEmpty();
1170 }
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001171 if (!finalClipRect.equals(mLastFinalClipRect)) {
1172 mLastFinalClipRect.set(finalClipRect);
1173 mSurfaceController.setFinalCropInTransaction(finalClipRect);
Chong Zhangcc3eccf2016-05-16 18:25:45 -07001174 if (mDestroyPreservedSurfaceUponRedraw && mPendingDestroySurface != null) {
1175 mPendingDestroySurface.setFinalCropInTransaction(finalClipRect);
1176 }
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001177 }
Dianne Hackborn3e52fc22012-05-15 17:58:02 -07001178 }
1179
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001180 private int resolveStackClip() {
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001181 // App animation overrides window animation stack clip mode.
1182 if (mAppAnimator != null && mAppAnimator.animation != null) {
1183 return mAppAnimator.getStackClip();
1184 } else {
1185 return mStackClip;
1186 }
1187 }
Wale Ogunwale4c5aa5172016-04-19 11:29:05 -07001188
Robert Carrfbbde852016-10-18 11:02:28 -07001189 private boolean shouldCropToStackBounds() {
1190 final WindowState w = mWin;
Wale Ogunwale4c5aa5172016-04-19 11:29:05 -07001191 final DisplayContent displayContent = w.getDisplayContent();
1192 if (displayContent != null && !displayContent.isDefaultDisplay) {
1193 // There are some windows that live on other displays while their app and main window
1194 // live on the default display (e.g. casting...). We don't want to crop this windows
1195 // to the stack bounds which is only currently supported on the default display.
1196 // TODO(multi-display): Need to support cropping to stack bounds on other displays
1197 // when we have stacks on other displays.
Robert Carrfbbde852016-10-18 11:02:28 -07001198 return false;
Wale Ogunwale4c5aa5172016-04-19 11:29:05 -07001199 }
1200
Chong Zhang112eb8c2015-11-02 11:17:00 -08001201 final Task task = w.getTask();
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001202 if (task == null || !task.cropWindowsToStackBounds()) {
Robert Carrfbbde852016-10-18 11:02:28 -07001203 return false;
Filip Gruszczynski4b8eea72015-09-14 18:16:19 -07001204 }
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001205
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001206 final int stackClip = resolveStackClip();
1207
1208 // It's animating and we don't want to clip it to stack bounds during animation - abort.
Jorim Jaggi5c80c412016-04-19 20:03:47 -07001209 if (isAnimationSet() && stackClip == STACK_CLIP_NONE) {
Robert Carrfbbde852016-10-18 11:02:28 -07001210 return false;
1211 }
1212 return true;
1213 }
1214
1215 private void adjustCropToStackBounds(Rect clipRect,
1216 boolean isFreeformResizing) {
1217 final WindowState w = mWin;
1218
1219 if (!shouldCropToStackBounds()) {
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001220 return;
1221 }
1222
Robert Carrfbbde852016-10-18 11:02:28 -07001223 final TaskStack stack = w.getTask().mStack;
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001224 stack.getDimBounds(mTmpStackBounds);
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001225 final Rect surfaceInsets = w.getAttrs().surfaceInsets;
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001226 // When we resize we use the big surface approach, which means we can't trust the
1227 // window frame bounds anymore. Instead, the window will be placed at 0, 0, but to avoid
1228 // hardcoding it, we use surface coordinates.
1229 final int frameX = isFreeformResizing ? (int) mSurfaceController.getX() :
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001230 w.mFrame.left + mWin.mXOffset - surfaceInsets.left;
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001231 final int frameY = isFreeformResizing ? (int) mSurfaceController.getY() :
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001232 w.mFrame.top + mWin.mYOffset - surfaceInsets.top;
Robert Carr0d00c2e2016-02-29 17:45:02 -08001233
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001234 // We need to do some acrobatics with surface position, because their clip region is
1235 // relative to the inside of the surface, but the stack bounds aren't.
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001236 final WindowConfiguration winConfig = w.getWindowConfiguration();
1237 if (winConfig.hasWindowShadow() && !winConfig.canResizeTask()) {
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001238 // The windows in this stack display drop shadows and the fill the entire stack
1239 // area. Adjust the stack bounds we will use to cropping take into account the
1240 // offsets we use to display the drop shadow so it doesn't get cropped.
1241 mTmpStackBounds.inset(-surfaceInsets.left, -surfaceInsets.top,
1242 -surfaceInsets.right, -surfaceInsets.bottom);
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001243 }
Robert Carrfbbde852016-10-18 11:02:28 -07001244
1245 clipRect.left = Math.max(0,
1246 Math.max(mTmpStackBounds.left, frameX + clipRect.left) - frameX);
1247 clipRect.top = Math.max(0,
1248 Math.max(mTmpStackBounds.top, frameY + clipRect.top) - frameY);
1249 clipRect.right = Math.max(0,
1250 Math.min(mTmpStackBounds.right, frameX + clipRect.right) - frameX);
1251 clipRect.bottom = Math.max(0,
1252 Math.min(mTmpStackBounds.bottom, frameY + clipRect.bottom) - frameY);
Filip Gruszczynski4b8eea72015-09-14 18:16:19 -07001253 }
1254
Wale Ogunwale4c8b7952015-04-07 10:49:40 -07001255 void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
Wale Ogunwale027f4752017-05-12 10:37:16 -07001256 if (mSurfaceController == null) {
1257 return;
1258 }
1259
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001260 final WindowState w = mWin;
Winson Chung08f81892017-03-02 15:40:51 -08001261 final LayoutParams attrs = mWin.getAttrs();
Robert Carr0d00c2e2016-02-29 17:45:02 -08001262 final Task task = w.getTask();
Alan Viveretteccb11e12014-07-08 16:04:02 -07001263
Jorim Jaggif3df0aa2016-04-06 15:56:33 -07001264 // We got resized, so block all updates until we got the new surface.
Andrii Kulianeb1d3222016-05-16 15:17:55 -07001265 if (w.isResizedWhileNotDragResizing() && !w.isGoneForLayoutLw()) {
Jorim Jaggif3df0aa2016-04-06 15:56:33 -07001266 return;
1267 }
1268
Filip Gruszczynski69cbc352015-11-11 13:46:04 -08001269 mTmpSize.set(w.mShownPosition.x, w.mShownPosition.y, 0, 0);
Winson Chung08f81892017-03-02 15:40:51 -08001270 calculateSurfaceBounds(w, attrs);
Chong Zhang0275e392015-09-17 10:41:44 -07001271
Robert Carr04092112016-06-02 12:56:12 -07001272 mExtraHScale = (float) 1.0;
1273 mExtraVScale = (float) 1.0;
Robert Carre1034cc32016-02-01 13:08:15 -08001274
Robert Carr6da3cc02016-06-16 15:17:07 -07001275 boolean wasForceScaled = mForceScaleUntilResize;
1276 boolean wasSeamlesslyRotated = w.mSeamlesslyRotated;
1277
Robert Carrfed10072016-05-26 11:48:49 -07001278 // Once relayout has been called at least once, we need to make sure
1279 // we only resize the client surface during calls to relayout. For
1280 // clients which use indeterminate measure specs (MATCH_PARENT),
1281 // we may try and change their window size without a call to relayout.
1282 // However, this would be unsafe, as the client may be in the middle
1283 // of producing a frame at the old size, having just completed layout
1284 // to find the surface size changed underneath it.
Robert Carr3ccc5272016-06-20 22:06:32 -07001285 if (!w.mRelayoutCalled || w.mInRelayout) {
Robert Carrfed10072016-05-26 11:48:49 -07001286 mSurfaceResized = mSurfaceController.setSizeInTransaction(
1287 mTmpSize.width(), mTmpSize.height(), recoveringMemory);
1288 } else {
1289 mSurfaceResized = false;
1290 }
Robert Carrc7294602016-05-13 11:32:05 -07001291 mForceScaleUntilResize = mForceScaleUntilResize && !mSurfaceResized;
Robert Carr6da3cc02016-06-16 15:17:07 -07001292 // If we are undergoing seamless rotation, the surface has already
1293 // been set up to persist at it's old location. We need to freeze
1294 // updates until a resize occurs.
Robert Carrb14d4abc2016-10-03 18:13:33 -07001295 mService.markForSeamlessRotation(w, w.mSeamlesslyRotated && !mSurfaceResized);
Robert Carrc7294602016-05-13 11:32:05 -07001296
Robert Carrfbbde852016-10-18 11:02:28 -07001297 Rect clipRect = null, finalClipRect = null;
1298 if (calculateCrop(mTmpClipRect)) {
1299 clipRect = mTmpClipRect;
1300 }
1301 if (calculateFinalCrop(mTmpFinalClipRect)) {
1302 finalClipRect = mTmpFinalClipRect;
1303 }
Robert Carra9408d42016-06-03 13:28:48 -07001304
1305 float surfaceWidth = mSurfaceController.getWidth();
1306 float surfaceHeight = mSurfaceController.getHeight();
1307
Robert Carr8f0a3ad2017-02-15 19:30:28 -08001308 if (isForceScaled()) {
Winson Chung08f81892017-03-02 15:40:51 -08001309 int hInsets = attrs.surfaceInsets.left + attrs.surfaceInsets.right;
1310 int vInsets = attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
1311 float surfaceContentWidth = surfaceWidth - hInsets;
1312 float surfaceContentHeight = surfaceHeight - vInsets;
Robert Carra9408d42016-06-03 13:28:48 -07001313 if (!mForceScaleUntilResize) {
1314 mSurfaceController.forceScaleableInTransaction(true);
1315 }
Robert Carrfd4c9892017-02-01 10:28:28 -08001316
Winson Chung08f81892017-03-02 15:40:51 -08001317 int posX = mTmpSize.left;
1318 int posY = mTmpSize.top;
Robert Carrfd4c9892017-02-01 10:28:28 -08001319 task.mStack.getDimBounds(mTmpStackBounds);
Robert Carr18f622f2017-05-08 11:20:43 -07001320
1321 boolean allowStretching = false;
Winson Chung8bca9e42017-04-16 15:59:43 -07001322 task.mStack.getFinalAnimationSourceHintBounds(mTmpSourceBounds);
Robert Carr18f622f2017-05-08 11:20:43 -07001323 // If we don't have source bounds, we can attempt to use the content insets
1324 // in the following scenario:
1325 // 1. We have content insets.
1326 // 2. We are not transitioning to full screen
1327 // We have to be careful to check "lastAnimatingBoundsWasToFullscreen" rather than
1328 // the mBoundsAnimating state, as we may have already left it and only be here
1329 // because of the force-scale until resize state.
1330 if (mTmpSourceBounds.isEmpty() && (mWin.mLastRelayoutContentInsets.width() > 0
1331 || mWin.mLastRelayoutContentInsets.height() > 0)
1332 && !task.mStack.lastAnimatingBoundsWasToFullscreen()) {
1333 mTmpSourceBounds.set(task.mStack.mPreAnimationBounds);
1334 mTmpSourceBounds.inset(mWin.mLastRelayoutContentInsets);
1335 allowStretching = true;
1336 }
Winson Chung08f81892017-03-02 15:40:51 -08001337 if (!mTmpSourceBounds.isEmpty()) {
1338 // Get the final target stack bounds, if we are not animating, this is just the
1339 // current stack bounds
Winson Chung40a5f932017-04-13 16:39:36 -07001340 task.mStack.getFinalAnimationBounds(mTmpAnimatingBounds);
Winson Chung08f81892017-03-02 15:40:51 -08001341
1342 // Calculate the current progress and interpolate the difference between the target
1343 // and source bounds
1344 float finalWidth = mTmpAnimatingBounds.width();
1345 float initialWidth = mTmpSourceBounds.width();
Robert Carr18f622f2017-05-08 11:20:43 -07001346 float tw = (surfaceContentWidth - mTmpStackBounds.width())
Winson Chung08f81892017-03-02 15:40:51 -08001347 / (surfaceContentWidth - mTmpAnimatingBounds.width());
Robert Carr18f622f2017-05-08 11:20:43 -07001348 float th = tw;
1349 mExtraHScale = (initialWidth + tw * (finalWidth - initialWidth)) / initialWidth;
1350 if (allowStretching) {
1351 float finalHeight = mTmpAnimatingBounds.height();
1352 float initialHeight = mTmpSourceBounds.height();
1353 th = (surfaceContentHeight - mTmpStackBounds.height())
1354 / (surfaceContentHeight - mTmpAnimatingBounds.height());
1355 mExtraVScale = (initialHeight + tw * (finalHeight - initialHeight))
1356 / initialHeight;
1357 } else {
1358 mExtraVScale = mExtraHScale;
1359 }
Winson Chung08f81892017-03-02 15:40:51 -08001360
1361 // Adjust the position to account for the inset bounds
Robert Carr18f622f2017-05-08 11:20:43 -07001362 posX -= (int) (tw * mExtraHScale * mTmpSourceBounds.left);
1363 posY -= (int) (th * mExtraVScale * mTmpSourceBounds.top);
Winson Chung08f81892017-03-02 15:40:51 -08001364
1365 // Always clip to the stack bounds since the surface can be larger with the current
1366 // scale
1367 clipRect = null;
1368 finalClipRect = mTmpStackBounds;
1369 } else {
1370 // We want to calculate the scaling based on the content area, not based on
1371 // the entire surface, so that we scale in sync with windows that don't have insets.
1372 mExtraHScale = mTmpStackBounds.width() / surfaceContentWidth;
1373 mExtraVScale = mTmpStackBounds.height() / surfaceContentHeight;
1374
1375 // Since we are scaled to fit in our previously desired crop, we can now
1376 // expose the whole window in buffer space, and not risk extending
1377 // past where the system would have cropped us
1378 clipRect = null;
1379 finalClipRect = null;
1380 }
Robert Carr0d00c2e2016-02-29 17:45:02 -08001381
Robert Carrfd4c9892017-02-01 10:28:28 -08001382 // In the case of ForceScaleToStack we scale entire tasks together,
Robert Carr0d00c2e2016-02-29 17:45:02 -08001383 // and so we need to scale our offsets relative to the task bounds
1384 // or parent and child windows would fall out of alignment.
Winson Chung08f81892017-03-02 15:40:51 -08001385 posX -= (int) (attrs.x * (1 - mExtraHScale));
1386 posY -= (int) (attrs.y * (1 - mExtraVScale));
1387
Robert Carrbc133762016-05-12 14:04:38 -07001388 // Imagine we are scaling down. As we scale the buffer down, we decrease the
1389 // distance between the surface top left, and the start of the surface contents
1390 // (previously it was surfaceInsets.left pixels in screen space but now it
Robert Carr04092112016-06-02 12:56:12 -07001391 // will be surfaceInsets.left*mExtraHScale). This means in order to keep the
Robert Carrbc133762016-05-12 14:04:38 -07001392 // non inset content at the same position, we have to shift the whole window
1393 // forward. Likewise for scaling up, we've increased this distance, and we need
1394 // to shift by a negative number to compensate.
Winson Chung08f81892017-03-02 15:40:51 -08001395 posX += attrs.surfaceInsets.left * (1 - mExtraHScale);
1396 posY += attrs.surfaceInsets.top * (1 - mExtraVScale);
Robert Carrbc133762016-05-12 14:04:38 -07001397
Winson Chung08f81892017-03-02 15:40:51 -08001398 mSurfaceController.setPositionInTransaction((float) Math.floor(posX),
1399 (float) Math.floor(posY), recoveringMemory);
Robert Carrc7294602016-05-13 11:32:05 -07001400
1401 // Various surfaces in the scaled stack may resize at different times.
1402 // We need to ensure for each surface, that we disable transformation matrix
1403 // scaling in the same transaction which we resize the surface in.
1404 // As we are in SCALING_MODE_SCALE_TO_WINDOW, SurfaceFlinger will
Robert Carra9408d42016-06-03 13:28:48 -07001405 // then take over the scaling until the new buffer arrives, and things
Robert Carrc7294602016-05-13 11:32:05 -07001406 // will be seamless.
1407 mForceScaleUntilResize = true;
Robert Carr0d00c2e2016-02-29 17:45:02 -08001408 } else {
Robert Carr6da3cc02016-06-16 15:17:07 -07001409 if (!w.mSeamlesslyRotated) {
1410 mSurfaceController.setPositionInTransaction(mTmpSize.left, mTmpSize.top,
1411 recoveringMemory);
1412 }
Robert Carr0d00c2e2016-02-29 17:45:02 -08001413 }
1414
Robert Carra9408d42016-06-03 13:28:48 -07001415 // If we are ending the scaling mode. We switch to SCALING_MODE_FREEZE
Robert Carr6da3cc02016-06-16 15:17:07 -07001416 // to prevent further updates until buffer latch.
1417 // When ending both force scaling, and seamless rotation, we need to freeze
1418 // the Surface geometry until a buffer comes in at the new size (normally position and crop
1419 // are unfrozen). setGeometryAppliesWithResizeInTransaction accomplishes this for us.
1420 if ((wasForceScaled && !mForceScaleUntilResize) ||
1421 (wasSeamlesslyRotated && !w.mSeamlesslyRotated)) {
1422 mSurfaceController.setGeometryAppliesWithResizeInTransaction(true);
Robert Carra9408d42016-06-03 13:28:48 -07001423 mSurfaceController.forceScaleableInTransaction(false);
1424 }
Robert Carr4320d332016-06-10 15:13:32 -07001425
Robert Carr6da3cc02016-06-16 15:17:07 -07001426 if (!w.mSeamlesslyRotated) {
Robert Carrfbbde852016-10-18 11:02:28 -07001427 applyCrop(clipRect, finalClipRect, recoveringMemory);
Robert Carr6da3cc02016-06-16 15:17:07 -07001428 mSurfaceController.setMatrixInTransaction(mDsDx * w.mHScale * mExtraHScale,
1429 mDtDx * w.mVScale * mExtraVScale,
Robert Carr0edf18f2017-02-21 20:01:47 -08001430 mDtDy * w.mHScale * mExtraHScale,
1431 mDsDy * w.mVScale * mExtraVScale, recoveringMemory);
Robert Carr6da3cc02016-06-16 15:17:07 -07001432 }
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001433
Robert Carre6a83512015-11-03 16:09:21 -08001434 if (mSurfaceResized) {
Chong Zhang5b2f1992015-11-13 15:40:36 -08001435 mReportSurfaceResized = true;
Robert Carre6a83512015-11-03 16:09:21 -08001436 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
1437 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001438 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001439 }
1440
Andrii Kulian283acd22017-08-03 04:03:51 -07001441 /**
1442 * Get rect of the task this window is currently in. If there is no task, rect will be set to
1443 * empty.
1444 */
1445 void getContainerRect(Rect rect) {
1446 final Task task = mWin.getTask();
1447 if (task != null) {
1448 task.getDimBounds(rect);
1449 } else {
1450 rect.left = rect.top = rect.right = rect.bottom = 0;
1451 }
1452 }
1453
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001454 void prepareSurfaceLocked(final boolean recoveringMemory) {
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001455 final WindowState w = mWin;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001456 if (!hasSurface()) {
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001457
1458 // There is no need to wait for an animation change if our window is gone for layout
1459 // already as we'll never be visible.
Bryce Lee8c3cf382017-07-06 19:47:10 -07001460 if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001461 if (DEBUG_ORIENTATION) {
1462 Slog.v(TAG, "Orientation change skips hidden " + w);
1463 }
Bryce Lee8c3cf382017-07-06 19:47:10 -07001464 w.setOrientationChanging(false);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001465 }
1466 return;
1467 }
1468
Chong Zhang70211742016-04-28 18:27:53 -07001469 // Do not change surface properties of opening apps if we are waiting for the
1470 // transition to be ready. transitionGoodToGo could be not ready even after all
1471 // opening apps are drawn. It's only waiting on isFetchingAppTransitionsSpecs()
1472 // to get the animation spec. (For example, go into Recents and immediately open
1473 // the same app again before the app's surface is destroyed or saved, the surface
1474 // is always ready in the whole process.) If we go ahead here, the opening app
1475 // will be shown with the full size before the correct animation spec arrives.
Chong Zhange22006d2016-05-09 10:59:59 -07001476 if (isWaitingForOpening()) {
Chong Zhang70211742016-04-28 18:27:53 -07001477 return;
1478 }
1479
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001480 boolean displayed = false;
1481
1482 computeShownFrameLocked();
1483
Craig Mautnera91f9e22012-09-14 16:22:08 -07001484 setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001485
Craig Mautner918b53b2012-07-09 14:15:54 -07001486 if (mIsWallpaper && !mWin.mWallpaperVisible) {
Craig Mautner0fa77c12012-06-11 15:57:19 -07001487 // Wallpaper is no longer visible and there is no wp target => hide it.
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001488 hide("prepareSurfaceLocked");
Wale Ogunwale9d147902016-07-16 11:58:55 -07001489 } else if (w.isParentWindowHidden() || !w.isOnScreen()) {
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001490 hide("prepareSurfaceLocked");
Wale Ogunwalee8069dc2015-08-18 09:52:01 -07001491 mWallpaperControllerLocked.hideWallpapers(w);
Craig Mautnerb9836b92012-06-11 11:40:09 -07001492
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001493 // If we are waiting for this window to handle an orientation change. If this window is
1494 // really hidden (gone for layout), there is no point in still waiting for it.
1495 // Note that this does introduce a potential glitch if the window becomes unhidden
1496 // before it has drawn for the new orientation.
Bryce Lee8c3cf382017-07-06 19:47:10 -07001497 if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
1498 w.setOrientationChanging(false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001499 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001500 "Orientation change skips hidden " + w);
1501 }
1502 } else if (mLastLayer != mAnimLayer
1503 || mLastAlpha != mShownAlpha
1504 || mLastDsDx != mDsDx
1505 || mLastDtDx != mDtDx
1506 || mLastDsDy != mDsDy
1507 || mLastDtDy != mDtDy
1508 || w.mLastHScale != w.mHScale
1509 || w.mLastVScale != w.mVScale
Craig Mautner749a7bb2012-04-02 13:49:53 -07001510 || mLastHidden) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001511 displayed = true;
1512 mLastAlpha = mShownAlpha;
1513 mLastLayer = mAnimLayer;
1514 mLastDsDx = mDsDx;
1515 mLastDtDx = mDtDx;
1516 mLastDsDy = mDsDy;
1517 mLastDtDy = mDtDy;
1518 w.mLastHScale = w.mHScale;
1519 w.mLastVScale = w.mVScale;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001520 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
Robert Carre6a83512015-11-03 16:09:21 -08001521 "controller=" + mSurfaceController +
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001522 "alpha=" + mShownAlpha + " layer=" + mAnimLayer
Craig Mautner78505d82014-09-02 14:36:31 -07001523 + " matrix=[" + mDsDx + "*" + w.mHScale
1524 + "," + mDtDx + "*" + w.mVScale
Robert Carr0edf18f2017-02-21 20:01:47 -08001525 + "][" + mDtDy + "*" + w.mHScale
1526 + "," + mDsDy + "*" + w.mVScale + "]", false);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001527
Robert Carre6a83512015-11-03 16:09:21 -08001528 boolean prepared =
Robert Carraf422a82017-04-10 18:34:33 -07001529 mSurfaceController.prepareToShowInTransaction(mShownAlpha,
Robert Carr04092112016-06-02 12:56:12 -07001530 mDsDx * w.mHScale * mExtraHScale,
1531 mDtDx * w.mVScale * mExtraVScale,
Robert Carr0edf18f2017-02-21 20:01:47 -08001532 mDtDy * w.mHScale * mExtraHScale,
1533 mDsDy * w.mVScale * mExtraVScale,
Robert Carre6a83512015-11-03 16:09:21 -08001534 recoveringMemory);
1535
Robert Carr03206af2017-07-10 18:24:21 -07001536 if (prepared && mDrawState == HAS_DRAWN) {
1537 if (mLastHidden) {
1538 if (showSurfaceRobustlyLocked()) {
1539 markPreservedSurfaceForDestroy();
1540 mAnimator.requestRemovalOfReplacedWindows(w);
1541 mLastHidden = false;
1542 if (mIsWallpaper) {
1543 w.dispatchWallpaperVisibility(true);
1544 }
1545 // This draw means the difference between unique content and mirroring.
1546 // Run another pass through performLayout to set mHasContent in the
1547 // LogicalDisplay.
1548 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
1549 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
1550 } else {
1551 w.setOrientationChanging(false);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001552 }
Robert Carr03206af2017-07-10 18:24:21 -07001553 }
1554 // We process mTurnOnScreen even for windows which have already
1555 // been shown, to handle cases where windows are not necessarily
1556 // hidden while the screen is turning off.
1557 // TODO(b/63773439): These cases should be eliminated, though we probably still
1558 // want to process mTurnOnScreen in this way for clarity.
chaviw35d7de02017-08-23 12:29:02 -07001559 if (mWin.mTurnOnScreen &&
1560 (mWin.mAppToken == null || mWin.mAppToken.canTurnScreenOn())) {
Robert Carr03206af2017-07-10 18:24:21 -07001561 if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
1562 mWin.mTurnOnScreen = false;
chaviwd3bf08d2017-08-01 17:24:59 -07001563
1564 // The window should only turn the screen on once per resume, but
1565 // prepareSurfaceLocked can be called multiple times. Set canTurnScreenOn to
1566 // false so the window doesn't turn the screen on again during this resume.
chaviw35d7de02017-08-23 12:29:02 -07001567 if (mWin.mAppToken != null) {
1568 mWin.mAppToken.setCanTurnScreenOn(false);
1569 }
Bryce Leec4c8baa2017-09-06 14:55:48 -07001570
1571 // We do not add {@code SET_TURN_ON_SCREEN} when the screen is already
1572 // interactive as the value may persist until the next animation, which could
1573 // potentially occurring while turning off the screen. This would lead to the
1574 // screen incorrectly turning back on.
1575 if (!mService.mPowerManager.isInteractive()) {
1576 mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
1577 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001578 }
1579 }
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001580 if (hasSurface()) {
Robert Carre6a83512015-11-03 16:09:21 -08001581 w.mToken.hasVisible = true;
1582 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001583 } else {
Jorim Jaggi5c80c412016-04-19 20:03:47 -07001584 if (DEBUG_ANIM && isAnimationSet()) {
Chong Zhange05db742016-02-16 16:58:37 -08001585 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
Craig Mautner83339b42012-05-01 22:13:23 -07001586 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001587 displayed = true;
1588 }
1589
Bryce Lee8c3cf382017-07-06 19:47:10 -07001590 if (w.getOrientationChanging()) {
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001591 if (!w.isDrawnLw()) {
1592 mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
1593 mAnimator.mLastWindowFreezeSource = w;
1594 if (DEBUG_ORIENTATION) Slog.v(TAG,
1595 "Orientation continue waiting for draw in " + w);
1596 } else {
Bryce Lee8c3cf382017-07-06 19:47:10 -07001597 w.setOrientationChanging(false);
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001598 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001599 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001600 }
1601
1602 if (displayed) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001603 w.mToken.hasVisible = true;
1604 }
1605 }
1606
Craig Mautneref655012013-01-03 11:20:24 -08001607 void setTransparentRegionHintLocked(final Region region) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001608 if (mSurfaceController == null) {
1609 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
1610 return;
1611 }
Robert Carre6a83512015-11-03 16:09:21 -08001612 mSurfaceController.setTransparentRegionHint(region);
Craig Mautner48ba1e72012-04-02 13:18:16 -07001613 }
1614
Filip Gruszczynski2a6a2c22015-10-14 12:00:53 -07001615 void setWallpaperOffset(Point shownPosition) {
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001616 final LayoutParams attrs = mWin.getAttrs();
Filip Gruszczynski2a6a2c22015-10-14 12:00:53 -07001617 final int left = shownPosition.x - attrs.surfaceInsets.left;
1618 final int top = shownPosition.y - attrs.surfaceInsets.top;
Robert Carre6a83512015-11-03 16:09:21 -08001619
1620 try {
Craig Mautner71dd1b62014-02-18 15:48:52 -08001621 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
Robert Carr68e5c9e2016-09-14 10:50:09 -07001622 mService.openSurfaceTransaction();
Robert Carre6a83512015-11-03 16:09:21 -08001623 mSurfaceController.setPositionInTransaction(mWin.mFrame.left + left,
1624 mWin.mFrame.top + top, false);
Robert Carrfbbde852016-10-18 11:02:28 -07001625 applyCrop(null, null, false);
Robert Carre6a83512015-11-03 16:09:21 -08001626 } catch (RuntimeException e) {
1627 Slog.w(TAG, "Error positioning surface of " + mWin
1628 + " pos=(" + left + "," + top + ")", e);
1629 } finally {
Adrian Roos111aff92017-09-27 18:11:46 +02001630 mService.closeSurfaceTransaction("setWallpaperOffset");
Robert Carre6a83512015-11-03 16:09:21 -08001631 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1632 "<<< CLOSE TRANSACTION setWallpaperOffset");
Craig Mautner48ba1e72012-04-02 13:18:16 -07001633 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001634 }
1635
John Reck80181b92015-05-19 11:09:32 -07001636 /**
1637 * Try to change the pixel format without recreating the surface. This
1638 * will be common in the case of changing from PixelFormat.OPAQUE to
1639 * PixelFormat.TRANSLUCENT in the hardware-accelerated case as both
1640 * requested formats resolve to the same underlying SurfaceControl format
1641 * @return True if format was succesfully changed, false otherwise
1642 */
1643 boolean tryChangeFormatInPlaceLocked() {
Robert Carre6a83512015-11-03 16:09:21 -08001644 if (mSurfaceController == null) {
John Reck80181b92015-05-19 11:09:32 -07001645 return false;
1646 }
1647 final LayoutParams attrs = mWin.getAttrs();
Wale Ogunwalee7bf46b2015-09-30 09:19:28 -07001648 final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
John Reck80181b92015-05-19 11:09:32 -07001649 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
1650 if (format == mSurfaceFormat) {
1651 setOpaqueLocked(!PixelFormat.formatHasAlpha(attrs.format));
1652 return true;
1653 }
1654 return false;
1655 }
1656
Craig Mautner6f612042014-09-07 13:13:23 -07001657 void setOpaqueLocked(boolean isOpaque) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001658 if (mSurfaceController == null) {
1659 return;
1660 }
Robert Carre6a83512015-11-03 16:09:21 -08001661 mSurfaceController.setOpaque(isOpaque);
Craig Mautner71dd1b62014-02-18 15:48:52 -08001662 }
1663
Wale Ogunwalef5ad42f2015-06-12 13:59:03 -07001664 void setSecureLocked(boolean isSecure) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001665 if (mSurfaceController == null) {
1666 return;
1667 }
Robert Carre6a83512015-11-03 16:09:21 -08001668 mSurfaceController.setSecure(isSecure);
Wale Ogunwalef5ad42f2015-06-12 13:59:03 -07001669 }
1670
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001671 /**
1672 * Have the surface flinger show a surface, robustly dealing with
1673 * error conditions. In particular, if there is not enough memory
1674 * to show the surface, then we will try to get rid of other surfaces
1675 * in order to succeed.
1676 *
1677 * @return Returns true if the surface was successfully shown.
1678 */
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001679 private boolean showSurfaceRobustlyLocked() {
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001680 if (mWin.getWindowConfiguration().windowsAreScaleable()) {
Robert Carr1b5ea722016-04-20 13:23:28 -07001681 mSurfaceController.forceScaleableInTransaction(true);
1682 }
1683
Robert Carre6a83512015-11-03 16:09:21 -08001684 boolean shown = mSurfaceController.showRobustlyInTransaction();
1685 if (!shown)
1686 return false;
1687
Robert Carre6a83512015-11-03 16:09:21 -08001688 return true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001689 }
1690
1691 void applyEnterAnimationLocked() {
Robert Carrb439a632016-04-07 22:52:10 -07001692 // If we are the new part of a window replacement transition and we have requested
1693 // not to animate, we instead want to make it seamless, so we don't want to apply
1694 // an enter transition.
1695 if (mWin.mSkipEnterAnimationForSeamlessReplacement) {
1696 return;
1697 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001698 final int transit;
1699 if (mEnterAnimationPending) {
1700 mEnterAnimationPending = false;
1701 transit = WindowManagerPolicy.TRANSIT_ENTER;
1702 } else {
1703 transit = WindowManagerPolicy.TRANSIT_SHOW;
1704 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001705 applyAnimationLocked(transit, true);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08001706 //TODO (multidisplay): Magnification is supported only for the default display.
Svetoslav8e3feb12014-02-24 13:46:47 -08001707 if (mService.mAccessibilityController != null
Filip Gruszczynski69cbc352015-11-11 13:46:04 -08001708 && mWin.getDisplayId() == DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08001709 mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07001710 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001711 }
1712
1713 /**
1714 * Choose the correct animation and set it to the passed WindowState.
Craig Mautner4b71aa12012-12-27 17:20:01 -08001715 * @param transit If AppTransition.TRANSIT_PREVIEW_DONE and the app window has been drawn
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001716 * then the animation will be app_starting_exit. Any other value loads the animation from
1717 * the switch statement below.
1718 * @param isEntrance The animation type the last time this was called. Used to keep from
1719 * loading the same animation twice.
1720 * @return true if an animation has been loaded.
1721 */
1722 boolean applyAnimationLocked(int transit, boolean isEntrance) {
Jorim Jaggife762342016-10-13 14:33:27 +02001723 if (mLocalAnimating && mAnimationIsEntrance == isEntrance) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001724 // If we are trying to apply an animation, but already running
Jorim Jaggif8d77da2014-11-11 16:59:12 +01001725 // an animation of the same type, then just leave that one alone.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001726 return true;
1727 }
1728
1729 // Only apply an animation if the display isn't frozen. If it is
1730 // frozen, there is no reason to animate and it can cause strange
1731 // artifacts when we unfreeze the display if some different animation
1732 // is running.
Chong Zhang8784be62016-06-28 15:25:07 -07001733 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#applyAnimationLocked");
David Stevens9440dc82017-03-16 19:00:20 -07001734 if (mWin.mToken.okToAnimate()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001735 int anim = mPolicy.selectAnimationLw(mWin, transit);
1736 int attr = -1;
1737 Animation a = null;
1738 if (anim != 0) {
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07001739 a = anim != -1 ? AnimationUtils.loadAnimation(mContext, anim) : null;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001740 } else {
1741 switch (transit) {
1742 case WindowManagerPolicy.TRANSIT_ENTER:
1743 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
1744 break;
1745 case WindowManagerPolicy.TRANSIT_EXIT:
1746 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
1747 break;
1748 case WindowManagerPolicy.TRANSIT_SHOW:
1749 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
1750 break;
1751 case WindowManagerPolicy.TRANSIT_HIDE:
1752 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
1753 break;
1754 }
1755 if (attr >= 0) {
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001756 a = mService.mAppTransition.loadAnimationAttr(mWin.mAttrs, attr);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001757 }
1758 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001759 if (DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001760 "applyAnimation: win=" + this
1761 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
Craig Mautner4d7349b2012-04-20 14:52:47 -07001762 + " a=" + a
Craig Mautner8863cca2012-09-18 15:04:34 -07001763 + " transit=" + transit
Craig Mautner83339b42012-05-01 22:13:23 -07001764 + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001765 if (a != null) {
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -08001766 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001767 setAnimation(a);
1768 mAnimationIsEntrance = isEntrance;
1769 }
1770 } else {
1771 clearAnimation();
1772 }
Chong Zhang8784be62016-06-28 15:25:07 -07001773 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1774
Jorim Jaggieb88d832016-04-13 20:17:43 -07001775 if (mWin.mAttrs.type == TYPE_INPUT_METHOD) {
Wale Ogunwale360a8bc2016-10-10 13:25:26 -07001776 mWin.getDisplayContent().adjustForImeIfNeeded();
Jorim Jaggi7a4fd5e2016-04-14 19:55:35 -07001777 if (isEntrance) {
1778 mWin.setDisplayLayoutNeeded();
1779 mService.mWindowPlacerLocked.requestTraversal();
1780 }
Jorim Jaggieb88d832016-04-13 20:17:43 -07001781 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001782 return mAnimation != null;
1783 }
1784
Jorim Jaggif8d77da2014-11-11 16:59:12 +01001785 private void applyFadeoutDuringKeyguardExitAnimation() {
1786 long startTime = mAnimation.getStartTime();
1787 long duration = mAnimation.getDuration();
1788 long elapsed = mLastAnimationTime - startTime;
1789 long fadeDuration = duration - elapsed;
1790 if (fadeDuration <= 0) {
1791 // Never mind, this would be no visible animation, so abort the animation change.
1792 return;
1793 }
1794 AnimationSet newAnimation = new AnimationSet(false /* shareInterpolator */);
1795 newAnimation.setDuration(duration);
1796 newAnimation.setStartTime(startTime);
1797 newAnimation.addAnimation(mAnimation);
1798 Animation fadeOut = AnimationUtils.loadAnimation(
1799 mContext, com.android.internal.R.anim.app_starting_exit);
1800 fadeOut.setDuration(fadeDuration);
1801 fadeOut.setStartOffset(elapsed);
1802 newAnimation.addAnimation(fadeOut);
Filip Gruszczynskif52dd202015-11-15 20:36:38 -08001803 newAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mAnimDx, mAnimDy);
Jorim Jaggif8d77da2014-11-11 16:59:12 +01001804 mAnimation = newAnimation;
1805 }
1806
Steven Timotiusaf03df62017-07-18 16:56:43 -07001807 void writeToProto(ProtoOutputStream proto, long fieldId) {
1808 final long token = proto.start(fieldId);
1809 mLastClipRect.writeToProto(proto, LAST_CLIP_RECT);
1810 if (mSurfaceController != null) {
1811 mSurfaceController.writeToProto(proto, SURFACE);
1812 }
1813 proto.end(token);
1814 }
1815
Craig Mautnera2c77052012-03-26 12:14:43 -07001816 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
1817 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
1818 || mAnimation != null) {
1819 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
1820 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
1821 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001822 pw.print(" mAnimation="); pw.print(mAnimation);
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001823 pw.print(" mStackClip="); pw.println(mStackClip);
Craig Mautnera2c77052012-03-26 12:14:43 -07001824 }
1825 if (mHasTransformation || mHasLocalTransformation) {
1826 pw.print(prefix); pw.print("XForm: has=");
1827 pw.print(mHasTransformation);
1828 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
1829 pw.print(" "); mTransformation.printShortString(pw);
1830 pw.println();
1831 }
Robert Carre6a83512015-11-03 16:09:21 -08001832 if (mSurfaceController != null) {
1833 mSurfaceController.dump(pw, prefix, dumpAll);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001834 }
Robert Carre6a83512015-11-03 16:09:21 -08001835 if (dumpAll) {
1836 pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString());
1837 pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden);
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -08001838 pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
1839 pw.print(" last="); mLastSystemDecorRect.printShortString(pw);
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001840 pw.print(" mHasClipRect="); pw.print(mHasClipRect);
1841 pw.print(" mLastClipRect="); mLastClipRect.printShortString(pw);
1842
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001843 if (!mLastFinalClipRect.isEmpty()) {
1844 pw.print(" mLastFinalClipRect="); mLastFinalClipRect.printShortString(pw);
1845 }
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -08001846 pw.println();
Robert Carre6a83512015-11-03 16:09:21 -08001847 }
1848
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001849 if (mPendingDestroySurface != null) {
1850 pw.print(prefix); pw.print("mPendingDestroySurface=");
1851 pw.println(mPendingDestroySurface);
1852 }
1853 if (mSurfaceResized || mSurfaceDestroyDeferred) {
1854 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1855 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1856 }
1857 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1858 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1859 pw.print(" mAlpha="); pw.print(mAlpha);
1860 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1861 }
1862 if (mHaveMatrix || mWin.mGlobalScale != 1) {
1863 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
1864 pw.print(" mDsDx="); pw.print(mDsDx);
1865 pw.print(" mDtDx="); pw.print(mDtDx);
Robert Carr0edf18f2017-02-21 20:01:47 -08001866 pw.print(" mDtDy="); pw.print(mDtDy);
1867 pw.print(" mDsDy="); pw.println(mDsDy);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001868 }
Jorim Jaggiff71d202016-04-14 13:12:36 -07001869 if (mAnimationStartDelayed) {
1870 pw.print(prefix); pw.print("mAnimationStartDelayed="); pw.print(mAnimationStartDelayed);
1871 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001872 }
1873
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001874 @Override
1875 public String toString() {
Dianne Hackborn529e7442012-11-01 14:22:28 -07001876 StringBuffer sb = new StringBuffer("WindowStateAnimator{");
1877 sb.append(Integer.toHexString(System.identityHashCode(this)));
1878 sb.append(' ');
1879 sb.append(mWin.mAttrs.getTitle());
1880 sb.append('}');
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001881 return sb.toString();
1882 }
Robert Carre6a83512015-11-03 16:09:21 -08001883
1884 void reclaimSomeSurfaceMemory(String operation, boolean secure) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001885 mService.mRoot.reclaimSomeSurfaceMemory(this, operation, secure);
Robert Carre6a83512015-11-03 16:09:21 -08001886 }
1887
1888 boolean getShown() {
1889 if (mSurfaceController != null) {
1890 return mSurfaceController.getShown();
1891 }
1892 return false;
1893 }
1894
1895 void destroySurface() {
Wale Ogunwale722ff892016-02-18 13:37:55 -08001896 try {
1897 if (mSurfaceController != null) {
1898 mSurfaceController.destroyInTransaction();
1899 }
1900 } catch (RuntimeException e) {
1901 Slog.w(TAG, "Exception thrown when destroying surface " + this
1902 + " surface " + mSurfaceController + " session " + mSession + ": " + e);
1903 } finally {
1904 mWin.setHasSurface(false);
1905 mSurfaceController = null;
1906 mDrawState = NO_SURFACE;
1907 }
Robert Carre6a83512015-11-03 16:09:21 -08001908 }
Filip Gruszczynskif52dd202015-11-15 20:36:38 -08001909
1910 void setMoveAnimation(int left, int top) {
1911 final Animation a = AnimationUtils.loadAnimation(mContext,
1912 com.android.internal.R.anim.window_move_from_decor);
1913 setAnimation(a);
1914 mAnimDx = mWin.mLastFrame.left - left;
1915 mAnimDy = mWin.mLastFrame.top - top;
1916 mAnimateMove = true;
1917 }
Robert Carr679c8072016-04-07 15:51:48 -07001918
1919 void deferTransactionUntilParentFrame(long frameNumber) {
1920 if (!mWin.isChildWindow()) {
1921 return;
1922 }
Robert Carr679c8072016-04-07 15:51:48 -07001923 mSurfaceController.deferTransactionUntil(
Wale Ogunwalecaa53af2016-07-17 14:50:26 -07001924 mWin.getParentWindow().mWinAnimator.mSurfaceController.getHandle(), frameNumber);
Robert Carr679c8072016-04-07 15:51:48 -07001925 }
1926
Jorim Jaggiff71d202016-04-14 13:12:36 -07001927 /**
1928 * Sometimes we need to synchronize the first frame of animation with some external event.
1929 * To achieve this, we prolong the start of the animation and keep producing the first frame of
1930 * the animation.
1931 */
1932 private long getAnimationFrameTime(Animation animation, long currentTime) {
1933 if (mAnimationStartDelayed) {
1934 animation.setStartTime(currentTime);
1935 return currentTime + 1;
1936 }
1937 return currentTime;
1938 }
1939
1940 void startDelayingAnimationStart() {
1941 mAnimationStartDelayed = true;
1942 }
1943
1944 void endDelayingAnimationStart() {
1945 mAnimationStartDelayed = false;
1946 }
Robert Carr6da3cc02016-06-16 15:17:07 -07001947
1948 void seamlesslyRotateWindow(int oldRotation, int newRotation) {
1949 final WindowState w = mWin;
1950 if (!w.isVisibleNow() || w.mIsWallpaper) {
1951 return;
1952 }
1953
1954 final Rect cropRect = mService.mTmpRect;
1955 final Rect displayRect = mService.mTmpRect2;
1956 final RectF frameRect = mService.mTmpRectF;
1957 final Matrix transform = mService.mTmpTransform;
1958
1959 final float x = w.mFrame.left;
1960 final float y = w.mFrame.top;
1961 final float width = w.mFrame.width();
1962 final float height = w.mFrame.height();
1963
Bryce Leef3c6a472017-11-14 14:53:06 -08001964 mService.getDefaultDisplayContentLocked().getBounds(displayRect);
Robert Carr6da3cc02016-06-16 15:17:07 -07001965 final float displayWidth = displayRect.width();
1966 final float displayHeight = displayRect.height();
1967
1968 // Compute a transform matrix to undo the coordinate space transformation,
1969 // and present the window at the same physical position it previously occupied.
1970 final int deltaRotation = DisplayContent.deltaRotation(newRotation, oldRotation);
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07001971 DisplayContent.createRotationMatrix(deltaRotation, x, y, displayWidth, displayHeight,
1972 transform);
Robert Carr6da3cc02016-06-16 15:17:07 -07001973
Robert Carr897215d2017-03-29 12:25:50 -07001974 // We just need to apply a rotation matrix to the window. For example
1975 // if we have a portrait window and rotate to landscape, the window is still portrait
1976 // and now extends off the bottom of the screen (and only halfway across). Essentially we
1977 // apply a transform to display the current buffer at it's old position
1978 // (in the new coordinate space). We then freeze layer updates until the resize
1979 // occurs, at which point we undo, them.
1980 mService.markForSeamlessRotation(w, true);
1981 transform.getValues(mService.mTmpFloats);
Robert Carr6da3cc02016-06-16 15:17:07 -07001982
Robert Carr897215d2017-03-29 12:25:50 -07001983 float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
1984 float DtDx = mService.mTmpFloats[Matrix.MSKEW_Y];
1985 float DtDy = mService.mTmpFloats[Matrix.MSKEW_X];
1986 float DsDy = mService.mTmpFloats[Matrix.MSCALE_Y];
1987 float nx = mService.mTmpFloats[Matrix.MTRANS_X];
1988 float ny = mService.mTmpFloats[Matrix.MTRANS_Y];
1989 mSurfaceController.setPositionInTransaction(nx, ny, false);
1990 mSurfaceController.setMatrixInTransaction(DsDx * w.mHScale,
1991 DtDx * w.mVScale,
1992 DtDy * w.mHScale,
1993 DsDy * w.mVScale, false);
Robert Carr6da3cc02016-06-16 15:17:07 -07001994 }
Robert Carr3b716242016-08-16 16:02:21 -07001995
1996 void enableSurfaceTrace(FileDescriptor fd) {
1997 if (mSurfaceController != null) {
1998 mSurfaceController.installRemoteTrace(fd);
1999 }
2000 }
2001
2002 void disableSurfaceTrace() {
2003 if (mSurfaceController != null) {
2004 try {
2005 mSurfaceController.removeRemoteTrace();
2006 } catch (ClassCastException e) {
2007 Slog.e(TAG, "Disable surface trace for " + this + " but its not enabled");
2008 }
2009 }
2010 }
Robert Carr8f0a3ad2017-02-15 19:30:28 -08002011
2012 /** The force-scaled state for a given window can persist past
2013 * the state for it's stack as the windows complete resizing
2014 * independently of one another.
2015 */
2016 boolean isForceScaled() {
2017 final Task task = mWin.getTask();
2018 if (task != null && task.mStack.isForceScaled()) {
2019 return true;
2020 }
2021 return mForceScaleUntilResize;
2022 }
Robert Carrd5c7dd62017-03-08 10:39:30 -08002023
2024 void detachChildren() {
2025 if (mSurfaceController != null) {
2026 mSurfaceController.detachChildren();
2027 }
2028 }
Craig Mautnera2c77052012-03-26 12:14:43 -07002029}