blob: 99577077d65d4290241aef4e612413ee921ba67d [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
Lucas Dupin13f4b8a2020-02-19 13:41:52 -080019import static android.graphics.Matrix.MSCALE_X;
20import static android.graphics.Matrix.MSCALE_Y;
21import static android.graphics.Matrix.MSKEW_X;
22import static android.graphics.Matrix.MSKEW_Y;
23import static android.graphics.Matrix.MTRANS_X;
24import static android.graphics.Matrix.MTRANS_Y;
Wale Ogunwalee7bf46b2015-09-30 09:19:28 -070025import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
Filip Gruszczynski69cbc352015-11-11 13:46:04 -080026import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
Robert Carr132c9f52017-07-31 17:02:30 -070027import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070028import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
lumarkce596d32019-06-12 16:58:35 +080029import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Jorim Jaggieb88d832016-04-13 20:17:43 -070030import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
Robert Carrfbbde852016-10-18 11:02:28 -070031import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Jorim Jaggi0a1523d2018-04-19 17:48:38 +020032import static android.view.WindowManager.TRANSIT_NONE;
chaviw9c81e632018-07-31 11:17:52 -070033
Jorim Jaggia5e10572017-11-15 14:36:26 +010034import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
35import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Adrian Roosb125e0b2019-10-02 14:55:14 +020036import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_DRAW;
37import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
38import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
39import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
40import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
lumark9bca6b42019-10-17 18:35:22 +080041import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
42import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
Adam Pardyl8c2d19c2019-09-16 17:15:38 +020043import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080044import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080045import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
Jorim Jaggie4b0f282017-05-17 15:10:29 +020046import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080047import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -080048import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080049import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080050import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
51import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Chong Zhang97782b42015-10-07 16:01:23 -070052import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -080053import static com.android.server.wm.WindowManagerService.logWithStack;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070054import static com.android.server.wm.WindowStateAnimatorProto.DRAW_STATE;
55import static com.android.server.wm.WindowStateAnimatorProto.LAST_CLIP_RECT;
56import static com.android.server.wm.WindowStateAnimatorProto.SURFACE;
57import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT;
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +020058import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070059
Craig Mautnerc2f9be02012-03-27 17:32:29 -070060import android.content.Context;
61import android.graphics.Matrix;
62import android.graphics.PixelFormat;
Craig Mautner7358fbf2012-04-12 21:06:33 -070063import android.graphics.Point;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070064import android.graphics.Rect;
Craig Mautner48ba1e72012-04-02 13:18:16 -070065import android.graphics.Region;
Craig Mautnera51a9562012-04-17 17:05:26 -070066import android.os.Debug;
Chong Zhang8784be62016-06-28 15:25:07 -070067import android.os.Trace;
Craig Mautnera2c77052012-03-26 12:14:43 -070068import android.util.Slog;
Steven Timotiusaf03df62017-07-18 16:56:43 -070069import android.util.proto.ProtoOutputStream;
Craig Mautner59c00972012-07-30 12:10:24 -070070import android.view.DisplayInfo;
Igor Murashkina86ab6402013-08-30 12:58:36 -070071import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080072import android.view.SurfaceControl;
Craig Mautnera2c77052012-03-26 12:14:43 -070073import android.view.WindowManager;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070074import android.view.WindowManager.LayoutParams;
Craig Mautnera2c77052012-03-26 12:14:43 -070075import android.view.animation.Animation;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070076import android.view.animation.AnimationUtils;
Craig Mautnera2c77052012-03-26 12:14:43 -070077
Adrian Roose99bc052017-11-20 17:55:31 +010078import com.android.server.policy.WindowManagerPolicy;
Adrian Roosb125e0b2019-10-02 14:55:14 +020079import com.android.server.protolog.common.ProtoLog;
Adrian Roose99bc052017-11-20 17:55:31 +010080
Jorim Jaggia5e10572017-11-15 14:36:26 +010081import java.io.PrintWriter;
Craig Mautnera2c77052012-03-26 12:14:43 -070082
83/**
Craig Mautnerc2f9be02012-03-27 17:32:29 -070084 * Keep track of animations and surface operations for a single WindowState.
85 **/
Craig Mautnera2c77052012-03-26 12:14:43 -070086class WindowStateAnimator {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080087 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowStateAnimator" : TAG_WM;
Chong Zhang97782b42015-10-07 16:01:23 -070088 static final int WINDOW_FREEZE_LAYER = TYPE_LAYER_MULTIPLIER * 200;
Tiger Huang9c8ee262019-02-19 20:44:27 +080089 static final int PRESERVED_SURFACE_LAYER = 1;
Craig Mautnera2c77052012-03-26 12:14:43 -070090
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +010091 /**
92 * Mode how the window gets clipped by the stack bounds during an animation: The clipping should
93 * be applied after applying the animation transformation, i.e. the stack bounds don't move
94 * during the animation.
95 */
96 static final int STACK_CLIP_AFTER_ANIM = 0;
97
98 /**
99 * Mode how the window gets clipped by the stack bounds: The clipping should be applied before
100 * applying the animation transformation, i.e. the stack bounds move with the window.
101 */
102 static final int STACK_CLIP_BEFORE_ANIM = 1;
103
104 /**
105 * Mode how window gets clipped by the stack bounds during an animation: Don't clip the window
106 * by the stack bounds.
107 */
108 static final int STACK_CLIP_NONE = 2;
109
Craig Mautner918b53b2012-07-09 14:15:54 -0700110 // Unchanging local convenience fields.
Craig Mautnera2c77052012-03-26 12:14:43 -0700111 final WindowManagerService mService;
112 final WindowState mWin;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700113 final WindowAnimator mAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700114 final Session mSession;
115 final WindowManagerPolicy mPolicy;
116 final Context mContext;
Craig Mautner918b53b2012-07-09 14:15:54 -0700117 final boolean mIsWallpaper;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700118 private final WallpaperController mWallpaperControllerLocked;
Craig Mautnera2c77052012-03-26 12:14:43 -0700119
Craig Mautnera2c77052012-03-26 12:14:43 -0700120 boolean mAnimationIsEntrance;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700121
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700122 /**
123 * Set when we have changed the size of the surface, to know that
124 * we must tell them application to resize (and thus redraw itself).
125 */
126 boolean mSurfaceResized;
Chong Zhang5b2f1992015-11-13 15:40:36 -0800127 /**
128 * Whether we should inform the client on next relayoutWindow that
129 * the surface has been resized since last time.
130 */
131 boolean mReportSurfaceResized;
Robert Carre6a83512015-11-03 16:09:21 -0800132 WindowSurfaceController mSurfaceController;
Filip Gruszczynski10a80e02015-11-06 09:21:17 -0800133 private WindowSurfaceController mPendingDestroySurface;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700134
135 /**
136 * Set if the client has asked that the destroy of its surface be delayed
137 * until it explicitly says it is okay.
138 */
139 boolean mSurfaceDestroyDeferred;
140
Filip Gruszczynski10a80e02015-11-06 09:21:17 -0800141 private boolean mDestroyPreservedSurfaceUponRedraw;
Craig Mautner7d8df392012-04-06 15:26:23 -0700142 float mShownAlpha = 0;
143 float mAlpha = 0;
144 float mLastAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700145
Winson Chung399f6202014-03-19 10:47:20 -0700146 Rect mTmpClipRect = new Rect();
147 Rect mLastClipRect = new Rect();
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100148 Rect mLastFinalClipRect = new Rect();
Filip Gruszczynski4b8eea72015-09-14 18:16:19 -0700149 Rect mTmpStackBounds = new Rect();
Winson Chung08f81892017-03-02 15:40:51 -0800150 private Rect mTmpAnimatingBounds = new Rect();
151 private Rect mTmpSourceBounds = new Rect();
Winson Chung399f6202014-03-19 10:47:20 -0700152
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -0800153 /**
154 * This is rectangle of the window's surface that is not covered by
155 * system decorations.
156 */
157 private final Rect mSystemDecorRect = new Rect();
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -0800158
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700159 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
Robert Carr0edf18f2017-02-21 20:01:47 -0800160 private float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700161
162 boolean mHaveMatrix;
163
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700164 // Set to true if, when the window gets displayed, it should perform
165 // an enter animation.
166 boolean mEnterAnimationPending;
Craig Mautnera2c77052012-03-26 12:14:43 -0700167
Craig Mautner9c795042014-10-28 19:59:59 -0700168 /** Used to indicate that this window is undergoing an enter animation. Used for system
169 * windows to make the callback to View.dispatchOnWindowShownCallback(). Set when the
170 * window is first added or shown, cleared when the callback has been made. */
171 boolean mEnteringAnimation;
172
Vishnu Nair33197392019-08-30 10:29:37 -0700173 private final SurfaceControl.Transaction mTmpTransaction;
Chavi Weingartenb736e322018-02-23 00:27:54 +0000174
John Reck80181b92015-05-19 11:09:32 -0700175 /** The pixel format of the underlying SurfaceControl */
176 int mSurfaceFormat;
177
Craig Mautner749a7bb2012-04-02 13:49:53 -0700178 /** This is set when there is no Surface */
179 static final int NO_SURFACE = 0;
180 /** This is set after the Surface has been created but before the window has been drawn. During
181 * this time the surface is hidden. */
182 static final int DRAW_PENDING = 1;
183 /** This is set after the window has finished drawing for the first time but before its surface
184 * is shown. The surface will be displayed when the next layout is run. */
185 static final int COMMIT_DRAW_PENDING = 2;
186 /** This is set during the time after the window's drawing has been committed, and before its
187 * surface is actually shown. It is used to delay showing the surface until all windows in a
188 * token are ready to be shown. */
189 static final int READY_TO_SHOW = 3;
190 /** Set when the window has been shown in the screen the first time. */
191 static final int HAS_DRAWN = 4;
Adrian Roos3eeb4e62014-05-19 12:43:26 +0200192
Craig Mautner276a6eb2014-11-04 15:32:57 -0800193 String drawStateToString() {
194 switch (mDrawState) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700195 case NO_SURFACE: return "NO_SURFACE";
196 case DRAW_PENDING: return "DRAW_PENDING";
197 case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
198 case READY_TO_SHOW: return "READY_TO_SHOW";
199 case HAS_DRAWN: return "HAS_DRAWN";
Craig Mautner276a6eb2014-11-04 15:32:57 -0800200 default: return Integer.toString(mDrawState);
Craig Mautner6fbda632012-07-03 09:26:39 -0700201 }
202 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700203 int mDrawState;
Craig Mautnera608b882012-03-30 13:03:49 -0700204
Craig Mautner749a7bb2012-04-02 13:49:53 -0700205 /** Was this window last hidden? */
206 boolean mLastHidden;
Craig Mautnera608b882012-03-30 13:03:49 -0700207
Craig Mautnerbec53f72012-04-05 11:49:05 -0700208 int mAttrType;
209
Robert Carrc7294602016-05-13 11:32:05 -0700210 boolean mForceScaleUntilResize;
211
Robert Carr04092112016-06-02 12:56:12 -0700212 // WindowState.mHScale and WindowState.mVScale contain the
213 // scale according to client specified layout parameters (e.g.
214 // one layout size, with another surface size, creates such scaling).
215 // Here we track an additional scaling factor used to follow stack
216 // scaling (as in the case of the Pinned stack animation).
217 float mExtraHScale = (float) 1.0;
218 float mExtraVScale = (float) 1.0;
219
Robert Carr217e7cc2018-01-31 18:08:39 -0800220 // An offset in pixel of the surface contents from the window position. Used for Wallpaper
221 // to provide the effect of scrolling within a large surface. We just use these values as
222 // a cache.
223 int mXOffset = 0;
224 int mYOffset = 0;
225
Lucas Dupin13f4b8a2020-02-19 13:41:52 -0800226 // A scale factor for the surface contents, that will be applied from the center of the visible
227 // region.
228 float mWallpaperScale = 1f;
229
chaviwbe43ac82018-04-04 15:14:49 -0700230 /**
231 * A flag to determine if the WSA needs to offset its position to compensate for the stack's
232 * position update before the WSA surface has resized.
233 */
234 private boolean mOffsetPositionForStackResize;
235
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800236 private final Rect mTmpSize = new Rect();
237
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700238 /**
239 * Handles surface changes synchronized to after the client has drawn the surface. This
240 * transaction is currently used to reparent the old surface children to the new surface once
241 * the client has completed drawing to the new surface.
242 * This transaction is also used to merge transactions parceled in by the client. The client
243 * uses the transaction to update the relative z of its children from the old parent surface
244 * to the new parent surface once window manager reparents its children.
245 */
246 private final SurfaceControl.Transaction mPostDrawTransaction =
247 new SurfaceControl.Transaction();
Robert Carrca4c5a62018-02-05 16:07:55 -0800248
Robert Carr7b3d11d2018-03-15 14:34:45 -0700249 // Used to track whether we have called detach children on the way to invisibility, in which
250 // case we need to give the client a new Surface if it lays back out to a visible state.
251 boolean mChildrenDetached = false;
252
Robert Carr2025bf842018-03-19 13:25:05 -0700253 // Set to true after the first frame of the Pinned stack animation
254 // and reset after the last to ensure we only reset mForceScaleUntilResize
255 // once per animation.
256 boolean mPipAnimationStarted = false;
257
chaviwbe43ac82018-04-04 15:14:49 -0700258 private final Point mTmpPos = new Point();
259
Craig Mautnerc431e892015-02-11 13:14:26 -0800260 WindowStateAnimator(final WindowState win) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800261 final WindowManagerService service = win.mWmService;
Craig Mautner918b53b2012-07-09 14:15:54 -0700262
Craig Mautnera2c77052012-03-26 12:14:43 -0700263 mService = service;
Vishnu Nair33197392019-08-30 10:29:37 -0700264 mTmpTransaction = service.mTransactionFactory.get();
Craig Mautner918b53b2012-07-09 14:15:54 -0700265 mAnimator = service.mAnimator;
266 mPolicy = service.mPolicy;
267 mContext = service.mContext;
Craig Mautner918b53b2012-07-09 14:15:54 -0700268
269 mWin = win;
Craig Mautner918b53b2012-07-09 14:15:54 -0700270 mSession = win.mSession;
Craig Mautner918b53b2012-07-09 14:15:54 -0700271 mAttrType = win.mAttrs.type;
272 mIsWallpaper = win.mIsWallpaper;
wilsonshihc32538e2018-11-07 17:27:34 +0800273 mWallpaperControllerLocked = win.getDisplayContent().mWallpaperController;
Craig Mautnera2c77052012-03-26 12:14:43 -0700274 }
275
Jorim Jaggia5e10572017-11-15 14:36:26 +0100276 void onAnimationFinished() {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700277 // Done animating, clean up.
278 if (DEBUG_ANIM) Slog.v(
Jorim Jaggia5e10572017-11-15 14:36:26 +0100279 TAG, "Animation done in " + this + ": exiting=" + mWin.mAnimatingExit
280 + ", reportedVisible="
Garfield Tane8d84ab2019-10-11 09:49:40 -0700281 + (mWin.mActivityRecord != null ? mWin.mActivityRecord.reportedVisible : false));
Craig Mautnera2c77052012-03-26 12:14:43 -0700282
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800283 mWin.checkPolicyVisibilityChange();
Jorim Jaggia5e10572017-11-15 14:36:26 +0100284 final DisplayContent displayContent = mWin.getDisplayContent();
wilsonshihe8321942019-10-18 18:39:46 +0800285 if ((mAttrType == LayoutParams.TYPE_STATUS_BAR
286 || mAttrType == LayoutParams.TYPE_NOTIFICATION_SHADE) && mWin.isVisibleByPolicy()) {
Craig Mautner81defc72013-10-29 11:10:42 -0700287 // Upon completion of a not-visible to visible status bar animation a relayout is
288 // required.
Riddle Hsu8419e4b2019-09-18 23:28:01 +0800289 displayContent.setLayoutNeeded();
Craig Mautnera2c77052012-03-26 12:14:43 -0700290 }
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700291 mWin.onExitAnimationDone();
Riddle Hsu8419e4b2019-09-18 23:28:01 +0800292 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100293 if (displayContent.mWallpaperController.isWallpaperTarget(mWin)) {
Riddle Hsu8419e4b2019-09-18 23:28:01 +0800294 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Jorim Jaggia5e10572017-11-15 14:36:26 +0100295 }
Riddle Hsu8419e4b2019-09-18 23:28:01 +0800296 if (DEBUG_LAYOUT_REPEATS) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700297 mService.mWindowPlacerLocked.debugLayoutRepeats(
Riddle Hsu8419e4b2019-09-18 23:28:01 +0800298 "WindowStateAnimator", displayContent.pendingLayoutChanges);
299 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700300
Garfield Tane8d84ab2019-10-11 09:49:40 -0700301 if (mWin.mActivityRecord != null) {
302 mWin.mActivityRecord.updateReportedVisibilityLocked();
Craig Mautnera2c77052012-03-26 12:14:43 -0700303 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700304 }
305
Chavi Weingartenb736e322018-02-23 00:27:54 +0000306 void hide(SurfaceControl.Transaction transaction, String reason) {
Craig Mautner0afddcb2012-05-08 15:38:00 -0700307 if (!mLastHidden) {
308 //dump();
309 mLastHidden = true;
Jorim Jaggi50575902018-04-10 17:49:30 +0200310
311 // We may have a preserved surface which we no longer need. If there was a quick
312 // VISIBLE, GONE, VISIBLE, GONE sequence, the surface may never draw, so we don't mark
313 // it to be destroyed in prepareSurfaceLocked.
314 markPreservedSurfaceForDestroy();
315
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800316 if (mSurfaceController != null) {
Chavi Weingartenb736e322018-02-23 00:27:54 +0000317 mSurfaceController.hide(transaction, reason);
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800318 }
Craig Mautner0afddcb2012-05-08 15:38:00 -0700319 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700320 }
321
Chavi Weingartenb736e322018-02-23 00:27:54 +0000322 void hide(String reason) {
323 hide(mTmpTransaction, reason);
324 SurfaceControl.mergeToGlobalTransaction(mTmpTransaction);
325 }
326
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700327 boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) {
Craig Mautner42d04db2014-11-06 12:13:23 -0800328 final boolean startingWindow =
329 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Adrian Roosb125e0b2019-10-02 14:55:14 +0200330 if (startingWindow) {
331 ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finishing drawing window %s: mDrawState=%s",
332 mWin, drawStateToString());
Craig Mautner6fbda632012-07-03 09:26:39 -0700333 }
Robert Carr1ca6a332016-04-11 18:00:43 -0700334
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200335 boolean layoutNeeded = false;
Chong Zhang92147042016-05-09 12:47:11 -0700336
Craig Mautner749a7bb2012-04-02 13:49:53 -0700337 if (mDrawState == DRAW_PENDING) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200338 ProtoLog.v(WM_DEBUG_DRAW,
339 "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", mWin,
340 mSurfaceController);
341 if (startingWindow) {
342 ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Draw state now committed in %s", mWin);
Craig Mautner6fbda632012-07-03 09:26:39 -0700343 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700344 mDrawState = COMMIT_DRAW_PENDING;
Chong Zhangcbbcc0f2016-05-17 20:46:58 -0700345 layoutNeeded = true;
Vishnu Nair8cb00ae2019-08-02 15:20:29 -0700346
347 if (postDrawTransaction != null) {
348 mPostDrawTransaction.merge(postDrawTransaction);
349 }
350 } else if (postDrawTransaction != null) {
351 // If draw state is not pending we may delay applying this transaction from the client,
352 // so apply it now.
353 postDrawTransaction.apply();
Vishnu Nairf7645aa2019-06-18 11:14:01 -0700354 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700355
Chong Zhangcbbcc0f2016-05-17 20:46:58 -0700356 return layoutNeeded;
Craig Mautnera608b882012-03-30 13:03:49 -0700357 }
358
359 // This must be called while inside a transaction.
Craig Mautnerc431e892015-02-11 13:14:26 -0800360 boolean commitFinishDrawingLocked() {
Jorim Jaggie4b0f282017-05-17 15:10:29 +0200361 if (DEBUG_STARTING_WINDOW_VERBOSE &&
Craig Mautner6fbda632012-07-03 09:26:39 -0700362 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
363 Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
Craig Mautner276a6eb2014-11-04 15:32:57 -0800364 + drawStateToString());
Craig Mautner6fbda632012-07-03 09:26:39 -0700365 }
Craig Mautner276a6eb2014-11-04 15:32:57 -0800366 if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
Craig Mautnera608b882012-03-30 13:03:49 -0700367 return false;
368 }
Robert Carre13b58e2017-08-31 14:50:44 -0700369 if (DEBUG_ANIM) {
Robert Carre6a83512015-11-03 16:09:21 -0800370 Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceController);
Craig Mautner6fbda632012-07-03 09:26:39 -0700371 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700372 mDrawState = READY_TO_SHOW;
Chong Zhang0275e392015-09-17 10:41:44 -0700373 boolean result = false;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700374 final ActivityRecord activity = mWin.mActivityRecord;
375 if (activity == null || activity.canShowWindows()
Jorim Jaggiaf0d6d22018-06-08 15:25:35 +0200376 || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
Wale Ogunwale9d147902016-07-16 11:58:55 -0700377 result = mWin.performShowLocked();
Chong Zhang0275e392015-09-17 10:41:44 -0700378 }
Chong Zhang97782b42015-10-07 16:01:23 -0700379 return result;
Craig Mautnera608b882012-03-30 13:03:49 -0700380 }
381
Chong Zhang97782b42015-10-07 16:01:23 -0700382 void preserveSurfaceLocked() {
383 if (mDestroyPreservedSurfaceUponRedraw) {
Chong Zhangb9b0fec2016-02-11 18:51:51 -0800384 // This could happen when switching the surface mode very fast. For example,
385 // we preserved a surface when dragResizing changed to true. Then before the
386 // preserved surface is removed, dragResizing changed to false again.
387 // In this case, we need to leave the preserved surface alone, and destroy
388 // the actual surface, so that the createSurface call could create a surface
389 // of the proper size. The preserved surface will still be removed when client
390 // finishes drawing to the new surface.
391 mSurfaceDestroyDeferred = false;
Vishnu Nair7c861472019-07-25 09:57:12 -0700392
393 // Make sure to reparent any children of the new surface back to the preserved
394 // surface before destroying it.
395 if (mSurfaceController != null && mPendingDestroySurface != null) {
Rob Carr698b6842020-03-06 15:33:31 -0800396 mPostDrawTransaction.reparentChildren(
397 mSurfaceController.getClientViewRootSurface(),
398 mPendingDestroySurface.mSurfaceControl).apply();
Vishnu Nair7c861472019-07-25 09:57:12 -0700399 }
Chong Zhangb9b0fec2016-02-11 18:51:51 -0800400 destroySurfaceLocked();
401 mSurfaceDestroyDeferred = true;
Chong Zhang97782b42015-10-07 16:01:23 -0700402 return;
403 }
Adrian Roosb125e0b2019-10-02 14:55:14 +0200404 ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SET FREEZE LAYER: %s", mWin);
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800405 if (mSurfaceController != null) {
Robert Carrb1579c82017-09-05 14:54:47 -0700406 // Our SurfaceControl is always at layer 0 within the parent Surface managed by
407 // window-state. We want this old Surface to stay on top of the new one
Tiger Huang9c8ee262019-02-19 20:44:27 +0800408 // until we do the swap, so we place it at a positive layer.
409 mSurfaceController.mSurfaceControl.setLayer(PRESERVED_SURFACE_LAYER);
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800410 }
Chong Zhang97782b42015-10-07 16:01:23 -0700411 mDestroyPreservedSurfaceUponRedraw = true;
412 mSurfaceDestroyDeferred = true;
413 destroySurfaceLocked();
414 }
415
416 void destroyPreservedSurfaceLocked() {
417 if (!mDestroyPreservedSurfaceUponRedraw) {
418 return;
419 }
Robert Carrd5c7dd62017-03-08 10:39:30 -0800420 if (mSurfaceController != null) {
421 if (mPendingDestroySurface != null) {
422 // If we are preserving a surface but we aren't relaunching that means
423 // we are just doing an in-place switch. In that case any SurfaceFlinger side
424 // child layers need to be reparented to the new surface to make this
425 // transparent to the app.
Garfield Tane8d84ab2019-10-11 09:49:40 -0700426 if (mWin.mActivityRecord == null || mWin.mActivityRecord.isRelaunching() == false) {
Rob Carr698b6842020-03-06 15:33:31 -0800427 mPostDrawTransaction.reparentChildren(
428 mPendingDestroySurface.getClientViewRootSurface(),
429 mSurfaceController.mSurfaceControl).apply();
Robert Carrd5c7dd62017-03-08 10:39:30 -0800430 }
431 }
432 }
433
Chong Zhang97782b42015-10-07 16:01:23 -0700434 destroyDeferredSurfaceLocked();
435 mDestroyPreservedSurfaceUponRedraw = false;
436 }
437
Chong Zhangeb665572016-05-09 18:28:27 -0700438 void markPreservedSurfaceForDestroy() {
439 if (mDestroyPreservedSurfaceUponRedraw
440 && !mService.mDestroyPreservedSurface.contains(mWin)) {
441 mService.mDestroyPreservedSurface.add(mWin);
442 }
443 }
444
Robert Carrecc06b32017-04-18 14:25:10 -0700445 void resetDrawState() {
446 mDrawState = DRAW_PENDING;
447
Garfield Tane8d84ab2019-10-11 09:49:40 -0700448 if (mWin.mActivityRecord == null) {
Robert Carrecc06b32017-04-18 14:25:10 -0700449 return;
450 }
451
lumark9bca6b42019-10-17 18:35:22 +0800452 if (!mWin.mActivityRecord.isAnimating(TRANSITION)) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700453 mWin.mActivityRecord.clearAllDrawn();
Robert Carrecc06b32017-04-18 14:25:10 -0700454 }
455 }
456
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500457 WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
Alan Viveretteccb11e12014-07-08 16:04:02 -0700458 final WindowState w = mWin;
Chong Zhanga8975bd2016-01-28 17:13:47 -0800459
Wale Ogunwale722ff892016-02-18 13:37:55 -0800460 if (mSurfaceController != null) {
461 return mSurfaceController;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700462 }
Robert Carr7b3d11d2018-03-15 14:34:45 -0700463 mChildrenDetached = false;
Wale Ogunwale722ff892016-02-18 13:37:55 -0800464
Robert Carr132c9f52017-07-31 17:02:30 -0700465 if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
466 windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT;
467 }
468
Wale Ogunwale722ff892016-02-18 13:37:55 -0800469 w.setHasSurface(false);
470
Adrian Roosb125e0b2019-10-02 14:55:14 +0200471 if (DEBUG_ANIM) {
472 Slog.i(TAG, "createSurface " + this + ": mDrawState=DRAW_PENDING");
473 }
Wale Ogunwale722ff892016-02-18 13:37:55 -0800474
Robert Carrecc06b32017-04-18 14:25:10 -0700475 resetDrawState();
Wale Ogunwale722ff892016-02-18 13:37:55 -0800476
477 mService.makeWindowFreezingScreenIfNeededLocked(w);
478
479 int flags = SurfaceControl.HIDDEN;
480 final WindowManager.LayoutParams attrs = w.mAttrs;
481
482 if (mService.isSecureLocked(w)) {
483 flags |= SurfaceControl.SECURE;
484 }
485
chaviw9c81e632018-07-31 11:17:52 -0700486 calculateSurfaceBounds(w, attrs, mTmpSize);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800487 final int width = mTmpSize.width();
488 final int height = mTmpSize.height();
489
490 if (DEBUG_VISIBILITY) {
491 Slog.v(TAG, "Creating surface in session "
492 + mSession.mSurfaceSession + " window " + this
493 + " w=" + width + " h=" + height
494 + " x=" + mTmpSize.left + " y=" + mTmpSize.top
495 + " format=" + attrs.format + " flags=" + flags);
496 }
497
498 // We may abort, so initialize to defaults.
Wale Ogunwale722ff892016-02-18 13:37:55 -0800499 mLastClipRect.set(0, 0, 0, 0);
500
501 // Set up surface control with initial size.
502 try {
503
504 final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
505 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
506 if (!PixelFormat.formatHasAlpha(attrs.format)
507 // Don't make surface with surfaceInsets opaque as they display a
508 // translucent shadow.
509 && attrs.surfaceInsets.left == 0
510 && attrs.surfaceInsets.top == 0
511 && attrs.surfaceInsets.right == 0
512 && attrs.surfaceInsets.bottom == 0
513 // Don't make surface opaque when resizing to reduce the amount of
514 // artifacts shown in areas the app isn't drawing content to.
515 && !w.isDragResizing()) {
516 flags |= SurfaceControl.OPAQUE;
517 }
518
chaviw619da692019-06-10 15:39:40 -0700519 mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
520 height, format, flags, this, windowType, ownerUid);
Peiyong Lin75045382019-03-04 19:22:33 -0800521 mSurfaceController.setColorSpaceAgnostic((attrs.privateFlags
522 & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);
chaviwbe43ac82018-04-04 15:14:49 -0700523
524 setOffsetPositionForStackResize(false);
Robert Carr486bbb72017-05-30 11:25:22 -0700525 mSurfaceFormat = format;
Wale Ogunwale722ff892016-02-18 13:37:55 -0800526
527 w.setHasSurface(true);
528
Adrian Roosb125e0b2019-10-02 14:55:14 +0200529 ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
530 " CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x / %s",
531 mSurfaceController, mSession.mSurfaceSession, mSession.mPid, attrs.format,
532 flags, this);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800533 } catch (OutOfResourcesException e) {
534 Slog.w(TAG, "OutOfResourcesException creating surface");
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700535 mService.mRoot.reclaimSomeSurfaceMemory(this, "create", true);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800536 mDrawState = NO_SURFACE;
537 return null;
538 } catch (Exception e) {
Robert Carrb0f39362018-03-14 13:52:25 -0700539 Slog.e(TAG, "Exception creating surface (parent dead?)", e);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800540 mDrawState = NO_SURFACE;
541 return null;
542 }
543
Adam Pardyl8c2d19c2019-09-16 17:15:38 +0200544 if (DEBUG) {
545 Slog.v(TAG, "Got surface: " + mSurfaceController
546 + ", set left=" + w.getFrameLw().left + " top=" + w.getFrameLw().top);
547 }
Wale Ogunwale722ff892016-02-18 13:37:55 -0800548
549 if (SHOW_LIGHT_TRANSACTIONS) {
550 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
551 WindowManagerService.logSurface(w, "CREATE pos=("
chaviw492139a2018-07-16 16:07:35 -0700552 + w.getFrameLw().left + "," + w.getFrameLw().top + ") ("
Jorim Jaggi35d328a2018-08-14 17:00:20 +0200553 + width + "x" + height + ")" + " HIDE", false);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800554 }
555
Wale Ogunwale722ff892016-02-18 13:37:55 -0800556 mLastHidden = true;
557
Adam Pardyl8c2d19c2019-09-16 17:15:38 +0200558 if (DEBUG) Slog.v(TAG, "Created surface " + this);
Robert Carre6a83512015-11-03 16:09:21 -0800559 return mSurfaceController;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700560 }
561
chaviw9c81e632018-07-31 11:17:52 -0700562 private void calculateSurfaceBounds(WindowState w, LayoutParams attrs, Rect outSize) {
563 outSize.setEmpty();
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800564 if ((attrs.flags & FLAG_SCALED) != 0) {
565 // For a scaled surface, we always want the requested size.
chaviw9c81e632018-07-31 11:17:52 -0700566 outSize.right = w.mRequestedWidth;
567 outSize.bottom = w.mRequestedHeight;
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800568 } else {
569 // When we're doing a drag-resizing, request a surface that's fullscreen size,
570 // so that we don't need to reallocate during the process. This also prevents
571 // buffer drops due to size mismatch.
572 if (w.isDragResizing()) {
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800573 final DisplayInfo displayInfo = w.getDisplayInfo();
chaviw9c81e632018-07-31 11:17:52 -0700574 outSize.right = displayInfo.logicalWidth;
575 outSize.bottom = displayInfo.logicalHeight;
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800576 } else {
chaviw9c81e632018-07-31 11:17:52 -0700577 w.getCompatFrameSize(outSize);
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800578 }
579 }
580
581 // Something is wrong and SurfaceFlinger will not like this, try to revert to sane values.
Filip Gruszczynskie6ed1952015-12-21 09:34:16 -0800582 // This doesn't necessarily mean that there is an error in the system. The sizes might be
583 // incorrect, because it is before the first layout or draw.
chaviw9c81e632018-07-31 11:17:52 -0700584 if (outSize.width() < 1) {
585 outSize.right = 1;
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800586 }
chaviw9c81e632018-07-31 11:17:52 -0700587 if (outSize.height() < 1) {
588 outSize.bottom = 1;
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800589 }
590
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800591 // Adjust for surface insets.
chaviw9c81e632018-07-31 11:17:52 -0700592 outSize.inset(-attrs.surfaceInsets.left, -attrs.surfaceInsets.top,
593 -attrs.surfaceInsets.right, -attrs.surfaceInsets.bottom);
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800594 }
595
Chong Zhangeb22e8e2016-01-20 19:52:22 -0800596 boolean hasSurface() {
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200597 return mSurfaceController != null && mSurfaceController.hasSurface();
Chong Zhangeb22e8e2016-01-20 19:52:22 -0800598 }
599
Craig Mautner96868332012-12-04 14:29:11 -0800600 void destroySurfaceLocked() {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700601 final ActivityRecord activity = mWin.mActivityRecord;
602 if (activity != null) {
603 if (mWin == activity.startingWindow) {
604 activity.startingDisplayed = false;
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700605 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700606 }
607
Wale Ogunwale722ff892016-02-18 13:37:55 -0800608 if (mSurfaceController == null) {
609 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700610 }
Wale Ogunwale722ff892016-02-18 13:37:55 -0800611
Wale Ogunwale722ff892016-02-18 13:37:55 -0800612 // When destroying a surface we want to make sure child windows are hidden. If we are
613 // preserving the surface until redraw though we intend to swap it out with another surface
614 // for resizing. In this case the window always remains visible to the user and the child
615 // windows should likewise remain visible.
Wale Ogunwale9d147902016-07-16 11:58:55 -0700616 if (!mDestroyPreservedSurfaceUponRedraw) {
617 mWin.mHidden = true;
Wale Ogunwale722ff892016-02-18 13:37:55 -0800618 }
619
620 try {
621 if (DEBUG_VISIBILITY) logWithStack(TAG, "Window " + this + " destroying surface "
622 + mSurfaceController + ", session " + mSession);
623 if (mSurfaceDestroyDeferred) {
624 if (mSurfaceController != null && mPendingDestroySurface != mSurfaceController) {
625 if (mPendingDestroySurface != null) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200626 ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY PENDING: %s. %s",
627 mWin, new RuntimeException().fillInStackTrace());
Robert Carra8828862018-02-05 16:17:36 -0800628 mPendingDestroySurface.destroyNotInTransaction();
Wale Ogunwale722ff892016-02-18 13:37:55 -0800629 }
630 mPendingDestroySurface = mSurfaceController;
631 }
632 } else {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200633 ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY: %s. %s",
634 mWin, new RuntimeException().fillInStackTrace());
Wale Ogunwale722ff892016-02-18 13:37:55 -0800635 destroySurface();
636 }
637 // Don't hide wallpaper if we're deferring the surface destroy
638 // because of a surface change.
639 if (!mDestroyPreservedSurfaceUponRedraw) {
640 mWallpaperControllerLocked.hideWallpapers(mWin);
641 }
642 } catch (RuntimeException e) {
643 Slog.w(TAG, "Exception thrown when destroying Window " + this
644 + " surface " + mSurfaceController + " session " + mSession + ": " + e.toString());
645 }
646
647 // Whether the surface was preserved (and copied to mPendingDestroySurface) or not, it
648 // needs to be cleared to match the WindowState.mHasSurface state. It is also necessary
649 // so it can be recreated successfully in mPendingDestroySurface case.
650 mWin.setHasSurface(false);
651 if (mSurfaceController != null) {
652 mSurfaceController.setShown(false);
653 }
654 mSurfaceController = null;
655 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700656 }
657
Craig Mautner96868332012-12-04 14:29:11 -0800658 void destroyDeferredSurfaceLocked() {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700659 try {
660 if (mPendingDestroySurface != null) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200661 ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY PENDING: %s. %s",
662 mWin, new RuntimeException().fillInStackTrace());
Robert Carra8828862018-02-05 16:17:36 -0800663 mPendingDestroySurface.destroyNotInTransaction();
Chong Zhang6e21cf42015-11-09 14:41:42 -0800664 // Don't hide wallpaper if we're destroying a deferred surface
665 // after a surface mode change.
666 if (!mDestroyPreservedSurfaceUponRedraw) {
667 mWallpaperControllerLocked.hideWallpapers(mWin);
668 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700669 }
670 } catch (RuntimeException e) {
Craig Mautnerd87946b2012-03-29 18:00:19 -0700671 Slog.w(TAG, "Exception thrown when destroying Window "
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700672 + this + " surface " + mPendingDestroySurface
673 + " session " + mSession + ": " + e.toString());
674 }
675 mSurfaceDestroyDeferred = false;
676 mPendingDestroySurface = null;
677 }
678
679 void computeShownFrameLocked() {
Craig Mautnera91f9e22012-09-14 16:22:08 -0700680 final ScreenRotationAnimation screenRotationAnimation =
Vadim Caenb3715832019-08-13 17:06:38 +0200681 mWin.getDisplayContent().getRotationAnimation();
Vishnu Nair83537a72018-07-19 21:27:48 -0700682 final boolean windowParticipatesInScreenRotationAnimation =
683 !mWin.mForceSeamlesslyRotate;
684 final boolean screenAnimation = screenRotationAnimation != null
685 && screenRotationAnimation.isAnimating()
686 && windowParticipatesInScreenRotationAnimation;
Robert Carr2f0fe622015-09-25 14:56:38 -0700687
Robert Carr44643c12017-09-27 14:57:38 -0700688 if (screenAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700689 // cache often used attributes locally
chaviw492139a2018-07-16 16:07:35 -0700690 final Rect frame = mWin.getFrameLw();
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700691 final float tmpFloats[] = mService.mTmpFloats;
692 final Matrix tmpMatrix = mWin.mTmpMatrix;
693
694 // Compute the desired transformation.
Robert Carr44643c12017-09-27 14:57:38 -0700695 if (screenRotationAnimation.isRotating()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700696 // If we are doing a screen animation, the global rotation
697 // applied to windows can result in windows that are carefully
698 // aligned with each other to slightly separate, allowing you
699 // to see what is behind them. An unsightly mess. This...
700 // thing... magically makes it call good: scale each window
701 // slightly (two pixels larger in each dimension, from the
702 // window's center).
703 final float w = frame.width();
704 final float h = frame.height();
705 if (w>=1 && h>=1) {
706 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
707 } else {
708 tmpMatrix.reset();
709 }
710 } else {
711 tmpMatrix.reset();
712 }
Robert Carr44643c12017-09-27 14:57:38 -0700713
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700714 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
Robert Carr29d196f2017-11-28 12:39:46 -0800715
Jorim Jaggi9af095b2017-12-12 17:18:57 +0100716 // WindowState.prepareSurfaces expands for surface insets (in order they don't get
717 // clipped by the WindowState surface), so we need to go into the other direction here.
Robert Carr217e7cc2018-01-31 18:08:39 -0800718 tmpMatrix.postTranslate(mWin.mAttrs.surfaceInsets.left,
719 mWin.mAttrs.surfaceInsets.top);
Jorim Jaggi9af095b2017-12-12 17:18:57 +0100720
Matthew Ng34a06d12017-02-03 11:56:08 -0800721
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700722 // "convert" it into SurfaceFlinger's format
723 // (a 2x2 matrix + an offset)
724 // Here we must not transform the position of the surface
725 // since it is already included in the transformation.
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800726 //Slog.i(TAG_WM, "Transform: " + matrix);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700727
728 mHaveMatrix = true;
729 tmpMatrix.getValues(tmpFloats);
730 mDsDx = tmpFloats[Matrix.MSCALE_X];
731 mDtDx = tmpFloats[Matrix.MSKEW_Y];
Robert Carr0edf18f2017-02-21 20:01:47 -0800732 mDtDy = tmpFloats[Matrix.MSKEW_X];
733 mDsDy = tmpFloats[Matrix.MSCALE_Y];
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700734
735 // Now set the alpha... but because our current hardware
736 // can't do alpha transformation on a non-opaque surface,
737 // turn it off if we are running an animation that is also
738 // transforming since it is more important to have that
739 // animation be smooth.
740 mShownAlpha = mAlpha;
741 if (!mService.mLimitedAlphaCompositing
742 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
Robert Carr217e7cc2018-01-31 18:08:39 -0800743 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)))) {
Vadim Caen641d39d2019-07-23 11:29:45 +0200744 mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700745 }
746
Adam Pardyl8c2d19c2019-09-16 17:15:38 +0200747 if ((DEBUG_ANIM || DEBUG) && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) {
748 Slog.v(TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
749 + " screen=" + (screenAnimation
750 ? screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
751 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700752 return;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700753 } else if (mIsWallpaper && mService.mRoot.mWallpaperActionPending) {
Craig Mautner4d7349b2012-04-20 14:52:47 -0700754 return;
Chong Zhang3005e752015-09-18 18:46:28 -0700755 } else if (mWin.isDragResizeChanged()) {
756 // This window is awaiting a relayout because user just started (or ended)
757 // drag-resizing. The shown frame (which affects surface size and pos)
758 // should not be updated until we get next finished draw with the new surface.
759 // Otherwise one or two frames rendered with old settings would be displayed
760 // with new geometry.
761 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700762 }
763
Adam Pardyl8c2d19c2019-09-16 17:15:38 +0200764 if (DEBUG) {
765 Slog.v(TAG, "computeShownFrameLocked: " + this
766 + " not attached, mAlpha=" + mAlpha);
767 }
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700768
Robert Carrb1579c82017-09-05 14:54:47 -0700769 mShownAlpha = mAlpha;
770 mHaveMatrix = false;
771 mDsDx = mWin.mGlobalScale;
772 mDtDx = 0;
773 mDtDy = 0;
774 mDsDy = mWin.mGlobalScale;
Robert Carref090ac2017-05-15 16:45:50 -0700775 }
776
Robert Carrfbbde852016-10-18 11:02:28 -0700777 /**
Robert Carrfbbde852016-10-18 11:02:28 -0700778 * Calculate the window-space crop rect and fill clipRect.
Wale Ogunwaleca9e0612016-12-02 07:45:59 -0800779 * @return true if clipRect has been filled otherwise, no window space crop should be applied.
Robert Carrfbbde852016-10-18 11:02:28 -0700780 */
Wale Ogunwaleca9e0612016-12-02 07:45:59 -0800781 private boolean calculateCrop(Rect clipRect) {
Robert Carrfbbde852016-10-18 11:02:28 -0700782 final WindowState w = mWin;
783 final DisplayContent displayContent = w.getDisplayContent();
784 clipRect.setEmpty();
785
786 if (displayContent == null) {
787 return false;
788 }
789
Evan Rosky1c66f442019-04-30 16:02:58 -0700790 if (w.getWindowConfiguration().tasksAreFloating()) {
Robert Carrfbbde852016-10-18 11:02:28 -0700791 return false;
792 }
793
Vishnu Nair83537a72018-07-19 21:27:48 -0700794 // During forced seamless rotation, the surface bounds get updated with the crop in the
795 // new rotation, which is not compatible with showing the surface in the old rotation.
796 // To work around that we disable cropping for such windows, as it is not necessary anyways.
797 if (w.mForceSeamlesslyRotate) {
798 return false;
799 }
800
Robert Carrfbbde852016-10-18 11:02:28 -0700801 // If we're animating, the wallpaper should only
802 // be updated at the end of the animation.
803 if (w.mAttrs.type == TYPE_WALLPAPER) {
804 return false;
805 }
806
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -0700807 if (DEBUG_WINDOW_CROP) Slog.d(TAG,
808 "Updating crop win=" + w + " mLastCrop=" + mLastClipRect);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -0700809
Robert Carrfbbde852016-10-18 11:02:28 -0700810 w.calculatePolicyCrop(mSystemDecorRect);
811
812 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
chaviw553b0212018-07-12 13:37:01 -0700813 + w.getDecorFrame() + " mSystemDecorRect=" + mSystemDecorRect);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -0700814
Robert Carr51a1b872015-12-08 14:03:13 -0800815 // We use the clip rect as provided by the tranformation for non-fullscreen windows to
816 // avoid premature clipping with the system decor rect.
Robert Carrf0586622018-01-29 13:03:43 -0800817 clipRect.set(mSystemDecorRect);
Evan Rosky4fb1e912019-03-06 13:54:43 -0800818 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect);
Robert Carr51a1b872015-12-08 14:03:13 -0800819
Robert Carrfbbde852016-10-18 11:02:28 -0700820 w.expandForSurfaceInsets(clipRect);
Alan Viverette49a22e82014-07-12 20:01:27 -0700821
Alan Viverette49a22e82014-07-12 20:01:27 -0700822 // The clip rect was generated assuming (0,0) as the window origin,
823 // so we need to translate to match the actual surface coordinates.
Robert Carrfbbde852016-10-18 11:02:28 -0700824 clipRect.offset(w.mAttrs.surfaceInsets.left, w.mAttrs.surfaceInsets.top);
Robert Carr58f29132015-10-29 14:19:05 -0700825
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -0700826 if (DEBUG_WINDOW_CROP) Slog.d(TAG,
827 "win=" + w + " Clip rect after stack adjustment=" + clipRect);
Robert Carr58f29132015-10-29 14:19:05 -0700828
Chia-I Wue6bcaf12016-05-27 10:58:48 +0800829 w.transformClipRectFromScreenToSurfaceSpace(clipRect);
Robert Carr58f29132015-10-29 14:19:05 -0700830
Robert Carrfbbde852016-10-18 11:02:28 -0700831 return true;
Robert Carr0d00c2e2016-02-29 17:45:02 -0800832 }
833
chaviw23012112017-12-20 15:29:04 -0800834 private void applyCrop(Rect clipRect, boolean recoveringMemory) {
Robert Carrfbbde852016-10-18 11:02:28 -0700835 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "applyCrop: win=" + mWin
chaviw23012112017-12-20 15:29:04 -0800836 + " clipRect=" + clipRect);
Robert Carr4320d332016-06-10 15:13:32 -0700837 if (clipRect != null) {
838 if (!clipRect.equals(mLastClipRect)) {
839 mLastClipRect.set(clipRect);
840 mSurfaceController.setCropInTransaction(clipRect, recoveringMemory);
841 }
842 } else {
843 mSurfaceController.clearCropInTransaction(recoveringMemory);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -0700844 }
Filip Gruszczynski4b8eea72015-09-14 18:16:19 -0700845 }
846
Wale Ogunwale4c8b7952015-04-07 10:49:40 -0700847 void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
Wale Ogunwale027f4752017-05-12 10:37:16 -0700848 if (mSurfaceController == null) {
849 return;
850 }
851
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700852 final WindowState w = mWin;
Winson Chung08f81892017-03-02 15:40:51 -0800853 final LayoutParams attrs = mWin.getAttrs();
Robert Carr0d00c2e2016-02-29 17:45:02 -0800854 final Task task = w.getTask();
Alan Viveretteccb11e12014-07-08 16:04:02 -0700855
chaviw9c81e632018-07-31 11:17:52 -0700856 calculateSurfaceBounds(w, attrs, mTmpSize);
Chong Zhang0275e392015-09-17 10:41:44 -0700857
Robert Carr04092112016-06-02 12:56:12 -0700858 mExtraHScale = (float) 1.0;
859 mExtraVScale = (float) 1.0;
Robert Carre1034cc32016-02-01 13:08:15 -0800860
Robert Carr6da3cc02016-06-16 15:17:07 -0700861 boolean wasForceScaled = mForceScaleUntilResize;
Robert Carr6da3cc02016-06-16 15:17:07 -0700862
Robert Carrfed10072016-05-26 11:48:49 -0700863 // Once relayout has been called at least once, we need to make sure
864 // we only resize the client surface during calls to relayout. For
865 // clients which use indeterminate measure specs (MATCH_PARENT),
866 // we may try and change their window size without a call to relayout.
867 // However, this would be unsafe, as the client may be in the middle
868 // of producing a frame at the old size, having just completed layout
869 // to find the surface size changed underneath it.
chaviwbe43ac82018-04-04 15:14:49 -0700870 final boolean relayout = !w.mRelayoutCalled || w.mInRelayout;
871 if (relayout) {
Vishnu Naire86bd982018-11-28 13:23:17 -0800872 mSurfaceResized = mSurfaceController.setBufferSizeInTransaction(
Robert Carrfed10072016-05-26 11:48:49 -0700873 mTmpSize.width(), mTmpSize.height(), recoveringMemory);
874 } else {
875 mSurfaceResized = false;
876 }
Robert Carrc7294602016-05-13 11:32:05 -0700877 mForceScaleUntilResize = mForceScaleUntilResize && !mSurfaceResized;
Robert Carr6da3cc02016-06-16 15:17:07 -0700878 // If we are undergoing seamless rotation, the surface has already
879 // been set up to persist at it's old location. We need to freeze
880 // updates until a resize occurs.
Robert Carrc7294602016-05-13 11:32:05 -0700881
chaviw23012112017-12-20 15:29:04 -0800882 Rect clipRect = null;
Robert Carrfbbde852016-10-18 11:02:28 -0700883 if (calculateCrop(mTmpClipRect)) {
884 clipRect = mTmpClipRect;
885 }
Robert Carra9408d42016-06-03 13:28:48 -0700886
Robert Carr711e7052020-02-19 11:14:33 -0800887 if (mSurfaceResized && (mAttrType == TYPE_BASE_APPLICATION) &&
888 (task != null) && (task.getMainWindowSizeChangeTransaction() != null)) {
Rob Carr698b6842020-03-06 15:33:31 -0800889 mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(),
Robert Carr711e7052020-02-19 11:14:33 -0800890 mWin.getFrameNumber());
891 SurfaceControl.mergeToGlobalTransaction(task.getMainWindowSizeChangeTransaction());
892 task.setMainWindowSizeChangeTransaction(null);
893 }
894
Robert Carra9408d42016-06-03 13:28:48 -0700895 float surfaceWidth = mSurfaceController.getWidth();
896 float surfaceHeight = mSurfaceController.getHeight();
897
Robert Carr74a66a22018-02-23 12:17:51 -0800898 final Rect insets = attrs.surfaceInsets;
899
Robert Carr8f0a3ad2017-02-15 19:30:28 -0800900 if (isForceScaled()) {
Robert Carr74a66a22018-02-23 12:17:51 -0800901 int hInsets = insets.left + insets.right;
902 int vInsets = insets.top + insets.bottom;
Winson Chung08f81892017-03-02 15:40:51 -0800903 float surfaceContentWidth = surfaceWidth - hInsets;
904 float surfaceContentHeight = surfaceHeight - vInsets;
Robert Carra9408d42016-06-03 13:28:48 -0700905 if (!mForceScaleUntilResize) {
906 mSurfaceController.forceScaleableInTransaction(true);
907 }
Robert Carrfd4c9892017-02-01 10:28:28 -0800908
Robert Carr74a66a22018-02-23 12:17:51 -0800909 int posX = 0;
910 int posY = 0;
Wale Ogunwale0b3d2922019-12-30 08:55:07 -0800911 task.getStack().getDimBounds(mTmpStackBounds);
Robert Carr18f622f2017-05-08 11:20:43 -0700912
913 boolean allowStretching = false;
Wale Ogunwale0b3d2922019-12-30 08:55:07 -0800914 task.getStack().getFinalAnimationSourceHintBounds(mTmpSourceBounds);
Robert Carr18f622f2017-05-08 11:20:43 -0700915 // If we don't have source bounds, we can attempt to use the content insets
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800916 // if we have content insets.
Robert Carr18f622f2017-05-08 11:20:43 -0700917 if (mTmpSourceBounds.isEmpty() && (mWin.mLastRelayoutContentInsets.width() > 0
Hongwei Wang85cf41f2020-01-15 15:14:47 -0800918 || mWin.mLastRelayoutContentInsets.height() > 0)) {
Wale Ogunwale0b3d2922019-12-30 08:55:07 -0800919 mTmpSourceBounds.set(task.getStack().mPreAnimationBounds);
Robert Carr18f622f2017-05-08 11:20:43 -0700920 mTmpSourceBounds.inset(mWin.mLastRelayoutContentInsets);
921 allowStretching = true;
922 }
Adrian Roos604ef952018-05-15 20:13:13 +0200923
924 // Make sure that what we're animating to and from is actually the right size in case
925 // the window cannot take up the full screen.
chaviw553b0212018-07-12 13:37:01 -0700926 mTmpStackBounds.intersectUnchecked(w.getParentFrame());
927 mTmpSourceBounds.intersectUnchecked(w.getParentFrame());
928 mTmpAnimatingBounds.intersectUnchecked(w.getParentFrame());
Adrian Roos604ef952018-05-15 20:13:13 +0200929
Winson Chung08f81892017-03-02 15:40:51 -0800930 if (!mTmpSourceBounds.isEmpty()) {
931 // Get the final target stack bounds, if we are not animating, this is just the
932 // current stack bounds
Wale Ogunwale0b3d2922019-12-30 08:55:07 -0800933 task.getStack().getFinalAnimationBounds(mTmpAnimatingBounds);
Winson Chung08f81892017-03-02 15:40:51 -0800934
935 // Calculate the current progress and interpolate the difference between the target
936 // and source bounds
937 float finalWidth = mTmpAnimatingBounds.width();
938 float initialWidth = mTmpSourceBounds.width();
Robert Carr18f622f2017-05-08 11:20:43 -0700939 float tw = (surfaceContentWidth - mTmpStackBounds.width())
Winson Chung08f81892017-03-02 15:40:51 -0800940 / (surfaceContentWidth - mTmpAnimatingBounds.width());
Robert Carr18f622f2017-05-08 11:20:43 -0700941 float th = tw;
942 mExtraHScale = (initialWidth + tw * (finalWidth - initialWidth)) / initialWidth;
943 if (allowStretching) {
944 float finalHeight = mTmpAnimatingBounds.height();
945 float initialHeight = mTmpSourceBounds.height();
946 th = (surfaceContentHeight - mTmpStackBounds.height())
947 / (surfaceContentHeight - mTmpAnimatingBounds.height());
948 mExtraVScale = (initialHeight + tw * (finalHeight - initialHeight))
949 / initialHeight;
950 } else {
951 mExtraVScale = mExtraHScale;
952 }
Winson Chung08f81892017-03-02 15:40:51 -0800953
954 // Adjust the position to account for the inset bounds
Robert Carr18f622f2017-05-08 11:20:43 -0700955 posX -= (int) (tw * mExtraHScale * mTmpSourceBounds.left);
956 posY -= (int) (th * mExtraVScale * mTmpSourceBounds.top);
Winson Chung08f81892017-03-02 15:40:51 -0800957
Robert Carr74a66a22018-02-23 12:17:51 -0800958 // In pinned mode the clip rectangle applied to us by our stack has been
959 // expanded outwards to allow for shadows. However in case of source bounds set
960 // we need to crop to within the surface. The code above has scaled and positioned
961 // the surface to fit the unexpanded stack bounds, but now we need to reapply
962 // the cropping that the stack would have applied if it weren't expanded. This
963 // can be different in each direction based on the source bounds.
964 clipRect = mTmpClipRect;
965 clipRect.set((int)((insets.left + mTmpSourceBounds.left) * tw),
966 (int)((insets.top + mTmpSourceBounds.top) * th),
967 insets.left + (int)(surfaceWidth
968 - (tw* (surfaceWidth - mTmpSourceBounds.right))),
969 insets.top + (int)(surfaceHeight
970 - (th * (surfaceHeight - mTmpSourceBounds.bottom))));
Winson Chung08f81892017-03-02 15:40:51 -0800971 } else {
972 // We want to calculate the scaling based on the content area, not based on
973 // the entire surface, so that we scale in sync with windows that don't have insets.
974 mExtraHScale = mTmpStackBounds.width() / surfaceContentWidth;
975 mExtraVScale = mTmpStackBounds.height() / surfaceContentHeight;
976
977 // Since we are scaled to fit in our previously desired crop, we can now
978 // expose the whole window in buffer space, and not risk extending
979 // past where the system would have cropped us
980 clipRect = null;
Winson Chung08f81892017-03-02 15:40:51 -0800981 }
Robert Carr0d00c2e2016-02-29 17:45:02 -0800982
Robert Carrfd4c9892017-02-01 10:28:28 -0800983 // In the case of ForceScaleToStack we scale entire tasks together,
Robert Carr0d00c2e2016-02-29 17:45:02 -0800984 // and so we need to scale our offsets relative to the task bounds
985 // or parent and child windows would fall out of alignment.
Winson Chung08f81892017-03-02 15:40:51 -0800986 posX -= (int) (attrs.x * (1 - mExtraHScale));
987 posY -= (int) (attrs.y * (1 - mExtraVScale));
988
Robert Carrbc133762016-05-12 14:04:38 -0700989 // Imagine we are scaling down. As we scale the buffer down, we decrease the
990 // distance between the surface top left, and the start of the surface contents
991 // (previously it was surfaceInsets.left pixels in screen space but now it
Robert Carr04092112016-06-02 12:56:12 -0700992 // will be surfaceInsets.left*mExtraHScale). This means in order to keep the
Robert Carrbc133762016-05-12 14:04:38 -0700993 // non inset content at the same position, we have to shift the whole window
994 // forward. Likewise for scaling up, we've increased this distance, and we need
995 // to shift by a negative number to compensate.
Robert Carr74a66a22018-02-23 12:17:51 -0800996 posX += insets.left * (1 - mExtraHScale);
997 posY += insets.top * (1 - mExtraVScale);
Robert Carrbc133762016-05-12 14:04:38 -0700998
Winson Chung08f81892017-03-02 15:40:51 -0800999 mSurfaceController.setPositionInTransaction((float) Math.floor(posX),
1000 (float) Math.floor(posY), recoveringMemory);
Robert Carrc7294602016-05-13 11:32:05 -07001001
1002 // Various surfaces in the scaled stack may resize at different times.
1003 // We need to ensure for each surface, that we disable transformation matrix
1004 // scaling in the same transaction which we resize the surface in.
1005 // As we are in SCALING_MODE_SCALE_TO_WINDOW, SurfaceFlinger will
Robert Carra9408d42016-06-03 13:28:48 -07001006 // then take over the scaling until the new buffer arrives, and things
Robert Carrc7294602016-05-13 11:32:05 -07001007 // will be seamless.
Robert Carr2025bf842018-03-19 13:25:05 -07001008 if (mPipAnimationStarted == false) {
1009 mForceScaleUntilResize = true;
1010 mPipAnimationStarted = true;
1011 }
Rob Carr06be6bb2018-02-06 16:26:06 +00001012 } else {
Robert Carr2025bf842018-03-19 13:25:05 -07001013 mPipAnimationStarted = false;
1014
Rob Carr06be6bb2018-02-06 16:26:06 +00001015 if (!w.mSeamlesslyRotated) {
chaviwbe43ac82018-04-04 15:14:49 -07001016 // Used to offset the WSA when stack position changes before a resize.
1017 int xOffset = mXOffset;
1018 int yOffset = mYOffset;
1019 if (mOffsetPositionForStackResize) {
1020 if (relayout) {
1021 // Once a relayout is called, reset the offset back to 0 and defer
1022 // setting it until a new frame with the updated size. This ensures that
1023 // the WS position is reset (so the stack position is shown) at the same
1024 // time that the buffer size changes.
1025 setOffsetPositionForStackResize(false);
Rob Carr698b6842020-03-06 15:33:31 -08001026 mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(),
chaviwbe43ac82018-04-04 15:14:49 -07001027 mWin.getFrameNumber());
1028 } else {
Wale Ogunwale1ebcd8e2020-01-21 11:27:03 -08001029 final ActivityStack stack = mWin.getRootTask();
chaviwbe43ac82018-04-04 15:14:49 -07001030 mTmpPos.x = 0;
1031 mTmpPos.y = 0;
1032 if (stack != null) {
Evan Rosky6ecd67c2020-04-14 11:50:43 -07001033 stack.getRelativePosition(mTmpPos);
chaviwbe43ac82018-04-04 15:14:49 -07001034 }
1035
1036 xOffset = -mTmpPos.x;
1037 yOffset = -mTmpPos.y;
1038
1039 // Crop also needs to be extended so the bottom isn't cut off when the WSA
1040 // position is moved.
1041 if (clipRect != null) {
1042 clipRect.right += mTmpPos.x;
1043 clipRect.bottom += mTmpPos.y;
1044 }
1045 }
1046 }
Lucas Dupin13f4b8a2020-02-19 13:41:52 -08001047 if (!mIsWallpaper) {
1048 mSurfaceController.setPositionInTransaction(xOffset, yOffset, recoveringMemory);
1049 } else {
1050 setWallpaperPositionAndScale(
1051 xOffset, yOffset, mWallpaperScale, recoveringMemory);
1052 }
Rob Carr06be6bb2018-02-06 16:26:06 +00001053 }
Robert Carr0d00c2e2016-02-29 17:45:02 -08001054 }
1055
Robert Carra9408d42016-06-03 13:28:48 -07001056 // If we are ending the scaling mode. We switch to SCALING_MODE_FREEZE
Robert Carr6da3cc02016-06-16 15:17:07 -07001057 // to prevent further updates until buffer latch.
Vishnu Nairddd80742018-08-21 14:12:46 -07001058 // We also need to freeze the Surface geometry until a buffer
1059 // comes in at the new size (normally position and crop are unfrozen).
chaviw007340c2019-09-04 16:07:37 -07001060 // deferTransactionUntil accomplishes this for us.
Vishnu Nairddd80742018-08-21 14:12:46 -07001061 if (wasForceScaled && !mForceScaleUntilResize) {
Rob Carr698b6842020-03-06 15:33:31 -08001062 mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(),
Vishnu Nairb040c012018-09-07 11:38:32 -07001063 mWin.getFrameNumber());
Robert Carra9408d42016-06-03 13:28:48 -07001064 mSurfaceController.forceScaleableInTransaction(false);
1065 }
Robert Carr4320d332016-06-10 15:13:32 -07001066
Vishnu Nairddd80742018-08-21 14:12:46 -07001067
Robert Carr6da3cc02016-06-16 15:17:07 -07001068 if (!w.mSeamlesslyRotated) {
Santiago Etchebeherea0876642020-03-30 11:28:49 -07001069 // Wallpaper is already updated above when calling setWallpaperPositionAndScale so
1070 // we only need to consider the non-wallpaper case here.
Lucas Dupin13f4b8a2020-02-19 13:41:52 -08001071 if (!mIsWallpaper) {
1072 applyCrop(clipRect, recoveringMemory);
Santiago Etchebeherea0876642020-03-30 11:28:49 -07001073 mSurfaceController.setMatrixInTransaction(
1074 mDsDx * w.mHScale * mExtraHScale,
Lucas Dupin13f4b8a2020-02-19 13:41:52 -08001075 mDtDx * w.mVScale * mExtraVScale,
1076 mDtDy * w.mHScale * mExtraHScale,
1077 mDsDy * w.mVScale * mExtraVScale, recoveringMemory);
Lucas Dupin13f4b8a2020-02-19 13:41:52 -08001078 }
Robert Carr6da3cc02016-06-16 15:17:07 -07001079 }
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001080
Robert Carre6a83512015-11-03 16:09:21 -08001081 if (mSurfaceResized) {
Chong Zhang5b2f1992015-11-13 15:40:36 -08001082 mReportSurfaceResized = true;
Riddle Hsu8419e4b2019-09-18 23:28:01 +08001083 mWin.getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001084 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001085 }
1086
Andrii Kulian283acd22017-08-03 04:03:51 -07001087 /**
1088 * Get rect of the task this window is currently in. If there is no task, rect will be set to
1089 * empty.
1090 */
1091 void getContainerRect(Rect rect) {
1092 final Task task = mWin.getTask();
1093 if (task != null) {
1094 task.getDimBounds(rect);
1095 } else {
1096 rect.left = rect.top = rect.right = rect.bottom = 0;
1097 }
1098 }
1099
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001100 void prepareSurfaceLocked(final boolean recoveringMemory) {
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001101 final WindowState w = mWin;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001102 if (!hasSurface()) {
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001103
1104 // There is no need to wait for an animation change if our window is gone for layout
1105 // already as we'll never be visible.
Bryce Lee8c3cf382017-07-06 19:47:10 -07001106 if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
Adrian Roosb125e0b2019-10-02 14:55:14 +02001107 ProtoLog.v(WM_DEBUG_ORIENTATION, "Orientation change skips hidden %s", w);
Bryce Lee8c3cf382017-07-06 19:47:10 -07001108 w.setOrientationChanging(false);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001109 }
1110 return;
1111 }
1112
1113 boolean displayed = false;
1114
1115 computeShownFrameLocked();
1116
Craig Mautnera91f9e22012-09-14 16:22:08 -07001117 setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001118
Tiger Huang50d45462018-05-25 22:57:52 +08001119 if (mIsWallpaper && !w.mWallpaperVisible) {
Craig Mautner0fa77c12012-06-11 15:57:19 -07001120 // Wallpaper is no longer visible and there is no wp target => hide it.
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001121 hide("prepareSurfaceLocked");
Wale Ogunwale9d147902016-07-16 11:58:55 -07001122 } else if (w.isParentWindowHidden() || !w.isOnScreen()) {
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001123 hide("prepareSurfaceLocked");
Wale Ogunwalee8069dc2015-08-18 09:52:01 -07001124 mWallpaperControllerLocked.hideWallpapers(w);
Craig Mautnerb9836b92012-06-11 11:40:09 -07001125
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001126 // If we are waiting for this window to handle an orientation change. If this window is
1127 // really hidden (gone for layout), there is no point in still waiting for it.
1128 // Note that this does introduce a potential glitch if the window becomes unhidden
1129 // before it has drawn for the new orientation.
Bryce Lee8c3cf382017-07-06 19:47:10 -07001130 if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
1131 w.setOrientationChanging(false);
Adrian Roosb125e0b2019-10-02 14:55:14 +02001132 ProtoLog.v(WM_DEBUG_ORIENTATION,
1133 "Orientation change skips hidden %s", w);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001134 }
Jorim Jaggi35d328a2018-08-14 17:00:20 +02001135 } else if (mLastAlpha != mShownAlpha
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001136 || mLastDsDx != mDsDx
1137 || mLastDtDx != mDtDx
1138 || mLastDsDy != mDsDy
1139 || mLastDtDy != mDtDy
1140 || w.mLastHScale != w.mHScale
1141 || w.mLastVScale != w.mVScale
Craig Mautner749a7bb2012-04-02 13:49:53 -07001142 || mLastHidden) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001143 displayed = true;
1144 mLastAlpha = mShownAlpha;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001145 mLastDsDx = mDsDx;
1146 mLastDtDx = mDtDx;
1147 mLastDsDy = mDsDy;
1148 mLastDtDy = mDtDy;
1149 w.mLastHScale = w.mHScale;
1150 w.mLastVScale = w.mVScale;
Adrian Roosb125e0b2019-10-02 14:55:14 +02001151 ProtoLog.i(WM_SHOW_TRANSACTIONS,
1152 "SURFACE controller=%s alpha=%f matrix=[%f*%f,%f*%f][%f*%f,%f*%f]: %s",
1153 mSurfaceController, mShownAlpha, mDsDx, w.mHScale, mDtDx, w.mVScale,
1154 mDtDy, w.mHScale, mDsDy, w.mVScale, w);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001155
Santiago Etchebeherea0876642020-03-30 11:28:49 -07001156 boolean prepared = true;
1157
1158 if (mIsWallpaper) {
1159 setWallpaperPositionAndScale(
1160 mXOffset, mYOffset, mWallpaperScale, recoveringMemory);
1161 } else {
1162 prepared =
1163 mSurfaceController.prepareToShowInTransaction(mShownAlpha,
Robert Carr04092112016-06-02 12:56:12 -07001164 mDsDx * w.mHScale * mExtraHScale,
1165 mDtDx * w.mVScale * mExtraVScale,
Robert Carr0edf18f2017-02-21 20:01:47 -08001166 mDtDy * w.mHScale * mExtraHScale,
1167 mDsDy * w.mVScale * mExtraVScale,
Robert Carre6a83512015-11-03 16:09:21 -08001168 recoveringMemory);
Santiago Etchebeherea0876642020-03-30 11:28:49 -07001169 }
Robert Carre6a83512015-11-03 16:09:21 -08001170
Robert Carr03206af2017-07-10 18:24:21 -07001171 if (prepared && mDrawState == HAS_DRAWN) {
1172 if (mLastHidden) {
1173 if (showSurfaceRobustlyLocked()) {
1174 markPreservedSurfaceForDestroy();
1175 mAnimator.requestRemovalOfReplacedWindows(w);
1176 mLastHidden = false;
1177 if (mIsWallpaper) {
1178 w.dispatchWallpaperVisibility(true);
1179 }
Riddle Hsu8419e4b2019-09-18 23:28:01 +08001180 final DisplayContent displayContent = w.getDisplayContent();
1181 if (!displayContent.getLastHasContent()) {
Jorim Jaggif1292892018-09-10 11:58:13 +02001182 // This draw means the difference between unique content and mirroring.
1183 // Run another pass through performLayout to set mHasContent in the
1184 // LogicalDisplay.
Riddle Hsu8419e4b2019-09-18 23:28:01 +08001185 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001186 if (DEBUG_LAYOUT_REPEATS) {
Jorim Jaggif1292892018-09-10 11:58:13 +02001187 mService.mWindowPlacerLocked.debugLayoutRepeats(
1188 "showSurfaceRobustlyLocked " + w,
Riddle Hsu8419e4b2019-09-18 23:28:01 +08001189 displayContent.pendingLayoutChanges);
Jorim Jaggif1292892018-09-10 11:58:13 +02001190 }
Tiger Huang50d45462018-05-25 22:57:52 +08001191 }
Robert Carr03206af2017-07-10 18:24:21 -07001192 } else {
1193 w.setOrientationChanging(false);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001194 }
Robert Carr03206af2017-07-10 18:24:21 -07001195 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001196 }
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001197 if (hasSurface()) {
Robert Carre6a83512015-11-03 16:09:21 -08001198 w.mToken.hasVisible = true;
1199 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001200 } else {
lumark9bca6b42019-10-17 18:35:22 +08001201 if (DEBUG_ANIM && mWin.isAnimating(TRANSITION | PARENTS)) {
Chong Zhange05db742016-02-16 16:58:37 -08001202 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
Craig Mautner83339b42012-05-01 22:13:23 -07001203 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001204 displayed = true;
1205 }
1206
Bryce Lee8c3cf382017-07-06 19:47:10 -07001207 if (w.getOrientationChanging()) {
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001208 if (!w.isDrawnLw()) {
1209 mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
1210 mAnimator.mLastWindowFreezeSource = w;
Adrian Roosb125e0b2019-10-02 14:55:14 +02001211 ProtoLog.v(WM_DEBUG_ORIENTATION,
1212 "Orientation continue waiting for draw in %s", w);
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001213 } else {
Bryce Lee8c3cf382017-07-06 19:47:10 -07001214 w.setOrientationChanging(false);
Adrian Roosb125e0b2019-10-02 14:55:14 +02001215 ProtoLog.v(WM_DEBUG_ORIENTATION, "Orientation change complete in %s", w);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001216 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001217 }
1218
1219 if (displayed) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001220 w.mToken.hasVisible = true;
1221 }
1222 }
1223
Craig Mautneref655012013-01-03 11:20:24 -08001224 void setTransparentRegionHintLocked(final Region region) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001225 if (mSurfaceController == null) {
1226 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
1227 return;
1228 }
Robert Carre6a83512015-11-03 16:09:21 -08001229 mSurfaceController.setTransparentRegionHint(region);
Craig Mautner48ba1e72012-04-02 13:18:16 -07001230 }
1231
Lucas Dupin13f4b8a2020-02-19 13:41:52 -08001232 boolean setWallpaperOffset(int dx, int dy, float scale) {
1233 if (mXOffset == dx && mYOffset == dy && Float.compare(mWallpaperScale, scale) == 0) {
Robert Carr217e7cc2018-01-31 18:08:39 -08001234 return false;
1235 }
1236 mXOffset = dx;
1237 mYOffset = dy;
Lucas Dupin13f4b8a2020-02-19 13:41:52 -08001238 mWallpaperScale = scale;
Robert Carre6a83512015-11-03 16:09:21 -08001239
1240 try {
Craig Mautner71dd1b62014-02-18 15:48:52 -08001241 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
Robert Carr68e5c9e2016-09-14 10:50:09 -07001242 mService.openSurfaceTransaction();
Lucas Dupin13f4b8a2020-02-19 13:41:52 -08001243 setWallpaperPositionAndScale(dx, dy, scale, false);
Robert Carre6a83512015-11-03 16:09:21 -08001244 } catch (RuntimeException e) {
1245 Slog.w(TAG, "Error positioning surface of " + mWin
Robert Carr217e7cc2018-01-31 18:08:39 -08001246 + " pos=(" + dx + "," + dy + ")", e);
Robert Carre6a83512015-11-03 16:09:21 -08001247 } finally {
Adrian Roos111aff92017-09-27 18:11:46 +02001248 mService.closeSurfaceTransaction("setWallpaperOffset");
Robert Carre6a83512015-11-03 16:09:21 -08001249 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1250 "<<< CLOSE TRANSACTION setWallpaperOffset");
Robert Carr217e7cc2018-01-31 18:08:39 -08001251 return true;
Craig Mautner48ba1e72012-04-02 13:18:16 -07001252 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001253 }
1254
Lucas Dupin13f4b8a2020-02-19 13:41:52 -08001255 private void setWallpaperPositionAndScale(int dx, int dy, float scale,
1256 boolean recoveringMemory) {
1257 DisplayInfo displayInfo = mWin.getDisplayInfo();
1258 Matrix matrix = mWin.mTmpMatrix;
1259 matrix.setTranslate(dx, dy);
1260 matrix.postScale(scale, scale, displayInfo.logicalWidth / 2f,
1261 displayInfo.logicalHeight / 2f);
1262 matrix.getValues(mWin.mTmpMatrixArray);
1263 matrix.reset();
1264
1265 mSurfaceController.setPositionInTransaction(mWin.mTmpMatrixArray[MTRANS_X],
1266 mWin.mTmpMatrixArray[MTRANS_Y], recoveringMemory);
1267 mSurfaceController.setMatrixInTransaction(
1268 mDsDx * mWin.mTmpMatrixArray[MSCALE_X] * mWin.mHScale * mExtraHScale,
1269 mDtDx * mWin.mTmpMatrixArray[MSKEW_Y] * mWin.mVScale * mExtraVScale,
1270 mDtDy * mWin.mTmpMatrixArray[MSKEW_X] * mWin.mHScale * mExtraHScale,
1271 mDsDy * mWin.mTmpMatrixArray[MSCALE_Y] * mWin.mVScale * mExtraVScale,
1272 recoveringMemory);
1273 applyCrop(null, recoveringMemory);
1274 }
1275
John Reck80181b92015-05-19 11:09:32 -07001276 /**
1277 * Try to change the pixel format without recreating the surface. This
1278 * will be common in the case of changing from PixelFormat.OPAQUE to
1279 * PixelFormat.TRANSLUCENT in the hardware-accelerated case as both
1280 * requested formats resolve to the same underlying SurfaceControl format
1281 * @return True if format was succesfully changed, false otherwise
1282 */
1283 boolean tryChangeFormatInPlaceLocked() {
Robert Carre6a83512015-11-03 16:09:21 -08001284 if (mSurfaceController == null) {
John Reck80181b92015-05-19 11:09:32 -07001285 return false;
1286 }
1287 final LayoutParams attrs = mWin.getAttrs();
Wale Ogunwalee7bf46b2015-09-30 09:19:28 -07001288 final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
John Reck80181b92015-05-19 11:09:32 -07001289 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
1290 if (format == mSurfaceFormat) {
1291 setOpaqueLocked(!PixelFormat.formatHasAlpha(attrs.format));
1292 return true;
1293 }
1294 return false;
1295 }
1296
Craig Mautner6f612042014-09-07 13:13:23 -07001297 void setOpaqueLocked(boolean isOpaque) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001298 if (mSurfaceController == null) {
1299 return;
1300 }
Robert Carre6a83512015-11-03 16:09:21 -08001301 mSurfaceController.setOpaque(isOpaque);
Craig Mautner71dd1b62014-02-18 15:48:52 -08001302 }
1303
Wale Ogunwalef5ad42f2015-06-12 13:59:03 -07001304 void setSecureLocked(boolean isSecure) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001305 if (mSurfaceController == null) {
1306 return;
1307 }
Robert Carre6a83512015-11-03 16:09:21 -08001308 mSurfaceController.setSecure(isSecure);
Wale Ogunwalef5ad42f2015-06-12 13:59:03 -07001309 }
1310
Peiyong Lin75045382019-03-04 19:22:33 -08001311 void setColorSpaceAgnosticLocked(boolean agnostic) {
1312 if (mSurfaceController == null) {
1313 return;
1314 }
1315 mSurfaceController.setColorSpaceAgnostic(agnostic);
1316 }
1317
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001318 /**
1319 * Have the surface flinger show a surface, robustly dealing with
1320 * error conditions. In particular, if there is not enough memory
1321 * to show the surface, then we will try to get rid of other surfaces
1322 * in order to succeed.
1323 *
1324 * @return Returns true if the surface was successfully shown.
1325 */
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001326 private boolean showSurfaceRobustlyLocked() {
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001327 if (mWin.getWindowConfiguration().windowsAreScaleable()) {
Robert Carr1b5ea722016-04-20 13:23:28 -07001328 mSurfaceController.forceScaleableInTransaction(true);
1329 }
1330
Robert Carre6a83512015-11-03 16:09:21 -08001331 boolean shown = mSurfaceController.showRobustlyInTransaction();
1332 if (!shown)
1333 return false;
1334
Robert Carr849d2932018-05-01 12:14:48 -07001335 // If we had a preserved surface it's no longer needed, and it may be harmful
1336 // if we are transparent.
1337 if (mPendingDestroySurface != null && mDestroyPreservedSurfaceUponRedraw) {
Vishnu Nairf7645aa2019-06-18 11:14:01 -07001338 final SurfaceControl pendingSurfaceControl = mPendingDestroySurface.mSurfaceControl;
Vishnu Nair8cb00ae2019-08-02 15:20:29 -07001339 mPostDrawTransaction.reparent(pendingSurfaceControl, null);
Rob Carr698b6842020-03-06 15:33:31 -08001340 mPostDrawTransaction.reparentChildren(
1341 mPendingDestroySurface.getClientViewRootSurface(),
1342 mSurfaceController.mSurfaceControl);
Robert Carr849d2932018-05-01 12:14:48 -07001343 }
1344
Vishnu Nair3b037f72019-07-22 12:55:58 -07001345 SurfaceControl.mergeToGlobalTransaction(mPostDrawTransaction);
Robert Carre6a83512015-11-03 16:09:21 -08001346 return true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001347 }
1348
1349 void applyEnterAnimationLocked() {
Robert Carrb439a632016-04-07 22:52:10 -07001350 // If we are the new part of a window replacement transition and we have requested
1351 // not to animate, we instead want to make it seamless, so we don't want to apply
1352 // an enter transition.
1353 if (mWin.mSkipEnterAnimationForSeamlessReplacement) {
1354 return;
1355 }
lumarkce596d32019-06-12 16:58:35 +08001356
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001357 final int transit;
1358 if (mEnterAnimationPending) {
1359 mEnterAnimationPending = false;
1360 transit = WindowManagerPolicy.TRANSIT_ENTER;
1361 } else {
1362 transit = WindowManagerPolicy.TRANSIT_SHOW;
1363 }
lumark2726eb62019-06-19 21:25:54 +08001364
1365 // We don't apply animation for application main window here since this window type
1366 // should be controlled by AppWindowToken in general.
1367 if (mAttrType != TYPE_BASE_APPLICATION) {
1368 applyAnimationLocked(transit, true);
1369 }
1370
Rhed Jao02655dc2018-10-30 20:44:52 +08001371 if (mService.mAccessibilityController != null) {
Svetoslav8e3feb12014-02-24 13:46:47 -08001372 mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07001373 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001374 }
1375
1376 /**
1377 * Choose the correct animation and set it to the passed WindowState.
Craig Mautner4b71aa12012-12-27 17:20:01 -08001378 * @param transit If AppTransition.TRANSIT_PREVIEW_DONE and the app window has been drawn
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001379 * then the animation will be app_starting_exit. Any other value loads the animation from
1380 * the switch statement below.
1381 * @param isEntrance The animation type the last time this was called. Used to keep from
1382 * loading the same animation twice.
1383 * @return true if an animation has been loaded.
1384 */
1385 boolean applyAnimationLocked(int transit, boolean isEntrance) {
lumark9bca6b42019-10-17 18:35:22 +08001386 if (mWin.isAnimating() && mAnimationIsEntrance == isEntrance) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001387 // If we are trying to apply an animation, but already running
Jorim Jaggif8d77da2014-11-11 16:59:12 +01001388 // an animation of the same type, then just leave that one alone.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001389 return true;
1390 }
1391
Taran Singhf69425e2020-04-01 16:57:50 -07001392 final boolean isImeWindow = mWin.mAttrs.type == TYPE_INPUT_METHOD;
1393 if (isEntrance && isImeWindow) {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001394 mWin.getDisplayContent().adjustForImeIfNeeded();
1395 mWin.setDisplayLayoutNeeded();
1396 mService.mWindowPlacerLocked.requestTraversal();
1397 }
1398
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001399 // Only apply an animation if the display isn't frozen. If it is
1400 // frozen, there is no reason to animate and it can cause strange
1401 // artifacts when we unfreeze the display if some different animation
1402 // is running.
David Stevens9440dc82017-03-16 19:00:20 -07001403 if (mWin.mToken.okToAnimate()) {
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001404 int anim = mWin.getDisplayContent().getDisplayPolicy().selectAnimation(mWin, transit);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001405 int attr = -1;
1406 Animation a = null;
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001407 if (anim != DisplayPolicy.ANIMATION_STYLEABLE) {
1408 if (anim != DisplayPolicy.ANIMATION_NONE) {
1409 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#loadAnimation");
1410 a = AnimationUtils.loadAnimation(mContext, anim);
1411 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1412 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001413 } else {
1414 switch (transit) {
1415 case WindowManagerPolicy.TRANSIT_ENTER:
1416 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
1417 break;
1418 case WindowManagerPolicy.TRANSIT_EXIT:
1419 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
1420 break;
1421 case WindowManagerPolicy.TRANSIT_SHOW:
1422 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
1423 break;
1424 case WindowManagerPolicy.TRANSIT_HIDE:
1425 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
1426 break;
1427 }
1428 if (attr >= 0) {
lumark588a3e82018-07-20 18:53:54 +08001429 a = mWin.getDisplayContent().mAppTransition.loadAnimationAttr(
1430 mWin.mAttrs, attr, TRANSIT_NONE);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001431 }
1432 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001433 if (DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001434 "applyAnimation: win=" + this
1435 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
Craig Mautner4d7349b2012-04-20 14:52:47 -07001436 + " a=" + a
Craig Mautner8863cca2012-09-18 15:04:34 -07001437 + " transit=" + transit
lumarkce596d32019-06-12 16:58:35 +08001438 + " type=" + mAttrType
Craig Mautner83339b42012-05-01 22:13:23 -07001439 + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001440 if (a != null) {
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -08001441 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001442 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#startAnimation");
Jorim Jaggia5e10572017-11-15 14:36:26 +01001443 mWin.startAnimation(a);
Riddle Hsu2ca561b2019-10-08 21:58:58 +08001444 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001445 mAnimationIsEntrance = isEntrance;
1446 }
Taran Singhf69425e2020-04-01 16:57:50 -07001447 } else if (!isImeWindow) {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001448 mWin.cancelAnimation();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001449 }
Chong Zhang8784be62016-06-28 15:25:07 -07001450
Taran Singhf69425e2020-04-01 16:57:50 -07001451 if (!isEntrance && isImeWindow) {
Wale Ogunwale360a8bc2016-10-10 13:25:26 -07001452 mWin.getDisplayContent().adjustForImeIfNeeded();
Jorim Jaggieb88d832016-04-13 20:17:43 -07001453 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001454
lumark5341d1c2019-12-14 01:54:02 +08001455 return mWin.isAnimating(PARENTS);
Jorim Jaggif8d77da2014-11-11 16:59:12 +01001456 }
1457
Jeffrey Huangcb782852019-12-05 11:28:11 -08001458 void dumpDebug(ProtoOutputStream proto, long fieldId) {
Steven Timotiusaf03df62017-07-18 16:56:43 -07001459 final long token = proto.start(fieldId);
Jeffrey Huangcb782852019-12-05 11:28:11 -08001460 mLastClipRect.dumpDebug(proto, LAST_CLIP_RECT);
Steven Timotiusaf03df62017-07-18 16:56:43 -07001461 if (mSurfaceController != null) {
Jeffrey Huangcb782852019-12-05 11:28:11 -08001462 mSurfaceController.dumpDebug(proto, SURFACE);
Steven Timotiusaf03df62017-07-18 16:56:43 -07001463 }
Vishnu Nair1d0fa072018-01-04 07:53:00 -08001464 proto.write(DRAW_STATE, mDrawState);
Jeffrey Huangcb782852019-12-05 11:28:11 -08001465 mSystemDecorRect.dumpDebug(proto, SYSTEM_DECOR_RECT);
Steven Timotiusaf03df62017-07-18 16:56:43 -07001466 proto.end(token);
1467 }
1468
Craig Mautnera2c77052012-03-26 12:14:43 -07001469 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001470 if (mAnimationIsEntrance) {
1471 pw.print(prefix); pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
Craig Mautnera2c77052012-03-26 12:14:43 -07001472 }
Robert Carre6a83512015-11-03 16:09:21 -08001473 if (mSurfaceController != null) {
1474 mSurfaceController.dump(pw, prefix, dumpAll);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001475 }
Robert Carre6a83512015-11-03 16:09:21 -08001476 if (dumpAll) {
1477 pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString());
1478 pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden);
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -08001479 pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001480 pw.print(" mLastClipRect="); mLastClipRect.printShortString(pw);
1481
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001482 if (!mLastFinalClipRect.isEmpty()) {
1483 pw.print(" mLastFinalClipRect="); mLastFinalClipRect.printShortString(pw);
1484 }
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -08001485 pw.println();
Robert Carre6a83512015-11-03 16:09:21 -08001486 }
1487
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001488 if (mPendingDestroySurface != null) {
1489 pw.print(prefix); pw.print("mPendingDestroySurface=");
1490 pw.println(mPendingDestroySurface);
1491 }
1492 if (mSurfaceResized || mSurfaceDestroyDeferred) {
1493 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1494 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1495 }
1496 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1497 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1498 pw.print(" mAlpha="); pw.print(mAlpha);
1499 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1500 }
1501 if (mHaveMatrix || mWin.mGlobalScale != 1) {
1502 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
1503 pw.print(" mDsDx="); pw.print(mDsDx);
1504 pw.print(" mDtDx="); pw.print(mDtDx);
Robert Carr0edf18f2017-02-21 20:01:47 -08001505 pw.print(" mDtDy="); pw.print(mDtDy);
1506 pw.print(" mDsDy="); pw.println(mDsDy);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001507 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001508 }
1509
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001510 @Override
1511 public String toString() {
Dianne Hackborn529e7442012-11-01 14:22:28 -07001512 StringBuffer sb = new StringBuffer("WindowStateAnimator{");
1513 sb.append(Integer.toHexString(System.identityHashCode(this)));
1514 sb.append(' ');
1515 sb.append(mWin.mAttrs.getTitle());
1516 sb.append('}');
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001517 return sb.toString();
1518 }
Robert Carre6a83512015-11-03 16:09:21 -08001519
1520 void reclaimSomeSurfaceMemory(String operation, boolean secure) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001521 mService.mRoot.reclaimSomeSurfaceMemory(this, operation, secure);
Robert Carre6a83512015-11-03 16:09:21 -08001522 }
1523
1524 boolean getShown() {
1525 if (mSurfaceController != null) {
1526 return mSurfaceController.getShown();
1527 }
1528 return false;
1529 }
1530
1531 void destroySurface() {
Wale Ogunwale722ff892016-02-18 13:37:55 -08001532 try {
1533 if (mSurfaceController != null) {
Robert Carra8828862018-02-05 16:17:36 -08001534 mSurfaceController.destroyNotInTransaction();
Wale Ogunwale722ff892016-02-18 13:37:55 -08001535 }
1536 } catch (RuntimeException e) {
1537 Slog.w(TAG, "Exception thrown when destroying surface " + this
1538 + " surface " + mSurfaceController + " session " + mSession + ": " + e);
1539 } finally {
1540 mWin.setHasSurface(false);
1541 mSurfaceController = null;
1542 mDrawState = NO_SURFACE;
1543 }
Robert Carre6a83512015-11-03 16:09:21 -08001544 }
Filip Gruszczynskif52dd202015-11-15 20:36:38 -08001545
Robert Carr8f0a3ad2017-02-15 19:30:28 -08001546 /** The force-scaled state for a given window can persist past
1547 * the state for it's stack as the windows complete resizing
1548 * independently of one another.
1549 */
1550 boolean isForceScaled() {
1551 final Task task = mWin.getTask();
Wale Ogunwale0b3d2922019-12-30 08:55:07 -08001552 if (task != null && task.getStack().isForceScaled()) {
Robert Carr8f0a3ad2017-02-15 19:30:28 -08001553 return true;
1554 }
1555 return mForceScaleUntilResize;
1556 }
Robert Carrd5c7dd62017-03-08 10:39:30 -08001557
1558 void detachChildren() {
Jorim Jaggi35e049a2019-07-16 15:03:14 +02001559
1560 // Do not detach children of starting windows, as their lifecycle is well under control and
1561 // it may lead to issues in case we relaunch when we just added the starting window.
1562 if (mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
1563 return;
1564 }
Robert Carrd5c7dd62017-03-08 10:39:30 -08001565 if (mSurfaceController != null) {
1566 mSurfaceController.detachChildren();
1567 }
Robert Carr7b3d11d2018-03-15 14:34:45 -07001568 mChildrenDetached = true;
Robert Carrd5c7dd62017-03-08 10:39:30 -08001569 }
Jorim Jaggia5e10572017-11-15 14:36:26 +01001570
chaviwbe43ac82018-04-04 15:14:49 -07001571 void setOffsetPositionForStackResize(boolean offsetPositionForStackResize) {
1572 mOffsetPositionForStackResize = offsetPositionForStackResize;
1573 }
Robert Carr2e20bcd2020-01-22 13:32:38 -08001574
Rob Carr698b6842020-03-06 15:33:31 -08001575 SurfaceControl getClientViewRootSurface() {
Robert Carr2e20bcd2020-01-22 13:32:38 -08001576 if (!hasSurface()) {
1577 return null;
1578 }
Rob Carr698b6842020-03-06 15:33:31 -08001579 return mSurfaceController.getClientViewRootSurface();
Robert Carr2e20bcd2020-01-22 13:32:38 -08001580 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001581}