blob: eda2f39480a8d444e2c886d84b6aa50c53527fbe [file] [log] [blame]
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001package com.android.server.wm;
2
Jorim Jaggi275561a2016-02-23 10:11:02 -05003import static android.app.ActivityManagerInternal.APP_TRANSITION_SAVED_SURFACE;
4import static android.app.ActivityManagerInternal.APP_TRANSITION_STARTING_WINDOW;
5import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
6import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07007import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
8import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
9import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
10import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
11import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Chong Zhangb58bbcc2016-03-23 11:57:36 -070012import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070013import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
14import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070015import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
16import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
17import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
18import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
19import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
20import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
21import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Jorim Jaggi192086e2016-03-11 17:17:03 +010022import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080023import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
24import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
25import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
26import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
27import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
28import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
29import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
30import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
31import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
32import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
33import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
34import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080035import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
36import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
Jorim Jaggi192086e2016-03-11 17:17:03 +010037import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080038import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Jorim Jaggi192086e2016-03-11 17:17:03 +010039import static com.android.server.wm.WindowManagerService.H.DO_TRAVERSAL;
40import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
41import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
42import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
43import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
44import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
45import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
46import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
47import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
48import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
49import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070050import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
51import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
52import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
53
54import android.graphics.Bitmap;
55import android.graphics.Canvas;
56import android.graphics.PixelFormat;
57import android.graphics.Rect;
58import android.os.Debug;
59import android.os.PowerManager;
60import android.os.RemoteException;
61import android.os.SystemClock;
62import android.os.Trace;
63import android.provider.Settings;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -070064import android.util.ArraySet;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070065import android.util.Slog;
66import android.view.Display;
67import android.view.DisplayInfo;
68import android.view.Surface;
69import android.view.SurfaceControl;
70import android.view.View;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -080071import android.view.WindowManager.LayoutParams;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070072import android.view.animation.Animation;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070073
Filip Gruszczynski24966d42015-09-05 15:00:00 -070074import java.io.PrintWriter;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070075import java.util.ArrayList;
76
77/**
78 * Positions windows and their surfaces.
79 *
80 * It sets positions of windows by calculating their frames and then applies this by positioning
81 * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
82 */
83class WindowSurfacePlacer {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -080084 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfacePlacer" : TAG_WM;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070085 private final WindowManagerService mService;
86 private final WallpaperController mWallpaperControllerLocked;
87
88 private boolean mInLayout = false;
89
90 /** Only do a maximum of 6 repeated layouts. After that quit */
91 private int mLayoutRepeatCount;
92
93 static final int SET_UPDATE_ROTATION = 1 << 0;
94 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
95 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
96 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
97 static final int SET_TURN_ON_SCREEN = 1 << 4;
98 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
99
100 boolean mWallpaperMayChange = false;
101 boolean mOrientationChangeComplete = true;
102 boolean mWallpaperActionPending = false;
103
104 private boolean mWallpaperForceHidingChanged = false;
105 private Object mLastWindowFreezeSource = null;
106 private Session mHoldScreen = null;
107 private boolean mObscured = false;
108 private boolean mSyswin = false;
109 private float mScreenBrightness = -1;
110 private float mButtonBrightness = -1;
111 private long mUserActivityTimeout = -1;
112 private boolean mUpdateRotation = false;
113 private final Rect mTmpStartRect = new Rect();
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800114 private final Rect mTmpContentRect = new Rect();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700115
116 // Set to true when the display contains content to show the user.
117 // When false, the display manager may choose to mirror or blank the display.
118 private boolean mDisplayHasContent = false;
119
120 // Only set while traversing the default display based on its content.
121 // Affects the behavior of mirroring on secondary displays.
122 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
123
124 private float mPreferredRefreshRate = 0;
125
126 private int mPreferredModeId = 0;
127
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700128 private boolean mTraversalScheduled;
Jorim Jaggic4025202015-10-22 16:43:34 +0200129 private int mDeferDepth = 0;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700130
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800131 private static final class LayerAndToken {
132 public int layer;
133 public AppWindowToken token;
134 }
135 private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
136
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100137 private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
138
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700139 public WindowSurfacePlacer(WindowManagerService service) {
140 mService = service;
141 mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
142 }
143
Jorim Jaggic4025202015-10-22 16:43:34 +0200144 /**
145 * See {@link WindowManagerService#deferSurfaceLayout()}
146 */
147 void deferLayout() {
148 mDeferDepth++;
149 }
150
151 /**
152 * See {@link WindowManagerService#continueSurfaceLayout()}
153 */
154 void continueLayout() {
155 mDeferDepth--;
156 if (mDeferDepth <= 0) {
157 performSurfacePlacement();
158 }
159 }
160
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700161 final void performSurfacePlacement() {
Jorim Jaggic4025202015-10-22 16:43:34 +0200162 if (mDeferDepth > 0) {
163 return;
164 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700165 int loopCount = 6;
166 do {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700167 mTraversalScheduled = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700168 performSurfacePlacementLoop();
169 mService.mH.removeMessages(DO_TRAVERSAL);
170 loopCount--;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700171 } while (mTraversalScheduled && loopCount > 0);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700172 mWallpaperActionPending = false;
173 }
174
175 private void performSurfacePlacementLoop() {
176 if (mInLayout) {
177 if (DEBUG) {
178 throw new RuntimeException("Recursive call!");
179 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800180 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700181 + Debug.getCallers(3));
182 return;
183 }
184
185 if (mService.mWaitingForConfig) {
186 // Our configuration has changed (most likely rotation), but we
187 // don't yet have the complete configuration to report to
188 // applications. Don't do any window layout until we have it.
189 return;
190 }
191
192 if (!mService.mDisplayReady) {
193 // Not yet initialized, nothing to do.
194 return;
195 }
196
197 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
198 mInLayout = true;
199
200 boolean recoveringMemory = false;
201 if (!mService.mForceRemoves.isEmpty()) {
202 recoveringMemory = true;
203 // Wait a little bit for things to settle down, and off we go.
204 while (!mService.mForceRemoves.isEmpty()) {
205 WindowState ws = mService.mForceRemoves.remove(0);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800206 Slog.i(TAG, "Force removing: " + ws);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700207 mService.removeWindowInnerLocked(ws);
208 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800209 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700210 Object tmp = new Object();
211 synchronized (tmp) {
212 try {
213 tmp.wait(250);
214 } catch (InterruptedException e) {
215 }
216 }
217 }
218
219 try {
220 performSurfacePlacementInner(recoveringMemory);
221
222 mInLayout = false;
223
224 if (mService.needsLayout()) {
225 if (++mLayoutRepeatCount < 6) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700226 requestTraversal();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700227 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800228 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700229 mLayoutRepeatCount = 0;
230 }
231 } else {
232 mLayoutRepeatCount = 0;
233 }
234
235 if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
236 mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
237 mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
238 }
239 } catch (RuntimeException e) {
240 mInLayout = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800241 Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700242 }
243
244 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
245 }
246
247 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
248 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800249 Slog.v(TAG, "Layouts looping: " + msg +
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700250 ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
251 }
252 }
253
254 // "Something has changed! Let's make it correct now."
255 private void performSurfacePlacementInner(boolean recoveringMemory) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800256 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
257 + Debug.getCallers(3));
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700258
259 int i;
260 boolean updateInputWindowsNeeded = false;
261
262 if (mService.mFocusMayChange) {
263 mService.mFocusMayChange = false;
264 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
265 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
266 }
267
268 // Initialize state of exiting tokens.
269 final int numDisplays = mService.mDisplayContents.size();
270 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
271 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
272 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
273 displayContent.mExitingTokens.get(i).hasVisible = false;
274 }
275 }
276
277 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
278 // Initialize state of exiting applications.
279 final AppTokenList exitingAppTokens =
280 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
281 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
282 exitingAppTokens.get(tokenNdx).hasVisible = false;
283 }
284 }
285
286 mHoldScreen = null;
287 mScreenBrightness = -1;
288 mButtonBrightness = -1;
289 mUserActivityTimeout = -1;
290 mObscureApplicationContentOnSecondaryDisplays = false;
291
292 mService.mTransactionSequence++;
293
294 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
295 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
296 final int defaultDw = defaultInfo.logicalWidth;
297 final int defaultDh = defaultInfo.logicalHeight;
298
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800299 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700300 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
301 SurfaceControl.openTransaction();
302 try {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700303 applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700304 } catch (RuntimeException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800305 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700306 } finally {
307 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800308 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700309 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
310 }
311
312 final WindowList defaultWindows = defaultDisplay.getWindowList();
313
314 // If we are ready to perform an app transition, check through
315 // all of the app tokens to be shown and see if they are ready
316 // to go.
317 if (mService.mAppTransition.isReady()) {
318 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
319 if (DEBUG_LAYOUT_REPEATS)
320 debugLayoutRepeats("after handleAppTransitionReadyLocked",
321 defaultDisplay.pendingLayoutChanges);
322 }
323
324 if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
325 // We have finished the animation of an app transition. To do
326 // this, we have delayed a lot of operations like showing and
327 // hiding apps, moving apps in Z-order, etc. The app token list
328 // reflects the correct Z-order, but the window list may now
329 // be out of sync with it. So here we will just rebuild the
330 // entire app window list. Fun!
331 defaultDisplay.pendingLayoutChanges |=
332 mService.handleAnimatingStoppedAndTransitionLocked();
333 if (DEBUG_LAYOUT_REPEATS)
334 debugLayoutRepeats("after handleAnimStopAndXitionLock",
335 defaultDisplay.pendingLayoutChanges);
336 }
337
338 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
339 && !mService.mAppTransition.isReady()) {
340 // At this point, there was a window with a wallpaper that
341 // was force hiding other windows behind it, but now it
342 // is going away. This may be simple -- just animate
343 // away the wallpaper and its window -- or it may be
344 // hard -- the wallpaper now needs to be shown behind
345 // something that was hidden.
346 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
347 if (DEBUG_LAYOUT_REPEATS)
348 debugLayoutRepeats("after animateAwayWallpaperLocked",
349 defaultDisplay.pendingLayoutChanges);
350 }
351 mWallpaperForceHidingChanged = false;
352
353 if (mWallpaperMayChange) {
354 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800355 Slog.v(TAG, "Wallpaper may change! Adjusting");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700356 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
357 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
358 defaultDisplay.pendingLayoutChanges);
359 }
360
361 if (mService.mFocusMayChange) {
362 mService.mFocusMayChange = false;
363 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
364 false /*updateInputWindows*/)) {
365 updateInputWindowsNeeded = true;
366 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
367 }
368 }
369
370 if (mService.needsLayout()) {
371 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
372 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
373 defaultDisplay.pendingLayoutChanges);
374 }
375
376 for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
377 WindowState win = mService.mResizingWindows.get(i);
378 if (win.mAppFreezing) {
379 // Don't remove this window until rotation has completed.
380 continue;
381 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700382 // Discard the saved surface if window size is changed, it can't be reused.
Chong Zhangbef461f2015-10-27 11:38:24 -0700383 if (win.mAppToken != null) {
384 win.mAppToken.destroySavedSurfaces();
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700385 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700386 win.reportResized();
387 mService.mResizingWindows.remove(i);
388 }
389
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800390 if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
391 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700392 if (mOrientationChangeComplete) {
393 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
394 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
395 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
396 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
397 }
398 mService.stopFreezingDisplayLocked();
399 }
400
401 // Destroy the surface of any windows that are no longer visible.
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800402 boolean wallpaperDestroyed = false;
403 i = mService.mDestroySurface.size();
404 if (i > 0) {
405 do {
406 i--;
407 WindowState win = mService.mDestroySurface.get(i);
408 win.mDestroying = false;
409 if (mService.mInputMethodWindow == win) {
410 mService.mInputMethodWindow = null;
411 }
412 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
413 wallpaperDestroyed = true;
414 }
Robert Carr13f7be9e2015-12-02 18:39:45 -0800415 win.destroyOrSaveSurface();
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800416 } while (i > 0);
417 mService.mDestroySurface.clear();
418 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700419
420 // Time to remove any exiting tokens?
421 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
422 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
423 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
424 for (i = exitingTokens.size() - 1; i >= 0; i--) {
425 WindowToken token = exitingTokens.get(i);
426 if (!token.hasVisible) {
427 exitingTokens.remove(i);
428 if (token.windowType == TYPE_WALLPAPER) {
429 mWallpaperControllerLocked.removeWallpaperToken(token);
430 }
431 }
432 }
433 }
434
435 // Time to remove any exiting applications?
436 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
437 // Initialize state of exiting applications.
438 final AppTokenList exitingAppTokens =
439 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
440 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
441 AppWindowToken token = exitingAppTokens.get(i);
442 if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
443 (!token.mIsExiting || token.allAppWindows.isEmpty())) {
444 // Make sure there is no animation running on this token,
445 // so any windows associated with it will be removed as
446 // soon as their animations are complete
447 token.mAppAnimator.clearAnimation();
448 token.mAppAnimator.animating = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800449 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
450 "performLayout: App token exiting now removed" + token);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700451 token.removeAppFromTaskLocked();
452 }
453 }
454 }
455
456 if (wallpaperDestroyed) {
457 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
458 defaultDisplay.layoutNeeded = true;
459 }
460
461 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
462 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
463 if (displayContent.pendingLayoutChanges != 0) {
464 displayContent.layoutNeeded = true;
465 }
466 }
467
468 // Finally update all input windows now that the window changes have stabilized.
469 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
470
471 mService.setHoldScreenLocked(mHoldScreen);
472 if (!mService.mDisplayFrozen) {
473 if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
474 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
475 } else {
476 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
477 toBrightnessOverride(mScreenBrightness));
478 }
479 if (mButtonBrightness < 0
480 || mButtonBrightness > 1.0f) {
481 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
482 } else {
483 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
484 toBrightnessOverride(mButtonBrightness));
485 }
486 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
487 mUserActivityTimeout);
488 }
489
490 if (mService.mTurnOnScreen) {
491 if (mService.mAllowTheaterModeWakeFromLayout
492 || Settings.Global.getInt(mService.mContext.getContentResolver(),
493 Settings.Global.THEATER_MODE_ON, 0) == 0) {
494 if (DEBUG_VISIBILITY || DEBUG_POWER) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800495 Slog.v(TAG, "Turning screen on after layout!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700496 }
497 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
498 "android.server.wm:TURN_ON");
499 }
500 mService.mTurnOnScreen = false;
501 }
502
503 if (mUpdateRotation) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800504 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700505 if (mService.updateRotationUncheckedLocked(false)) {
506 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
507 } else {
508 mUpdateRotation = false;
509 }
510 }
511
512 if (mService.mWaitingForDrawnCallback != null ||
513 (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
514 !mUpdateRotation)) {
515 mService.checkDrawnWindowsLocked();
516 }
517
518 final int N = mService.mPendingRemove.size();
519 if (N > 0) {
520 if (mService.mPendingRemoveTmp.length < N) {
521 mService.mPendingRemoveTmp = new WindowState[N+10];
522 }
523 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
524 mService.mPendingRemove.clear();
525 DisplayContentList displayList = new DisplayContentList();
526 for (i = 0; i < N; i++) {
527 WindowState w = mService.mPendingRemoveTmp[i];
528 mService.removeWindowInnerLocked(w);
529 final DisplayContent displayContent = w.getDisplayContent();
530 if (displayContent != null && !displayList.contains(displayContent)) {
531 displayList.add(displayContent);
532 }
533 }
534
535 for (DisplayContent displayContent : displayList) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800536 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700537 displayContent.layoutNeeded = true;
538 }
539 }
540
541 // Remove all deferred displays stacks, tasks, and activities.
542 for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
543 mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
544 }
545
546 if (updateInputWindowsNeeded) {
547 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
548 }
Chong Zhangb15758a2015-11-17 12:12:03 -0800549 mService.setFocusTaskRegionLocked();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700550
551 // Check to see if we are now in a state where the screen should
552 // be enabled, because the window obscured flags have changed.
553 mService.enableScreenIfNeededLocked();
554
555 mService.scheduleAnimationLocked();
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100556 mService.mWindowPlacerLocked.destroyPendingSurfaces();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700557
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800558 if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
Wale Ogunwale69cf50f2015-11-13 11:08:36 -0800559 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700560 }
561
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700562 private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
563 int defaultDw, int defaultDh) {
564 if (mService.mWatermark != null) {
565 mService.mWatermark.positionSurface(defaultDw, defaultDh);
566 }
567 if (mService.mStrictModeFlash != null) {
568 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
569 }
570 if (mService.mCircularDisplayMask != null) {
571 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
572 mService.mRotation);
573 }
574 if (mService.mEmulatorDisplayOverlay != null) {
575 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
576 mService.mRotation);
577 }
578
579 boolean focusDisplayed = false;
580
581 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
582 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
583 boolean updateAllDrawn = false;
584 WindowList windows = displayContent.getWindowList();
585 DisplayInfo displayInfo = displayContent.getDisplayInfo();
586 final int displayId = displayContent.getDisplayId();
587 final int dw = displayInfo.logicalWidth;
588 final int dh = displayInfo.logicalHeight;
589 final int innerDw = displayInfo.appWidth;
590 final int innerDh = displayInfo.appHeight;
591 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
592
593 // Reset for each display.
594 mDisplayHasContent = false;
595 mPreferredRefreshRate = 0;
596 mPreferredModeId = 0;
597
598 int repeats = 0;
599 do {
600 repeats++;
601 if (repeats > 6) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800602 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700603 displayContent.layoutNeeded = false;
604 break;
605 }
606
607 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
608 "On entry to LockedInner", displayContent.pendingLayoutChanges);
609
610 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
611 mWallpaperControllerLocked.adjustWallpaperWindows()) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800612 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700613 displayContent.layoutNeeded = true;
614 }
615
616 if (isDefaultDisplay
617 && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800618 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700619 if (mService.updateOrientationFromAppTokensLocked(true)) {
620 displayContent.layoutNeeded = true;
621 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
622 }
623 }
624
625 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
626 displayContent.layoutNeeded = true;
627 }
628
629 // FIRST LOOP: Perform a layout, if needed.
630 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
631 performLayoutLockedInner(displayContent, repeats == 1,
632 false /* updateInputWindows */);
633 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800634 Slog.w(TAG, "Layout repeat skipped after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700635 }
636
637 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
638 // it is animating.
639 displayContent.pendingLayoutChanges = 0;
640
641 if (isDefaultDisplay) {
642 mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
643 for (int i = windows.size() - 1; i >= 0; i--) {
644 WindowState w = windows.get(i);
645 if (w.mHasSurface) {
646 mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
647 w.mAttachedWindow);
648 }
649 }
650 displayContent.pendingLayoutChanges |=
651 mService.mPolicy.finishPostLayoutPolicyLw();
652 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
653 displayContent.pendingLayoutChanges);
654 }
655 } while (displayContent.pendingLayoutChanges != 0);
656
657 mObscured = false;
658 mSyswin = false;
659 displayContent.resetDimming();
660
661 // Only used if default window
662 final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
663
664 for (int i = windows.size() - 1; i >= 0; i--) {
665 WindowState w = windows.get(i);
Robert Carr0d00c2e2016-02-29 17:45:02 -0800666 final Task task = w.getTask();
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700667 final boolean obscuredChanged = w.mObscured != mObscured;
668
669 // Update effect.
670 w.mObscured = mObscured;
671 if (!mObscured) {
Chong Zhang0abb20f2015-11-19 14:17:31 -0800672 handleNotObscuredLocked(w, displayInfo);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700673 }
674
Chong Zhang112eb8c2015-11-02 11:17:00 -0800675 w.applyDimLayerIfNeeded();
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700676
677 if (isDefaultDisplay && obscuredChanged
678 && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
679 // This is the wallpaper target and its obscured state
680 // changed... make sure the current wallaper's visibility
681 // has been updated accordingly.
682 mWallpaperControllerLocked.updateWallpaperVisibility();
683 }
684
685 final WindowStateAnimator winAnimator = w.mWinAnimator;
686
687 // If the window has moved due to its containing content frame changing, then
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800688 // notify the listeners and optionally animate it. Simply checking a change of
689 // position is not enough, because being move due to dock divider is not a trigger
690 // for animation.
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700691 if (w.hasMoved()) {
692 // Frame has moved, containing content frame has also moved, and we're not
693 // currently animating... let's do something.
694 final int left = w.mFrame.left;
695 final int top = w.mFrame.top;
Chong Zhangbaba7832016-03-24 10:21:26 -0700696 final boolean adjustedForMinimizedDockOrIme = task != null
697 && (task.mStack.isAdjustedForMinimizedDockedStack()
698 || task.mStack.isAdjustedForIme());
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800699 if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
Chong Zhangbaba7832016-03-24 10:21:26 -0700700 && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
Jorim Jaggi192086e2016-03-11 17:17:03 +0100701 && (task == null || !w.getTask().mStack.getFreezeMovementAnimations())
702 && !w.mWinAnimator.mLastHidden) {
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800703 winAnimator.setMoveAnimation(left, top);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700704 }
705
706 //TODO (multidisplay): Accessibility supported only for the default display.
707 if (mService.mAccessibilityController != null
708 && displayId == Display.DEFAULT_DISPLAY) {
709 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
710 }
711
712 try {
713 w.mClient.moved(left, top);
714 } catch (RemoteException e) {
715 }
Jorim Jaggi192086e2016-03-11 17:17:03 +0100716 w.mMovedByResize = false;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700717 }
718
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800719 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700720 w.mContentChanged = false;
721
722 // Moved from updateWindowsAndWallpaperLocked().
723 if (w.mHasSurface) {
724 // Take care of the window being ready to display.
725 final boolean committed = winAnimator.commitFinishDrawingLocked();
726 if (isDefaultDisplay && committed) {
727 if (w.mAttrs.type == TYPE_DREAM) {
728 // HACK: When a dream is shown, it may at that
729 // point hide the lock screen. So we need to
730 // redo the layout to let the phone window manager
731 // make this happen.
732 displayContent.pendingLayoutChanges |=
733 FINISH_LAYOUT_REDO_LAYOUT;
734 if (DEBUG_LAYOUT_REPEATS) {
735 debugLayoutRepeats("dream and commitFinishDrawingLocked true",
736 displayContent.pendingLayoutChanges);
737 }
738 }
739 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
740 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800741 Slog.v(TAG, "First draw done in potential wallpaper target " + w);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700742 mWallpaperMayChange = true;
743 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
744 if (DEBUG_LAYOUT_REPEATS) {
745 debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
746 displayContent.pendingLayoutChanges);
747 }
748 }
749 }
Filip Gruszczynskic46f41c2016-01-05 11:29:21 -0800750 if (!winAnimator.isAnimating()) {
751 // Updates the shown frame before we set up the surface. This is needed
752 // because the resizing could change the top-left position (in addition to
753 // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
754 // position the surface. We only apply it to windows that aren't animating,
755 // because we depend on the animation to calculate the correct shown frame
756 // on the next animation step.
757 winAnimator.computeShownFrameLocked();
758 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700759 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
760 }
761
762 final AppWindowToken atoken = w.mAppToken;
763 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800764 Slog.d(TAG, "updateWindows: starting " + w
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700765 + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
766 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
767 }
768 if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
769 if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
770 atoken.lastTransactionSequence = mService.mTransactionSequence;
771 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
772 atoken.startingDisplayed = false;
773 }
774 if ((w.isOnScreenIgnoringKeyguard()
775 || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800776 && !w.mAnimatingExit && !w.mDestroying) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700777 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800778 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700779 + w.isDrawnLw()
780 + ", isAnimating=" + winAnimator.isAnimating());
781 if (!w.isDrawnLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800782 Slog.v(TAG, "Not displayed: s="
Robert Carre6a83512015-11-03 16:09:21 -0800783 + winAnimator.mSurfaceController
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700784 + " pv=" + w.mPolicyVisibility
785 + " mDrawState=" + winAnimator.drawStateToString()
786 + " ah=" + w.mAttachedHidden
787 + " th=" + atoken.hiddenRequested
788 + " a=" + winAnimator.mAnimating);
789 }
790 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800791 if (w != atoken.startingWindow) {
792 if (!w.mAppDied &&
793 (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing)) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700794 atoken.numInterestingWindows++;
795 if (w.isDrawnLw()) {
796 atoken.numDrawnWindows++;
797 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800798 Slog.v(TAG, "tokenMayBeDrawn: " + atoken
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700799 + " freezingScreen="
800 + atoken.mAppAnimator.freezingScreen
801 + " mAppFreezing=" + w.mAppFreezing);
802 updateAllDrawn = true;
803 }
804 }
805 } else if (w.isDrawnLw()) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500806 mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700807 atoken.startingDisplayed = true;
808 }
809 }
810 }
811
812 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
813 && w.isDisplayedLw()) {
814 focusDisplayed = true;
815 }
816
817 mService.updateResizingWindows(w);
818 }
819
820 mService.mDisplayManagerInternal.setDisplayProperties(displayId,
821 mDisplayHasContent,
822 mPreferredRefreshRate,
823 mPreferredModeId,
824 true /* inTraversal, must call performTraversalInTrans... below */);
825
826 mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
827
828 if (updateAllDrawn) {
829 updateAllDrawnLocked(displayContent);
830 }
831 }
832
833 if (focusDisplayed) {
834 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
835 }
836
837 // Give the display manager a chance to adjust properties
838 // like display rotation if it needs to.
839 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
840 }
841
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700842 boolean isInLayout() {
843 return mInLayout;
844 }
845
846 final void performLayoutLockedInner(final DisplayContent displayContent,
847 boolean initial, boolean updateInputWindows) {
848 if (!displayContent.layoutNeeded) {
849 return;
850 }
851 displayContent.layoutNeeded = false;
852 WindowList windows = displayContent.getWindowList();
853 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
854
855 DisplayInfo displayInfo = displayContent.getDisplayInfo();
856 final int dw = displayInfo.logicalWidth;
857 final int dh = displayInfo.logicalHeight;
858
859 if (mService.mInputConsumer != null) {
860 mService.mInputConsumer.layout(dw, dh);
861 }
862
Vladislav Kaznacheev0d50d862016-03-29 15:43:28 -0700863 if (mService.mWallpaperInputConsumer != null) {
864 mService.mWallpaperInputConsumer.layout(dw, dh);
865 }
866
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700867 final int N = windows.size();
868 int i;
869
870 if (DEBUG_LAYOUT) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800871 Slog.v(TAG, "-------------------------------------");
872 Slog.v(TAG, "performLayout: needed="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700873 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
874 }
875
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800876 mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
877 mService.mCurConfiguration.uiMode);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700878 if (isDefaultDisplay) {
879 // Not needed on non-default displays.
880 mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
881 mService.mScreenRect.set(0, 0, dw, dh);
882 }
883
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800884 mService.mPolicy.getContentRectLw(mTmpContentRect);
885 displayContent.resize(mTmpContentRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700886
887 int seq = mService.mLayoutSeq+1;
888 if (seq < 0) seq = 0;
889 mService.mLayoutSeq = seq;
890
891 boolean behindDream = false;
892
893 // First perform layout of any root windows (not attached
894 // to another window).
895 int topAttached = -1;
896 for (i = N-1; i >= 0; i--) {
897 final WindowState win = windows.get(i);
898
899 // Don't do layout of a window if it is not visible, or
900 // soon won't be visible, to avoid wasting time and funky
901 // changes while a window is animating away.
902 final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
903 || win.isGoneForLayoutLw();
904
905 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800906 Slog.v(TAG, "1ST PASS " + win
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700907 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
908 + " mLayoutAttached=" + win.mLayoutAttached
909 + " screen changed=" + win.isConfigChanged());
910 final AppWindowToken atoken = win.mAppToken;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800911 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700912 + win.mViewVisibility + " mRelayoutCalled="
913 + win.mRelayoutCalled + " hidden="
914 + win.mRootToken.hidden + " hiddenRequested="
915 + (atoken != null && atoken.hiddenRequested)
916 + " mAttachedHidden=" + win.mAttachedHidden);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800917 else Slog.v(TAG, " VIS: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700918 + win.mViewVisibility + " mRelayoutCalled="
919 + win.mRelayoutCalled + " hidden="
920 + win.mRootToken.hidden + " hiddenRequested="
921 + (atoken != null && atoken.hiddenRequested)
922 + " mAttachedHidden=" + win.mAttachedHidden);
923 }
924
925 // If this view is GONE, then skip it -- keep the current
926 // frame, and let the caller know so they can ignore it
927 // if they want. (We do the normal layout for INVISIBLE
928 // windows, since that means "perform layout as normal,
929 // just don't display").
930 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
931 || ((win.isConfigChanged() || win.setInsetsChanged()) &&
932 ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
933 (win.mHasSurface && win.mAppToken != null &&
934 win.mAppToken.layoutConfigChanges)))) {
935 if (!win.mLayoutAttached) {
936 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800937 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700938 win.mContentChanged = false;
939 }
940 if (win.mAttrs.type == TYPE_DREAM) {
941 // Don't layout windows behind a dream, so that if it
942 // does stuff like hide the status bar we won't get a
943 // bad transition when it goes away.
944 behindDream = true;
945 }
946 win.mLayoutNeeded = false;
947 win.prelayout();
948 mService.mPolicy.layoutWindowLw(win, null);
949 win.mLayoutSeq = seq;
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800950
951 // Window frames may have changed. Update dim layer with the new bounds.
952 final Task task = win.getTask();
953 if (task != null) {
954 displayContent.mDimLayerController.updateDimLayer(task);
955 }
956
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800957 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700958 " LAYOUT: mFrame="
959 + win.mFrame + " mContainingFrame="
960 + win.mContainingFrame + " mDisplayFrame="
961 + win.mDisplayFrame);
962 } else {
963 if (topAttached < 0) topAttached = i;
964 }
965 }
966 }
967
968 boolean attachedBehindDream = false;
969
970 // Now perform layout of attached windows, which usually
971 // depend on the position of the window they are attached to.
972 // XXX does not deal with windows that are attached to windows
973 // that are themselves attached.
974 for (i = topAttached; i >= 0; i--) {
975 final WindowState win = windows.get(i);
976
977 if (win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800978 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700979 "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
980 + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
981 // If this view is GONE, then skip it -- keep the current
982 // frame, and let the caller know so they can ignore it
983 // if they want. (We do the normal layout for INVISIBLE
984 // windows, since that means "perform layout as normal,
985 // just don't display").
986 if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
987 continue;
988 }
989 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
990 || !win.mHaveFrame || win.mLayoutNeeded) {
991 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800992 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700993 win.mContentChanged = false;
994 }
995 win.mLayoutNeeded = false;
996 win.prelayout();
997 mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
998 win.mLayoutSeq = seq;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800999 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001000 " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
1001 + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
1002 }
1003 } else if (win.mAttrs.type == TYPE_DREAM) {
1004 // Don't layout windows behind a dream, so that if it
1005 // does stuff like hide the status bar we won't get a
1006 // bad transition when it goes away.
1007 attachedBehindDream = behindDream;
1008 }
1009 }
1010
Chong Zhang4c9ba52a2015-11-10 18:36:33 -08001011 // Window frames may have changed. Tell the input dispatcher about it.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001012 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
1013 if (updateInputWindows) {
1014 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
1015 }
1016
1017 mService.mPolicy.finishLayoutLw();
Jorim Jaggi61f39a72015-10-29 16:54:18 +01001018 mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001019 }
1020
1021 /**
1022 * @param windows List of windows on default display.
1023 * @return bitmap indicating if another pass through layout must be made.
1024 */
1025 private int handleAppTransitionReadyLocked(WindowList windows) {
1026 int appsCount = mService.mOpeningApps.size();
1027 if (!transitionGoodToGo(appsCount)) {
1028 return 0;
1029 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001030 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001031 int transit = mService.mAppTransition.getAppTransition();
1032 if (mService.mSkipAppTransitionAnimation) {
1033 transit = AppTransition.TRANSIT_UNSET;
1034 }
1035 mService.mSkipAppTransitionAnimation = false;
1036 mService.mNoAnimationNotifyOnTransitionFinished.clear();
1037
1038 mService.mH.removeMessages(APP_TRANSITION_TIMEOUT);
1039
1040 mService.rebuildAppWindowListLocked();
1041
1042 mWallpaperMayChange = false;
1043
1044 // The top-most window will supply the layout params,
1045 // and we will determine it below.
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001046 LayoutParams animLp = null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001047 int bestAnimLayer = -1;
1048 boolean fullscreenAnim = false;
1049 boolean voiceInteraction = false;
1050
1051 final WindowState lowerWallpaperTarget =
1052 mWallpaperControllerLocked.getLowerWallpaperTarget();
1053 final WindowState upperWallpaperTarget =
1054 mWallpaperControllerLocked.getUpperWallpaperTarget();
1055
1056 boolean openingAppHasWallpaper = false;
1057 boolean closingAppHasWallpaper = false;
1058 final AppWindowToken lowerWallpaperAppToken;
1059 final AppWindowToken upperWallpaperAppToken;
1060 if (lowerWallpaperTarget == null) {
1061 lowerWallpaperAppToken = upperWallpaperAppToken = null;
1062 } else {
1063 lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
1064 upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
1065 }
1066
1067 int i;
1068 // Do a first pass through the tokens for two
1069 // things:
1070 // (1) Determine if both the closing and opening
1071 // app token sets are wallpaper targets, in which
1072 // case special animations are needed
1073 // (since the wallpaper needs to stay static
1074 // behind them).
1075 // (2) Find the layout params of the top-most
1076 // application window in the tokens, which is
1077 // what will control the animation theme.
1078 final int closingAppsCount = mService.mClosingApps.size();
1079 appsCount = closingAppsCount + mService.mOpeningApps.size();
1080 for (i = 0; i < appsCount; i++) {
1081 final AppWindowToken wtoken;
1082 if (i < closingAppsCount) {
1083 wtoken = mService.mClosingApps.valueAt(i);
1084 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1085 closingAppHasWallpaper = true;
1086 }
1087 } else {
1088 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
1089 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1090 openingAppHasWallpaper = true;
1091 }
1092 }
1093
1094 voiceInteraction |= wtoken.voiceInteraction;
1095
1096 if (wtoken.appFullscreen) {
1097 WindowState ws = wtoken.findMainWindow();
1098 if (ws != null) {
1099 animLp = ws.mAttrs;
1100 bestAnimLayer = ws.mLayer;
1101 fullscreenAnim = true;
1102 }
1103 } else if (!fullscreenAnim) {
1104 WindowState ws = wtoken.findMainWindow();
1105 if (ws != null) {
1106 if (ws.mLayer > bestAnimLayer) {
1107 animLp = ws.mAttrs;
1108 bestAnimLayer = ws.mLayer;
1109 }
1110 }
1111 }
1112 }
1113
1114 transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
1115 closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
1116
1117 // If all closing windows are obscured, then there is
1118 // no need to do an animation. This is the case, for
1119 // example, when this transition is being done behind
1120 // the lock screen.
1121 if (!mService.mPolicy.allowAppAnimationsLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001122 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001123 "Animations disallowed by keyguard or dream.");
1124 animLp = null;
1125 }
1126
1127 processApplicationsAnimatingInPlace(transit);
1128
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001129 mTmpLayerAndToken.token = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001130 handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
1131 final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
1132 final int topClosingLayer = mTmpLayerAndToken.layer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001133
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001134 final AppWindowToken topOpeningApp = handleOpeningApps(transit,
1135 animLp, voiceInteraction, topClosingLayer);
1136
1137 final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
1138 topOpeningApp.mAppAnimator;
1139 final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
1140 topClosingApp.mAppAnimator;
1141
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001142 mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
1143 mService.mOpeningApps, mService.mClosingApps);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001144 mService.mAppTransition.postAnimationCallback();
1145 mService.mAppTransition.clear();
1146
1147 mService.mOpeningApps.clear();
1148 mService.mClosingApps.clear();
1149
1150 // This has changed the visibility of windows, so perform
1151 // a new layout to get them all up-to-date.
1152 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1153
1154 // TODO(multidisplay): IMEs are only supported on the default display.
1155 if (windows == mService.getDefaultWindowListLocked()
1156 && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -08001157 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001158 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001159 mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1160 true /*updateInputWindows*/);
1161 mService.mFocusMayChange = false;
1162 mService.notifyActivityDrawnForKeyguard();
1163 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
1164 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001165
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001166 private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
1167 boolean voiceInteraction, int topClosingLayer) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001168 AppWindowToken topOpeningApp = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001169 final int appsCount = mService.mOpeningApps.size();
1170 for (int i = 0; i < appsCount; i++) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001171 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1172 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001173 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001174
1175 if (!appAnimator.usingTransferredAnimation) {
1176 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -07001177 appAnimator.setNullAnimation();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001178 }
1179 wtoken.inPendingTransaction = false;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001180
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001181 if (!mService.setTokenVisibilityLocked(
1182 wtoken, animLp, true, transit, false, voiceInteraction)){
1183 // This token isn't going to be animating. Add it to the list of tokens to
1184 // be notified of app transition complete since the notification will not be
1185 // sent be the app window animator.
1186 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
1187 }
1188 wtoken.updateReportedVisibilityLocked();
1189 wtoken.waitingToShow = false;
1190
1191 appAnimator.mAllAppWinAnimators.clear();
1192 final int windowsCount = wtoken.allAppWindows.size();
1193 for (int j = 0; j < windowsCount; j++) {
1194 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1195 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001196 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001197 ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
1198 SurfaceControl.openTransaction();
1199 try {
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001200 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001201 } finally {
1202 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001203 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001204 "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
1205 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001206 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1207
1208 int topOpeningLayer = 0;
1209 if (animLp != null) {
1210 int layer = -1;
1211 for (int j = 0; j < wtoken.windows.size(); j++) {
Chong Zhangbef461f2015-10-27 11:38:24 -07001212 final WindowState win = wtoken.windows.get(j);
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001213 // Clearing the mAnimatingExit flag before entering animation. It will be set to true
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001214 // if app window is removed, or window relayout to invisible. We don't want to
1215 // clear it out for windows that get replaced, because the animation depends on
1216 // the flag to remove the replaced window.
Robert Carr7fed68d2016-01-19 21:24:57 -08001217 //
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001218 // We also don't clear the mAnimatingExit flag for windows which have the
Robert Carr7fed68d2016-01-19 21:24:57 -08001219 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
1220 // by the client. We should let animation proceed and not clear this flag or
1221 // they won't eventually be removed by WindowStateAnimator#finishExit.
1222 if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001223 win.mAnimatingExit = false;
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001224 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001225 if (win.mWinAnimator.mAnimLayer > layer) {
1226 layer = win.mWinAnimator.mAnimLayer;
1227 }
1228 }
1229 if (topOpeningApp == null || layer > topOpeningLayer) {
1230 topOpeningApp = wtoken;
1231 topOpeningLayer = layer;
1232 }
1233 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001234 if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
1235 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
1236 }
Jorim Jaggi192086e2016-03-11 17:17:03 +01001237 if (mService.mAppTransition.getAppTransition()
1238 == AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS) {
1239 appAnimator.startProlongAnimation(PROLONG_ANIMATION_AT_START);
1240 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001241 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001242 return topOpeningApp;
1243 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001244
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001245 private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
1246 LayerAndToken layerAndToken) {
1247 final int appsCount;
1248 appsCount = mService.mClosingApps.size();
1249 for (int i = 0; i < appsCount; i++) {
1250 AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
1251 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001252 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001253 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -07001254 appAnimator.setNullAnimation();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001255 wtoken.inPendingTransaction = false;
1256 mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
1257 voiceInteraction);
1258 wtoken.updateReportedVisibilityLocked();
1259 // Force the allDrawn flag, because we want to start
1260 // this guy's animations regardless of whether it's
1261 // gotten drawn.
1262 wtoken.allDrawn = true;
1263 wtoken.deferClearAllDrawn = false;
1264 // Ensure that apps that are mid-starting are also scheduled to have their
1265 // starting windows removed after the animation is complete
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001266 if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001267 mService.scheduleRemoveStartingWindowLocked(wtoken);
1268 }
1269 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001270
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001271 if (animLp != null) {
1272 int layer = -1;
1273 for (int j = 0; j < wtoken.windows.size(); j++) {
1274 WindowState win = wtoken.windows.get(j);
1275 if (win.mWinAnimator.mAnimLayer > layer) {
1276 layer = win.mWinAnimator.mAnimLayer;
1277 }
1278 }
1279 if (layerAndToken.token == null || layer > layerAndToken.layer) {
1280 layerAndToken.token = wtoken;
1281 layerAndToken.layer = layer;
1282 }
1283 }
1284 if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
1285 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
1286 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001287 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001288 }
1289
1290 private boolean transitionGoodToGo(int appsCount) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001291 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001292 "Checking " + appsCount + " opening apps (frozen="
1293 + mService.mDisplayFrozen + " timeout="
1294 + mService.mAppTransition.isTimeout() + ")...");
Jorim Jaggi275561a2016-02-23 10:11:02 -05001295 int reason = APP_TRANSITION_TIMEOUT;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001296 if (!mService.mAppTransition.isTimeout()) {
1297 for (int i = 0; i < appsCount; i++) {
1298 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001299 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001300 "Check opening app=" + wtoken + ": allDrawn="
1301 + wtoken.allDrawn + " startingDisplayed="
1302 + wtoken.startingDisplayed + " startingMoved="
Chong Zhangd78ddb42016-03-02 17:01:14 -08001303 + wtoken.startingMoved + " isRelaunching()="
1304 + wtoken.isRelaunching());
1305
1306 if (wtoken.isRelaunching()) {
1307 return false;
1308 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -07001309
Jorim Jaggi275561a2016-02-23 10:11:02 -05001310 final boolean drawnBeforeRestoring = wtoken.allDrawn;
Chong Zhangbfc2f8f2016-01-29 15:50:34 -08001311 wtoken.restoreSavedSurfaces();
1312
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001313 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
1314 return false;
1315 }
Jorim Jaggi275561a2016-02-23 10:11:02 -05001316 if (wtoken.allDrawn) {
1317 reason = drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
1318 : APP_TRANSITION_SAVED_SURFACE;
1319 } else {
1320 reason = APP_TRANSITION_STARTING_WINDOW;
1321 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001322 }
1323
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001324 // We also need to wait for the specs to be fetched, if needed.
1325 if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001326 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001327 return false;
1328 }
1329
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001330 // If the wallpaper is visible, we need to check it's ready too.
Jorim Jaggi275561a2016-02-23 10:11:02 -05001331 boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001332 mWallpaperControllerLocked.wallpaperTransitionReady();
Jorim Jaggi275561a2016-02-23 10:11:02 -05001333 if (wallpaperReady) {
1334 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1335 return true;
1336 }
1337 return false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001338 }
Jorim Jaggi275561a2016-02-23 10:11:02 -05001339 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001340 return true;
1341 }
1342
1343 private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
1344 boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
1345 WindowState upperWallpaperTarget) {
1346 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
1347 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
1348 final WindowState oldWallpaper =
1349 mWallpaperControllerLocked.isWallpaperTargetAnimating()
1350 ? null : wallpaperTarget;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001351 final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
1352 final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001353 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001354 "New wallpaper target=" + wallpaperTarget
1355 + ", oldWallpaper=" + oldWallpaper
1356 + ", lower target=" + lowerWallpaperTarget
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001357 + ", upper target=" + upperWallpaperTarget
1358 + ", openingApps=" + openingApps
1359 + ", closingApps=" + closingApps);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001360 mService.mAnimateWallpaperWithTarget = false;
1361 if (closingAppHasWallpaper && openingAppHasWallpaper) {
1362 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001363 Slog.v(TAG, "Wallpaper animation!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001364 switch (transit) {
1365 case AppTransition.TRANSIT_ACTIVITY_OPEN:
1366 case AppTransition.TRANSIT_TASK_OPEN:
1367 case AppTransition.TRANSIT_TASK_TO_FRONT:
1368 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
1369 break;
1370 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
1371 case AppTransition.TRANSIT_TASK_CLOSE:
1372 case AppTransition.TRANSIT_TASK_TO_BACK:
1373 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
1374 break;
1375 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001376 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001377 "New transit: " + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001378 } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
1379 && !openingApps.contains(oldWallpaper.mAppToken)
1380 && closingApps.contains(oldWallpaper.mAppToken)) {
1381 // We are transitioning from an activity with a wallpaper to one without.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001382 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001383 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001384 "New transit away from wallpaper: "
1385 + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001386 } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
1387 openingApps.contains(wallpaperTarget.mAppToken)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001388 // We are transitioning from an activity without
1389 // a wallpaper to now showing the wallpaper
1390 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001391 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001392 "New transit into wallpaper: "
1393 + AppTransition.appTransitionToString(transit));
1394 } else {
1395 mService.mAnimateWallpaperWithTarget = true;
1396 }
1397 return transit;
1398 }
1399
1400 /**
1401 * @param w WindowState this method is applied to.
Chong Zhang0abb20f2015-11-19 14:17:31 -08001402 * @param dispInfo info of the display that the window's obscuring state is checked against.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001403 */
Chong Zhang0abb20f2015-11-19 14:17:31 -08001404 private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001405 final LayoutParams attrs = w.mAttrs;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001406 final int attrFlags = attrs.flags;
1407 final boolean canBeSeen = w.isDisplayedLw();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001408
Chong Zhang0abb20f2015-11-19 14:17:31 -08001409 if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001410 // This window completely covers everything behind it,
1411 // so we want to leave all of them as undimmed (for
1412 // performance reasons).
1413 mObscured = true;
1414 }
1415
1416 if (w.mHasSurface) {
1417 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
1418 mHoldScreen = w.mSession;
1419 }
1420 if (!mSyswin && w.mAttrs.screenBrightness >= 0
1421 && mScreenBrightness < 0) {
1422 mScreenBrightness = w.mAttrs.screenBrightness;
1423 }
1424 if (!mSyswin && w.mAttrs.buttonBrightness >= 0
1425 && mButtonBrightness < 0) {
1426 mButtonBrightness = w.mAttrs.buttonBrightness;
1427 }
1428 if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
1429 && mUserActivityTimeout < 0) {
1430 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1431 }
1432
1433 final int type = attrs.type;
1434 if (canBeSeen
1435 && (type == TYPE_SYSTEM_DIALOG
1436 || type == TYPE_SYSTEM_ERROR
1437 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
1438 mSyswin = true;
1439 }
1440
1441 if (canBeSeen) {
1442 // This function assumes that the contents of the default display are
1443 // processed first before secondary displays.
1444 final DisplayContent displayContent = w.getDisplayContent();
1445 if (displayContent != null && displayContent.isDefaultDisplay) {
1446 // While a dream or keyguard is showing, obscure ordinary application
1447 // content on secondary displays (by forcibly enabling mirroring unless
1448 // there is other content we want to show) but still allow opaque
1449 // keyguard dialogs to be shown.
1450 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1451 mObscureApplicationContentOnSecondaryDisplays = true;
1452 }
1453 mDisplayHasContent = true;
1454 } else if (displayContent != null &&
1455 (!mObscureApplicationContentOnSecondaryDisplays
1456 || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1457 // Allow full screen keyguard presentation dialogs to be seen.
1458 mDisplayHasContent = true;
1459 }
1460 if (mPreferredRefreshRate == 0
1461 && w.mAttrs.preferredRefreshRate != 0) {
1462 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1463 }
1464 if (mPreferredModeId == 0
1465 && w.mAttrs.preferredDisplayModeId != 0) {
1466 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1467 }
1468 }
1469 }
1470 }
1471
1472 private void updateAllDrawnLocked(DisplayContent displayContent) {
1473 // See if any windows have been drawn, so they (and others
1474 // associated with them) can now be shown.
1475 ArrayList<TaskStack> stacks = displayContent.getStacks();
1476 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1477 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
1478 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1479 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1480 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
1481 final AppWindowToken wtoken = tokens.get(tokenNdx);
1482 if (!wtoken.allDrawn) {
1483 int numInteresting = wtoken.numInterestingWindows;
1484 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
1485 if (DEBUG_VISIBILITY)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001486 Slog.v(TAG, "allDrawn: " + wtoken
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001487 + " interesting=" + numInteresting
1488 + " drawn=" + wtoken.numDrawnWindows);
1489 wtoken.allDrawn = true;
1490 // Force an additional layout pass where WindowStateAnimator#
1491 // commitFinishDrawingLocked() will call performShowLocked().
1492 displayContent.layoutNeeded = true;
1493 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
1494 wtoken.token).sendToTarget();
1495 }
1496 }
1497 }
1498 }
1499 }
1500 }
1501
1502 private static int toBrightnessOverride(float value) {
1503 return (int)(value * PowerManager.BRIGHTNESS_ON);
1504 }
1505
1506 private void processApplicationsAnimatingInPlace(int transit) {
1507 if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
1508 // Find the focused window
1509 final WindowState win = mService.findFocusedWindowLocked(
1510 mService.getDefaultDisplayContentLocked());
1511 if (win != null) {
1512 final AppWindowToken wtoken = win.mAppToken;
1513 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1514 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001515 Slog.v(TAG, "Now animating app in place " + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001516 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -07001517 appAnimator.setNullAnimation();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001518 mService.updateTokenInPlaceLocked(wtoken, transit);
1519 wtoken.updateReportedVisibilityLocked();
1520
1521 appAnimator.mAllAppWinAnimators.clear();
1522 final int N = wtoken.allAppWindows.size();
1523 for (int j = 0; j < N; j++) {
1524 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1525 }
1526 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001527 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001528 }
1529 }
1530 }
1531
1532 private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
1533 int openingLayer, int closingLayer) {
1534 AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
1535 if (openingAppAnimator == null || openingAppAnimator.animation == null) {
1536 return;
1537 }
1538 final int taskId = appToken.mTask.mTaskId;
1539 Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
1540 if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001541 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001542 return;
1543 }
1544 // This thumbnail animation is very special, we need to have
1545 // an extra surface with the thumbnail included with the animation.
1546 Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
1547 try {
1548 // TODO(multi-display): support other displays
1549 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1550 final Display display = displayContent.getDisplay();
1551 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1552
1553 // Create a new surface for the thumbnail
1554 SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
1555 "thumbnail anim", dirty.width(), dirty.height(),
1556 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
1557 surfaceControl.setLayerStack(display.getLayerStack());
1558 if (SHOW_TRANSACTIONS) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001559 Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001560 }
1561
1562 // Draw the thumbnail onto the surface
1563 Surface drawSurface = new Surface();
1564 drawSurface.copyFrom(surfaceControl);
1565 Canvas c = drawSurface.lockCanvas(dirty);
1566 c.drawBitmap(thumbnailHeader, 0, 0, null);
1567 drawSurface.unlockCanvasAndPost(c);
1568 drawSurface.release();
1569
1570 // Get the thumbnail animation
1571 Animation anim;
1572 if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
1573 // If this is a multi-window scenario, we use the windows frame as
1574 // destination of the thumbnail header animation. If this is a full screen
1575 // window scenario, we use the whole display as the target.
1576 WindowState win = appToken.findMainWindow();
1577 Rect appRect = win != null ? win.getContentFrameLw() :
1578 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
Jorim Jaggide63d442016-03-14 14:56:56 +01001579 Rect insets = win != null ? win.mContentInsets : null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001580 // For the new aspect-scaled transition, we want it to always show
1581 // above the animating opening/closing window, and we want to
1582 // synchronize its thumbnail surface with the surface for the
1583 // open/close animation (only on the way down)
1584 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
Jorim Jaggi09072002016-03-25 16:48:42 -07001585 insets, thumbnailHeader, taskId, mService.mCurConfiguration.orientation);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001586 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
1587 openingAppAnimator.deferThumbnailDestruction =
1588 !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
1589 } else {
1590 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
1591 displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
1592 }
1593 anim.restrictDuration(MAX_ANIMATION_DURATION);
1594 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1595
1596 openingAppAnimator.thumbnail = surfaceControl;
1597 openingAppAnimator.thumbnailLayer = openingLayer;
1598 openingAppAnimator.thumbnailAnimation = anim;
1599 mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001600 } catch (Surface.OutOfResourcesException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001601 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001602 + dirty.width() + " h=" + dirty.height(), e);
1603 openingAppAnimator.clearThumbnail();
1604 }
1605 }
1606
1607 boolean copyAnimToLayoutParamsLocked() {
1608 boolean doRequest = false;
1609
1610 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1611 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1612 mUpdateRotation = true;
1613 doRequest = true;
1614 }
1615 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1616 mWallpaperMayChange = true;
1617 doRequest = true;
1618 }
1619 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1620 mWallpaperForceHidingChanged = true;
1621 doRequest = true;
1622 }
1623 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1624 mOrientationChangeComplete = false;
1625 } else {
1626 mOrientationChangeComplete = true;
1627 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1628 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1629 doRequest = true;
1630 }
1631 }
1632 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1633 mService.mTurnOnScreen = true;
1634 }
1635 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1636 mWallpaperActionPending = true;
1637 }
1638
1639 return doRequest;
1640 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001641
1642 void requestTraversal() {
1643 if (!mTraversalScheduled) {
1644 mTraversalScheduled = true;
1645 mService.mH.sendEmptyMessage(DO_TRAVERSAL);
1646 }
1647 }
1648
Jorim Jaggi3dac63a2016-03-01 12:37:07 +01001649 /**
1650 * Puts the {@param surface} into a pending list to be destroyed after the current transaction
1651 * has been committed.
1652 */
1653 void destroyAfterTransaction(SurfaceControl surface) {
1654 mPendingDestroyingSurfaces.add(surface);
1655 }
1656
1657 /**
1658 * Destroys any surfaces that have been put into the pending list with
1659 * {@link #destroyAfterTransaction}.
1660 */
1661 void destroyPendingSurfaces() {
1662 for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
1663 mPendingDestroyingSurfaces.get(i).destroy();
1664 }
1665 mPendingDestroyingSurfaces.clear();
1666 }
1667
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001668 public void dump(PrintWriter pw, String prefix) {
1669 pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
1670 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001671}