blob: 1cfa95625a88d460492a4865432b1b083a2a77a4 [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 Jaggia5e10572017-11-15 14:36:26 +010026import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
27import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Jorim Jaggi0b46f3c2016-03-14 12:21:37 +010028import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080029import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080030import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
31import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
32import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
Jorim Jaggie4b0f282017-05-17 15:10:29 +020033import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080034import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -080035import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080036import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
37import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
38import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
39import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
40import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Chong Zhang97782b42015-10-07 16:01:23 -070041import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -080042import static com.android.server.wm.WindowManagerService.logWithStack;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070043import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
Vishnu Nair1d0fa072018-01-04 07:53:00 -080044import static com.android.server.wm.proto.WindowStateAnimatorProto.DRAW_STATE;
Steven Timotiusaf03df62017-07-18 16:56:43 -070045import static com.android.server.wm.proto.WindowStateAnimatorProto.LAST_CLIP_RECT;
46import static com.android.server.wm.proto.WindowStateAnimatorProto.SURFACE;
Vishnu Nair1d0fa072018-01-04 07:53:00 -080047import static com.android.server.wm.proto.WindowStateAnimatorProto.SYSTEM_DECOR_RECT;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -070048
Craig Mautnerc2f9be02012-03-27 17:32:29 -070049import android.content.Context;
50import android.graphics.Matrix;
51import android.graphics.PixelFormat;
Craig Mautner7358fbf2012-04-12 21:06:33 -070052import android.graphics.Point;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070053import android.graphics.Rect;
Robert Carr6da3cc02016-06-16 15:17:07 -070054import android.graphics.RectF;
Craig Mautner48ba1e72012-04-02 13:18:16 -070055import android.graphics.Region;
Craig Mautnera51a9562012-04-17 17:05:26 -070056import android.os.Debug;
Chong Zhang8784be62016-06-28 15:25:07 -070057import android.os.Trace;
Craig Mautnera2c77052012-03-26 12:14:43 -070058import android.util.Slog;
Steven Timotiusaf03df62017-07-18 16:56:43 -070059import android.util.proto.ProtoOutputStream;
Craig Mautner59c00972012-07-30 12:10:24 -070060import android.view.DisplayInfo;
Igor Murashkina86ab6402013-08-30 12:58:36 -070061import android.view.Surface.OutOfResourcesException;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080062import android.view.SurfaceControl;
Craig Mautnera2c77052012-03-26 12:14:43 -070063import android.view.WindowManager;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070064import android.view.WindowManager.LayoutParams;
Craig Mautnera2c77052012-03-26 12:14:43 -070065import android.view.animation.Animation;
Craig Mautnerc2f9be02012-03-27 17:32:29 -070066import android.view.animation.AnimationUtils;
Craig Mautnera2c77052012-03-26 12:14:43 -070067
Adrian Roose99bc052017-11-20 17:55:31 +010068import com.android.server.policy.WindowManagerPolicy;
69
Robert Carr3b716242016-08-16 16:02:21 -070070import java.io.FileDescriptor;
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;
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700102 private final WindowStateAnimator mParentWinAnimator;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700103 final WindowAnimator mAnimator;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700104 final Session mSession;
105 final WindowManagerPolicy mPolicy;
106 final Context mContext;
Craig Mautner918b53b2012-07-09 14:15:54 -0700107 final boolean mIsWallpaper;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700108 private final WallpaperController mWallpaperControllerLocked;
Craig Mautnera2c77052012-03-26 12:14:43 -0700109
Craig Mautnera2c77052012-03-26 12:14:43 -0700110 boolean mAnimationIsEntrance;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700111 int mAnimLayer;
112 int mLastLayer;
113
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700114 /**
115 * Set when we have changed the size of the surface, to know that
116 * we must tell them application to resize (and thus redraw itself).
117 */
118 boolean mSurfaceResized;
Chong Zhang5b2f1992015-11-13 15:40:36 -0800119 /**
120 * Whether we should inform the client on next relayoutWindow that
121 * the surface has been resized since last time.
122 */
123 boolean mReportSurfaceResized;
Robert Carre6a83512015-11-03 16:09:21 -0800124 WindowSurfaceController mSurfaceController;
Filip Gruszczynski10a80e02015-11-06 09:21:17 -0800125 private WindowSurfaceController mPendingDestroySurface;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700126
127 /**
128 * Set if the client has asked that the destroy of its surface be delayed
129 * until it explicitly says it is okay.
130 */
131 boolean mSurfaceDestroyDeferred;
132
Filip Gruszczynski10a80e02015-11-06 09:21:17 -0800133 private boolean mDestroyPreservedSurfaceUponRedraw;
Craig Mautner7d8df392012-04-06 15:26:23 -0700134 float mShownAlpha = 0;
135 float mAlpha = 0;
136 float mLastAlpha = 0;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700137
Winson Chung399f6202014-03-19 10:47:20 -0700138 boolean mHasClipRect;
139 Rect mClipRect = new Rect();
140 Rect mTmpClipRect = new Rect();
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100141 Rect mTmpFinalClipRect = new Rect();
Winson Chung399f6202014-03-19 10:47:20 -0700142 Rect mLastClipRect = new Rect();
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +0100143 Rect mLastFinalClipRect = new Rect();
Filip Gruszczynski4b8eea72015-09-14 18:16:19 -0700144 Rect mTmpStackBounds = new Rect();
Winson Chung08f81892017-03-02 15:40:51 -0800145 private Rect mTmpAnimatingBounds = new Rect();
146 private Rect mTmpSourceBounds = new Rect();
Winson Chung399f6202014-03-19 10:47:20 -0700147
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -0800148 /**
149 * This is rectangle of the window's surface that is not covered by
150 * system decorations.
151 */
152 private final Rect mSystemDecorRect = new Rect();
153 private final Rect mLastSystemDecorRect = new Rect();
154
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700155 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
Robert Carr0edf18f2017-02-21 20:01:47 -0800156 private float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700157
158 boolean mHaveMatrix;
159
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700160 // Set to true if, when the window gets displayed, it should perform
161 // an enter animation.
162 boolean mEnterAnimationPending;
Craig Mautnera2c77052012-03-26 12:14:43 -0700163
Craig Mautner9c795042014-10-28 19:59:59 -0700164 /** Used to indicate that this window is undergoing an enter animation. Used for system
165 * windows to make the callback to View.dispatchOnWindowShownCallback(). Set when the
166 * window is first added or shown, cleared when the callback has been made. */
167 boolean mEnteringAnimation;
168
Jorim Jaggiff71d202016-04-14 13:12:36 -0700169 private boolean mAnimationStartDelayed;
170
John Reck80181b92015-05-19 11:09:32 -0700171 /** The pixel format of the underlying SurfaceControl */
172 int mSurfaceFormat;
173
Craig Mautner749a7bb2012-04-02 13:49:53 -0700174 /** This is set when there is no Surface */
175 static final int NO_SURFACE = 0;
176 /** This is set after the Surface has been created but before the window has been drawn. During
177 * this time the surface is hidden. */
178 static final int DRAW_PENDING = 1;
179 /** This is set after the window has finished drawing for the first time but before its surface
180 * is shown. The surface will be displayed when the next layout is run. */
181 static final int COMMIT_DRAW_PENDING = 2;
182 /** This is set during the time after the window's drawing has been committed, and before its
183 * surface is actually shown. It is used to delay showing the surface until all windows in a
184 * token are ready to be shown. */
185 static final int READY_TO_SHOW = 3;
186 /** Set when the window has been shown in the screen the first time. */
187 static final int HAS_DRAWN = 4;
Adrian Roos3eeb4e62014-05-19 12:43:26 +0200188
Craig Mautner276a6eb2014-11-04 15:32:57 -0800189 String drawStateToString() {
190 switch (mDrawState) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700191 case NO_SURFACE: return "NO_SURFACE";
192 case DRAW_PENDING: return "DRAW_PENDING";
193 case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
194 case READY_TO_SHOW: return "READY_TO_SHOW";
195 case HAS_DRAWN: return "HAS_DRAWN";
Craig Mautner276a6eb2014-11-04 15:32:57 -0800196 default: return Integer.toString(mDrawState);
Craig Mautner6fbda632012-07-03 09:26:39 -0700197 }
198 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700199 int mDrawState;
Craig Mautnera608b882012-03-30 13:03:49 -0700200
Craig Mautner749a7bb2012-04-02 13:49:53 -0700201 /** Was this window last hidden? */
202 boolean mLastHidden;
Craig Mautnera608b882012-03-30 13:03:49 -0700203
Craig Mautnerbec53f72012-04-05 11:49:05 -0700204 int mAttrType;
205
Robert Carrc7294602016-05-13 11:32:05 -0700206 boolean mForceScaleUntilResize;
207
Robert Carr04092112016-06-02 12:56:12 -0700208 // WindowState.mHScale and WindowState.mVScale contain the
209 // scale according to client specified layout parameters (e.g.
210 // one layout size, with another surface size, creates such scaling).
211 // Here we track an additional scaling factor used to follow stack
212 // scaling (as in the case of the Pinned stack animation).
213 float mExtraHScale = (float) 1.0;
214 float mExtraVScale = (float) 1.0;
215
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800216 private final Rect mTmpSize = new Rect();
217
Craig Mautnerc431e892015-02-11 13:14:26 -0800218 WindowStateAnimator(final WindowState win) {
Craig Mautner918b53b2012-07-09 14:15:54 -0700219 final WindowManagerService service = win.mService;
220
Craig Mautnera2c77052012-03-26 12:14:43 -0700221 mService = service;
Craig Mautner918b53b2012-07-09 14:15:54 -0700222 mAnimator = service.mAnimator;
223 mPolicy = service.mPolicy;
224 mContext = service.mContext;
Craig Mautner918b53b2012-07-09 14:15:54 -0700225
226 mWin = win;
Wale Ogunwalecaa53af2016-07-17 14:50:26 -0700227 mParentWinAnimator = !win.isChildWindow() ? null : win.getParentWindow().mWinAnimator;
Craig Mautner918b53b2012-07-09 14:15:54 -0700228 mSession = win.mSession;
Craig Mautner918b53b2012-07-09 14:15:54 -0700229 mAttrType = win.mAttrs.type;
230 mIsWallpaper = win.mIsWallpaper;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700231 mWallpaperControllerLocked = mService.mRoot.mWallpaperController;
Craig Mautnera2c77052012-03-26 12:14:43 -0700232 }
233
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700234 /**
235 * Is the window or its container currently set to animate or currently animating?
236 */
237 boolean isAnimationSet() {
Jorim Jaggia5e10572017-11-15 14:36:26 +0100238 return mWin.isAnimating();
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700239 }
240
Craig Mautnera2c77052012-03-26 12:14:43 -0700241 void cancelExitAnimationForNextAnimationLocked() {
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800242 if (DEBUG_ANIM) Slog.d(TAG,
243 "cancelExitAnimationForNextAnimationLocked: " + mWin);
244
Jorim Jaggia5e10572017-11-15 14:36:26 +0100245 mWin.cancelAnimation();
246 mWin.destroySurfaceUnchecked();
Craig Mautnera2c77052012-03-26 12:14:43 -0700247 }
248
Jorim Jaggia5e10572017-11-15 14:36:26 +0100249 void onAnimationFinished() {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700250 // Done animating, clean up.
251 if (DEBUG_ANIM) Slog.v(
Jorim Jaggia5e10572017-11-15 14:36:26 +0100252 TAG, "Animation done in " + this + ": exiting=" + mWin.mAnimatingExit
253 + ", reportedVisible="
254 + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
Craig Mautnera2c77052012-03-26 12:14:43 -0700255
Craig Mautnere7ae2502012-03-26 17:11:19 -0700256 if (mAnimator.mWindowDetachedWallpaper == mWin) {
257 mAnimator.mWindowDetachedWallpaper = null;
Craig Mautnera2c77052012-03-26 12:14:43 -0700258 }
Jorim Jaggia5e10572017-11-15 14:36:26 +0100259
Filip Gruszczynski14b4e572015-11-03 15:53:55 -0800260 mWin.checkPolicyVisibilityChange();
Jorim Jaggia5e10572017-11-15 14:36:26 +0100261 final DisplayContent displayContent = mWin.getDisplayContent();
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800262 if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.mPolicyVisibility) {
Craig Mautner81defc72013-10-29 11:10:42 -0700263 // Upon completion of a not-visible to visible status bar animation a relayout is
264 // required.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800265 if (displayContent != null) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700266 displayContent.setLayoutNeeded();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800267 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700268 }
269
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700270 mWin.onExitAnimationDone();
Craig Mautnerdf88d732014-01-27 09:21:32 -0800271 final int displayId = mWin.getDisplayId();
Jorim Jaggia5e10572017-11-15 14:36:26 +0100272 int pendingLayoutChanges = FINISH_LAYOUT_REDO_ANIM;
273 if (displayContent.mWallpaperController.isWallpaperTarget(mWin)) {
274 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
275 }
276 mAnimator.setPendingLayoutChanges(displayId, pendingLayoutChanges);
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800277 if (DEBUG_LAYOUT_REPEATS)
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700278 mService.mWindowPlacerLocked.debugLayoutRepeats(
279 "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
Craig Mautnera2c77052012-03-26 12:14:43 -0700280
281 if (mWin.mAppToken != null) {
282 mWin.mAppToken.updateReportedVisibilityLocked();
283 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700284 }
285
Filip Gruszczynski63a35e22015-11-05 15:38:59 -0800286 void hide(String reason) {
Craig Mautner0afddcb2012-05-08 15:38:00 -0700287 if (!mLastHidden) {
288 //dump();
289 mLastHidden = true;
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800290 if (mSurfaceController != null) {
291 mSurfaceController.hideInTransaction(reason);
292 }
Craig Mautner0afddcb2012-05-08 15:38:00 -0700293 }
Craig Mautnera2c77052012-03-26 12:14:43 -0700294 }
295
Craig Mautnera608b882012-03-30 13:03:49 -0700296 boolean finishDrawingLocked() {
Craig Mautner42d04db2014-11-06 12:13:23 -0800297 final boolean startingWindow =
298 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
299 if (DEBUG_STARTING_WINDOW && startingWindow) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700300 Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
Craig Mautner276a6eb2014-11-04 15:32:57 -0800301 + drawStateToString());
Craig Mautner6fbda632012-07-03 09:26:39 -0700302 }
Robert Carr1ca6a332016-04-11 18:00:43 -0700303
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200304 boolean layoutNeeded = false;
Chong Zhang92147042016-05-09 12:47:11 -0700305
Craig Mautner749a7bb2012-04-02 13:49:53 -0700306 if (mDrawState == DRAW_PENDING) {
Robert Carre13b58e2017-08-31 14:50:44 -0700307 if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
Chong Zhang5b2f1992015-11-13 15:40:36 -0800308 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
Robert Carre6a83512015-11-03 16:09:21 -0800309 + mSurfaceController);
Craig Mautner42d04db2014-11-06 12:13:23 -0800310 if (DEBUG_STARTING_WINDOW && startingWindow) {
Craig Mautner6fbda632012-07-03 09:26:39 -0700311 Slog.v(TAG, "Draw state now committed in " + mWin);
312 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700313 mDrawState = COMMIT_DRAW_PENDING;
Chong Zhangcbbcc0f2016-05-17 20:46:58 -0700314 layoutNeeded = true;
Craig Mautnera608b882012-03-30 13:03:49 -0700315 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700316
Chong Zhangcbbcc0f2016-05-17 20:46:58 -0700317 return layoutNeeded;
Craig Mautnera608b882012-03-30 13:03:49 -0700318 }
319
320 // This must be called while inside a transaction.
Craig Mautnerc431e892015-02-11 13:14:26 -0800321 boolean commitFinishDrawingLocked() {
Jorim Jaggie4b0f282017-05-17 15:10:29 +0200322 if (DEBUG_STARTING_WINDOW_VERBOSE &&
Craig Mautner6fbda632012-07-03 09:26:39 -0700323 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
324 Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
Craig Mautner276a6eb2014-11-04 15:32:57 -0800325 + drawStateToString());
Craig Mautner6fbda632012-07-03 09:26:39 -0700326 }
Craig Mautner276a6eb2014-11-04 15:32:57 -0800327 if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
Craig Mautnera608b882012-03-30 13:03:49 -0700328 return false;
329 }
Robert Carre13b58e2017-08-31 14:50:44 -0700330 if (DEBUG_ANIM) {
Robert Carre6a83512015-11-03 16:09:21 -0800331 Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceController);
Craig Mautner6fbda632012-07-03 09:26:39 -0700332 }
Craig Mautner749a7bb2012-04-02 13:49:53 -0700333 mDrawState = READY_TO_SHOW;
Chong Zhang0275e392015-09-17 10:41:44 -0700334 boolean result = false;
Craig Mautnera608b882012-03-30 13:03:49 -0700335 final AppWindowToken atoken = mWin.mAppToken;
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800336 if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
Wale Ogunwale9d147902016-07-16 11:58:55 -0700337 result = mWin.performShowLocked();
Chong Zhang0275e392015-09-17 10:41:44 -0700338 }
Chong Zhang97782b42015-10-07 16:01:23 -0700339 return result;
Craig Mautnera608b882012-03-30 13:03:49 -0700340 }
341
Chong Zhang97782b42015-10-07 16:01:23 -0700342 void preserveSurfaceLocked() {
343 if (mDestroyPreservedSurfaceUponRedraw) {
Chong Zhangb9b0fec2016-02-11 18:51:51 -0800344 // This could happen when switching the surface mode very fast. For example,
345 // we preserved a surface when dragResizing changed to true. Then before the
346 // preserved surface is removed, dragResizing changed to false again.
347 // In this case, we need to leave the preserved surface alone, and destroy
348 // the actual surface, so that the createSurface call could create a surface
349 // of the proper size. The preserved surface will still be removed when client
350 // finishes drawing to the new surface.
351 mSurfaceDestroyDeferred = false;
352 destroySurfaceLocked();
353 mSurfaceDestroyDeferred = true;
Chong Zhang97782b42015-10-07 16:01:23 -0700354 return;
355 }
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -0800356 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "SET FREEZE LAYER", false);
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800357 if (mSurfaceController != null) {
Robert Carrb1579c82017-09-05 14:54:47 -0700358 // Our SurfaceControl is always at layer 0 within the parent Surface managed by
359 // window-state. We want this old Surface to stay on top of the new one
360 // until we do the swap, so we place it at layer 1.
361 mSurfaceController.mSurfaceControl.setLayer(1);
Wale Ogunwalef9e09782015-11-09 12:42:37 -0800362 }
Chong Zhang97782b42015-10-07 16:01:23 -0700363 mDestroyPreservedSurfaceUponRedraw = true;
364 mSurfaceDestroyDeferred = true;
365 destroySurfaceLocked();
366 }
367
368 void destroyPreservedSurfaceLocked() {
369 if (!mDestroyPreservedSurfaceUponRedraw) {
370 return;
371 }
Robert Carrd5c7dd62017-03-08 10:39:30 -0800372 if (mSurfaceController != null) {
373 if (mPendingDestroySurface != null) {
374 // If we are preserving a surface but we aren't relaunching that means
375 // we are just doing an in-place switch. In that case any SurfaceFlinger side
376 // child layers need to be reparented to the new surface to make this
377 // transparent to the app.
378 if (mWin.mAppToken == null || mWin.mAppToken.isRelaunching() == false) {
379 SurfaceControl.openTransaction();
380 mPendingDestroySurface.reparentChildrenInTransaction(mSurfaceController);
381 SurfaceControl.closeTransaction();
382 }
383 }
384 }
385
Chong Zhang97782b42015-10-07 16:01:23 -0700386 destroyDeferredSurfaceLocked();
387 mDestroyPreservedSurfaceUponRedraw = false;
388 }
389
Chong Zhangeb665572016-05-09 18:28:27 -0700390 void markPreservedSurfaceForDestroy() {
391 if (mDestroyPreservedSurfaceUponRedraw
392 && !mService.mDestroyPreservedSurface.contains(mWin)) {
393 mService.mDestroyPreservedSurface.add(mWin);
394 }
395 }
396
Robert Carrda61ba92017-03-29 15:52:23 -0700397 private int getLayerStack() {
398 return mWin.getDisplayContent().getDisplay().getLayerStack();
399 }
400
Robert Carrecc06b32017-04-18 14:25:10 -0700401 void resetDrawState() {
402 mDrawState = DRAW_PENDING;
403
404 if (mWin.mAppToken == null) {
405 return;
406 }
407
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200408 if (!mWin.mAppToken.isSelfAnimating()) {
Robert Carrecc06b32017-04-18 14:25:10 -0700409 mWin.mAppToken.clearAllDrawn();
410 } else {
411 // Currently animating, persist current state of allDrawn until animation
412 // is complete.
413 mWin.mAppToken.deferClearAllDrawn = true;
414 }
415 }
416
Albert Chaulk3bf2e572016-11-22 13:59:19 -0500417 WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
Alan Viveretteccb11e12014-07-08 16:04:02 -0700418 final WindowState w = mWin;
Chong Zhanga8975bd2016-01-28 17:13:47 -0800419
Wale Ogunwale722ff892016-02-18 13:37:55 -0800420 if (mSurfaceController != null) {
421 return mSurfaceController;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700422 }
Wale Ogunwale722ff892016-02-18 13:37:55 -0800423
Robert Carr132c9f52017-07-31 17:02:30 -0700424 if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
425 windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT;
426 }
427
Wale Ogunwale722ff892016-02-18 13:37:55 -0800428 w.setHasSurface(false);
429
430 if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
431 "createSurface " + this + ": mDrawState=DRAW_PENDING");
432
Robert Carrecc06b32017-04-18 14:25:10 -0700433 resetDrawState();
Wale Ogunwale722ff892016-02-18 13:37:55 -0800434
435 mService.makeWindowFreezingScreenIfNeededLocked(w);
436
437 int flags = SurfaceControl.HIDDEN;
438 final WindowManager.LayoutParams attrs = w.mAttrs;
439
440 if (mService.isSecureLocked(w)) {
441 flags |= SurfaceControl.SECURE;
442 }
443
444 mTmpSize.set(w.mFrame.left + w.mXOffset, w.mFrame.top + w.mYOffset, 0, 0);
445 calculateSurfaceBounds(w, attrs);
446 final int width = mTmpSize.width();
447 final int height = mTmpSize.height();
448
449 if (DEBUG_VISIBILITY) {
450 Slog.v(TAG, "Creating surface in session "
451 + mSession.mSurfaceSession + " window " + this
452 + " w=" + width + " h=" + height
453 + " x=" + mTmpSize.left + " y=" + mTmpSize.top
454 + " format=" + attrs.format + " flags=" + flags);
455 }
456
457 // We may abort, so initialize to defaults.
458 mLastSystemDecorRect.set(0, 0, 0, 0);
459 mHasClipRect = false;
460 mClipRect.set(0, 0, 0, 0);
461 mLastClipRect.set(0, 0, 0, 0);
462
463 // Set up surface control with initial size.
464 try {
465
466 final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
467 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
468 if (!PixelFormat.formatHasAlpha(attrs.format)
469 // Don't make surface with surfaceInsets opaque as they display a
470 // translucent shadow.
471 && attrs.surfaceInsets.left == 0
472 && attrs.surfaceInsets.top == 0
473 && attrs.surfaceInsets.right == 0
474 && attrs.surfaceInsets.bottom == 0
475 // Don't make surface opaque when resizing to reduce the amount of
476 // artifacts shown in areas the app isn't drawing content to.
477 && !w.isDragResizing()) {
478 flags |= SurfaceControl.OPAQUE;
479 }
480
481 mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
Jorim Jaggia5e10572017-11-15 14:36:26 +0100482 attrs.getTitle().toString(), width, height, format, flags, this,
483 windowType, ownerUid);
Robert Carr486bbb72017-05-30 11:25:22 -0700484 mSurfaceFormat = format;
Wale Ogunwale722ff892016-02-18 13:37:55 -0800485
486 w.setHasSurface(true);
487
488 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
489 Slog.i(TAG, " CREATE SURFACE "
490 + mSurfaceController + " IN SESSION "
491 + mSession.mSurfaceSession
492 + ": pid=" + mSession.mPid + " format="
493 + attrs.format + " flags=0x"
494 + Integer.toHexString(flags)
495 + " / " + this);
496 }
497 } catch (OutOfResourcesException e) {
498 Slog.w(TAG, "OutOfResourcesException creating surface");
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700499 mService.mRoot.reclaimSomeSurfaceMemory(this, "create", true);
Wale Ogunwale722ff892016-02-18 13:37:55 -0800500 mDrawState = NO_SURFACE;
501 return null;
502 } catch (Exception e) {
503 Slog.e(TAG, "Exception creating surface", e);
504 mDrawState = NO_SURFACE;
505 return null;
506 }
507
508 if (WindowManagerService.localLOGV) Slog.v(TAG, "Got surface: " + mSurfaceController
509 + ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
510 + ", animLayer=" + mAnimLayer);
511
512 if (SHOW_LIGHT_TRANSACTIONS) {
513 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
514 WindowManagerService.logSurface(w, "CREATE pos=("
515 + w.mFrame.left + "," + w.mFrame.top + ") ("
516 + width + "x" + height + "), layer=" + mAnimLayer + " HIDE", false);
517 }
518
Wale Ogunwale722ff892016-02-18 13:37:55 -0800519 mLastHidden = true;
520
521 if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this);
Robert Carre6a83512015-11-03 16:09:21 -0800522 return mSurfaceController;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700523 }
524
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800525 private void calculateSurfaceBounds(WindowState w, LayoutParams attrs) {
526 if ((attrs.flags & FLAG_SCALED) != 0) {
527 // For a scaled surface, we always want the requested size.
528 mTmpSize.right = mTmpSize.left + w.mRequestedWidth;
529 mTmpSize.bottom = mTmpSize.top + w.mRequestedHeight;
530 } else {
531 // When we're doing a drag-resizing, request a surface that's fullscreen size,
532 // so that we don't need to reallocate during the process. This also prevents
533 // buffer drops due to size mismatch.
534 if (w.isDragResizing()) {
535 if (w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM) {
536 mTmpSize.left = 0;
537 mTmpSize.top = 0;
538 }
539 final DisplayInfo displayInfo = w.getDisplayInfo();
540 mTmpSize.right = mTmpSize.left + displayInfo.logicalWidth;
541 mTmpSize.bottom = mTmpSize.top + displayInfo.logicalHeight;
542 } else {
543 mTmpSize.right = mTmpSize.left + w.mCompatFrame.width();
544 mTmpSize.bottom = mTmpSize.top + w.mCompatFrame.height();
545 }
546 }
547
548 // Something is wrong and SurfaceFlinger will not like this, try to revert to sane values.
Filip Gruszczynskie6ed1952015-12-21 09:34:16 -0800549 // This doesn't necessarily mean that there is an error in the system. The sizes might be
550 // incorrect, because it is before the first layout or draw.
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800551 if (mTmpSize.width() < 1) {
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800552 mTmpSize.right = mTmpSize.left + 1;
553 }
554 if (mTmpSize.height() < 1) {
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800555 mTmpSize.bottom = mTmpSize.top + 1;
556 }
557
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800558 // Adjust for surface insets.
Phil Weavera4b32b92016-06-02 13:55:39 -0700559 mTmpSize.left -= attrs.surfaceInsets.left;
560 mTmpSize.top -= attrs.surfaceInsets.top;
561 mTmpSize.right += attrs.surfaceInsets.right;
562 mTmpSize.bottom += attrs.surfaceInsets.bottom;
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800563 }
564
Chong Zhangeb22e8e2016-01-20 19:52:22 -0800565 boolean hasSurface() {
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200566 return mSurfaceController != null && mSurfaceController.hasSurface();
Chong Zhangeb22e8e2016-01-20 19:52:22 -0800567 }
568
Craig Mautner96868332012-12-04 14:29:11 -0800569 void destroySurfaceLocked() {
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700570 final AppWindowToken wtoken = mWin.mAppToken;
571 if (wtoken != null) {
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700572 if (mWin == wtoken.startingWindow) {
573 wtoken.startingDisplayed = false;
574 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700575 }
576
Wale Ogunwale722ff892016-02-18 13:37:55 -0800577 if (mSurfaceController == null) {
578 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700579 }
Wale Ogunwale722ff892016-02-18 13:37:55 -0800580
Wale Ogunwale722ff892016-02-18 13:37:55 -0800581 // When destroying a surface we want to make sure child windows are hidden. If we are
582 // preserving the surface until redraw though we intend to swap it out with another surface
583 // for resizing. In this case the window always remains visible to the user and the child
584 // windows should likewise remain visible.
Wale Ogunwale9d147902016-07-16 11:58:55 -0700585 if (!mDestroyPreservedSurfaceUponRedraw) {
586 mWin.mHidden = true;
Wale Ogunwale722ff892016-02-18 13:37:55 -0800587 }
588
589 try {
590 if (DEBUG_VISIBILITY) logWithStack(TAG, "Window " + this + " destroying surface "
591 + mSurfaceController + ", session " + mSession);
592 if (mSurfaceDestroyDeferred) {
593 if (mSurfaceController != null && mPendingDestroySurface != mSurfaceController) {
594 if (mPendingDestroySurface != null) {
595 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
596 WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
597 }
598 mPendingDestroySurface.destroyInTransaction();
599 }
600 mPendingDestroySurface = mSurfaceController;
601 }
602 } else {
603 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
604 WindowManagerService.logSurface(mWin, "DESTROY", true);
605 }
606 destroySurface();
607 }
608 // Don't hide wallpaper if we're deferring the surface destroy
609 // because of a surface change.
610 if (!mDestroyPreservedSurfaceUponRedraw) {
611 mWallpaperControllerLocked.hideWallpapers(mWin);
612 }
613 } catch (RuntimeException e) {
614 Slog.w(TAG, "Exception thrown when destroying Window " + this
615 + " surface " + mSurfaceController + " session " + mSession + ": " + e.toString());
616 }
617
618 // Whether the surface was preserved (and copied to mPendingDestroySurface) or not, it
619 // needs to be cleared to match the WindowState.mHasSurface state. It is also necessary
620 // so it can be recreated successfully in mPendingDestroySurface case.
621 mWin.setHasSurface(false);
622 if (mSurfaceController != null) {
623 mSurfaceController.setShown(false);
624 }
625 mSurfaceController = null;
626 mDrawState = NO_SURFACE;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700627 }
628
Craig Mautner96868332012-12-04 14:29:11 -0800629 void destroyDeferredSurfaceLocked() {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700630 try {
631 if (mPendingDestroySurface != null) {
632 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -0800633 WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700634 }
Robert Carre6a83512015-11-03 16:09:21 -0800635 mPendingDestroySurface.destroyInTransaction();
Chong Zhang6e21cf42015-11-09 14:41:42 -0800636 // Don't hide wallpaper if we're destroying a deferred surface
637 // after a surface mode change.
638 if (!mDestroyPreservedSurfaceUponRedraw) {
639 mWallpaperControllerLocked.hideWallpapers(mWin);
640 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700641 }
642 } catch (RuntimeException e) {
Craig Mautnerd87946b2012-03-29 18:00:19 -0700643 Slog.w(TAG, "Exception thrown when destroying Window "
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700644 + this + " surface " + mPendingDestroySurface
645 + " session " + mSession + ": " + e.toString());
646 }
647 mSurfaceDestroyDeferred = false;
648 mPendingDestroySurface = null;
649 }
650
651 void computeShownFrameLocked() {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700652
Craig Mautnera91f9e22012-09-14 16:22:08 -0700653 final int displayId = mWin.getDisplayId();
654 final ScreenRotationAnimation screenRotationAnimation =
655 mAnimator.getScreenRotationAnimationLocked(displayId);
656 final boolean screenAnimation =
657 screenRotationAnimation != null && screenRotationAnimation.isAnimating();
Robert Carr2f0fe622015-09-25 14:56:38 -0700658
659 mHasClipRect = false;
Robert Carr44643c12017-09-27 14:57:38 -0700660 if (screenAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700661 // cache often used attributes locally
662 final Rect frame = mWin.mFrame;
663 final float tmpFloats[] = mService.mTmpFloats;
664 final Matrix tmpMatrix = mWin.mTmpMatrix;
665
666 // Compute the desired transformation.
Robert Carr44643c12017-09-27 14:57:38 -0700667 if (screenRotationAnimation.isRotating()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700668 // If we are doing a screen animation, the global rotation
669 // applied to windows can result in windows that are carefully
670 // aligned with each other to slightly separate, allowing you
671 // to see what is behind them. An unsightly mess. This...
672 // thing... magically makes it call good: scale each window
673 // slightly (two pixels larger in each dimension, from the
674 // window's center).
675 final float w = frame.width();
676 final float h = frame.height();
677 if (w>=1 && h>=1) {
678 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
679 } else {
680 tmpMatrix.reset();
681 }
682 } else {
683 tmpMatrix.reset();
684 }
Robert Carr44643c12017-09-27 14:57:38 -0700685
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700686 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
Robert Carr29d196f2017-11-28 12:39:46 -0800687
Jorim Jaggi9af095b2017-12-12 17:18:57 +0100688 // WindowState.prepareSurfaces expands for surface insets (in order they don't get
689 // clipped by the WindowState surface), so we need to go into the other direction here.
690 tmpMatrix.postTranslate(mWin.mXOffset + mWin.mAttrs.surfaceInsets.left,
691 mWin.mYOffset + mWin.mAttrs.surfaceInsets.top);
692
Matthew Ng34a06d12017-02-03 11:56:08 -0800693
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700694 // "convert" it into SurfaceFlinger's format
695 // (a 2x2 matrix + an offset)
696 // Here we must not transform the position of the surface
697 // since it is already included in the transformation.
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800698 //Slog.i(TAG_WM, "Transform: " + matrix);
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700699
700 mHaveMatrix = true;
701 tmpMatrix.getValues(tmpFloats);
702 mDsDx = tmpFloats[Matrix.MSCALE_X];
703 mDtDx = tmpFloats[Matrix.MSKEW_Y];
Robert Carr0edf18f2017-02-21 20:01:47 -0800704 mDtDy = tmpFloats[Matrix.MSKEW_X];
705 mDsDy = tmpFloats[Matrix.MSCALE_Y];
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700706 float x = tmpFloats[Matrix.MTRANS_X];
707 float y = tmpFloats[Matrix.MTRANS_Y];
Qiushi Han32fed962016-10-01 17:06:49 +0800708 mWin.mShownPosition.set(Math.round(x), Math.round(y));
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700709
710 // Now set the alpha... but because our current hardware
711 // can't do alpha transformation on a non-opaque surface,
712 // turn it off if we are running an animation that is also
713 // transforming since it is more important to have that
714 // animation be smooth.
715 mShownAlpha = mAlpha;
716 if (!mService.mLimitedAlphaCompositing
717 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
Robert Carr0edf18f2017-02-21 20:01:47 -0800718 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700719 && x == frame.left && y == frame.top))) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800720 //Slog.i(TAG_WM, "Applying alpha transform");
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700721 if (screenAnimation) {
Craig Mautnera91f9e22012-09-14 16:22:08 -0700722 mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700723 }
724 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800725 //Slog.i(TAG_WM, "Not applying alpha transform");
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700726 }
727
Robert Carre13b58e2017-08-31 14:50:44 -0700728 if ((DEBUG_ANIM || WindowManagerService.localLOGV)
Craig Mautnera91f9e22012-09-14 16:22:08 -0700729 && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
730 TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
Craig Mautnera91f9e22012-09-14 16:22:08 -0700731 + " screen=" + (screenAnimation ?
732 screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700733 return;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700734 } else if (mIsWallpaper && mService.mRoot.mWallpaperActionPending) {
Craig Mautner4d7349b2012-04-20 14:52:47 -0700735 return;
Chong Zhang3005e752015-09-18 18:46:28 -0700736 } else if (mWin.isDragResizeChanged()) {
737 // This window is awaiting a relayout because user just started (or ended)
738 // drag-resizing. The shown frame (which affects surface size and pos)
739 // should not be updated until we get next finished draw with the new surface.
740 // Otherwise one or two frames rendered with old settings would be displayed
741 // with new geometry.
742 return;
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700743 }
744
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800745 if (WindowManagerService.localLOGV) Slog.v(
Craig Mautner4d7349b2012-04-20 14:52:47 -0700746 TAG, "computeShownFrameLocked: " + this +
747 " not attached, mAlpha=" + mAlpha);
Svetoslav Ganov1cf70bb2012-08-06 10:53:34 -0700748
Jorim Jaggi9af095b2017-12-12 17:18:57 +0100749 // WindowState.prepareSurfaces expands for surface insets (in order they don't get
750 // clipped by the WindowState surface), so we need to go into the other direction here.
751 mWin.mShownPosition.set(mWin.mXOffset + mWin.mAttrs.surfaceInsets.left,
752 mWin.mYOffset + mWin.mAttrs.surfaceInsets.top);
Robert Carrb1579c82017-09-05 14:54:47 -0700753 mShownAlpha = mAlpha;
754 mHaveMatrix = false;
755 mDsDx = mWin.mGlobalScale;
756 mDtDx = 0;
757 mDtDy = 0;
758 mDsDy = mWin.mGlobalScale;
Robert Carref090ac2017-05-15 16:45:50 -0700759 }
760
Robert Carrfbbde852016-10-18 11:02:28 -0700761 /**
Robert Carrfbbde852016-10-18 11:02:28 -0700762 * Calculate the window-space crop rect and fill clipRect.
Wale Ogunwaleca9e0612016-12-02 07:45:59 -0800763 * @return true if clipRect has been filled otherwise, no window space crop should be applied.
Robert Carrfbbde852016-10-18 11:02:28 -0700764 */
Wale Ogunwaleca9e0612016-12-02 07:45:59 -0800765 private boolean calculateCrop(Rect clipRect) {
Robert Carrfbbde852016-10-18 11:02:28 -0700766 final WindowState w = mWin;
767 final DisplayContent displayContent = w.getDisplayContent();
768 clipRect.setEmpty();
769
770 if (displayContent == null) {
771 return false;
772 }
773
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700774 if (w.inPinnedWindowingMode()) {
Robert Carrfbbde852016-10-18 11:02:28 -0700775 return false;
776 }
777
778 // If we're animating, the wallpaper should only
779 // be updated at the end of the animation.
780 if (w.mAttrs.type == TYPE_WALLPAPER) {
781 return false;
782 }
783
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -0700784 if (DEBUG_WINDOW_CROP) Slog.d(TAG,
785 "Updating crop win=" + w + " mLastCrop=" + mLastClipRect);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -0700786
Robert Carrfbbde852016-10-18 11:02:28 -0700787 w.calculatePolicyCrop(mSystemDecorRect);
788
789 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
790 + w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -0700791
Andrii Kulian283acd22017-08-03 04:03:51 -0700792 final Task task = w.getTask();
793 final boolean fullscreen = w.fillsDisplay() || (task != null && task.isFullscreen());
Jorim Jaggi253a20f2015-11-03 12:38:42 +0100794 final boolean isFreeformResizing =
Jorim Jaggidcf467c2015-11-05 13:59:32 +0100795 w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
Robert Carr51a1b872015-12-08 14:03:13 -0800796
797 // We use the clip rect as provided by the tranformation for non-fullscreen windows to
798 // avoid premature clipping with the system decor rect.
799 clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : mSystemDecorRect);
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -0700800 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect
801 + " mHasClipRect=" + mHasClipRect + " fullscreen=" + fullscreen);
Robert Carr51a1b872015-12-08 14:03:13 -0800802
803 if (isFreeformResizing && !w.isChildWindow()) {
804 // For freeform resizing non child windows, we are using the big surface positioned
805 // at 0,0. Thus we must express the crop in that coordinate space.
806 clipRect.offset(w.mShownPosition.x, w.mShownPosition.y);
Chong Zhang09b21ef2015-09-14 10:20:21 -0700807 }
Robert Carr51a1b872015-12-08 14:03:13 -0800808
Robert Carrfbbde852016-10-18 11:02:28 -0700809 w.expandForSurfaceInsets(clipRect);
Alan Viverette49a22e82014-07-12 20:01:27 -0700810
Wale Ogunwaleb3eba812015-07-30 20:20:16 -0700811 if (mHasClipRect && fullscreen) {
812 // We intersect the clip rect specified by the transformation with the expanded system
813 // decor rect to prevent artifacts from drawing during animation if the transformation
814 // clip rect extends outside the system decor rect.
815 clipRect.intersect(mClipRect);
816 }
Alan Viverette49a22e82014-07-12 20:01:27 -0700817 // The clip rect was generated assuming (0,0) as the window origin,
818 // so we need to translate to match the actual surface coordinates.
Robert Carrfbbde852016-10-18 11:02:28 -0700819 clipRect.offset(w.mAttrs.surfaceInsets.left, w.mAttrs.surfaceInsets.top);
Robert Carr58f29132015-10-29 14:19:05 -0700820
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -0700821 if (DEBUG_WINDOW_CROP) Slog.d(TAG,
822 "win=" + w + " Clip rect after stack adjustment=" + clipRect);
Robert Carr58f29132015-10-29 14:19:05 -0700823
Chia-I Wue6bcaf12016-05-27 10:58:48 +0800824 w.transformClipRectFromScreenToSurfaceSpace(clipRect);
Robert Carr58f29132015-10-29 14:19:05 -0700825
Robert Carrfbbde852016-10-18 11:02:28 -0700826 return true;
Robert Carr0d00c2e2016-02-29 17:45:02 -0800827 }
828
chaviw23012112017-12-20 15:29:04 -0800829 private void applyCrop(Rect clipRect, boolean recoveringMemory) {
Robert Carrfbbde852016-10-18 11:02:28 -0700830 if (DEBUG_WINDOW_CROP) Slog.d(TAG, "applyCrop: win=" + mWin
chaviw23012112017-12-20 15:29:04 -0800831 + " clipRect=" + clipRect);
Robert Carr4320d332016-06-10 15:13:32 -0700832 if (clipRect != null) {
833 if (!clipRect.equals(mLastClipRect)) {
834 mLastClipRect.set(clipRect);
835 mSurfaceController.setCropInTransaction(clipRect, recoveringMemory);
836 }
837 } else {
838 mSurfaceController.clearCropInTransaction(recoveringMemory);
Dianne Hackborn3e52fc22012-05-15 17:58:02 -0700839 }
Filip Gruszczynski4b8eea72015-09-14 18:16:19 -0700840 }
841
Wale Ogunwale4c8b7952015-04-07 10:49:40 -0700842 void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
Wale Ogunwale027f4752017-05-12 10:37:16 -0700843 if (mSurfaceController == null) {
844 return;
845 }
846
Craig Mautnerc2f9be02012-03-27 17:32:29 -0700847 final WindowState w = mWin;
Winson Chung08f81892017-03-02 15:40:51 -0800848 final LayoutParams attrs = mWin.getAttrs();
Robert Carr0d00c2e2016-02-29 17:45:02 -0800849 final Task task = w.getTask();
Alan Viveretteccb11e12014-07-08 16:04:02 -0700850
Jorim Jaggif3df0aa2016-04-06 15:56:33 -0700851 // We got resized, so block all updates until we got the new surface.
Andrii Kulianeb1d3222016-05-16 15:17:55 -0700852 if (w.isResizedWhileNotDragResizing() && !w.isGoneForLayoutLw()) {
Jorim Jaggif3df0aa2016-04-06 15:56:33 -0700853 return;
854 }
855
Filip Gruszczynski69cbc352015-11-11 13:46:04 -0800856 mTmpSize.set(w.mShownPosition.x, w.mShownPosition.y, 0, 0);
Winson Chung08f81892017-03-02 15:40:51 -0800857 calculateSurfaceBounds(w, attrs);
Chong Zhang0275e392015-09-17 10:41:44 -0700858
Robert Carr04092112016-06-02 12:56:12 -0700859 mExtraHScale = (float) 1.0;
860 mExtraVScale = (float) 1.0;
Robert Carre1034cc32016-02-01 13:08:15 -0800861
Robert Carr6da3cc02016-06-16 15:17:07 -0700862 boolean wasForceScaled = mForceScaleUntilResize;
863 boolean wasSeamlesslyRotated = w.mSeamlesslyRotated;
864
Robert Carrfed10072016-05-26 11:48:49 -0700865 // Once relayout has been called at least once, we need to make sure
866 // we only resize the client surface during calls to relayout. For
867 // clients which use indeterminate measure specs (MATCH_PARENT),
868 // we may try and change their window size without a call to relayout.
869 // However, this would be unsafe, as the client may be in the middle
870 // of producing a frame at the old size, having just completed layout
871 // to find the surface size changed underneath it.
Robert Carr3ccc5272016-06-20 22:06:32 -0700872 if (!w.mRelayoutCalled || w.mInRelayout) {
Robert Carrfed10072016-05-26 11:48:49 -0700873 mSurfaceResized = mSurfaceController.setSizeInTransaction(
874 mTmpSize.width(), mTmpSize.height(), recoveringMemory);
875 } else {
876 mSurfaceResized = false;
877 }
Robert Carrc7294602016-05-13 11:32:05 -0700878 mForceScaleUntilResize = mForceScaleUntilResize && !mSurfaceResized;
Robert Carr6da3cc02016-06-16 15:17:07 -0700879 // If we are undergoing seamless rotation, the surface has already
880 // been set up to persist at it's old location. We need to freeze
881 // updates until a resize occurs.
Robert Carrb14d4abc2016-10-03 18:13:33 -0700882 mService.markForSeamlessRotation(w, w.mSeamlesslyRotated && !mSurfaceResized);
Robert Carrc7294602016-05-13 11:32:05 -0700883
chaviw23012112017-12-20 15:29:04 -0800884 Rect clipRect = null;
Robert Carrfbbde852016-10-18 11:02:28 -0700885 if (calculateCrop(mTmpClipRect)) {
886 clipRect = mTmpClipRect;
887 }
Robert Carra9408d42016-06-03 13:28:48 -0700888
889 float surfaceWidth = mSurfaceController.getWidth();
890 float surfaceHeight = mSurfaceController.getHeight();
891
Robert Carr8f0a3ad2017-02-15 19:30:28 -0800892 if (isForceScaled()) {
Winson Chung08f81892017-03-02 15:40:51 -0800893 int hInsets = attrs.surfaceInsets.left + attrs.surfaceInsets.right;
894 int vInsets = attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
895 float surfaceContentWidth = surfaceWidth - hInsets;
896 float surfaceContentHeight = surfaceHeight - vInsets;
Robert Carra9408d42016-06-03 13:28:48 -0700897 if (!mForceScaleUntilResize) {
898 mSurfaceController.forceScaleableInTransaction(true);
899 }
Robert Carrfd4c9892017-02-01 10:28:28 -0800900
Winson Chung08f81892017-03-02 15:40:51 -0800901 int posX = mTmpSize.left;
902 int posY = mTmpSize.top;
Robert Carrfd4c9892017-02-01 10:28:28 -0800903 task.mStack.getDimBounds(mTmpStackBounds);
Robert Carr18f622f2017-05-08 11:20:43 -0700904
905 boolean allowStretching = false;
Winson Chung8bca9e42017-04-16 15:59:43 -0700906 task.mStack.getFinalAnimationSourceHintBounds(mTmpSourceBounds);
Robert Carr18f622f2017-05-08 11:20:43 -0700907 // If we don't have source bounds, we can attempt to use the content insets
908 // in the following scenario:
909 // 1. We have content insets.
910 // 2. We are not transitioning to full screen
911 // We have to be careful to check "lastAnimatingBoundsWasToFullscreen" rather than
912 // the mBoundsAnimating state, as we may have already left it and only be here
913 // because of the force-scale until resize state.
914 if (mTmpSourceBounds.isEmpty() && (mWin.mLastRelayoutContentInsets.width() > 0
915 || mWin.mLastRelayoutContentInsets.height() > 0)
916 && !task.mStack.lastAnimatingBoundsWasToFullscreen()) {
917 mTmpSourceBounds.set(task.mStack.mPreAnimationBounds);
918 mTmpSourceBounds.inset(mWin.mLastRelayoutContentInsets);
919 allowStretching = true;
920 }
Winson Chung08f81892017-03-02 15:40:51 -0800921 if (!mTmpSourceBounds.isEmpty()) {
922 // Get the final target stack bounds, if we are not animating, this is just the
923 // current stack bounds
Winson Chung40a5f932017-04-13 16:39:36 -0700924 task.mStack.getFinalAnimationBounds(mTmpAnimatingBounds);
Winson Chung08f81892017-03-02 15:40:51 -0800925
926 // Calculate the current progress and interpolate the difference between the target
927 // and source bounds
928 float finalWidth = mTmpAnimatingBounds.width();
929 float initialWidth = mTmpSourceBounds.width();
Robert Carr18f622f2017-05-08 11:20:43 -0700930 float tw = (surfaceContentWidth - mTmpStackBounds.width())
Winson Chung08f81892017-03-02 15:40:51 -0800931 / (surfaceContentWidth - mTmpAnimatingBounds.width());
Robert Carr18f622f2017-05-08 11:20:43 -0700932 float th = tw;
933 mExtraHScale = (initialWidth + tw * (finalWidth - initialWidth)) / initialWidth;
934 if (allowStretching) {
935 float finalHeight = mTmpAnimatingBounds.height();
936 float initialHeight = mTmpSourceBounds.height();
937 th = (surfaceContentHeight - mTmpStackBounds.height())
938 / (surfaceContentHeight - mTmpAnimatingBounds.height());
939 mExtraVScale = (initialHeight + tw * (finalHeight - initialHeight))
940 / initialHeight;
941 } else {
942 mExtraVScale = mExtraHScale;
943 }
Winson Chung08f81892017-03-02 15:40:51 -0800944
945 // Adjust the position to account for the inset bounds
Robert Carr18f622f2017-05-08 11:20:43 -0700946 posX -= (int) (tw * mExtraHScale * mTmpSourceBounds.left);
947 posY -= (int) (th * mExtraVScale * mTmpSourceBounds.top);
Winson Chung08f81892017-03-02 15:40:51 -0800948
949 // Always clip to the stack bounds since the surface can be larger with the current
950 // scale
951 clipRect = null;
Winson Chung08f81892017-03-02 15:40:51 -0800952 } else {
953 // We want to calculate the scaling based on the content area, not based on
954 // the entire surface, so that we scale in sync with windows that don't have insets.
955 mExtraHScale = mTmpStackBounds.width() / surfaceContentWidth;
956 mExtraVScale = mTmpStackBounds.height() / surfaceContentHeight;
957
958 // Since we are scaled to fit in our previously desired crop, we can now
959 // expose the whole window in buffer space, and not risk extending
960 // past where the system would have cropped us
961 clipRect = null;
Winson Chung08f81892017-03-02 15:40:51 -0800962 }
Robert Carr0d00c2e2016-02-29 17:45:02 -0800963
Robert Carrfd4c9892017-02-01 10:28:28 -0800964 // In the case of ForceScaleToStack we scale entire tasks together,
Robert Carr0d00c2e2016-02-29 17:45:02 -0800965 // and so we need to scale our offsets relative to the task bounds
966 // or parent and child windows would fall out of alignment.
Winson Chung08f81892017-03-02 15:40:51 -0800967 posX -= (int) (attrs.x * (1 - mExtraHScale));
968 posY -= (int) (attrs.y * (1 - mExtraVScale));
969
Robert Carrbc133762016-05-12 14:04:38 -0700970 // Imagine we are scaling down. As we scale the buffer down, we decrease the
971 // distance between the surface top left, and the start of the surface contents
972 // (previously it was surfaceInsets.left pixels in screen space but now it
Robert Carr04092112016-06-02 12:56:12 -0700973 // will be surfaceInsets.left*mExtraHScale). This means in order to keep the
Robert Carrbc133762016-05-12 14:04:38 -0700974 // non inset content at the same position, we have to shift the whole window
975 // forward. Likewise for scaling up, we've increased this distance, and we need
976 // to shift by a negative number to compensate.
Winson Chung08f81892017-03-02 15:40:51 -0800977 posX += attrs.surfaceInsets.left * (1 - mExtraHScale);
978 posY += attrs.surfaceInsets.top * (1 - mExtraVScale);
Robert Carrbc133762016-05-12 14:04:38 -0700979
Winson Chung08f81892017-03-02 15:40:51 -0800980 mSurfaceController.setPositionInTransaction((float) Math.floor(posX),
981 (float) Math.floor(posY), recoveringMemory);
Robert Carrc7294602016-05-13 11:32:05 -0700982
983 // Various surfaces in the scaled stack may resize at different times.
984 // We need to ensure for each surface, that we disable transformation matrix
985 // scaling in the same transaction which we resize the surface in.
986 // As we are in SCALING_MODE_SCALE_TO_WINDOW, SurfaceFlinger will
Robert Carra9408d42016-06-03 13:28:48 -0700987 // then take over the scaling until the new buffer arrives, and things
Robert Carrc7294602016-05-13 11:32:05 -0700988 // will be seamless.
989 mForceScaleUntilResize = true;
Robert Carr0d00c2e2016-02-29 17:45:02 -0800990 } else {
Robert Carr6da3cc02016-06-16 15:17:07 -0700991 if (!w.mSeamlesslyRotated) {
992 mSurfaceController.setPositionInTransaction(mTmpSize.left, mTmpSize.top,
993 recoveringMemory);
994 }
Robert Carr0d00c2e2016-02-29 17:45:02 -0800995 }
996
Robert Carra9408d42016-06-03 13:28:48 -0700997 // If we are ending the scaling mode. We switch to SCALING_MODE_FREEZE
Robert Carr6da3cc02016-06-16 15:17:07 -0700998 // to prevent further updates until buffer latch.
999 // When ending both force scaling, and seamless rotation, we need to freeze
1000 // the Surface geometry until a buffer comes in at the new size (normally position and crop
1001 // are unfrozen). setGeometryAppliesWithResizeInTransaction accomplishes this for us.
1002 if ((wasForceScaled && !mForceScaleUntilResize) ||
1003 (wasSeamlesslyRotated && !w.mSeamlesslyRotated)) {
1004 mSurfaceController.setGeometryAppliesWithResizeInTransaction(true);
Robert Carra9408d42016-06-03 13:28:48 -07001005 mSurfaceController.forceScaleableInTransaction(false);
1006 }
Robert Carr4320d332016-06-10 15:13:32 -07001007
Robert Carr6da3cc02016-06-16 15:17:07 -07001008 if (!w.mSeamlesslyRotated) {
chaviw23012112017-12-20 15:29:04 -08001009 applyCrop(clipRect, recoveringMemory);
Robert Carr6da3cc02016-06-16 15:17:07 -07001010 mSurfaceController.setMatrixInTransaction(mDsDx * w.mHScale * mExtraHScale,
1011 mDtDx * w.mVScale * mExtraVScale,
Robert Carr0edf18f2017-02-21 20:01:47 -08001012 mDtDy * w.mHScale * mExtraHScale,
1013 mDsDy * w.mVScale * mExtraVScale, recoveringMemory);
Robert Carr6da3cc02016-06-16 15:17:07 -07001014 }
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001015
Robert Carre6a83512015-11-03 16:09:21 -08001016 if (mSurfaceResized) {
Chong Zhang5b2f1992015-11-13 15:40:36 -08001017 mReportSurfaceResized = true;
Robert Carre6a83512015-11-03 16:09:21 -08001018 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
Jorim Jaggia5e10572017-11-15 14:36:26 +01001019 FINISH_LAYOUT_REDO_WALLPAPER);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001020 }
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001021 }
1022
Andrii Kulian283acd22017-08-03 04:03:51 -07001023 /**
1024 * Get rect of the task this window is currently in. If there is no task, rect will be set to
1025 * empty.
1026 */
1027 void getContainerRect(Rect rect) {
1028 final Task task = mWin.getTask();
1029 if (task != null) {
1030 task.getDimBounds(rect);
1031 } else {
1032 rect.left = rect.top = rect.right = rect.bottom = 0;
1033 }
1034 }
1035
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001036 void prepareSurfaceLocked(final boolean recoveringMemory) {
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001037 final WindowState w = mWin;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001038 if (!hasSurface()) {
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001039
1040 // There is no need to wait for an animation change if our window is gone for layout
1041 // already as we'll never be visible.
Bryce Lee8c3cf382017-07-06 19:47:10 -07001042 if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001043 if (DEBUG_ORIENTATION) {
1044 Slog.v(TAG, "Orientation change skips hidden " + w);
1045 }
Bryce Lee8c3cf382017-07-06 19:47:10 -07001046 w.setOrientationChanging(false);
Craig Mautneracaf9cc2012-04-17 11:45:25 -07001047 }
1048 return;
1049 }
1050
1051 boolean displayed = false;
1052
1053 computeShownFrameLocked();
1054
Craig Mautnera91f9e22012-09-14 16:22:08 -07001055 setSurfaceBoundariesLocked(recoveringMemory);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001056
Craig Mautner918b53b2012-07-09 14:15:54 -07001057 if (mIsWallpaper && !mWin.mWallpaperVisible) {
Craig Mautner0fa77c12012-06-11 15:57:19 -07001058 // Wallpaper is no longer visible and there is no wp target => hide it.
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001059 hide("prepareSurfaceLocked");
Wale Ogunwale9d147902016-07-16 11:58:55 -07001060 } else if (w.isParentWindowHidden() || !w.isOnScreen()) {
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08001061 hide("prepareSurfaceLocked");
Wale Ogunwalee8069dc2015-08-18 09:52:01 -07001062 mWallpaperControllerLocked.hideWallpapers(w);
Craig Mautnerb9836b92012-06-11 11:40:09 -07001063
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001064 // If we are waiting for this window to handle an orientation change. If this window is
1065 // really hidden (gone for layout), there is no point in still waiting for it.
1066 // Note that this does introduce a potential glitch if the window becomes unhidden
1067 // before it has drawn for the new orientation.
Bryce Lee8c3cf382017-07-06 19:47:10 -07001068 if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
1069 w.setOrientationChanging(false);
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001070 if (DEBUG_ORIENTATION) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001071 "Orientation change skips hidden " + w);
1072 }
1073 } else if (mLastLayer != mAnimLayer
1074 || mLastAlpha != mShownAlpha
1075 || mLastDsDx != mDsDx
1076 || mLastDtDx != mDtDx
1077 || mLastDsDy != mDsDy
1078 || mLastDtDy != mDtDy
1079 || w.mLastHScale != w.mHScale
1080 || w.mLastVScale != w.mVScale
Craig Mautner749a7bb2012-04-02 13:49:53 -07001081 || mLastHidden) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001082 displayed = true;
1083 mLastAlpha = mShownAlpha;
1084 mLastLayer = mAnimLayer;
1085 mLastDsDx = mDsDx;
1086 mLastDtDx = mDtDx;
1087 mLastDsDy = mDsDy;
1088 mLastDtDy = mDtDy;
1089 w.mLastHScale = w.mHScale;
1090 w.mLastVScale = w.mVScale;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001091 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
Robert Carre6a83512015-11-03 16:09:21 -08001092 "controller=" + mSurfaceController +
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001093 "alpha=" + mShownAlpha + " layer=" + mAnimLayer
Craig Mautner78505d82014-09-02 14:36:31 -07001094 + " matrix=[" + mDsDx + "*" + w.mHScale
1095 + "," + mDtDx + "*" + w.mVScale
Robert Carr0edf18f2017-02-21 20:01:47 -08001096 + "][" + mDtDy + "*" + w.mHScale
1097 + "," + mDsDy + "*" + w.mVScale + "]", false);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001098
Robert Carre6a83512015-11-03 16:09:21 -08001099 boolean prepared =
Robert Carraf422a82017-04-10 18:34:33 -07001100 mSurfaceController.prepareToShowInTransaction(mShownAlpha,
Robert Carr04092112016-06-02 12:56:12 -07001101 mDsDx * w.mHScale * mExtraHScale,
1102 mDtDx * w.mVScale * mExtraVScale,
Robert Carr0edf18f2017-02-21 20:01:47 -08001103 mDtDy * w.mHScale * mExtraHScale,
1104 mDsDy * w.mVScale * mExtraVScale,
Robert Carre6a83512015-11-03 16:09:21 -08001105 recoveringMemory);
1106
Robert Carr03206af2017-07-10 18:24:21 -07001107 if (prepared && mDrawState == HAS_DRAWN) {
1108 if (mLastHidden) {
1109 if (showSurfaceRobustlyLocked()) {
1110 markPreservedSurfaceForDestroy();
1111 mAnimator.requestRemovalOfReplacedWindows(w);
1112 mLastHidden = false;
1113 if (mIsWallpaper) {
1114 w.dispatchWallpaperVisibility(true);
1115 }
1116 // This draw means the difference between unique content and mirroring.
1117 // Run another pass through performLayout to set mHasContent in the
1118 // LogicalDisplay.
1119 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
Jorim Jaggia5e10572017-11-15 14:36:26 +01001120 FINISH_LAYOUT_REDO_ANIM);
Robert Carr03206af2017-07-10 18:24:21 -07001121 } else {
1122 w.setOrientationChanging(false);
Craig Mautner749a7bb2012-04-02 13:49:53 -07001123 }
Robert Carr03206af2017-07-10 18:24:21 -07001124 }
1125 // We process mTurnOnScreen even for windows which have already
1126 // been shown, to handle cases where windows are not necessarily
1127 // hidden while the screen is turning off.
1128 // TODO(b/63773439): These cases should be eliminated, though we probably still
1129 // want to process mTurnOnScreen in this way for clarity.
chaviw35d7de02017-08-23 12:29:02 -07001130 if (mWin.mTurnOnScreen &&
1131 (mWin.mAppToken == null || mWin.mAppToken.canTurnScreenOn())) {
Robert Carr03206af2017-07-10 18:24:21 -07001132 if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin);
1133 mWin.mTurnOnScreen = false;
chaviwd3bf08d2017-08-01 17:24:59 -07001134
1135 // The window should only turn the screen on once per resume, but
1136 // prepareSurfaceLocked can be called multiple times. Set canTurnScreenOn to
1137 // false so the window doesn't turn the screen on again during this resume.
chaviw35d7de02017-08-23 12:29:02 -07001138 if (mWin.mAppToken != null) {
1139 mWin.mAppToken.setCanTurnScreenOn(false);
1140 }
Bryce Leec4c8baa2017-09-06 14:55:48 -07001141
1142 // We do not add {@code SET_TURN_ON_SCREEN} when the screen is already
1143 // interactive as the value may persist until the next animation, which could
1144 // potentially occurring while turning off the screen. This would lead to the
1145 // screen incorrectly turning back on.
1146 if (!mService.mPowerManager.isInteractive()) {
chaviw042059d2018-01-11 11:24:08 -08001147 mService.mTurnOnScreen = true;
Bryce Leec4c8baa2017-09-06 14:55:48 -07001148 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001149 }
1150 }
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001151 if (hasSurface()) {
Robert Carre6a83512015-11-03 16:09:21 -08001152 w.mToken.hasVisible = true;
1153 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001154 } else {
Jorim Jaggi5c80c412016-04-19 20:03:47 -07001155 if (DEBUG_ANIM && isAnimationSet()) {
Chong Zhange05db742016-02-16 16:58:37 -08001156 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
Craig Mautner83339b42012-05-01 22:13:23 -07001157 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001158 displayed = true;
1159 }
1160
Bryce Lee8c3cf382017-07-06 19:47:10 -07001161 if (w.getOrientationChanging()) {
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001162 if (!w.isDrawnLw()) {
1163 mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
1164 mAnimator.mLastWindowFreezeSource = w;
1165 if (DEBUG_ORIENTATION) Slog.v(TAG,
1166 "Orientation continue waiting for draw in " + w);
1167 } else {
Bryce Lee8c3cf382017-07-06 19:47:10 -07001168 w.setOrientationChanging(false);
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001169 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001170 }
Jorim Jaggi38d44ec2017-06-14 16:04:59 -07001171 }
1172
1173 if (displayed) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001174 w.mToken.hasVisible = true;
1175 }
1176 }
1177
Craig Mautneref655012013-01-03 11:20:24 -08001178 void setTransparentRegionHintLocked(final Region region) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001179 if (mSurfaceController == null) {
1180 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
1181 return;
1182 }
Robert Carre6a83512015-11-03 16:09:21 -08001183 mSurfaceController.setTransparentRegionHint(region);
Craig Mautner48ba1e72012-04-02 13:18:16 -07001184 }
1185
Filip Gruszczynski2a6a2c22015-10-14 12:00:53 -07001186 void setWallpaperOffset(Point shownPosition) {
Dianne Hackborn067e5f62014-09-07 23:14:30 -07001187 final LayoutParams attrs = mWin.getAttrs();
Filip Gruszczynski2a6a2c22015-10-14 12:00:53 -07001188 final int left = shownPosition.x - attrs.surfaceInsets.left;
1189 final int top = shownPosition.y - attrs.surfaceInsets.top;
Robert Carre6a83512015-11-03 16:09:21 -08001190
1191 try {
Craig Mautner71dd1b62014-02-18 15:48:52 -08001192 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
Robert Carr68e5c9e2016-09-14 10:50:09 -07001193 mService.openSurfaceTransaction();
Robert Carre6a83512015-11-03 16:09:21 -08001194 mSurfaceController.setPositionInTransaction(mWin.mFrame.left + left,
1195 mWin.mFrame.top + top, false);
chaviw23012112017-12-20 15:29:04 -08001196 applyCrop(null, false);
Robert Carre6a83512015-11-03 16:09:21 -08001197 } catch (RuntimeException e) {
1198 Slog.w(TAG, "Error positioning surface of " + mWin
1199 + " pos=(" + left + "," + top + ")", e);
1200 } finally {
Adrian Roos111aff92017-09-27 18:11:46 +02001201 mService.closeSurfaceTransaction("setWallpaperOffset");
Robert Carre6a83512015-11-03 16:09:21 -08001202 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1203 "<<< CLOSE TRANSACTION setWallpaperOffset");
Craig Mautner48ba1e72012-04-02 13:18:16 -07001204 }
Craig Mautner48ba1e72012-04-02 13:18:16 -07001205 }
1206
John Reck80181b92015-05-19 11:09:32 -07001207 /**
1208 * Try to change the pixel format without recreating the surface. This
1209 * will be common in the case of changing from PixelFormat.OPAQUE to
1210 * PixelFormat.TRANSLUCENT in the hardware-accelerated case as both
1211 * requested formats resolve to the same underlying SurfaceControl format
1212 * @return True if format was succesfully changed, false otherwise
1213 */
1214 boolean tryChangeFormatInPlaceLocked() {
Robert Carre6a83512015-11-03 16:09:21 -08001215 if (mSurfaceController == null) {
John Reck80181b92015-05-19 11:09:32 -07001216 return false;
1217 }
1218 final LayoutParams attrs = mWin.getAttrs();
Wale Ogunwalee7bf46b2015-09-30 09:19:28 -07001219 final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
John Reck80181b92015-05-19 11:09:32 -07001220 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
1221 if (format == mSurfaceFormat) {
1222 setOpaqueLocked(!PixelFormat.formatHasAlpha(attrs.format));
1223 return true;
1224 }
1225 return false;
1226 }
1227
Craig Mautner6f612042014-09-07 13:13:23 -07001228 void setOpaqueLocked(boolean isOpaque) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001229 if (mSurfaceController == null) {
1230 return;
1231 }
Robert Carre6a83512015-11-03 16:09:21 -08001232 mSurfaceController.setOpaque(isOpaque);
Craig Mautner71dd1b62014-02-18 15:48:52 -08001233 }
1234
Wale Ogunwalef5ad42f2015-06-12 13:59:03 -07001235 void setSecureLocked(boolean isSecure) {
Wale Ogunwalef9e09782015-11-09 12:42:37 -08001236 if (mSurfaceController == null) {
1237 return;
1238 }
Robert Carre6a83512015-11-03 16:09:21 -08001239 mSurfaceController.setSecure(isSecure);
Wale Ogunwalef5ad42f2015-06-12 13:59:03 -07001240 }
1241
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001242 /**
1243 * Have the surface flinger show a surface, robustly dealing with
1244 * error conditions. In particular, if there is not enough memory
1245 * to show the surface, then we will try to get rid of other surfaces
1246 * in order to succeed.
1247 *
1248 * @return Returns true if the surface was successfully shown.
1249 */
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001250 private boolean showSurfaceRobustlyLocked() {
Wale Ogunwale3382ab12017-07-27 08:55:03 -07001251 if (mWin.getWindowConfiguration().windowsAreScaleable()) {
Robert Carr1b5ea722016-04-20 13:23:28 -07001252 mSurfaceController.forceScaleableInTransaction(true);
1253 }
1254
Robert Carre6a83512015-11-03 16:09:21 -08001255 boolean shown = mSurfaceController.showRobustlyInTransaction();
1256 if (!shown)
1257 return false;
1258
Robert Carre6a83512015-11-03 16:09:21 -08001259 return true;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001260 }
1261
1262 void applyEnterAnimationLocked() {
Robert Carrb439a632016-04-07 22:52:10 -07001263 // If we are the new part of a window replacement transition and we have requested
1264 // not to animate, we instead want to make it seamless, so we don't want to apply
1265 // an enter transition.
1266 if (mWin.mSkipEnterAnimationForSeamlessReplacement) {
1267 return;
1268 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001269 final int transit;
1270 if (mEnterAnimationPending) {
1271 mEnterAnimationPending = false;
1272 transit = WindowManagerPolicy.TRANSIT_ENTER;
1273 } else {
1274 transit = WindowManagerPolicy.TRANSIT_SHOW;
1275 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001276 applyAnimationLocked(transit, true);
Svetoslav Ganov545252f2012-12-10 18:29:24 -08001277 //TODO (multidisplay): Magnification is supported only for the default display.
Svetoslav8e3feb12014-02-24 13:46:47 -08001278 if (mService.mAccessibilityController != null
Filip Gruszczynski69cbc352015-11-11 13:46:04 -08001279 && mWin.getDisplayId() == DEFAULT_DISPLAY) {
Svetoslav8e3feb12014-02-24 13:46:47 -08001280 mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -07001281 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001282 }
1283
1284 /**
1285 * Choose the correct animation and set it to the passed WindowState.
Craig Mautner4b71aa12012-12-27 17:20:01 -08001286 * @param transit If AppTransition.TRANSIT_PREVIEW_DONE and the app window has been drawn
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001287 * then the animation will be app_starting_exit. Any other value loads the animation from
1288 * the switch statement below.
1289 * @param isEntrance The animation type the last time this was called. Used to keep from
1290 * loading the same animation twice.
1291 * @return true if an animation has been loaded.
1292 */
1293 boolean applyAnimationLocked(int transit, boolean isEntrance) {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001294 if (mWin.isSelfAnimating() && mAnimationIsEntrance == isEntrance) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001295 // If we are trying to apply an animation, but already running
Jorim Jaggif8d77da2014-11-11 16:59:12 +01001296 // an animation of the same type, then just leave that one alone.
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001297 return true;
1298 }
1299
Jorim Jaggia5e10572017-11-15 14:36:26 +01001300 if (isEntrance && mWin.mAttrs.type == TYPE_INPUT_METHOD) {
1301 mWin.getDisplayContent().adjustForImeIfNeeded();
1302 mWin.setDisplayLayoutNeeded();
1303 mService.mWindowPlacerLocked.requestTraversal();
1304 }
1305
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001306 // Only apply an animation if the display isn't frozen. If it is
1307 // frozen, there is no reason to animate and it can cause strange
1308 // artifacts when we unfreeze the display if some different animation
1309 // is running.
Chong Zhang8784be62016-06-28 15:25:07 -07001310 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#applyAnimationLocked");
David Stevens9440dc82017-03-16 19:00:20 -07001311 if (mWin.mToken.okToAnimate()) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001312 int anim = mPolicy.selectAnimationLw(mWin, transit);
1313 int attr = -1;
1314 Animation a = null;
1315 if (anim != 0) {
Dianne Hackborn4c1e3182012-10-05 18:37:54 -07001316 a = anim != -1 ? AnimationUtils.loadAnimation(mContext, anim) : null;
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001317 } else {
1318 switch (transit) {
1319 case WindowManagerPolicy.TRANSIT_ENTER:
1320 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
1321 break;
1322 case WindowManagerPolicy.TRANSIT_EXIT:
1323 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
1324 break;
1325 case WindowManagerPolicy.TRANSIT_SHOW:
1326 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
1327 break;
1328 case WindowManagerPolicy.TRANSIT_HIDE:
1329 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
1330 break;
1331 }
1332 if (attr >= 0) {
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001333 a = mService.mAppTransition.loadAnimationAttr(mWin.mAttrs, attr);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001334 }
1335 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001336 if (DEBUG_ANIM) Slog.v(TAG,
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001337 "applyAnimation: win=" + this
1338 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
Craig Mautner4d7349b2012-04-20 14:52:47 -07001339 + " a=" + a
Craig Mautner8863cca2012-09-18 15:04:34 -07001340 + " transit=" + transit
Craig Mautner83339b42012-05-01 22:13:23 -07001341 + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001342 if (a != null) {
Filip Gruszczynski198dcbf2016-01-18 10:02:00 -08001343 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
Jorim Jaggia5e10572017-11-15 14:36:26 +01001344 mWin.startAnimation(a);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001345 mAnimationIsEntrance = isEntrance;
1346 }
1347 } else {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001348 mWin.cancelAnimation();
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001349 }
Chong Zhang8784be62016-06-28 15:25:07 -07001350
Jorim Jaggia5e10572017-11-15 14:36:26 +01001351 if (!isEntrance && mWin.mAttrs.type == TYPE_INPUT_METHOD) {
Wale Ogunwale360a8bc2016-10-10 13:25:26 -07001352 mWin.getDisplayContent().adjustForImeIfNeeded();
Jorim Jaggieb88d832016-04-13 20:17:43 -07001353 }
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001354
Jorim Jaggia5e10572017-11-15 14:36:26 +01001355 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1356 return isAnimationSet();
Jorim Jaggif8d77da2014-11-11 16:59:12 +01001357 }
1358
Steven Timotiusaf03df62017-07-18 16:56:43 -07001359 void writeToProto(ProtoOutputStream proto, long fieldId) {
1360 final long token = proto.start(fieldId);
1361 mLastClipRect.writeToProto(proto, LAST_CLIP_RECT);
1362 if (mSurfaceController != null) {
1363 mSurfaceController.writeToProto(proto, SURFACE);
1364 }
Vishnu Nair1d0fa072018-01-04 07:53:00 -08001365 proto.write(DRAW_STATE, mDrawState);
1366 mSystemDecorRect.writeToProto(proto, SYSTEM_DECOR_RECT);
Steven Timotiusaf03df62017-07-18 16:56:43 -07001367 proto.end(token);
1368 }
1369
Craig Mautnera2c77052012-03-26 12:14:43 -07001370 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
Jorim Jaggia5e10572017-11-15 14:36:26 +01001371 if (mAnimationIsEntrance) {
1372 pw.print(prefix); pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
Craig Mautnera2c77052012-03-26 12:14:43 -07001373 }
Robert Carre6a83512015-11-03 16:09:21 -08001374 if (mSurfaceController != null) {
1375 mSurfaceController.dump(pw, prefix, dumpAll);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001376 }
Robert Carre6a83512015-11-03 16:09:21 -08001377 if (dumpAll) {
1378 pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString());
1379 pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden);
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -08001380 pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
1381 pw.print(" last="); mLastSystemDecorRect.printShortString(pw);
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07001382 pw.print(" mHasClipRect="); pw.print(mHasClipRect);
1383 pw.print(" mLastClipRect="); mLastClipRect.printShortString(pw);
1384
Jorim Jaggi6a7c90a2016-03-11 15:04:59 +01001385 if (!mLastFinalClipRect.isEmpty()) {
1386 pw.print(" mLastFinalClipRect="); mLastFinalClipRect.printShortString(pw);
1387 }
Filip Gruszczynskif34a04c2015-12-07 15:05:49 -08001388 pw.println();
Robert Carre6a83512015-11-03 16:09:21 -08001389 }
1390
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001391 if (mPendingDestroySurface != null) {
1392 pw.print(prefix); pw.print("mPendingDestroySurface=");
1393 pw.println(mPendingDestroySurface);
1394 }
1395 if (mSurfaceResized || mSurfaceDestroyDeferred) {
1396 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1397 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1398 }
1399 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1400 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1401 pw.print(" mAlpha="); pw.print(mAlpha);
1402 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1403 }
1404 if (mHaveMatrix || mWin.mGlobalScale != 1) {
1405 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
1406 pw.print(" mDsDx="); pw.print(mDsDx);
1407 pw.print(" mDtDx="); pw.print(mDtDx);
Robert Carr0edf18f2017-02-21 20:01:47 -08001408 pw.print(" mDtDy="); pw.print(mDtDy);
1409 pw.print(" mDsDy="); pw.println(mDsDy);
Craig Mautnerc2f9be02012-03-27 17:32:29 -07001410 }
Jorim Jaggiff71d202016-04-14 13:12:36 -07001411 if (mAnimationStartDelayed) {
1412 pw.print(prefix); pw.print("mAnimationStartDelayed="); pw.print(mAnimationStartDelayed);
1413 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001414 }
1415
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001416 @Override
1417 public String toString() {
Dianne Hackborn529e7442012-11-01 14:22:28 -07001418 StringBuffer sb = new StringBuffer("WindowStateAnimator{");
1419 sb.append(Integer.toHexString(System.identityHashCode(this)));
1420 sb.append(' ');
1421 sb.append(mWin.mAttrs.getTitle());
1422 sb.append('}');
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001423 return sb.toString();
1424 }
Robert Carre6a83512015-11-03 16:09:21 -08001425
1426 void reclaimSomeSurfaceMemory(String operation, boolean secure) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001427 mService.mRoot.reclaimSomeSurfaceMemory(this, operation, secure);
Robert Carre6a83512015-11-03 16:09:21 -08001428 }
1429
1430 boolean getShown() {
1431 if (mSurfaceController != null) {
1432 return mSurfaceController.getShown();
1433 }
1434 return false;
1435 }
1436
1437 void destroySurface() {
Wale Ogunwale722ff892016-02-18 13:37:55 -08001438 try {
1439 if (mSurfaceController != null) {
1440 mSurfaceController.destroyInTransaction();
1441 }
1442 } catch (RuntimeException e) {
1443 Slog.w(TAG, "Exception thrown when destroying surface " + this
1444 + " surface " + mSurfaceController + " session " + mSession + ": " + e);
1445 } finally {
1446 mWin.setHasSurface(false);
1447 mSurfaceController = null;
1448 mDrawState = NO_SURFACE;
1449 }
Robert Carre6a83512015-11-03 16:09:21 -08001450 }
Filip Gruszczynskif52dd202015-11-15 20:36:38 -08001451
Robert Carr6da3cc02016-06-16 15:17:07 -07001452 void seamlesslyRotateWindow(int oldRotation, int newRotation) {
1453 final WindowState w = mWin;
1454 if (!w.isVisibleNow() || w.mIsWallpaper) {
1455 return;
1456 }
1457
1458 final Rect cropRect = mService.mTmpRect;
1459 final Rect displayRect = mService.mTmpRect2;
1460 final RectF frameRect = mService.mTmpRectF;
1461 final Matrix transform = mService.mTmpTransform;
1462
1463 final float x = w.mFrame.left;
1464 final float y = w.mFrame.top;
1465 final float width = w.mFrame.width();
1466 final float height = w.mFrame.height();
1467
Bryce Leef3c6a472017-11-14 14:53:06 -08001468 mService.getDefaultDisplayContentLocked().getBounds(displayRect);
Robert Carr6da3cc02016-06-16 15:17:07 -07001469 final float displayWidth = displayRect.width();
1470 final float displayHeight = displayRect.height();
1471
1472 // Compute a transform matrix to undo the coordinate space transformation,
1473 // and present the window at the same physical position it previously occupied.
1474 final int deltaRotation = DisplayContent.deltaRotation(newRotation, oldRotation);
Andrii Kulian4dfb9c42016-10-11 20:06:27 -07001475 DisplayContent.createRotationMatrix(deltaRotation, x, y, displayWidth, displayHeight,
1476 transform);
Robert Carr6da3cc02016-06-16 15:17:07 -07001477
Robert Carr897215d2017-03-29 12:25:50 -07001478 // We just need to apply a rotation matrix to the window. For example
1479 // if we have a portrait window and rotate to landscape, the window is still portrait
1480 // and now extends off the bottom of the screen (and only halfway across). Essentially we
1481 // apply a transform to display the current buffer at it's old position
1482 // (in the new coordinate space). We then freeze layer updates until the resize
1483 // occurs, at which point we undo, them.
1484 mService.markForSeamlessRotation(w, true);
1485 transform.getValues(mService.mTmpFloats);
Robert Carr6da3cc02016-06-16 15:17:07 -07001486
Robert Carr897215d2017-03-29 12:25:50 -07001487 float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
1488 float DtDx = mService.mTmpFloats[Matrix.MSKEW_Y];
1489 float DtDy = mService.mTmpFloats[Matrix.MSKEW_X];
1490 float DsDy = mService.mTmpFloats[Matrix.MSCALE_Y];
1491 float nx = mService.mTmpFloats[Matrix.MTRANS_X];
1492 float ny = mService.mTmpFloats[Matrix.MTRANS_Y];
1493 mSurfaceController.setPositionInTransaction(nx, ny, false);
1494 mSurfaceController.setMatrixInTransaction(DsDx * w.mHScale,
1495 DtDx * w.mVScale,
1496 DtDy * w.mHScale,
1497 DsDy * w.mVScale, false);
Robert Carr6da3cc02016-06-16 15:17:07 -07001498 }
Robert Carr3b716242016-08-16 16:02:21 -07001499
1500 void enableSurfaceTrace(FileDescriptor fd) {
1501 if (mSurfaceController != null) {
1502 mSurfaceController.installRemoteTrace(fd);
1503 }
1504 }
1505
1506 void disableSurfaceTrace() {
1507 if (mSurfaceController != null) {
1508 try {
1509 mSurfaceController.removeRemoteTrace();
1510 } catch (ClassCastException e) {
1511 Slog.e(TAG, "Disable surface trace for " + this + " but its not enabled");
1512 }
1513 }
1514 }
Robert Carr8f0a3ad2017-02-15 19:30:28 -08001515
1516 /** The force-scaled state for a given window can persist past
1517 * the state for it's stack as the windows complete resizing
1518 * independently of one another.
1519 */
1520 boolean isForceScaled() {
1521 final Task task = mWin.getTask();
1522 if (task != null && task.mStack.isForceScaled()) {
1523 return true;
1524 }
1525 return mForceScaleUntilResize;
1526 }
Robert Carrd5c7dd62017-03-08 10:39:30 -08001527
1528 void detachChildren() {
1529 if (mSurfaceController != null) {
1530 mSurfaceController.detachChildren();
1531 }
1532 }
Jorim Jaggia5e10572017-11-15 14:36:26 +01001533
1534 int getLayer() {
1535 return mLastLayer;
1536 }
Craig Mautnera2c77052012-03-26 12:14:43 -07001537}