blob: 3eef12540e7f8a370f5aa973f6266d333ce90ae4 [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 Jaggi0a1523d2018-04-19 17:48:38 +020026import static android.view.WindowManager.TRANSIT_NONE;
Jorim Jaggia5e10572017-11-15 14:36:26 +010027import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
28import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Jorim Jaggi0b46f3c2016-03-14 12:21:37 +010029import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080030import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080031import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
32import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
33import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
Jorim Jaggie4b0f282017-05-17 15:10:29 +020034import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080035import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
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 Gruszczynski198dcbf2016-01-18 10:02:00 -080043import static com.android.server.wm.WindowManagerService.logWithStack;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070044import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070045import static com.android.server.wm.WindowStateAnimatorProto.DRAW_STATE;
46import static com.android.server.wm.WindowStateAnimatorProto.LAST_CLIP_RECT;
47import static com.android.server.wm.WindowStateAnimatorProto.SURFACE;
48import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070049
Craig Mautnerc2f9be02012-03-27 17:32:29 -070050import android.content.Context;
51import android.graphics.Matrix;
52import android.graphics.PixelFormat;
Craig Mautner7358fbf2012-04-12 21:06:33 -070053import android.graphics.Point;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070054import android.graphics.Rect;
Robert Carr6da3cc02016-06-16 15:17:07 -070055import android.graphics.RectF;
Craig Mautner48ba1e72012-04-02 13:18:16 -070056import android.graphics.Region;
Craig Mautnera51a9562012-04-17 17:05:26 -070057import android.os.Debug;
Chong Zhang8784be62016-06-28 15:25:07 -070058import android.os.Trace;
Craig Mautnera2c77052012-03-26 12:14:43 -070059import android.util.Slog;
Steven Timotiusaf03df62017-07-18 16:56:43 -070060import android.util.proto.ProtoOutputStream;
Craig Mautner59c00972012-07-30 12:10:24 -070061import android.view.DisplayInfo;
Igor Murashkina86ab6402013-08-30 12:58:36 -070062import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080063import android.view.SurfaceControl;
Craig Mautnera2c77052012-03-26 12:14:43 -070064import android.view.WindowManager;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070065import android.view.WindowManager.LayoutParams;
Craig Mautnera2c77052012-03-26 12:14:43 -070066import android.view.animation.Animation;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070067import android.view.animation.AnimationUtils;
Craig Mautnera2c77052012-03-26 12:14:43 -070068
Adrian Roose99bc052017-11-20 17:55:31 +010069import com.android.server.policy.WindowManagerPolicy;
70
Jorim Jaggia5e10572017-11-15 14:36:26 +010071import java.io.PrintWriter;
Craig Mautnera2c77052012-03-26 12:14:43 -070072
73/**
Craig Mautnerc2f9be02012-03-27 17:32:29 -070074 * Keep track of animations and surface operations for a single WindowState.
75 **/
Craig Mautnera2c77052012-03-26 12:14:43 -070076class WindowStateAnimator {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080077 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowStateAnimator" : TAG_WM;
Chong Zhang97782b42015-10-07 16:01:23 -070078 static final int WINDOW_FREEZE_LAYER = TYPE_LAYER_MULTIPLIER * 200;
Craig Mautnera2c77052012-03-26 12:14:43 -070079
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +010080 /**
81 * Mode how the window gets clipped by the stack bounds during an animation: The clipping should
82 * be applied after applying the animation transformation, i.e. the stack bounds don't move
83 * during the animation.
84 */
85 static final int STACK_CLIP_AFTER_ANIM = 0;
86
87 /**
88 * Mode how the window gets clipped by the stack bounds: The clipping should be applied before
89 * applying the animation transformation, i.e. the stack bounds move with the window.
90 */
91 static final int STACK_CLIP_BEFORE_ANIM = 1;
92
93 /**
94 * Mode how window gets clipped by the stack bounds during an animation: Don't clip the window
95 * by the stack bounds.
96 */
97 static final int STACK_CLIP_NONE = 2;
98
Craig Mautner918b53b2012-07-09 14:15:54 -070099 // Unchanging local convenience fields.
Craig Mautnera2c77052012-03-26 12:14:43 -0700100 final WindowManagerService mService;
101 final WindowState mWin;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700102 final WindowAnimator mAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700103 final Session mSession;
104 final WindowManagerPolicy mPolicy;
105 final Context mContext;
Craig Mautner918b53b2012-07-09 14:15:54 -0700106 final boolean mIsWallpaper;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700107 private final WallpaperController mWallpaperControllerLocked;
Craig Mautnera2c77052012-03-26 12:14:43 -0700108
Craig Mautnera2c77052012-03-26 12:14:43 -0700109 boolean mAnimationIsEntrance;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700110 int mAnimLayer;
111 int mLastLayer;
112
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700113 /**
114 * Set when we have changed the size of the surface, to know that
115 * we must tell them application to resize (and thus redraw itself).
116 */
117 boolean mSurfaceResized;
Chong Zhang5b2f1992015-11-13 15:40:36 -0800118 /**
119 * Whether we should inform the client on next relayoutWindow that
120 * the surface has been resized since last time.
121 */
122 boolean mReportSurfaceResized;
Robert Carre6a83512015-11-03 16:09:21 -0800123 WindowSurfaceController mSurfaceController;
Filip Gruszczynski10a80e02015-11-06 09:21:17 -0800124 private WindowSurfaceController mPendingDestroySurface;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700125
126 /**
127 * Set if the client has asked that the destroy of its surface be delayed
128 * until it explicitly says it is okay.
129 */
130 boolean mSurfaceDestroyDeferred;
131
Filip Gruszczynski10a80e02015-11-06 09:21:17 -0800132 private boolean mDestroyPreservedSurfaceUponRedraw;
Craig Mautner7d8df392012-04-06 15:26:23 -0700133 float mShownAlpha = 0;
134 float mAlpha = 0;
135 float mLastAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700136
Winson Chung399f6202014-03-19 10:47:20 -0700137 Rect mTmpClipRect = new Rect();
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100138 Rect mTmpFinalClipRect = new Rect();
Winson Chung399f6202014-03-19 10:47:20 -0700139 Rect mLastClipRect = new Rect();
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100140 Rect mLastFinalClipRect = new Rect();
Filip Gruszczynski4b8eea72015-09-14 18:16:19 -0700141 Rect mTmpStackBounds = new Rect();
Winson Chung08f81892017-03-02 15:40:51 -0800142 private Rect mTmpAnimatingBounds = new Rect();
143 private Rect mTmpSourceBounds = new Rect();
Winson Chung399f6202014-03-19 10:47:20 -0700144
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -0800145 /**
146 * This is rectangle of the window's surface that is not covered by
147 * system decorations.
148 */
149 private final Rect mSystemDecorRect = new Rect();
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -0800150
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700151 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
Robert Carr0edf18f2017-02-21 20:01:47 -0800152 private float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700153
154 boolean mHaveMatrix;
155
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700156 // Set to true if, when the window gets displayed, it should perform
157 // an enter animation.
158 boolean mEnterAnimationPending;
Craig Mautnera2c77052012-03-26 12:14:43 -0700159
Craig Mautner9c795042014-10-28 19:59:59 -0700160 /** Used to indicate that this window is undergoing an enter animation. Used for system
161 * windows to make the callback to View.dispatchOnWindowShownCallback(). Set when the
162 * window is first added or shown, cleared when the callback has been made. */
163 boolean mEnteringAnimation;
164
Jorim Jaggiff71d202016-04-14 13:12:36 -0700165 private boolean mAnimationStartDelayed;
166
Chavi Weingartenb736e322018-02-23 00:27:54 +0000167 private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
168
John Reck80181b92015-05-19 11:09:32 -0700169 /** The pixel format of the underlying SurfaceControl */
170 int mSurfaceFormat;
171
Craig Mautner749a7bb2012-04-02 13:49:53 -0700172 /** This is set when there is no Surface */
173 static final int NO_SURFACE = 0;
174 /** This is set after the Surface has been created but before the window has been drawn. During
175 * this time the surface is hidden. */
176 static final int DRAW_PENDING = 1;
177 /** This is set after the window has finished drawing for the first time but before its surface
178 * is shown. The surface will be displayed when the next layout is run. */
179 static final int COMMIT_DRAW_PENDING = 2;
180 /** This is set during the time after the window's drawing has been committed, and before its
181 * surface is actually shown. It is used to delay showing the surface until all windows in a
182 * token are ready to be shown. */
183 static final int READY_TO_SHOW = 3;
184 /** Set when the window has been shown in the screen the first time. */
185 static final int HAS_DRAWN = 4;
Adrian Roos3eeb4e62014-05-19 12:43:26 +0200186
Craig Mautner276a6eb2014-11-04 15:32:57 -0800187 String drawStateToString() {
188 switch (mDrawState) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700189 case NO_SURFACE: return "NO_SURFACE";
190 case DRAW_PENDING: return "DRAW_PENDING";
191 case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
192 case READY_TO_SHOW: return "READY_TO_SHOW";
193 case HAS_DRAWN: return "HAS_DRAWN";
Craig Mautner276a6eb2014-11-04 15:32:57 -0800194 default: return Integer.toString(mDrawState);
Craig Mautner6fbda632012-07-03 09:26:39 -0700195 }
196 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700197 int mDrawState;
Craig Mautnera608b882012-03-30 13:03:49 -0700198
Craig Mautner749a7bb2012-04-02 13:49:53 -0700199 /** Was this window last hidden? */
200 boolean mLastHidden;
Craig Mautnera608b882012-03-30 13:03:49 -0700201
Craig Mautnerbec53f72012-04-05 11:49:05 -0700202 int mAttrType;
203
Robert Carrc7294602016-05-13 11:32:05 -0700204 boolean mForceScaleUntilResize;
205
Robert Carr04092112016-06-02 12:56:12 -0700206 // WindowState.mHScale and WindowState.mVScale contain the
207 // scale according to client specified layout parameters (e.g.
208 // one layout size, with another surface size, creates such scaling).
209 // Here we track an additional scaling factor used to follow stack
210 // scaling (as in the case of the Pinned stack animation).
211 float mExtraHScale = (float) 1.0;
212 float mExtraVScale = (float) 1.0;
213
Robert Carr217e7cc2018-01-31 18:08:39 -0800214 // An offset in pixel of the surface contents from the window position. Used for Wallpaper
215 // to provide the effect of scrolling within a large surface. We just use these values as
216 // a cache.
217 int mXOffset = 0;
218 int mYOffset = 0;
219
chaviwbe43ac82018-04-04 15:14:49 -0700220 /**
221 * A flag to determine if the WSA needs to offset its position to compensate for the stack's
222 * position update before the WSA surface has resized.
223 */
224 private boolean mOffsetPositionForStackResize;
225
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800226 private final Rect mTmpSize = new Rect();
227
Robert Carrca4c5a62018-02-05 16:07:55 -0800228 private final SurfaceControl.Transaction mReparentTransaction = new SurfaceControl.Transaction();
229
Robert Carr7b3d11d2018-03-15 14:34:45 -0700230 // Used to track whether we have called detach children on the way to invisibility, in which
231 // case we need to give the client a new Surface if it lays back out to a visible state.
232 boolean mChildrenDetached = false;
233
Robert Carr2025bf842018-03-19 13:25:05 -0700234 // Set to true after the first frame of the Pinned stack animation
235 // and reset after the last to ensure we only reset mForceScaleUntilResize
236 // once per animation.
237 boolean mPipAnimationStarted = false;
238
chaviwbe43ac82018-04-04 15:14:49 -0700239 private final Point mTmpPos = new Point();
240
Craig Mautnerc431e892015-02-11 13:14:26 -0800241 WindowStateAnimator(final WindowState win) {
Craig Mautner918b53b2012-07-09 14:15:54 -0700242 final WindowManagerService service = win.mService;
243
Craig Mautnera2c77052012-03-26 12:14:43 -0700244 mService = service;
Craig Mautner918b53b2012-07-09 14:15:54 -0700245 mAnimator = service.mAnimator;
246 mPolicy = service.mPolicy;
247 mContext = service.mContext;
Craig Mautner918b53b2012-07-09 14:15:54 -0700248
249 mWin = win;
Craig Mautner918b53b2012-07-09 14:15:54 -0700250 mSession = win.mSession;
Craig Mautner918b53b2012-07-09 14:15:54 -0700251 mAttrType = win.mAttrs.type;
252 mIsWallpaper = win.mIsWallpaper;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700253 mWallpaperControllerLocked = mService.mRoot.mWallpaperController;
Craig Mautnera2c77052012-03-26 12:14:43 -0700254 }
255
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700256 /**
257 * Is the window or its container currently set to animate or currently animating?
258 */
259 boolean isAnimationSet() {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100260 return mWin.isAnimating();
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700261 }
262
Craig Mautnera2c77052012-03-26 12:14:43 -0700263 void cancelExitAnimationForNextAnimationLocked() {
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800264 if (DEBUG_ANIM) Slog.d(TAG,
265 "cancelExitAnimationForNextAnimationLocked: " + mWin);
266
Jorim Jaggia5e10572017-11-15 14:36:26 +0100267 mWin.cancelAnimation();
268 mWin.destroySurfaceUnchecked();
Craig Mautnera2c77052012-03-26 12:14:43 -0700269 }
270
Jorim Jaggia5e10572017-11-15 14:36:26 +0100271 void onAnimationFinished() {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700272 // Done animating, clean up.
273 if (DEBUG_ANIM) Slog.v(
Jorim Jaggia5e10572017-11-15 14:36:26 +0100274 TAG, "Animation done in " + this + ": exiting=" + mWin.mAnimatingExit
275 + ", reportedVisible="
276 + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
Craig Mautnera2c77052012-03-26 12:14:43 -0700277
Craig Mautnere7ae2502012-03-26 17:11:19 -0700278 if (mAnimator.mWindowDetachedWallpaper == mWin) {
279 mAnimator.mWindowDetachedWallpaper = null;
Craig Mautnera2c77052012-03-26 12:14:43 -0700280 }
Jorim Jaggia5e10572017-11-15 14:36:26 +0100281
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800282 mWin.checkPolicyVisibilityChange();
Jorim Jaggia5e10572017-11-15 14:36:26 +0100283 final DisplayContent displayContent = mWin.getDisplayContent();
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800284 if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.mPolicyVisibility) {
Craig Mautner81defc72013-10-29 11:10:42 -0700285 // Upon completion of a not-visible to visible status bar animation a relayout is
286 // required.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800287 if (displayContent != null) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700288 displayContent.setLayoutNeeded();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800289 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700290 }
291
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700292 mWin.onExitAnimationDone();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800293 final int displayId = mWin.getDisplayId();
Jorim Jaggia5e10572017-11-15 14:36:26 +0100294 int pendingLayoutChanges = FINISH_LAYOUT_REDO_ANIM;
295 if (displayContent.mWallpaperController.isWallpaperTarget(mWin)) {
296 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
297 }
298 mAnimator.setPendingLayoutChanges(displayId, pendingLayoutChanges);
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800299 if (DEBUG_LAYOUT_REPEATS)
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700300 mService.mWindowPlacerLocked.debugLayoutRepeats(
301 "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
Craig Mautnera2c77052012-03-26 12:14:43 -0700302
303 if (mWin.mAppToken != null) {
304 mWin.mAppToken.updateReportedVisibilityLocked();
305 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700306 }
307
Chavi Weingartenb736e322018-02-23 00:27:54 +0000308 void hide(SurfaceControl.Transaction transaction, String reason) {
Craig Mautner0afddcb2012-05-08 15:38:00 -0700309 if (!mLastHidden) {
310 //dump();
311 mLastHidden = true;
Jorim Jaggi50575902018-04-10 17:49:30 +0200312
313 // We may have a preserved surface which we no longer need. If there was a quick
314 // VISIBLE, GONE, VISIBLE, GONE sequence, the surface may never draw, so we don't mark
315 // it to be destroyed in prepareSurfaceLocked.
316 markPreservedSurfaceForDestroy();
317
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800318 if (mSurfaceController != null) {
Chavi Weingartenb736e322018-02-23 00:27:54 +0000319 mSurfaceController.hide(transaction, reason);
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800320 }
Craig Mautner0afddcb2012-05-08 15:38:00 -0700321 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700322 }
323
Chavi Weingartenb736e322018-02-23 00:27:54 +0000324 void hide(String reason) {
325 hide(mTmpTransaction, reason);
326 SurfaceControl.mergeToGlobalTransaction(mTmpTransaction);
327 }
328
Craig Mautnera608b882012-03-30 13:03:49 -0700329 boolean finishDrawingLocked() {
Craig Mautner42d04db2014-11-06 12:13:23 -0800330 final boolean startingWindow =
331 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
332 if (DEBUG_STARTING_WINDOW && startingWindow) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700333 Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
Craig Mautner276a6eb2014-11-04 15:32:57 -0800334 + drawStateToString());
Craig Mautner6fbda632012-07-03 09:26:39 -0700335 }
Robert Carr1ca6a332016-04-11 18:00:43 -0700336
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200337 boolean layoutNeeded = false;
Chong Zhang92147042016-05-09 12:47:11 -0700338
Craig Mautner749a7bb2012-04-02 13:49:53 -0700339 if (mDrawState == DRAW_PENDING) {
Robert Carre13b58e2017-08-31 14:50:44 -0700340 if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
Chong Zhang5b2f1992015-11-13 15:40:36 -0800341 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
Robert Carre6a83512015-11-03 16:09:21 -0800342 + mSurfaceController);
Craig Mautner42d04db2014-11-06 12:13:23 -0800343 if (DEBUG_STARTING_WINDOW && startingWindow) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700344 Slog.v(TAG, "Draw state now committed in " + mWin);
345 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700346 mDrawState = COMMIT_DRAW_PENDING;
Chong Zhangcbbcc0f2016-05-17 20:46:58 -0700347 layoutNeeded = true;
Craig Mautnera608b882012-03-30 13:03:49 -0700348 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700349
Chong Zhangcbbcc0f2016-05-17 20:46:58 -0700350 return layoutNeeded;
Craig Mautnera608b882012-03-30 13:03:49 -0700351 }
352
353 // This must be called while inside a transaction.
Craig Mautnerc431e892015-02-11 13:14:26 -0800354 boolean commitFinishDrawingLocked() {
Jorim Jaggie4b0f282017-05-17 15:10:29 +0200355 if (DEBUG_STARTING_WINDOW_VERBOSE &&
Craig Mautner6fbda632012-07-03 09:26:39 -0700356 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
357 Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
Craig Mautner276a6eb2014-11-04 15:32:57 -0800358 + drawStateToString());
Craig Mautner6fbda632012-07-03 09:26:39 -0700359 }
Craig Mautner276a6eb2014-11-04 15:32:57 -0800360 if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
Craig Mautnera608b882012-03-30 13:03:49 -0700361 return false;
362 }
Robert Carre13b58e2017-08-31 14:50:44 -0700363 if (DEBUG_ANIM) {
Robert Carre6a83512015-11-03 16:09:21 -0800364 Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceController);
Craig Mautner6fbda632012-07-03 09:26:39 -0700365 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700366 mDrawState = READY_TO_SHOW;
Chong Zhang0275e392015-09-17 10:41:44 -0700367 boolean result = false;
Craig Mautnera608b882012-03-30 13:03:49 -0700368 final AppWindowToken atoken = mWin.mAppToken;
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800369 if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
Wale Ogunwale9d147902016-07-16 11:58:55 -0700370 result = mWin.performShowLocked();
Chong Zhang0275e392015-09-17 10:41:44 -0700371 }
Chong Zhang97782b42015-10-07 16:01:23 -0700372 return result;
Craig Mautnera608b882012-03-30 13:03:49 -0700373 }
374
Chong Zhang97782b42015-10-07 16:01:23 -0700375 void preserveSurfaceLocked() {
376 if (mDestroyPreservedSurfaceUponRedraw) {
Chong Zhangb9b0fec2016-02-11 18:51:51 -0800377 // This could happen when switching the surface mode very fast. For example,
378 // we preserved a surface when dragResizing changed to true. Then before the
379 // preserved surface is removed, dragResizing changed to false again.
380 // In this case, we need to leave the preserved surface alone, and destroy
381 // the actual surface, so that the createSurface call could create a surface
382 // of the proper size. The preserved surface will still be removed when client
383 // finishes drawing to the new surface.
384 mSurfaceDestroyDeferred = false;
385 destroySurfaceLocked();
386 mSurfaceDestroyDeferred = true;
Chong Zhang97782b42015-10-07 16:01:23 -0700387 return;
388 }
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -0800389 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "SET FREEZE LAYER", false);
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800390 if (mSurfaceController != null) {
Robert Carrb1579c82017-09-05 14:54:47 -0700391 // Our SurfaceControl is always at layer 0 within the parent Surface managed by
392 // window-state. We want this old Surface to stay on top of the new one
393 // until we do the swap, so we place it at layer 1.
394 mSurfaceController.mSurfaceControl.setLayer(1);
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800395 }
Chong Zhang97782b42015-10-07 16:01:23 -0700396 mDestroyPreservedSurfaceUponRedraw = true;
397 mSurfaceDestroyDeferred = true;
398 destroySurfaceLocked();
399 }
400
401 void destroyPreservedSurfaceLocked() {
402 if (!mDestroyPreservedSurfaceUponRedraw) {
403 return;
404 }
Robert Carrd5c7dd62017-03-08 10:39:30 -0800405 if (mSurfaceController != null) {
406 if (mPendingDestroySurface != null) {
407 // If we are preserving a surface but we aren't relaunching that means
408 // we are just doing an in-place switch. In that case any SurfaceFlinger side
409 // child layers need to be reparented to the new surface to make this
410 // transparent to the app.
411 if (mWin.mAppToken == null || mWin.mAppToken.isRelaunching() == false) {
Robert Carrca4c5a62018-02-05 16:07:55 -0800412 mReparentTransaction.reparentChildren(mPendingDestroySurface.mSurfaceControl,
413 mSurfaceController.mSurfaceControl.getHandle())
414 .apply();
Robert Carrd5c7dd62017-03-08 10:39:30 -0800415 }
416 }
417 }
418
Chong Zhang97782b42015-10-07 16:01:23 -0700419 destroyDeferredSurfaceLocked();
420 mDestroyPreservedSurfaceUponRedraw = false;
421 }
422
Chong Zhangeb665572016-05-09 18:28:27 -0700423 void markPreservedSurfaceForDestroy() {
424 if (mDestroyPreservedSurfaceUponRedraw
425 && !mService.mDestroyPreservedSurface.contains(mWin)) {
426 mService.mDestroyPreservedSurface.add(mWin);
427 }
428 }
429
Robert Carrda61ba92017-03-29 15:52:23 -0700430 private int getLayerStack() {
431 return mWin.getDisplayContent().getDisplay().getLayerStack();
432 }
433
Robert Carrecc06b32017-04-18 14:25:10 -0700434 void resetDrawState() {
435 mDrawState = DRAW_PENDING;
436
437 if (mWin.mAppToken == null) {
438 return;
439 }
440
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200441 if (!mWin.mAppToken.isSelfAnimating()) {
Robert Carrecc06b32017-04-18 14:25:10 -0700442 mWin.mAppToken.clearAllDrawn();
443 } else {
444 // Currently animating, persist current state of allDrawn until animation
445 // is complete.
446 mWin.mAppToken.deferClearAllDrawn = true;
447 }
448 }
449
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500450 WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
Alan Viveretteccb11e12014-07-08 16:04:02 -0700451 final WindowState w = mWin;
Chong Zhanga8975bd2016-01-28 17:13:47 -0800452
Wale Ogunwale722ff892016-02-18 13:37:55 -0800453 if (mSurfaceController != null) {
454 return mSurfaceController;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700455 }
Robert Carr7b3d11d2018-03-15 14:34:45 -0700456 mChildrenDetached = false;
Wale Ogunwale722ff892016-02-18 13:37:55 -0800457
Robert Carr132c9f52017-07-31 17:02:30 -0700458 if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
459 windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT;
460 }
461
Wale Ogunwale722ff892016-02-18 13:37:55 -0800462 w.setHasSurface(false);
463
464 if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
465 "createSurface " + this + ": mDrawState=DRAW_PENDING");
466
Robert Carrecc06b32017-04-18 14:25:10 -0700467 resetDrawState();
Wale Ogunwale722ff892016-02-18 13:37:55 -0800468
469 mService.makeWindowFreezingScreenIfNeededLocked(w);
470
471 int flags = SurfaceControl.HIDDEN;
472 final WindowManager.LayoutParams attrs = w.mAttrs;
473
474 if (mService.isSecureLocked(w)) {
475 flags |= SurfaceControl.SECURE;
476 }
477
Robert Carr217e7cc2018-01-31 18:08:39 -0800478 mTmpSize.set(0, 0, 0, 0);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800479 calculateSurfaceBounds(w, attrs);
480 final int width = mTmpSize.width();
481 final int height = mTmpSize.height();
482
483 if (DEBUG_VISIBILITY) {
484 Slog.v(TAG, "Creating surface in session "
485 + mSession.mSurfaceSession + " window " + this
486 + " w=" + width + " h=" + height
487 + " x=" + mTmpSize.left + " y=" + mTmpSize.top
488 + " format=" + attrs.format + " flags=" + flags);
489 }
490
491 // We may abort, so initialize to defaults.
Wale Ogunwale722ff892016-02-18 13:37:55 -0800492 mLastClipRect.set(0, 0, 0, 0);
493
494 // Set up surface control with initial size.
495 try {
496
497 final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
498 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
499 if (!PixelFormat.formatHasAlpha(attrs.format)
500 // Don't make surface with surfaceInsets opaque as they display a
501 // translucent shadow.
502 && attrs.surfaceInsets.left == 0
503 && attrs.surfaceInsets.top == 0
504 && attrs.surfaceInsets.right == 0
505 && attrs.surfaceInsets.bottom == 0
506 // Don't make surface opaque when resizing to reduce the amount of
507 // artifacts shown in areas the app isn't drawing content to.
508 && !w.isDragResizing()) {
509 flags |= SurfaceControl.OPAQUE;
510 }
511
512 mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
Jorim Jaggia5e10572017-11-15 14:36:26 +0100513 attrs.getTitle().toString(), width, height, format, flags, this,
514 windowType, ownerUid);
chaviwbe43ac82018-04-04 15:14:49 -0700515
516 setOffsetPositionForStackResize(false);
Robert Carr486bbb72017-05-30 11:25:22 -0700517 mSurfaceFormat = format;
Wale Ogunwale722ff892016-02-18 13:37:55 -0800518
519 w.setHasSurface(true);
520
521 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
522 Slog.i(TAG, " CREATE SURFACE "
523 + mSurfaceController + " IN SESSION "
524 + mSession.mSurfaceSession
525 + ": pid=" + mSession.mPid + " format="
526 + attrs.format + " flags=0x"
527 + Integer.toHexString(flags)
528 + " / " + this);
529 }
530 } catch (OutOfResourcesException e) {
531 Slog.w(TAG, "OutOfResourcesException creating surface");
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700532 mService.mRoot.reclaimSomeSurfaceMemory(this, "create", true);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800533 mDrawState = NO_SURFACE;
534 return null;
535 } catch (Exception e) {
Robert Carrb0f39362018-03-14 13:52:25 -0700536 Slog.e(TAG, "Exception creating surface (parent dead?)", e);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800537 mDrawState = NO_SURFACE;
538 return null;
539 }
540
541 if (WindowManagerService.localLOGV) Slog.v(TAG, "Got surface: " + mSurfaceController
542 + ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
543 + ", animLayer=" + mAnimLayer);
544
545 if (SHOW_LIGHT_TRANSACTIONS) {
546 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
547 WindowManagerService.logSurface(w, "CREATE pos=("
548 + w.mFrame.left + "," + w.mFrame.top + ") ("
549 + width + "x" + height + "), layer=" + mAnimLayer + " HIDE", false);
550 }
551
Wale Ogunwale722ff892016-02-18 13:37:55 -0800552 mLastHidden = true;
553
554 if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this);
Robert Carre6a83512015-11-03 16:09:21 -0800555 return mSurfaceController;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700556 }
557
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800558 private void calculateSurfaceBounds(WindowState w, LayoutParams attrs) {
559 if ((attrs.flags & FLAG_SCALED) != 0) {
560 // For a scaled surface, we always want the requested size.
561 mTmpSize.right = mTmpSize.left + w.mRequestedWidth;
562 mTmpSize.bottom = mTmpSize.top + w.mRequestedHeight;
563 } else {
564 // When we're doing a drag-resizing, request a surface that's fullscreen size,
565 // so that we don't need to reallocate during the process. This also prevents
566 // buffer drops due to size mismatch.
567 if (w.isDragResizing()) {
568 if (w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM) {
569 mTmpSize.left = 0;
570 mTmpSize.top = 0;
571 }
572 final DisplayInfo displayInfo = w.getDisplayInfo();
573 mTmpSize.right = mTmpSize.left + displayInfo.logicalWidth;
574 mTmpSize.bottom = mTmpSize.top + displayInfo.logicalHeight;
575 } else {
576 mTmpSize.right = mTmpSize.left + w.mCompatFrame.width();
577 mTmpSize.bottom = mTmpSize.top + w.mCompatFrame.height();
578 }
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.
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800584 if (mTmpSize.width() < 1) {
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800585 mTmpSize.right = mTmpSize.left + 1;
586 }
587 if (mTmpSize.height() < 1) {
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800588 mTmpSize.bottom = mTmpSize.top + 1;
589 }
590
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800591 // Adjust for surface insets.
Phil Weavera4b32b92016-06-02 13:55:39 -0700592 mTmpSize.left -= attrs.surfaceInsets.left;
593 mTmpSize.top -= attrs.surfaceInsets.top;
594 mTmpSize.right += attrs.surfaceInsets.right;
595 mTmpSize.bottom += attrs.surfaceInsets.bottom;
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800596 }
597
Chong Zhangeb22e8e2016-01-20 19:52:22 -0800598 boolean hasSurface() {
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200599 return mSurfaceController != null && mSurfaceController.hasSurface();
Chong Zhangeb22e8e2016-01-20 19:52:22 -0800600 }
601
Craig Mautner96868332012-12-04 14:29:11 -0800602 void destroySurfaceLocked() {
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700603 final AppWindowToken wtoken = mWin.mAppToken;
604 if (wtoken != null) {
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700605 if (mWin == wtoken.startingWindow) {
606 wtoken.startingDisplayed = false;
607 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700608 }
609
Wale Ogunwale722ff892016-02-18 13:37:55 -0800610 if (mSurfaceController == null) {
611 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700612 }
Wale Ogunwale722ff892016-02-18 13:37:55 -0800613
Wale Ogunwale722ff892016-02-18 13:37:55 -0800614 // When destroying a surface we want to make sure child windows are hidden. If we are
615 // preserving the surface until redraw though we intend to swap it out with another surface
616 // for resizing. In this case the window always remains visible to the user and the child
617 // windows should likewise remain visible.
Wale Ogunwale9d147902016-07-16 11:58:55 -0700618 if (!mDestroyPreservedSurfaceUponRedraw) {
619 mWin.mHidden = true;
Wale Ogunwale722ff892016-02-18 13:37:55 -0800620 }
621
622 try {
623 if (DEBUG_VISIBILITY) logWithStack(TAG, "Window " + this + " destroying surface "
624 + mSurfaceController + ", session " + mSession);
625 if (mSurfaceDestroyDeferred) {
626 if (mSurfaceController != null && mPendingDestroySurface != mSurfaceController) {
627 if (mPendingDestroySurface != null) {
628 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
629 WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
630 }
Robert Carra8828862018-02-05 16:17:36 -0800631 mPendingDestroySurface.destroyNotInTransaction();
Wale Ogunwale722ff892016-02-18 13:37:55 -0800632 }
633 mPendingDestroySurface = mSurfaceController;
634 }
635 } else {
636 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
637 WindowManagerService.logSurface(mWin, "DESTROY", true);
638 }
639 destroySurface();
640 }
641 // Don't hide wallpaper if we're deferring the surface destroy
642 // because of a surface change.
643 if (!mDestroyPreservedSurfaceUponRedraw) {
644 mWallpaperControllerLocked.hideWallpapers(mWin);
645 }
646 } catch (RuntimeException e) {
647 Slog.w(TAG, "Exception thrown when destroying Window " + this
648 + " surface " + mSurfaceController + " session " + mSession + ": " + e.toString());
649 }
650
651 // Whether the surface was preserved (and copied to mPendingDestroySurface) or not, it
652 // needs to be cleared to match the WindowState.mHasSurface state. It is also necessary
653 // so it can be recreated successfully in mPendingDestroySurface case.
654 mWin.setHasSurface(false);
655 if (mSurfaceController != null) {
656 mSurfaceController.setShown(false);
657 }
658 mSurfaceController = null;
659 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700660 }
661
Craig Mautner96868332012-12-04 14:29:11 -0800662 void destroyDeferredSurfaceLocked() {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700663 try {
664 if (mPendingDestroySurface != null) {
665 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -0800666 WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700667 }
Robert Carra8828862018-02-05 16:17:36 -0800668 mPendingDestroySurface.destroyNotInTransaction();
Chong Zhang6e21cf42015-11-09 14:41:42 -0800669 // Don't hide wallpaper if we're destroying a deferred surface
670 // after a surface mode change.
671 if (!mDestroyPreservedSurfaceUponRedraw) {
672 mWallpaperControllerLocked.hideWallpapers(mWin);
673 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700674 }
675 } catch (RuntimeException e) {
Craig Mautnerd87946b2012-03-29 18:00:19 -0700676 Slog.w(TAG, "Exception thrown when destroying Window "
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700677 + this + " surface " + mPendingDestroySurface
678 + " session " + mSession + ": " + e.toString());
679 }
680 mSurfaceDestroyDeferred = false;
681 mPendingDestroySurface = null;
682 }
683
684 void computeShownFrameLocked() {
Craig Mautnera91f9e22012-09-14 16:22:08 -0700685 final int displayId = mWin.getDisplayId();
686 final ScreenRotationAnimation screenRotationAnimation =
687 mAnimator.getScreenRotationAnimationLocked(displayId);
688 final boolean screenAnimation =
689 screenRotationAnimation != null && screenRotationAnimation.isAnimating();
Robert Carr2f0fe622015-09-25 14:56:38 -0700690
Robert Carr44643c12017-09-27 14:57:38 -0700691 if (screenAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700692 // cache often used attributes locally
693 final Rect frame = mWin.mFrame;
694 final float tmpFloats[] = mService.mTmpFloats;
695 final Matrix tmpMatrix = mWin.mTmpMatrix;
696
697 // Compute the desired transformation.
Robert Carr44643c12017-09-27 14:57:38 -0700698 if (screenRotationAnimation.isRotating()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700699 // If we are doing a screen animation, the global rotation
700 // applied to windows can result in windows that are carefully
701 // aligned with each other to slightly separate, allowing you
702 // to see what is behind them. An unsightly mess. This...
703 // thing... magically makes it call good: scale each window
704 // slightly (two pixels larger in each dimension, from the
705 // window's center).
706 final float w = frame.width();
707 final float h = frame.height();
708 if (w>=1 && h>=1) {
709 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
710 } else {
711 tmpMatrix.reset();
712 }
713 } else {
714 tmpMatrix.reset();
715 }
Robert Carr44643c12017-09-27 14:57:38 -0700716
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700717 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
Robert Carr29d196f2017-11-28 12:39:46 -0800718
Jorim Jaggi9af095b2017-12-12 17:18:57 +0100719 // WindowState.prepareSurfaces expands for surface insets (in order they don't get
720 // clipped by the WindowState surface), so we need to go into the other direction here.
Robert Carr217e7cc2018-01-31 18:08:39 -0800721 tmpMatrix.postTranslate(mWin.mAttrs.surfaceInsets.left,
722 mWin.mAttrs.surfaceInsets.top);
Jorim Jaggi9af095b2017-12-12 17:18:57 +0100723
Matthew Ng34a06d12017-02-03 11:56:08 -0800724
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700725 // "convert" it into SurfaceFlinger's format
726 // (a 2x2 matrix + an offset)
727 // Here we must not transform the position of the surface
728 // since it is already included in the transformation.
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800729 //Slog.i(TAG_WM, "Transform: " + matrix);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700730
731 mHaveMatrix = true;
732 tmpMatrix.getValues(tmpFloats);
733 mDsDx = tmpFloats[Matrix.MSCALE_X];
734 mDtDx = tmpFloats[Matrix.MSKEW_Y];
Robert Carr0edf18f2017-02-21 20:01:47 -0800735 mDtDy = tmpFloats[Matrix.MSKEW_X];
736 mDsDy = tmpFloats[Matrix.MSCALE_Y];
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700737
738 // Now set the alpha... but because our current hardware
739 // can't do alpha transformation on a non-opaque surface,
740 // turn it off if we are running an animation that is also
741 // transforming since it is more important to have that
742 // animation be smooth.
743 mShownAlpha = mAlpha;
744 if (!mService.mLimitedAlphaCompositing
745 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
Robert Carr217e7cc2018-01-31 18:08:39 -0800746 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)))) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800747 //Slog.i(TAG_WM, "Applying alpha transform");
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700748 if (screenAnimation) {
Craig Mautnera91f9e22012-09-14 16:22:08 -0700749 mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700750 }
751 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800752 //Slog.i(TAG_WM, "Not applying alpha transform");
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700753 }
754
Robert Carre13b58e2017-08-31 14:50:44 -0700755 if ((DEBUG_ANIM || WindowManagerService.localLOGV)
Craig Mautnera91f9e22012-09-14 16:22:08 -0700756 && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
757 TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
Craig Mautnera91f9e22012-09-14 16:22:08 -0700758 + " screen=" + (screenAnimation ?
759 screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700760 return;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700761 } else if (mIsWallpaper && mService.mRoot.mWallpaperActionPending) {
Craig Mautner4d7349b2012-04-20 14:52:47 -0700762 return;
Chong Zhang3005e752015-09-18 18:46:28 -0700763 } else if (mWin.isDragResizeChanged()) {
764 // This window is awaiting a relayout because user just started (or ended)
765 // drag-resizing. The shown frame (which affects surface size and pos)
766 // should not be updated until we get next finished draw with the new surface.
767 // Otherwise one or two frames rendered with old settings would be displayed
768 // with new geometry.
769 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700770 }
771
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800772 if (WindowManagerService.localLOGV) Slog.v(
Craig Mautner4d7349b2012-04-20 14:52:47 -0700773 TAG, "computeShownFrameLocked: " + this +
774 " not attached, mAlpha=" + mAlpha);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700775
Robert Carrb1579c82017-09-05 14:54:47 -0700776 mShownAlpha = mAlpha;
777 mHaveMatrix = false;
778 mDsDx = mWin.mGlobalScale;
779 mDtDx = 0;
780 mDtDy = 0;
781 mDsDy = mWin.mGlobalScale;
Robert Carref090ac2017-05-15 16:45:50 -0700782 }
783
Robert Carrfbbde852016-10-18 11:02:28 -0700784 /**
Robert Carrfbbde852016-10-18 11:02:28 -0700785 * Calculate the window-space crop rect and fill clipRect.
Wale Ogunwaleca9e0612016-12-02 07:45:59 -0800786 * @return true if clipRect has been filled otherwise, no window space crop should be applied.
Robert Carrfbbde852016-10-18 11:02:28 -0700787 */
Wale Ogunwaleca9e0612016-12-02 07:45:59 -0800788 private boolean calculateCrop(Rect clipRect) {
Robert Carrfbbde852016-10-18 11:02:28 -0700789 final WindowState w = mWin;
790 final DisplayContent displayContent = w.getDisplayContent();
791 clipRect.setEmpty();
792
793 if (displayContent == null) {
794 return false;
795 }
796
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700797 if (w.inPinnedWindowingMode()) {
Robert Carrfbbde852016-10-18 11:02:28 -0700798 return false;
799 }
800
801 // 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="
813 + w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -0700814
Andrii Kulian283acd22017-08-03 04:03:51 -0700815 final Task task = w.getTask();
816 final boolean fullscreen = w.fillsDisplay() || (task != null && task.isFullscreen());
Jorim Jaggi253a20f2015-11-03 12:38:42 +0100817 final boolean isFreeformResizing =
Jorim Jaggidcf467c2015-11-05 13:59:32 +0100818 w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
Robert Carr51a1b872015-12-08 14:03:13 -0800819
820 // We use the clip rect as provided by the tranformation for non-fullscreen windows to
821 // avoid premature clipping with the system decor rect.
Robert Carrf0586622018-01-29 13:03:43 -0800822 clipRect.set(mSystemDecorRect);
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -0700823 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect
Robert Carrf0586622018-01-29 13:03:43 -0800824 + " fullscreen=" + fullscreen);
Robert Carr51a1b872015-12-08 14:03:13 -0800825
Robert Carrfbbde852016-10-18 11:02:28 -0700826 w.expandForSurfaceInsets(clipRect);
Alan Viverette49a22e82014-07-12 20:01:27 -0700827
Alan Viverette49a22e82014-07-12 20:01:27 -0700828 // The clip rect was generated assuming (0,0) as the window origin,
829 // so we need to translate to match the actual surface coordinates.
Robert Carrfbbde852016-10-18 11:02:28 -0700830 clipRect.offset(w.mAttrs.surfaceInsets.left, w.mAttrs.surfaceInsets.top);
Robert Carr58f29132015-10-29 14:19:05 -0700831
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -0700832 if (DEBUG_WINDOW_CROP) Slog.d(TAG,
833 "win=" + w + " Clip rect after stack adjustment=" + clipRect);
Robert Carr58f29132015-10-29 14:19:05 -0700834
Chia-I Wue6bcaf12016-05-27 10:58:48 +0800835 w.transformClipRectFromScreenToSurfaceSpace(clipRect);
Robert Carr58f29132015-10-29 14:19:05 -0700836
Robert Carrfbbde852016-10-18 11:02:28 -0700837 return true;
Robert Carr0d00c2e2016-02-29 17:45:02 -0800838 }
839
chaviw23012112017-12-20 15:29:04 -0800840 private void applyCrop(Rect clipRect, boolean recoveringMemory) {
Robert Carrfbbde852016-10-18 11:02:28 -0700841 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "applyCrop: win=" + mWin
chaviw23012112017-12-20 15:29:04 -0800842 + " clipRect=" + clipRect);
Robert Carr4320d332016-06-10 15:13:32 -0700843 if (clipRect != null) {
844 if (!clipRect.equals(mLastClipRect)) {
845 mLastClipRect.set(clipRect);
846 mSurfaceController.setCropInTransaction(clipRect, recoveringMemory);
847 }
848 } else {
849 mSurfaceController.clearCropInTransaction(recoveringMemory);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -0700850 }
Filip Gruszczynski4b8eea72015-09-14 18:16:19 -0700851 }
852
Wale Ogunwale4c8b7952015-04-07 10:49:40 -0700853 void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
Wale Ogunwale027f4752017-05-12 10:37:16 -0700854 if (mSurfaceController == null) {
855 return;
856 }
857
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700858 final WindowState w = mWin;
Winson Chung08f81892017-03-02 15:40:51 -0800859 final LayoutParams attrs = mWin.getAttrs();
Robert Carr0d00c2e2016-02-29 17:45:02 -0800860 final Task task = w.getTask();
Alan Viveretteccb11e12014-07-08 16:04:02 -0700861
Robert Carr217e7cc2018-01-31 18:08:39 -0800862 mTmpSize.set(0, 0, 0, 0);
Winson Chung08f81892017-03-02 15:40:51 -0800863 calculateSurfaceBounds(w, attrs);
Chong Zhang0275e392015-09-17 10:41:44 -0700864
Robert Carr04092112016-06-02 12:56:12 -0700865 mExtraHScale = (float) 1.0;
866 mExtraVScale = (float) 1.0;
Robert Carre1034cc32016-02-01 13:08:15 -0800867
Robert Carr6da3cc02016-06-16 15:17:07 -0700868 boolean wasForceScaled = mForceScaleUntilResize;
869 boolean wasSeamlesslyRotated = w.mSeamlesslyRotated;
870
Robert Carrfed10072016-05-26 11:48:49 -0700871 // Once relayout has been called at least once, we need to make sure
872 // we only resize the client surface during calls to relayout. For
873 // clients which use indeterminate measure specs (MATCH_PARENT),
874 // we may try and change their window size without a call to relayout.
875 // However, this would be unsafe, as the client may be in the middle
876 // of producing a frame at the old size, having just completed layout
877 // to find the surface size changed underneath it.
chaviwbe43ac82018-04-04 15:14:49 -0700878 final boolean relayout = !w.mRelayoutCalled || w.mInRelayout;
879 if (relayout) {
Robert Carrfed10072016-05-26 11:48:49 -0700880 mSurfaceResized = mSurfaceController.setSizeInTransaction(
881 mTmpSize.width(), mTmpSize.height(), recoveringMemory);
882 } else {
883 mSurfaceResized = false;
884 }
Robert Carrc7294602016-05-13 11:32:05 -0700885 mForceScaleUntilResize = mForceScaleUntilResize && !mSurfaceResized;
Robert Carr6da3cc02016-06-16 15:17:07 -0700886 // If we are undergoing seamless rotation, the surface has already
887 // been set up to persist at it's old location. We need to freeze
888 // updates until a resize occurs.
Robert Carrb14d4abc2016-10-03 18:13:33 -0700889 mService.markForSeamlessRotation(w, w.mSeamlesslyRotated && !mSurfaceResized);
Robert Carrc7294602016-05-13 11:32:05 -0700890
chaviw23012112017-12-20 15:29:04 -0800891 Rect clipRect = null;
Robert Carrfbbde852016-10-18 11:02:28 -0700892 if (calculateCrop(mTmpClipRect)) {
893 clipRect = mTmpClipRect;
894 }
Robert Carra9408d42016-06-03 13:28:48 -0700895
896 float surfaceWidth = mSurfaceController.getWidth();
897 float surfaceHeight = mSurfaceController.getHeight();
898
Robert Carr74a66a22018-02-23 12:17:51 -0800899 final Rect insets = attrs.surfaceInsets;
900
Robert Carr8f0a3ad2017-02-15 19:30:28 -0800901 if (isForceScaled()) {
Robert Carr74a66a22018-02-23 12:17:51 -0800902 int hInsets = insets.left + insets.right;
903 int vInsets = insets.top + insets.bottom;
Winson Chung08f81892017-03-02 15:40:51 -0800904 float surfaceContentWidth = surfaceWidth - hInsets;
905 float surfaceContentHeight = surfaceHeight - vInsets;
Robert Carra9408d42016-06-03 13:28:48 -0700906 if (!mForceScaleUntilResize) {
907 mSurfaceController.forceScaleableInTransaction(true);
908 }
Robert Carrfd4c9892017-02-01 10:28:28 -0800909
Robert Carr74a66a22018-02-23 12:17:51 -0800910 int posX = 0;
911 int posY = 0;
Robert Carrfd4c9892017-02-01 10:28:28 -0800912 task.mStack.getDimBounds(mTmpStackBounds);
Robert Carr18f622f2017-05-08 11:20:43 -0700913
914 boolean allowStretching = false;
Winson Chung8bca9e42017-04-16 15:59:43 -0700915 task.mStack.getFinalAnimationSourceHintBounds(mTmpSourceBounds);
Robert Carr18f622f2017-05-08 11:20:43 -0700916 // If we don't have source bounds, we can attempt to use the content insets
917 // in the following scenario:
918 // 1. We have content insets.
919 // 2. We are not transitioning to full screen
920 // We have to be careful to check "lastAnimatingBoundsWasToFullscreen" rather than
921 // the mBoundsAnimating state, as we may have already left it and only be here
922 // because of the force-scale until resize state.
923 if (mTmpSourceBounds.isEmpty() && (mWin.mLastRelayoutContentInsets.width() > 0
924 || mWin.mLastRelayoutContentInsets.height() > 0)
925 && !task.mStack.lastAnimatingBoundsWasToFullscreen()) {
926 mTmpSourceBounds.set(task.mStack.mPreAnimationBounds);
927 mTmpSourceBounds.inset(mWin.mLastRelayoutContentInsets);
928 allowStretching = true;
929 }
Adrian Roos604ef952018-05-15 20:13:13 +0200930
931 // Make sure that what we're animating to and from is actually the right size in case
932 // the window cannot take up the full screen.
933 mTmpStackBounds.intersectUnchecked(w.mParentFrame);
934 mTmpSourceBounds.intersectUnchecked(w.mParentFrame);
935 mTmpAnimatingBounds.intersectUnchecked(w.mParentFrame);
936
Winson Chung08f81892017-03-02 15:40:51 -0800937 if (!mTmpSourceBounds.isEmpty()) {
938 // Get the final target stack bounds, if we are not animating, this is just the
939 // current stack bounds
Winson Chung40a5f932017-04-13 16:39:36 -0700940 task.mStack.getFinalAnimationBounds(mTmpAnimatingBounds);
Winson Chung08f81892017-03-02 15:40:51 -0800941
942 // Calculate the current progress and interpolate the difference between the target
943 // and source bounds
944 float finalWidth = mTmpAnimatingBounds.width();
945 float initialWidth = mTmpSourceBounds.width();
Robert Carr18f622f2017-05-08 11:20:43 -0700946 float tw = (surfaceContentWidth - mTmpStackBounds.width())
Winson Chung08f81892017-03-02 15:40:51 -0800947 / (surfaceContentWidth - mTmpAnimatingBounds.width());
Robert Carr18f622f2017-05-08 11:20:43 -0700948 float th = tw;
949 mExtraHScale = (initialWidth + tw * (finalWidth - initialWidth)) / initialWidth;
950 if (allowStretching) {
951 float finalHeight = mTmpAnimatingBounds.height();
952 float initialHeight = mTmpSourceBounds.height();
953 th = (surfaceContentHeight - mTmpStackBounds.height())
954 / (surfaceContentHeight - mTmpAnimatingBounds.height());
955 mExtraVScale = (initialHeight + tw * (finalHeight - initialHeight))
956 / initialHeight;
957 } else {
958 mExtraVScale = mExtraHScale;
959 }
Winson Chung08f81892017-03-02 15:40:51 -0800960
961 // Adjust the position to account for the inset bounds
Robert Carr18f622f2017-05-08 11:20:43 -0700962 posX -= (int) (tw * mExtraHScale * mTmpSourceBounds.left);
963 posY -= (int) (th * mExtraVScale * mTmpSourceBounds.top);
Winson Chung08f81892017-03-02 15:40:51 -0800964
Robert Carr74a66a22018-02-23 12:17:51 -0800965 // In pinned mode the clip rectangle applied to us by our stack has been
966 // expanded outwards to allow for shadows. However in case of source bounds set
967 // we need to crop to within the surface. The code above has scaled and positioned
968 // the surface to fit the unexpanded stack bounds, but now we need to reapply
969 // the cropping that the stack would have applied if it weren't expanded. This
970 // can be different in each direction based on the source bounds.
971 clipRect = mTmpClipRect;
972 clipRect.set((int)((insets.left + mTmpSourceBounds.left) * tw),
973 (int)((insets.top + mTmpSourceBounds.top) * th),
974 insets.left + (int)(surfaceWidth
975 - (tw* (surfaceWidth - mTmpSourceBounds.right))),
976 insets.top + (int)(surfaceHeight
977 - (th * (surfaceHeight - mTmpSourceBounds.bottom))));
Winson Chung08f81892017-03-02 15:40:51 -0800978 } else {
979 // We want to calculate the scaling based on the content area, not based on
980 // the entire surface, so that we scale in sync with windows that don't have insets.
981 mExtraHScale = mTmpStackBounds.width() / surfaceContentWidth;
982 mExtraVScale = mTmpStackBounds.height() / surfaceContentHeight;
983
984 // Since we are scaled to fit in our previously desired crop, we can now
985 // expose the whole window in buffer space, and not risk extending
986 // past where the system would have cropped us
987 clipRect = null;
Winson Chung08f81892017-03-02 15:40:51 -0800988 }
Robert Carr0d00c2e2016-02-29 17:45:02 -0800989
Robert Carrfd4c9892017-02-01 10:28:28 -0800990 // In the case of ForceScaleToStack we scale entire tasks together,
Robert Carr0d00c2e2016-02-29 17:45:02 -0800991 // and so we need to scale our offsets relative to the task bounds
992 // or parent and child windows would fall out of alignment.
Winson Chung08f81892017-03-02 15:40:51 -0800993 posX -= (int) (attrs.x * (1 - mExtraHScale));
994 posY -= (int) (attrs.y * (1 - mExtraVScale));
995
Robert Carrbc133762016-05-12 14:04:38 -0700996 // Imagine we are scaling down. As we scale the buffer down, we decrease the
997 // distance between the surface top left, and the start of the surface contents
998 // (previously it was surfaceInsets.left pixels in screen space but now it
Robert Carr04092112016-06-02 12:56:12 -0700999 // will be surfaceInsets.left*mExtraHScale). This means in order to keep the
Robert Carrbc133762016-05-12 14:04:38 -07001000 // non inset content at the same position, we have to shift the whole window
1001 // forward. Likewise for scaling up, we've increased this distance, and we need
1002 // to shift by a negative number to compensate.
Robert Carr74a66a22018-02-23 12:17:51 -08001003 posX += insets.left * (1 - mExtraHScale);
1004 posY += insets.top * (1 - mExtraVScale);
Robert Carrbc133762016-05-12 14:04:38 -07001005
Winson Chung08f81892017-03-02 15:40:51 -08001006 mSurfaceController.setPositionInTransaction((float) Math.floor(posX),
1007 (float) Math.floor(posY), recoveringMemory);
Robert Carrc7294602016-05-13 11:32:05 -07001008
1009 // Various surfaces in the scaled stack may resize at different times.
1010 // We need to ensure for each surface, that we disable transformation matrix
1011 // scaling in the same transaction which we resize the surface in.
1012 // As we are in SCALING_MODE_SCALE_TO_WINDOW, SurfaceFlinger will
Robert Carra9408d42016-06-03 13:28:48 -07001013 // then take over the scaling until the new buffer arrives, and things
Robert Carrc7294602016-05-13 11:32:05 -07001014 // will be seamless.
Robert Carr2025bf842018-03-19 13:25:05 -07001015 if (mPipAnimationStarted == false) {
1016 mForceScaleUntilResize = true;
1017 mPipAnimationStarted = true;
1018 }
Rob Carr06be6bb2018-02-06 16:26:06 +00001019 } else {
Robert Carr2025bf842018-03-19 13:25:05 -07001020 mPipAnimationStarted = false;
1021
Rob Carr06be6bb2018-02-06 16:26:06 +00001022 if (!w.mSeamlesslyRotated) {
chaviwbe43ac82018-04-04 15:14:49 -07001023 // Used to offset the WSA when stack position changes before a resize.
1024 int xOffset = mXOffset;
1025 int yOffset = mYOffset;
1026 if (mOffsetPositionForStackResize) {
1027 if (relayout) {
1028 // Once a relayout is called, reset the offset back to 0 and defer
1029 // setting it until a new frame with the updated size. This ensures that
1030 // the WS position is reset (so the stack position is shown) at the same
1031 // time that the buffer size changes.
1032 setOffsetPositionForStackResize(false);
1033 mSurfaceController.deferTransactionUntil(mSurfaceController.getHandle(),
1034 mWin.getFrameNumber());
1035 } else {
1036 final TaskStack stack = mWin.getStack();
1037 mTmpPos.x = 0;
1038 mTmpPos.y = 0;
1039 if (stack != null) {
1040 stack.getRelativePosition(mTmpPos);
1041 }
1042
1043 xOffset = -mTmpPos.x;
1044 yOffset = -mTmpPos.y;
1045
1046 // Crop also needs to be extended so the bottom isn't cut off when the WSA
1047 // position is moved.
1048 if (clipRect != null) {
1049 clipRect.right += mTmpPos.x;
1050 clipRect.bottom += mTmpPos.y;
1051 }
1052 }
1053 }
1054 mSurfaceController.setPositionInTransaction(xOffset, yOffset, recoveringMemory);
Rob Carr06be6bb2018-02-06 16:26:06 +00001055 }
Robert Carr0d00c2e2016-02-29 17:45:02 -08001056 }
1057
Robert Carra9408d42016-06-03 13:28:48 -07001058 // If we are ending the scaling mode. We switch to SCALING_MODE_FREEZE
Robert Carr6da3cc02016-06-16 15:17:07 -07001059 // to prevent further updates until buffer latch.
1060 // When ending both force scaling, and seamless rotation, we need to freeze
1061 // the Surface geometry until a buffer comes in at the new size (normally position and crop
1062 // are unfrozen). setGeometryAppliesWithResizeInTransaction accomplishes this for us.
1063 if ((wasForceScaled && !mForceScaleUntilResize) ||
1064 (wasSeamlesslyRotated && !w.mSeamlesslyRotated)) {
1065 mSurfaceController.setGeometryAppliesWithResizeInTransaction(true);
Robert Carra9408d42016-06-03 13:28:48 -07001066 mSurfaceController.forceScaleableInTransaction(false);
1067 }
Robert Carr4320d332016-06-10 15:13:32 -07001068
Robert Carr6da3cc02016-06-16 15:17:07 -07001069 if (!w.mSeamlesslyRotated) {
chaviw23012112017-12-20 15:29:04 -08001070 applyCrop(clipRect, recoveringMemory);
Robert Carr6da3cc02016-06-16 15:17:07 -07001071 mSurfaceController.setMatrixInTransaction(mDsDx * w.mHScale * mExtraHScale,
1072 mDtDx * w.mVScale * mExtraVScale,
Robert Carr0edf18f2017-02-21 20:01:47 -08001073 mDtDy * w.mHScale * mExtraHScale,
1074 mDsDy * w.mVScale * mExtraVScale, recoveringMemory);
Robert Carr6da3cc02016-06-16 15:17:07 -07001075 }
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001076
Robert Carre6a83512015-11-03 16:09:21 -08001077 if (mSurfaceResized) {
Chong Zhang5b2f1992015-11-13 15:40:36 -08001078 mReportSurfaceResized = true;
Robert Carre6a83512015-11-03 16:09:21 -08001079 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
Jorim Jaggia5e10572017-11-15 14:36:26 +01001080 FINISH_LAYOUT_REDO_WALLPAPER);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001081 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001082 }
1083
Andrii Kulian283acd22017-08-03 04:03:51 -07001084 /**
1085 * Get rect of the task this window is currently in. If there is no task, rect will be set to
1086 * empty.
1087 */
1088 void getContainerRect(Rect rect) {
1089 final Task task = mWin.getTask();
1090 if (task != null) {
1091 task.getDimBounds(rect);
1092 } else {
1093 rect.left = rect.top = rect.right = rect.bottom = 0;
1094 }
1095 }
1096
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001097 void prepareSurfaceLocked(final boolean recoveringMemory) {
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001098 final WindowState w = mWin;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001099 if (!hasSurface()) {
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001100
1101 // There is no need to wait for an animation change if our window is gone for layout
1102 // already as we'll never be visible.
Bryce Lee8c3cf382017-07-06 19:47:10 -07001103 if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001104 if (DEBUG_ORIENTATION) {
1105 Slog.v(TAG, "Orientation change skips hidden " + w);
1106 }
Bryce Lee8c3cf382017-07-06 19:47:10 -07001107 w.setOrientationChanging(false);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001108 }
1109 return;
1110 }
1111
1112 boolean displayed = false;
1113
1114 computeShownFrameLocked();
1115
Craig Mautnera91f9e22012-09-14 16:22:08 -07001116 setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001117
Craig Mautner918b53b2012-07-09 14:15:54 -07001118 if (mIsWallpaper && !mWin.mWallpaperVisible) {
Craig Mautner0fa77c12012-06-11 15:57:19 -07001119 // Wallpaper is no longer visible and there is no wp target => hide it.
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001120 hide("prepareSurfaceLocked");
Wale Ogunwale9d147902016-07-16 11:58:55 -07001121 } else if (w.isParentWindowHidden() || !w.isOnScreen()) {
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001122 hide("prepareSurfaceLocked");
Wale Ogunwalee8069dc2015-08-18 09:52:01 -07001123 mWallpaperControllerLocked.hideWallpapers(w);
Craig Mautnerb9836b92012-06-11 11:40:09 -07001124
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001125 // If we are waiting for this window to handle an orientation change. If this window is
1126 // really hidden (gone for layout), there is no point in still waiting for it.
1127 // Note that this does introduce a potential glitch if the window becomes unhidden
1128 // before it has drawn for the new orientation.
Bryce Lee8c3cf382017-07-06 19:47:10 -07001129 if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
1130 w.setOrientationChanging(false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001131 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001132 "Orientation change skips hidden " + w);
1133 }
1134 } else if (mLastLayer != mAnimLayer
1135 || mLastAlpha != mShownAlpha
1136 || 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;
1145 mLastLayer = mAnimLayer;
1146 mLastDsDx = mDsDx;
1147 mLastDtDx = mDtDx;
1148 mLastDsDy = mDsDy;
1149 mLastDtDy = mDtDy;
1150 w.mLastHScale = w.mHScale;
1151 w.mLastVScale = w.mVScale;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001152 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
Robert Carre6a83512015-11-03 16:09:21 -08001153 "controller=" + mSurfaceController +
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001154 "alpha=" + mShownAlpha + " layer=" + mAnimLayer
Craig Mautner78505d82014-09-02 14:36:31 -07001155 + " matrix=[" + mDsDx + "*" + w.mHScale
1156 + "," + mDtDx + "*" + w.mVScale
Robert Carr0edf18f2017-02-21 20:01:47 -08001157 + "][" + mDtDy + "*" + w.mHScale
1158 + "," + mDsDy + "*" + w.mVScale + "]", false);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001159
Robert Carre6a83512015-11-03 16:09:21 -08001160 boolean prepared =
Robert Carraf422a82017-04-10 18:34:33 -07001161 mSurfaceController.prepareToShowInTransaction(mShownAlpha,
Robert Carr04092112016-06-02 12:56:12 -07001162 mDsDx * w.mHScale * mExtraHScale,
1163 mDtDx * w.mVScale * mExtraVScale,
Robert Carr0edf18f2017-02-21 20:01:47 -08001164 mDtDy * w.mHScale * mExtraHScale,
1165 mDsDy * w.mVScale * mExtraVScale,
Robert Carre6a83512015-11-03 16:09:21 -08001166 recoveringMemory);
1167
Robert Carr03206af2017-07-10 18:24:21 -07001168 if (prepared && mDrawState == HAS_DRAWN) {
1169 if (mLastHidden) {
1170 if (showSurfaceRobustlyLocked()) {
1171 markPreservedSurfaceForDestroy();
1172 mAnimator.requestRemovalOfReplacedWindows(w);
1173 mLastHidden = false;
1174 if (mIsWallpaper) {
1175 w.dispatchWallpaperVisibility(true);
1176 }
1177 // This draw means the difference between unique content and mirroring.
1178 // Run another pass through performLayout to set mHasContent in the
1179 // LogicalDisplay.
1180 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
Jorim Jaggia5e10572017-11-15 14:36:26 +01001181 FINISH_LAYOUT_REDO_ANIM);
Robert Carr03206af2017-07-10 18:24:21 -07001182 } else {
1183 w.setOrientationChanging(false);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001184 }
Robert Carr03206af2017-07-10 18:24:21 -07001185 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001186 }
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001187 if (hasSurface()) {
Robert Carre6a83512015-11-03 16:09:21 -08001188 w.mToken.hasVisible = true;
1189 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001190 } else {
Jorim Jaggi5c80c412016-04-19 20:03:47 -07001191 if (DEBUG_ANIM && isAnimationSet()) {
Chong Zhange05db742016-02-16 16:58:37 -08001192 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
Craig Mautner83339b42012-05-01 22:13:23 -07001193 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001194 displayed = true;
1195 }
1196
Bryce Lee8c3cf382017-07-06 19:47:10 -07001197 if (w.getOrientationChanging()) {
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001198 if (!w.isDrawnLw()) {
1199 mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
1200 mAnimator.mLastWindowFreezeSource = w;
1201 if (DEBUG_ORIENTATION) Slog.v(TAG,
1202 "Orientation continue waiting for draw in " + w);
1203 } else {
Bryce Lee8c3cf382017-07-06 19:47:10 -07001204 w.setOrientationChanging(false);
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001205 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001206 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001207 }
1208
1209 if (displayed) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001210 w.mToken.hasVisible = true;
1211 }
1212 }
1213
Craig Mautneref655012013-01-03 11:20:24 -08001214 void setTransparentRegionHintLocked(final Region region) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001215 if (mSurfaceController == null) {
1216 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
1217 return;
1218 }
Robert Carre6a83512015-11-03 16:09:21 -08001219 mSurfaceController.setTransparentRegionHint(region);
Craig Mautner48ba1e72012-04-02 13:18:16 -07001220 }
1221
Robert Carr217e7cc2018-01-31 18:08:39 -08001222 boolean setWallpaperOffset(int dx, int dy) {
1223 if (mXOffset == dx && mYOffset == dy) {
1224 return false;
1225 }
1226 mXOffset = dx;
1227 mYOffset = dy;
Robert Carre6a83512015-11-03 16:09:21 -08001228
1229 try {
Craig Mautner71dd1b62014-02-18 15:48:52 -08001230 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
Robert Carr68e5c9e2016-09-14 10:50:09 -07001231 mService.openSurfaceTransaction();
Robert Carr217e7cc2018-01-31 18:08:39 -08001232 mSurfaceController.setPositionInTransaction(dx, dy, false);
chaviw23012112017-12-20 15:29:04 -08001233 applyCrop(null, false);
Robert Carre6a83512015-11-03 16:09:21 -08001234 } catch (RuntimeException e) {
1235 Slog.w(TAG, "Error positioning surface of " + mWin
Robert Carr217e7cc2018-01-31 18:08:39 -08001236 + " pos=(" + dx + "," + dy + ")", e);
Robert Carre6a83512015-11-03 16:09:21 -08001237 } finally {
Adrian Roos111aff92017-09-27 18:11:46 +02001238 mService.closeSurfaceTransaction("setWallpaperOffset");
Robert Carre6a83512015-11-03 16:09:21 -08001239 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1240 "<<< CLOSE TRANSACTION setWallpaperOffset");
Robert Carr217e7cc2018-01-31 18:08:39 -08001241 return true;
Craig Mautner48ba1e72012-04-02 13:18:16 -07001242 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001243 }
1244
John Reck80181b92015-05-19 11:09:32 -07001245 /**
1246 * Try to change the pixel format without recreating the surface. This
1247 * will be common in the case of changing from PixelFormat.OPAQUE to
1248 * PixelFormat.TRANSLUCENT in the hardware-accelerated case as both
1249 * requested formats resolve to the same underlying SurfaceControl format
1250 * @return True if format was succesfully changed, false otherwise
1251 */
1252 boolean tryChangeFormatInPlaceLocked() {
Robert Carre6a83512015-11-03 16:09:21 -08001253 if (mSurfaceController == null) {
John Reck80181b92015-05-19 11:09:32 -07001254 return false;
1255 }
1256 final LayoutParams attrs = mWin.getAttrs();
Wale Ogunwalee7bf46b2015-09-30 09:19:28 -07001257 final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
John Reck80181b92015-05-19 11:09:32 -07001258 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
1259 if (format == mSurfaceFormat) {
1260 setOpaqueLocked(!PixelFormat.formatHasAlpha(attrs.format));
1261 return true;
1262 }
1263 return false;
1264 }
1265
Craig Mautner6f612042014-09-07 13:13:23 -07001266 void setOpaqueLocked(boolean isOpaque) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001267 if (mSurfaceController == null) {
1268 return;
1269 }
Robert Carre6a83512015-11-03 16:09:21 -08001270 mSurfaceController.setOpaque(isOpaque);
Craig Mautner71dd1b62014-02-18 15:48:52 -08001271 }
1272
Wale Ogunwalef5ad42f2015-06-12 13:59:03 -07001273 void setSecureLocked(boolean isSecure) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001274 if (mSurfaceController == null) {
1275 return;
1276 }
Robert Carre6a83512015-11-03 16:09:21 -08001277 mSurfaceController.setSecure(isSecure);
Wale Ogunwalef5ad42f2015-06-12 13:59:03 -07001278 }
1279
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001280 /**
1281 * Have the surface flinger show a surface, robustly dealing with
1282 * error conditions. In particular, if there is not enough memory
1283 * to show the surface, then we will try to get rid of other surfaces
1284 * in order to succeed.
1285 *
1286 * @return Returns true if the surface was successfully shown.
1287 */
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001288 private boolean showSurfaceRobustlyLocked() {
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001289 if (mWin.getWindowConfiguration().windowsAreScaleable()) {
Robert Carr1b5ea722016-04-20 13:23:28 -07001290 mSurfaceController.forceScaleableInTransaction(true);
1291 }
1292
Robert Carre6a83512015-11-03 16:09:21 -08001293 boolean shown = mSurfaceController.showRobustlyInTransaction();
1294 if (!shown)
1295 return false;
1296
Robert Carr849d2932018-05-01 12:14:48 -07001297 // If we had a preserved surface it's no longer needed, and it may be harmful
1298 // if we are transparent.
1299 if (mPendingDestroySurface != null && mDestroyPreservedSurfaceUponRedraw) {
1300 mPendingDestroySurface.mSurfaceControl.hide();
Robert Carrba993782018-05-15 15:16:40 -07001301 mPendingDestroySurface.reparentChildrenInTransaction(mSurfaceController);
Robert Carr849d2932018-05-01 12:14:48 -07001302 }
1303
Robert Carre6a83512015-11-03 16:09:21 -08001304 return true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001305 }
1306
1307 void applyEnterAnimationLocked() {
Robert Carrb439a632016-04-07 22:52:10 -07001308 // If we are the new part of a window replacement transition and we have requested
1309 // not to animate, we instead want to make it seamless, so we don't want to apply
1310 // an enter transition.
1311 if (mWin.mSkipEnterAnimationForSeamlessReplacement) {
1312 return;
1313 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001314 final int transit;
1315 if (mEnterAnimationPending) {
1316 mEnterAnimationPending = false;
1317 transit = WindowManagerPolicy.TRANSIT_ENTER;
1318 } else {
1319 transit = WindowManagerPolicy.TRANSIT_SHOW;
1320 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001321 applyAnimationLocked(transit, true);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08001322 //TODO (multidisplay): Magnification is supported only for the default display.
Svetoslav8e3feb12014-02-24 13:46:47 -08001323 if (mService.mAccessibilityController != null
Filip Gruszczynski69cbc352015-11-11 13:46:04 -08001324 && mWin.getDisplayId() == DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08001325 mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07001326 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001327 }
1328
1329 /**
1330 * Choose the correct animation and set it to the passed WindowState.
Craig Mautner4b71aa12012-12-27 17:20:01 -08001331 * @param transit If AppTransition.TRANSIT_PREVIEW_DONE and the app window has been drawn
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001332 * then the animation will be app_starting_exit. Any other value loads the animation from
1333 * the switch statement below.
1334 * @param isEntrance The animation type the last time this was called. Used to keep from
1335 * loading the same animation twice.
1336 * @return true if an animation has been loaded.
1337 */
1338 boolean applyAnimationLocked(int transit, boolean isEntrance) {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001339 if (mWin.isSelfAnimating() && mAnimationIsEntrance == isEntrance) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001340 // If we are trying to apply an animation, but already running
Jorim Jaggif8d77da2014-11-11 16:59:12 +01001341 // an animation of the same type, then just leave that one alone.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001342 return true;
1343 }
1344
Jorim Jaggia5e10572017-11-15 14:36:26 +01001345 if (isEntrance && mWin.mAttrs.type == TYPE_INPUT_METHOD) {
1346 mWin.getDisplayContent().adjustForImeIfNeeded();
1347 mWin.setDisplayLayoutNeeded();
1348 mService.mWindowPlacerLocked.requestTraversal();
1349 }
1350
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001351 // Only apply an animation if the display isn't frozen. If it is
1352 // frozen, there is no reason to animate and it can cause strange
1353 // artifacts when we unfreeze the display if some different animation
1354 // is running.
Chong Zhang8784be62016-06-28 15:25:07 -07001355 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#applyAnimationLocked");
David Stevens9440dc82017-03-16 19:00:20 -07001356 if (mWin.mToken.okToAnimate()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001357 int anim = mPolicy.selectAnimationLw(mWin, transit);
1358 int attr = -1;
1359 Animation a = null;
1360 if (anim != 0) {
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07001361 a = anim != -1 ? AnimationUtils.loadAnimation(mContext, anim) : null;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001362 } else {
1363 switch (transit) {
1364 case WindowManagerPolicy.TRANSIT_ENTER:
1365 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
1366 break;
1367 case WindowManagerPolicy.TRANSIT_EXIT:
1368 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
1369 break;
1370 case WindowManagerPolicy.TRANSIT_SHOW:
1371 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
1372 break;
1373 case WindowManagerPolicy.TRANSIT_HIDE:
1374 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
1375 break;
1376 }
1377 if (attr >= 0) {
Jorim Jaggi0a1523d2018-04-19 17:48:38 +02001378 a = mService.mAppTransition.loadAnimationAttr(mWin.mAttrs, attr, TRANSIT_NONE);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001379 }
1380 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001381 if (DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001382 "applyAnimation: win=" + this
1383 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
Craig Mautner4d7349b2012-04-20 14:52:47 -07001384 + " a=" + a
Craig Mautner8863cca2012-09-18 15:04:34 -07001385 + " transit=" + transit
Craig Mautner83339b42012-05-01 22:13:23 -07001386 + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001387 if (a != null) {
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -08001388 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
Jorim Jaggia5e10572017-11-15 14:36:26 +01001389 mWin.startAnimation(a);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001390 mAnimationIsEntrance = isEntrance;
1391 }
1392 } else {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001393 mWin.cancelAnimation();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001394 }
Chong Zhang8784be62016-06-28 15:25:07 -07001395
Jorim Jaggia5e10572017-11-15 14:36:26 +01001396 if (!isEntrance && mWin.mAttrs.type == TYPE_INPUT_METHOD) {
Wale Ogunwale360a8bc2016-10-10 13:25:26 -07001397 mWin.getDisplayContent().adjustForImeIfNeeded();
Jorim Jaggieb88d832016-04-13 20:17:43 -07001398 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001399
Jorim Jaggia5e10572017-11-15 14:36:26 +01001400 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1401 return isAnimationSet();
Jorim Jaggif8d77da2014-11-11 16:59:12 +01001402 }
1403
Steven Timotiusaf03df62017-07-18 16:56:43 -07001404 void writeToProto(ProtoOutputStream proto, long fieldId) {
1405 final long token = proto.start(fieldId);
1406 mLastClipRect.writeToProto(proto, LAST_CLIP_RECT);
1407 if (mSurfaceController != null) {
1408 mSurfaceController.writeToProto(proto, SURFACE);
1409 }
Vishnu Nair1d0fa072018-01-04 07:53:00 -08001410 proto.write(DRAW_STATE, mDrawState);
1411 mSystemDecorRect.writeToProto(proto, SYSTEM_DECOR_RECT);
Steven Timotiusaf03df62017-07-18 16:56:43 -07001412 proto.end(token);
1413 }
1414
Craig Mautnera2c77052012-03-26 12:14:43 -07001415 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001416 if (mAnimationIsEntrance) {
1417 pw.print(prefix); pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
Craig Mautnera2c77052012-03-26 12:14:43 -07001418 }
Robert Carre6a83512015-11-03 16:09:21 -08001419 if (mSurfaceController != null) {
1420 mSurfaceController.dump(pw, prefix, dumpAll);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001421 }
Robert Carre6a83512015-11-03 16:09:21 -08001422 if (dumpAll) {
1423 pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString());
1424 pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden);
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -08001425 pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001426 pw.print(" mLastClipRect="); mLastClipRect.printShortString(pw);
1427
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001428 if (!mLastFinalClipRect.isEmpty()) {
1429 pw.print(" mLastFinalClipRect="); mLastFinalClipRect.printShortString(pw);
1430 }
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -08001431 pw.println();
Robert Carre6a83512015-11-03 16:09:21 -08001432 }
1433
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001434 if (mPendingDestroySurface != null) {
1435 pw.print(prefix); pw.print("mPendingDestroySurface=");
1436 pw.println(mPendingDestroySurface);
1437 }
1438 if (mSurfaceResized || mSurfaceDestroyDeferred) {
1439 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1440 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1441 }
1442 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1443 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1444 pw.print(" mAlpha="); pw.print(mAlpha);
1445 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1446 }
1447 if (mHaveMatrix || mWin.mGlobalScale != 1) {
1448 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
1449 pw.print(" mDsDx="); pw.print(mDsDx);
1450 pw.print(" mDtDx="); pw.print(mDtDx);
Robert Carr0edf18f2017-02-21 20:01:47 -08001451 pw.print(" mDtDy="); pw.print(mDtDy);
1452 pw.print(" mDsDy="); pw.println(mDsDy);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001453 }
Jorim Jaggiff71d202016-04-14 13:12:36 -07001454 if (mAnimationStartDelayed) {
1455 pw.print(prefix); pw.print("mAnimationStartDelayed="); pw.print(mAnimationStartDelayed);
1456 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001457 }
1458
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001459 @Override
1460 public String toString() {
Dianne Hackborn529e7442012-11-01 14:22:28 -07001461 StringBuffer sb = new StringBuffer("WindowStateAnimator{");
1462 sb.append(Integer.toHexString(System.identityHashCode(this)));
1463 sb.append(' ');
1464 sb.append(mWin.mAttrs.getTitle());
1465 sb.append('}');
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001466 return sb.toString();
1467 }
Robert Carre6a83512015-11-03 16:09:21 -08001468
1469 void reclaimSomeSurfaceMemory(String operation, boolean secure) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001470 mService.mRoot.reclaimSomeSurfaceMemory(this, operation, secure);
Robert Carre6a83512015-11-03 16:09:21 -08001471 }
1472
1473 boolean getShown() {
1474 if (mSurfaceController != null) {
1475 return mSurfaceController.getShown();
1476 }
1477 return false;
1478 }
1479
1480 void destroySurface() {
Wale Ogunwale722ff892016-02-18 13:37:55 -08001481 try {
1482 if (mSurfaceController != null) {
Robert Carra8828862018-02-05 16:17:36 -08001483 mSurfaceController.destroyNotInTransaction();
Wale Ogunwale722ff892016-02-18 13:37:55 -08001484 }
1485 } catch (RuntimeException e) {
1486 Slog.w(TAG, "Exception thrown when destroying surface " + this
1487 + " surface " + mSurfaceController + " session " + mSession + ": " + e);
1488 } finally {
1489 mWin.setHasSurface(false);
1490 mSurfaceController = null;
1491 mDrawState = NO_SURFACE;
1492 }
Robert Carre6a83512015-11-03 16:09:21 -08001493 }
Filip Gruszczynskif52dd202015-11-15 20:36:38 -08001494
Robert Carrae606b42018-02-15 15:36:23 -08001495 void seamlesslyRotateWindow(SurfaceControl.Transaction t,
1496 int oldRotation, int newRotation) {
Robert Carr6da3cc02016-06-16 15:17:07 -07001497 final WindowState w = mWin;
1498 if (!w.isVisibleNow() || w.mIsWallpaper) {
1499 return;
1500 }
1501
1502 final Rect cropRect = mService.mTmpRect;
1503 final Rect displayRect = mService.mTmpRect2;
1504 final RectF frameRect = mService.mTmpRectF;
1505 final Matrix transform = mService.mTmpTransform;
1506
1507 final float x = w.mFrame.left;
1508 final float y = w.mFrame.top;
1509 final float width = w.mFrame.width();
1510 final float height = w.mFrame.height();
1511
Bryce Leef3c6a472017-11-14 14:53:06 -08001512 mService.getDefaultDisplayContentLocked().getBounds(displayRect);
Robert Carr6da3cc02016-06-16 15:17:07 -07001513 final float displayWidth = displayRect.width();
1514 final float displayHeight = displayRect.height();
1515
1516 // Compute a transform matrix to undo the coordinate space transformation,
1517 // and present the window at the same physical position it previously occupied.
1518 final int deltaRotation = DisplayContent.deltaRotation(newRotation, oldRotation);
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07001519 DisplayContent.createRotationMatrix(deltaRotation, x, y, displayWidth, displayHeight,
1520 transform);
Robert Carr6da3cc02016-06-16 15:17:07 -07001521
Robert Carr897215d2017-03-29 12:25:50 -07001522 // We just need to apply a rotation matrix to the window. For example
1523 // if we have a portrait window and rotate to landscape, the window is still portrait
1524 // and now extends off the bottom of the screen (and only halfway across). Essentially we
1525 // apply a transform to display the current buffer at it's old position
1526 // (in the new coordinate space). We then freeze layer updates until the resize
1527 // occurs, at which point we undo, them.
1528 mService.markForSeamlessRotation(w, true);
1529 transform.getValues(mService.mTmpFloats);
Robert Carr6da3cc02016-06-16 15:17:07 -07001530
Robert Carr897215d2017-03-29 12:25:50 -07001531 float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
1532 float DtDx = mService.mTmpFloats[Matrix.MSKEW_Y];
1533 float DtDy = mService.mTmpFloats[Matrix.MSKEW_X];
1534 float DsDy = mService.mTmpFloats[Matrix.MSCALE_Y];
1535 float nx = mService.mTmpFloats[Matrix.MTRANS_X];
1536 float ny = mService.mTmpFloats[Matrix.MTRANS_Y];
Robert Carr19cdd092018-03-14 11:50:52 -07001537 mSurfaceController.setPosition(t, nx, ny, false);
1538 mSurfaceController.setMatrix(t, DsDx * w.mHScale, DtDx * w.mVScale, DtDy
1539 * w.mHScale, DsDy * w.mVScale, false);
Robert Carr6da3cc02016-06-16 15:17:07 -07001540 }
Robert Carr3b716242016-08-16 16:02:21 -07001541
Robert Carr8f0a3ad2017-02-15 19:30:28 -08001542 /** The force-scaled state for a given window can persist past
1543 * the state for it's stack as the windows complete resizing
1544 * independently of one another.
1545 */
1546 boolean isForceScaled() {
1547 final Task task = mWin.getTask();
1548 if (task != null && task.mStack.isForceScaled()) {
1549 return true;
1550 }
1551 return mForceScaleUntilResize;
1552 }
Robert Carrd5c7dd62017-03-08 10:39:30 -08001553
1554 void detachChildren() {
1555 if (mSurfaceController != null) {
1556 mSurfaceController.detachChildren();
1557 }
Robert Carr7b3d11d2018-03-15 14:34:45 -07001558 mChildrenDetached = true;
Robert Carrd5c7dd62017-03-08 10:39:30 -08001559 }
Jorim Jaggia5e10572017-11-15 14:36:26 +01001560
1561 int getLayer() {
1562 return mLastLayer;
1563 }
chaviwbe43ac82018-04-04 15:14:49 -07001564
1565 void setOffsetPositionForStackResize(boolean offsetPositionForStackResize) {
1566 mOffsetPositionForStackResize = offsetPositionForStackResize;
1567 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001568}