blob: 3e5ddbce5a7b30edfd72a0ecc0c04ad0b27f158d [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
863 final int N = windows.size();
864 int i;
865
866 if (DEBUG_LAYOUT) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800867 Slog.v(TAG, "-------------------------------------");
868 Slog.v(TAG, "performLayout: needed="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700869 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
870 }
871
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800872 mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
873 mService.mCurConfiguration.uiMode);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700874 if (isDefaultDisplay) {
875 // Not needed on non-default displays.
876 mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
877 mService.mScreenRect.set(0, 0, dw, dh);
878 }
879
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800880 mService.mPolicy.getContentRectLw(mTmpContentRect);
881 displayContent.resize(mTmpContentRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700882
883 int seq = mService.mLayoutSeq+1;
884 if (seq < 0) seq = 0;
885 mService.mLayoutSeq = seq;
886
887 boolean behindDream = false;
888
889 // First perform layout of any root windows (not attached
890 // to another window).
891 int topAttached = -1;
892 for (i = N-1; i >= 0; i--) {
893 final WindowState win = windows.get(i);
894
895 // Don't do layout of a window if it is not visible, or
896 // soon won't be visible, to avoid wasting time and funky
897 // changes while a window is animating away.
898 final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
899 || win.isGoneForLayoutLw();
900
901 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800902 Slog.v(TAG, "1ST PASS " + win
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700903 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
904 + " mLayoutAttached=" + win.mLayoutAttached
905 + " screen changed=" + win.isConfigChanged());
906 final AppWindowToken atoken = win.mAppToken;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800907 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700908 + win.mViewVisibility + " mRelayoutCalled="
909 + win.mRelayoutCalled + " hidden="
910 + win.mRootToken.hidden + " hiddenRequested="
911 + (atoken != null && atoken.hiddenRequested)
912 + " mAttachedHidden=" + win.mAttachedHidden);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800913 else Slog.v(TAG, " VIS: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700914 + win.mViewVisibility + " mRelayoutCalled="
915 + win.mRelayoutCalled + " hidden="
916 + win.mRootToken.hidden + " hiddenRequested="
917 + (atoken != null && atoken.hiddenRequested)
918 + " mAttachedHidden=" + win.mAttachedHidden);
919 }
920
921 // If this view is GONE, then skip it -- keep the current
922 // frame, and let the caller know so they can ignore it
923 // if they want. (We do the normal layout for INVISIBLE
924 // windows, since that means "perform layout as normal,
925 // just don't display").
926 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
927 || ((win.isConfigChanged() || win.setInsetsChanged()) &&
928 ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
929 (win.mHasSurface && win.mAppToken != null &&
930 win.mAppToken.layoutConfigChanges)))) {
931 if (!win.mLayoutAttached) {
932 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800933 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700934 win.mContentChanged = false;
935 }
936 if (win.mAttrs.type == TYPE_DREAM) {
937 // Don't layout windows behind a dream, so that if it
938 // does stuff like hide the status bar we won't get a
939 // bad transition when it goes away.
940 behindDream = true;
941 }
942 win.mLayoutNeeded = false;
943 win.prelayout();
944 mService.mPolicy.layoutWindowLw(win, null);
945 win.mLayoutSeq = seq;
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800946
947 // Window frames may have changed. Update dim layer with the new bounds.
948 final Task task = win.getTask();
949 if (task != null) {
950 displayContent.mDimLayerController.updateDimLayer(task);
951 }
952
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800953 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700954 " LAYOUT: mFrame="
955 + win.mFrame + " mContainingFrame="
956 + win.mContainingFrame + " mDisplayFrame="
957 + win.mDisplayFrame);
958 } else {
959 if (topAttached < 0) topAttached = i;
960 }
961 }
962 }
963
964 boolean attachedBehindDream = false;
965
966 // Now perform layout of attached windows, which usually
967 // depend on the position of the window they are attached to.
968 // XXX does not deal with windows that are attached to windows
969 // that are themselves attached.
970 for (i = topAttached; i >= 0; i--) {
971 final WindowState win = windows.get(i);
972
973 if (win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800974 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700975 "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
976 + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
977 // If this view is GONE, then skip it -- keep the current
978 // frame, and let the caller know so they can ignore it
979 // if they want. (We do the normal layout for INVISIBLE
980 // windows, since that means "perform layout as normal,
981 // just don't display").
982 if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
983 continue;
984 }
985 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
986 || !win.mHaveFrame || win.mLayoutNeeded) {
987 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800988 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700989 win.mContentChanged = false;
990 }
991 win.mLayoutNeeded = false;
992 win.prelayout();
993 mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
994 win.mLayoutSeq = seq;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800995 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700996 " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
997 + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
998 }
999 } else if (win.mAttrs.type == TYPE_DREAM) {
1000 // Don't layout windows behind a dream, so that if it
1001 // does stuff like hide the status bar we won't get a
1002 // bad transition when it goes away.
1003 attachedBehindDream = behindDream;
1004 }
1005 }
1006
Chong Zhang4c9ba52a2015-11-10 18:36:33 -08001007 // Window frames may have changed. Tell the input dispatcher about it.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001008 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
1009 if (updateInputWindows) {
1010 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
1011 }
1012
1013 mService.mPolicy.finishLayoutLw();
Jorim Jaggi61f39a72015-10-29 16:54:18 +01001014 mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001015 }
1016
1017 /**
1018 * @param windows List of windows on default display.
1019 * @return bitmap indicating if another pass through layout must be made.
1020 */
1021 private int handleAppTransitionReadyLocked(WindowList windows) {
1022 int appsCount = mService.mOpeningApps.size();
1023 if (!transitionGoodToGo(appsCount)) {
1024 return 0;
1025 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001026 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001027 int transit = mService.mAppTransition.getAppTransition();
1028 if (mService.mSkipAppTransitionAnimation) {
1029 transit = AppTransition.TRANSIT_UNSET;
1030 }
1031 mService.mSkipAppTransitionAnimation = false;
1032 mService.mNoAnimationNotifyOnTransitionFinished.clear();
1033
1034 mService.mH.removeMessages(APP_TRANSITION_TIMEOUT);
1035
1036 mService.rebuildAppWindowListLocked();
1037
1038 mWallpaperMayChange = false;
1039
1040 // The top-most window will supply the layout params,
1041 // and we will determine it below.
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001042 LayoutParams animLp = null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001043 int bestAnimLayer = -1;
1044 boolean fullscreenAnim = false;
1045 boolean voiceInteraction = false;
1046
1047 final WindowState lowerWallpaperTarget =
1048 mWallpaperControllerLocked.getLowerWallpaperTarget();
1049 final WindowState upperWallpaperTarget =
1050 mWallpaperControllerLocked.getUpperWallpaperTarget();
1051
1052 boolean openingAppHasWallpaper = false;
1053 boolean closingAppHasWallpaper = false;
1054 final AppWindowToken lowerWallpaperAppToken;
1055 final AppWindowToken upperWallpaperAppToken;
1056 if (lowerWallpaperTarget == null) {
1057 lowerWallpaperAppToken = upperWallpaperAppToken = null;
1058 } else {
1059 lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
1060 upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
1061 }
1062
1063 int i;
1064 // Do a first pass through the tokens for two
1065 // things:
1066 // (1) Determine if both the closing and opening
1067 // app token sets are wallpaper targets, in which
1068 // case special animations are needed
1069 // (since the wallpaper needs to stay static
1070 // behind them).
1071 // (2) Find the layout params of the top-most
1072 // application window in the tokens, which is
1073 // what will control the animation theme.
1074 final int closingAppsCount = mService.mClosingApps.size();
1075 appsCount = closingAppsCount + mService.mOpeningApps.size();
1076 for (i = 0; i < appsCount; i++) {
1077 final AppWindowToken wtoken;
1078 if (i < closingAppsCount) {
1079 wtoken = mService.mClosingApps.valueAt(i);
1080 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1081 closingAppHasWallpaper = true;
1082 }
1083 } else {
1084 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
1085 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1086 openingAppHasWallpaper = true;
1087 }
1088 }
1089
1090 voiceInteraction |= wtoken.voiceInteraction;
1091
1092 if (wtoken.appFullscreen) {
1093 WindowState ws = wtoken.findMainWindow();
1094 if (ws != null) {
1095 animLp = ws.mAttrs;
1096 bestAnimLayer = ws.mLayer;
1097 fullscreenAnim = true;
1098 }
1099 } else if (!fullscreenAnim) {
1100 WindowState ws = wtoken.findMainWindow();
1101 if (ws != null) {
1102 if (ws.mLayer > bestAnimLayer) {
1103 animLp = ws.mAttrs;
1104 bestAnimLayer = ws.mLayer;
1105 }
1106 }
1107 }
1108 }
1109
1110 transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
1111 closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
1112
1113 // If all closing windows are obscured, then there is
1114 // no need to do an animation. This is the case, for
1115 // example, when this transition is being done behind
1116 // the lock screen.
1117 if (!mService.mPolicy.allowAppAnimationsLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001118 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001119 "Animations disallowed by keyguard or dream.");
1120 animLp = null;
1121 }
1122
1123 processApplicationsAnimatingInPlace(transit);
1124
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001125 mTmpLayerAndToken.token = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001126 handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
1127 final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
1128 final int topClosingLayer = mTmpLayerAndToken.layer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001129
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001130 final AppWindowToken topOpeningApp = handleOpeningApps(transit,
1131 animLp, voiceInteraction, topClosingLayer);
1132
1133 final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
1134 topOpeningApp.mAppAnimator;
1135 final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
1136 topClosingApp.mAppAnimator;
1137
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001138 mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
1139 mService.mOpeningApps, mService.mClosingApps);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001140 mService.mAppTransition.postAnimationCallback();
1141 mService.mAppTransition.clear();
1142
1143 mService.mOpeningApps.clear();
1144 mService.mClosingApps.clear();
1145
1146 // This has changed the visibility of windows, so perform
1147 // a new layout to get them all up-to-date.
1148 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1149
1150 // TODO(multidisplay): IMEs are only supported on the default display.
1151 if (windows == mService.getDefaultWindowListLocked()
1152 && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -08001153 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001154 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001155 mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1156 true /*updateInputWindows*/);
1157 mService.mFocusMayChange = false;
1158 mService.notifyActivityDrawnForKeyguard();
1159 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
1160 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001161
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001162 private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
1163 boolean voiceInteraction, int topClosingLayer) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001164 AppWindowToken topOpeningApp = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001165 final int appsCount = mService.mOpeningApps.size();
1166 for (int i = 0; i < appsCount; i++) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001167 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1168 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001169 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001170
1171 if (!appAnimator.usingTransferredAnimation) {
1172 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -07001173 appAnimator.setNullAnimation();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001174 }
1175 wtoken.inPendingTransaction = false;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001176
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001177 if (!mService.setTokenVisibilityLocked(
1178 wtoken, animLp, true, transit, false, voiceInteraction)){
1179 // This token isn't going to be animating. Add it to the list of tokens to
1180 // be notified of app transition complete since the notification will not be
1181 // sent be the app window animator.
1182 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
1183 }
1184 wtoken.updateReportedVisibilityLocked();
1185 wtoken.waitingToShow = false;
1186
1187 appAnimator.mAllAppWinAnimators.clear();
1188 final int windowsCount = wtoken.allAppWindows.size();
1189 for (int j = 0; j < windowsCount; j++) {
1190 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1191 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001192 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001193 ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
1194 SurfaceControl.openTransaction();
1195 try {
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001196 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001197 } finally {
1198 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001199 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001200 "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
1201 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001202 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1203
1204 int topOpeningLayer = 0;
1205 if (animLp != null) {
1206 int layer = -1;
1207 for (int j = 0; j < wtoken.windows.size(); j++) {
Chong Zhangbef461f2015-10-27 11:38:24 -07001208 final WindowState win = wtoken.windows.get(j);
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001209 // Clearing the mAnimatingExit flag before entering animation. It will be set to true
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001210 // if app window is removed, or window relayout to invisible. We don't want to
1211 // clear it out for windows that get replaced, because the animation depends on
1212 // the flag to remove the replaced window.
Robert Carr7fed68d2016-01-19 21:24:57 -08001213 //
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001214 // We also don't clear the mAnimatingExit flag for windows which have the
Robert Carr7fed68d2016-01-19 21:24:57 -08001215 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
1216 // by the client. We should let animation proceed and not clear this flag or
1217 // they won't eventually be removed by WindowStateAnimator#finishExit.
1218 if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001219 win.mAnimatingExit = false;
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001220 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001221 if (win.mWinAnimator.mAnimLayer > layer) {
1222 layer = win.mWinAnimator.mAnimLayer;
1223 }
1224 }
1225 if (topOpeningApp == null || layer > topOpeningLayer) {
1226 topOpeningApp = wtoken;
1227 topOpeningLayer = layer;
1228 }
1229 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001230 if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
1231 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
1232 }
Jorim Jaggi192086e2016-03-11 17:17:03 +01001233 if (mService.mAppTransition.getAppTransition()
1234 == AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS) {
1235 appAnimator.startProlongAnimation(PROLONG_ANIMATION_AT_START);
1236 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001237 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001238 return topOpeningApp;
1239 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001240
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001241 private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
1242 LayerAndToken layerAndToken) {
1243 final int appsCount;
1244 appsCount = mService.mClosingApps.size();
1245 for (int i = 0; i < appsCount; i++) {
1246 AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
1247 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001248 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001249 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -07001250 appAnimator.setNullAnimation();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001251 wtoken.inPendingTransaction = false;
1252 mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
1253 voiceInteraction);
1254 wtoken.updateReportedVisibilityLocked();
1255 // Force the allDrawn flag, because we want to start
1256 // this guy's animations regardless of whether it's
1257 // gotten drawn.
1258 wtoken.allDrawn = true;
1259 wtoken.deferClearAllDrawn = false;
1260 // Ensure that apps that are mid-starting are also scheduled to have their
1261 // starting windows removed after the animation is complete
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001262 if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001263 mService.scheduleRemoveStartingWindowLocked(wtoken);
1264 }
1265 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001266
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001267 if (animLp != null) {
1268 int layer = -1;
1269 for (int j = 0; j < wtoken.windows.size(); j++) {
1270 WindowState win = wtoken.windows.get(j);
1271 if (win.mWinAnimator.mAnimLayer > layer) {
1272 layer = win.mWinAnimator.mAnimLayer;
1273 }
1274 }
1275 if (layerAndToken.token == null || layer > layerAndToken.layer) {
1276 layerAndToken.token = wtoken;
1277 layerAndToken.layer = layer;
1278 }
1279 }
1280 if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
1281 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
1282 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001283 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001284 }
1285
1286 private boolean transitionGoodToGo(int appsCount) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001287 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001288 "Checking " + appsCount + " opening apps (frozen="
1289 + mService.mDisplayFrozen + " timeout="
1290 + mService.mAppTransition.isTimeout() + ")...");
Jorim Jaggi275561a2016-02-23 10:11:02 -05001291 int reason = APP_TRANSITION_TIMEOUT;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001292 if (!mService.mAppTransition.isTimeout()) {
1293 for (int i = 0; i < appsCount; i++) {
1294 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001295 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001296 "Check opening app=" + wtoken + ": allDrawn="
1297 + wtoken.allDrawn + " startingDisplayed="
1298 + wtoken.startingDisplayed + " startingMoved="
Chong Zhangd78ddb42016-03-02 17:01:14 -08001299 + wtoken.startingMoved + " isRelaunching()="
1300 + wtoken.isRelaunching());
1301
1302 if (wtoken.isRelaunching()) {
1303 return false;
1304 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -07001305
Jorim Jaggi275561a2016-02-23 10:11:02 -05001306 final boolean drawnBeforeRestoring = wtoken.allDrawn;
Chong Zhangbfc2f8f2016-01-29 15:50:34 -08001307 wtoken.restoreSavedSurfaces();
1308
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001309 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
1310 return false;
1311 }
Jorim Jaggi275561a2016-02-23 10:11:02 -05001312 if (wtoken.allDrawn) {
1313 reason = drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
1314 : APP_TRANSITION_SAVED_SURFACE;
1315 } else {
1316 reason = APP_TRANSITION_STARTING_WINDOW;
1317 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001318 }
1319
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001320 // We also need to wait for the specs to be fetched, if needed.
1321 if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001322 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001323 return false;
1324 }
1325
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001326 // If the wallpaper is visible, we need to check it's ready too.
Jorim Jaggi275561a2016-02-23 10:11:02 -05001327 boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001328 mWallpaperControllerLocked.wallpaperTransitionReady();
Jorim Jaggi275561a2016-02-23 10:11:02 -05001329 if (wallpaperReady) {
1330 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1331 return true;
1332 }
1333 return false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001334 }
Jorim Jaggi275561a2016-02-23 10:11:02 -05001335 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001336 return true;
1337 }
1338
1339 private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
1340 boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
1341 WindowState upperWallpaperTarget) {
1342 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
1343 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
1344 final WindowState oldWallpaper =
1345 mWallpaperControllerLocked.isWallpaperTargetAnimating()
1346 ? null : wallpaperTarget;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001347 final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
1348 final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001349 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001350 "New wallpaper target=" + wallpaperTarget
1351 + ", oldWallpaper=" + oldWallpaper
1352 + ", lower target=" + lowerWallpaperTarget
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001353 + ", upper target=" + upperWallpaperTarget
1354 + ", openingApps=" + openingApps
1355 + ", closingApps=" + closingApps);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001356 mService.mAnimateWallpaperWithTarget = false;
1357 if (closingAppHasWallpaper && openingAppHasWallpaper) {
1358 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001359 Slog.v(TAG, "Wallpaper animation!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001360 switch (transit) {
1361 case AppTransition.TRANSIT_ACTIVITY_OPEN:
1362 case AppTransition.TRANSIT_TASK_OPEN:
1363 case AppTransition.TRANSIT_TASK_TO_FRONT:
1364 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
1365 break;
1366 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
1367 case AppTransition.TRANSIT_TASK_CLOSE:
1368 case AppTransition.TRANSIT_TASK_TO_BACK:
1369 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
1370 break;
1371 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001372 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001373 "New transit: " + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001374 } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
1375 && !openingApps.contains(oldWallpaper.mAppToken)
1376 && closingApps.contains(oldWallpaper.mAppToken)) {
1377 // We are transitioning from an activity with a wallpaper to one without.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001378 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001379 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001380 "New transit away from wallpaper: "
1381 + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001382 } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
1383 openingApps.contains(wallpaperTarget.mAppToken)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001384 // We are transitioning from an activity without
1385 // a wallpaper to now showing the wallpaper
1386 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001387 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001388 "New transit into wallpaper: "
1389 + AppTransition.appTransitionToString(transit));
1390 } else {
1391 mService.mAnimateWallpaperWithTarget = true;
1392 }
1393 return transit;
1394 }
1395
1396 /**
1397 * @param w WindowState this method is applied to.
Chong Zhang0abb20f2015-11-19 14:17:31 -08001398 * @param dispInfo info of the display that the window's obscuring state is checked against.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001399 */
Chong Zhang0abb20f2015-11-19 14:17:31 -08001400 private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001401 final LayoutParams attrs = w.mAttrs;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001402 final int attrFlags = attrs.flags;
1403 final boolean canBeSeen = w.isDisplayedLw();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001404
Chong Zhang0abb20f2015-11-19 14:17:31 -08001405 if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001406 // This window completely covers everything behind it,
1407 // so we want to leave all of them as undimmed (for
1408 // performance reasons).
1409 mObscured = true;
1410 }
1411
1412 if (w.mHasSurface) {
1413 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
1414 mHoldScreen = w.mSession;
1415 }
1416 if (!mSyswin && w.mAttrs.screenBrightness >= 0
1417 && mScreenBrightness < 0) {
1418 mScreenBrightness = w.mAttrs.screenBrightness;
1419 }
1420 if (!mSyswin && w.mAttrs.buttonBrightness >= 0
1421 && mButtonBrightness < 0) {
1422 mButtonBrightness = w.mAttrs.buttonBrightness;
1423 }
1424 if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
1425 && mUserActivityTimeout < 0) {
1426 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1427 }
1428
1429 final int type = attrs.type;
1430 if (canBeSeen
1431 && (type == TYPE_SYSTEM_DIALOG
1432 || type == TYPE_SYSTEM_ERROR
1433 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
1434 mSyswin = true;
1435 }
1436
1437 if (canBeSeen) {
1438 // This function assumes that the contents of the default display are
1439 // processed first before secondary displays.
1440 final DisplayContent displayContent = w.getDisplayContent();
1441 if (displayContent != null && displayContent.isDefaultDisplay) {
1442 // While a dream or keyguard is showing, obscure ordinary application
1443 // content on secondary displays (by forcibly enabling mirroring unless
1444 // there is other content we want to show) but still allow opaque
1445 // keyguard dialogs to be shown.
1446 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1447 mObscureApplicationContentOnSecondaryDisplays = true;
1448 }
1449 mDisplayHasContent = true;
1450 } else if (displayContent != null &&
1451 (!mObscureApplicationContentOnSecondaryDisplays
1452 || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1453 // Allow full screen keyguard presentation dialogs to be seen.
1454 mDisplayHasContent = true;
1455 }
1456 if (mPreferredRefreshRate == 0
1457 && w.mAttrs.preferredRefreshRate != 0) {
1458 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1459 }
1460 if (mPreferredModeId == 0
1461 && w.mAttrs.preferredDisplayModeId != 0) {
1462 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1463 }
1464 }
1465 }
1466 }
1467
1468 private void updateAllDrawnLocked(DisplayContent displayContent) {
1469 // See if any windows have been drawn, so they (and others
1470 // associated with them) can now be shown.
1471 ArrayList<TaskStack> stacks = displayContent.getStacks();
1472 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1473 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
1474 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1475 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1476 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
1477 final AppWindowToken wtoken = tokens.get(tokenNdx);
1478 if (!wtoken.allDrawn) {
1479 int numInteresting = wtoken.numInterestingWindows;
1480 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
1481 if (DEBUG_VISIBILITY)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001482 Slog.v(TAG, "allDrawn: " + wtoken
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001483 + " interesting=" + numInteresting
1484 + " drawn=" + wtoken.numDrawnWindows);
1485 wtoken.allDrawn = true;
1486 // Force an additional layout pass where WindowStateAnimator#
1487 // commitFinishDrawingLocked() will call performShowLocked().
1488 displayContent.layoutNeeded = true;
1489 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
1490 wtoken.token).sendToTarget();
1491 }
1492 }
1493 }
1494 }
1495 }
1496 }
1497
1498 private static int toBrightnessOverride(float value) {
1499 return (int)(value * PowerManager.BRIGHTNESS_ON);
1500 }
1501
1502 private void processApplicationsAnimatingInPlace(int transit) {
1503 if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
1504 // Find the focused window
1505 final WindowState win = mService.findFocusedWindowLocked(
1506 mService.getDefaultDisplayContentLocked());
1507 if (win != null) {
1508 final AppWindowToken wtoken = win.mAppToken;
1509 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1510 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001511 Slog.v(TAG, "Now animating app in place " + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001512 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -07001513 appAnimator.setNullAnimation();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001514 mService.updateTokenInPlaceLocked(wtoken, transit);
1515 wtoken.updateReportedVisibilityLocked();
1516
1517 appAnimator.mAllAppWinAnimators.clear();
1518 final int N = wtoken.allAppWindows.size();
1519 for (int j = 0; j < N; j++) {
1520 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1521 }
1522 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001523 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001524 }
1525 }
1526 }
1527
1528 private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
1529 int openingLayer, int closingLayer) {
1530 AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
1531 if (openingAppAnimator == null || openingAppAnimator.animation == null) {
1532 return;
1533 }
1534 final int taskId = appToken.mTask.mTaskId;
1535 Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
1536 if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001537 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001538 return;
1539 }
1540 // This thumbnail animation is very special, we need to have
1541 // an extra surface with the thumbnail included with the animation.
1542 Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
1543 try {
1544 // TODO(multi-display): support other displays
1545 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1546 final Display display = displayContent.getDisplay();
1547 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1548
1549 // Create a new surface for the thumbnail
1550 SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
1551 "thumbnail anim", dirty.width(), dirty.height(),
1552 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
1553 surfaceControl.setLayerStack(display.getLayerStack());
1554 if (SHOW_TRANSACTIONS) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001555 Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001556 }
1557
1558 // Draw the thumbnail onto the surface
1559 Surface drawSurface = new Surface();
1560 drawSurface.copyFrom(surfaceControl);
1561 Canvas c = drawSurface.lockCanvas(dirty);
1562 c.drawBitmap(thumbnailHeader, 0, 0, null);
1563 drawSurface.unlockCanvasAndPost(c);
1564 drawSurface.release();
1565
1566 // Get the thumbnail animation
1567 Animation anim;
1568 if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
1569 // If this is a multi-window scenario, we use the windows frame as
1570 // destination of the thumbnail header animation. If this is a full screen
1571 // window scenario, we use the whole display as the target.
1572 WindowState win = appToken.findMainWindow();
1573 Rect appRect = win != null ? win.getContentFrameLw() :
1574 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
Jorim Jaggide63d442016-03-14 14:56:56 +01001575 Rect insets = win != null ? win.mContentInsets : null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001576 // For the new aspect-scaled transition, we want it to always show
1577 // above the animating opening/closing window, and we want to
1578 // synchronize its thumbnail surface with the surface for the
1579 // open/close animation (only on the way down)
1580 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
Jorim Jaggi09072002016-03-25 16:48:42 -07001581 insets, thumbnailHeader, taskId, mService.mCurConfiguration.orientation);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001582 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
1583 openingAppAnimator.deferThumbnailDestruction =
1584 !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
1585 } else {
1586 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
1587 displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
1588 }
1589 anim.restrictDuration(MAX_ANIMATION_DURATION);
1590 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1591
1592 openingAppAnimator.thumbnail = surfaceControl;
1593 openingAppAnimator.thumbnailLayer = openingLayer;
1594 openingAppAnimator.thumbnailAnimation = anim;
1595 mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001596 } catch (Surface.OutOfResourcesException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001597 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001598 + dirty.width() + " h=" + dirty.height(), e);
1599 openingAppAnimator.clearThumbnail();
1600 }
1601 }
1602
1603 boolean copyAnimToLayoutParamsLocked() {
1604 boolean doRequest = false;
1605
1606 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1607 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1608 mUpdateRotation = true;
1609 doRequest = true;
1610 }
1611 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1612 mWallpaperMayChange = true;
1613 doRequest = true;
1614 }
1615 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1616 mWallpaperForceHidingChanged = true;
1617 doRequest = true;
1618 }
1619 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1620 mOrientationChangeComplete = false;
1621 } else {
1622 mOrientationChangeComplete = true;
1623 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1624 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1625 doRequest = true;
1626 }
1627 }
1628 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1629 mService.mTurnOnScreen = true;
1630 }
1631 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1632 mWallpaperActionPending = true;
1633 }
1634
1635 return doRequest;
1636 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001637
1638 void requestTraversal() {
1639 if (!mTraversalScheduled) {
1640 mTraversalScheduled = true;
1641 mService.mH.sendEmptyMessage(DO_TRAVERSAL);
1642 }
1643 }
1644
Jorim Jaggi3dac63a2016-03-01 12:37:07 +01001645 /**
1646 * Puts the {@param surface} into a pending list to be destroyed after the current transaction
1647 * has been committed.
1648 */
1649 void destroyAfterTransaction(SurfaceControl surface) {
1650 mPendingDestroyingSurfaces.add(surface);
1651 }
1652
1653 /**
1654 * Destroys any surfaces that have been put into the pending list with
1655 * {@link #destroyAfterTransaction}.
1656 */
1657 void destroyPendingSurfaces() {
1658 for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
1659 mPendingDestroyingSurfaces.get(i).destroy();
1660 }
1661 mPendingDestroyingSurfaces.clear();
1662 }
1663
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001664 public void dump(PrintWriter pw, String prefix) {
1665 pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
1666 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001667}