blob: f705df8ea3946c5b310fb6afcbf88111cf133e7a [file] [log] [blame]
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001package com.android.server.wm;
2
3import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
4import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
5import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
6import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
7import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
8import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
9import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070010import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
11import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
12import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
13import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
14import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
15import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
16import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080017import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
18import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
19import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
20import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
21import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
22import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
23import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
24import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
25import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
26import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
27import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
28import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -080029import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070030import static com.android.server.wm.WindowManagerService.H.*;
31import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
32import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080033import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
34import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
35import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070036import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
37import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
38import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
39
40import android.graphics.Bitmap;
41import android.graphics.Canvas;
42import android.graphics.PixelFormat;
43import android.graphics.Rect;
44import android.os.Debug;
45import android.os.PowerManager;
46import android.os.RemoteException;
47import android.os.SystemClock;
48import android.os.Trace;
49import android.provider.Settings;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -070050import android.util.ArraySet;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070051import android.util.Slog;
52import android.view.Display;
53import android.view.DisplayInfo;
54import android.view.Surface;
55import android.view.SurfaceControl;
56import android.view.View;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -080057import android.view.WindowManager.LayoutParams;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070058import android.view.animation.Animation;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070059
Filip Gruszczynski24966d42015-09-05 15:00:00 -070060import java.io.PrintWriter;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070061import java.util.ArrayList;
62
63/**
64 * Positions windows and their surfaces.
65 *
66 * It sets positions of windows by calculating their frames and then applies this by positioning
67 * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
68 */
69class WindowSurfacePlacer {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -080070 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfacePlacer" : TAG_WM;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070071 private final WindowManagerService mService;
72 private final WallpaperController mWallpaperControllerLocked;
73
74 private boolean mInLayout = false;
75
76 /** Only do a maximum of 6 repeated layouts. After that quit */
77 private int mLayoutRepeatCount;
78
79 static final int SET_UPDATE_ROTATION = 1 << 0;
80 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
81 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
82 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
83 static final int SET_TURN_ON_SCREEN = 1 << 4;
84 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
85
86 boolean mWallpaperMayChange = false;
87 boolean mOrientationChangeComplete = true;
88 boolean mWallpaperActionPending = false;
89
90 private boolean mWallpaperForceHidingChanged = false;
91 private Object mLastWindowFreezeSource = null;
92 private Session mHoldScreen = null;
93 private boolean mObscured = false;
94 private boolean mSyswin = false;
95 private float mScreenBrightness = -1;
96 private float mButtonBrightness = -1;
97 private long mUserActivityTimeout = -1;
98 private boolean mUpdateRotation = false;
99 private final Rect mTmpStartRect = new Rect();
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800100 private final Rect mTmpContentRect = new Rect();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700101
102 // Set to true when the display contains content to show the user.
103 // When false, the display manager may choose to mirror or blank the display.
104 private boolean mDisplayHasContent = false;
105
106 // Only set while traversing the default display based on its content.
107 // Affects the behavior of mirroring on secondary displays.
108 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
109
110 private float mPreferredRefreshRate = 0;
111
112 private int mPreferredModeId = 0;
113
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700114 private boolean mTraversalScheduled;
Jorim Jaggic4025202015-10-22 16:43:34 +0200115 private int mDeferDepth = 0;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700116
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800117 private static final class LayerAndToken {
118 public int layer;
119 public AppWindowToken token;
120 }
121 private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
122
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700123 public WindowSurfacePlacer(WindowManagerService service) {
124 mService = service;
125 mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
126 }
127
Jorim Jaggic4025202015-10-22 16:43:34 +0200128 /**
129 * See {@link WindowManagerService#deferSurfaceLayout()}
130 */
131 void deferLayout() {
132 mDeferDepth++;
133 }
134
135 /**
136 * See {@link WindowManagerService#continueSurfaceLayout()}
137 */
138 void continueLayout() {
139 mDeferDepth--;
140 if (mDeferDepth <= 0) {
141 performSurfacePlacement();
142 }
143 }
144
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700145 final void performSurfacePlacement() {
Jorim Jaggic4025202015-10-22 16:43:34 +0200146 if (mDeferDepth > 0) {
147 return;
148 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700149 int loopCount = 6;
150 do {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700151 mTraversalScheduled = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700152 performSurfacePlacementLoop();
153 mService.mH.removeMessages(DO_TRAVERSAL);
154 loopCount--;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700155 } while (mTraversalScheduled && loopCount > 0);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700156 mWallpaperActionPending = false;
157 }
158
159 private void performSurfacePlacementLoop() {
160 if (mInLayout) {
161 if (DEBUG) {
162 throw new RuntimeException("Recursive call!");
163 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800164 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700165 + Debug.getCallers(3));
166 return;
167 }
168
169 if (mService.mWaitingForConfig) {
170 // Our configuration has changed (most likely rotation), but we
171 // don't yet have the complete configuration to report to
172 // applications. Don't do any window layout until we have it.
173 return;
174 }
175
176 if (!mService.mDisplayReady) {
177 // Not yet initialized, nothing to do.
178 return;
179 }
180
181 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
182 mInLayout = true;
183
184 boolean recoveringMemory = false;
185 if (!mService.mForceRemoves.isEmpty()) {
186 recoveringMemory = true;
187 // Wait a little bit for things to settle down, and off we go.
188 while (!mService.mForceRemoves.isEmpty()) {
189 WindowState ws = mService.mForceRemoves.remove(0);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800190 Slog.i(TAG, "Force removing: " + ws);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700191 mService.removeWindowInnerLocked(ws);
192 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800193 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700194 Object tmp = new Object();
195 synchronized (tmp) {
196 try {
197 tmp.wait(250);
198 } catch (InterruptedException e) {
199 }
200 }
201 }
202
203 try {
204 performSurfacePlacementInner(recoveringMemory);
205
206 mInLayout = false;
207
208 if (mService.needsLayout()) {
209 if (++mLayoutRepeatCount < 6) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700210 requestTraversal();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700211 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800212 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700213 mLayoutRepeatCount = 0;
214 }
215 } else {
216 mLayoutRepeatCount = 0;
217 }
218
219 if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
220 mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
221 mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
222 }
223 } catch (RuntimeException e) {
224 mInLayout = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800225 Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700226 }
227
228 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
229 }
230
231 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
232 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800233 Slog.v(TAG, "Layouts looping: " + msg +
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700234 ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
235 }
236 }
237
238 // "Something has changed! Let's make it correct now."
239 private void performSurfacePlacementInner(boolean recoveringMemory) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800240 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
241 + Debug.getCallers(3));
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700242
243 int i;
244 boolean updateInputWindowsNeeded = false;
245
246 if (mService.mFocusMayChange) {
247 mService.mFocusMayChange = false;
248 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
249 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
250 }
251
252 // Initialize state of exiting tokens.
253 final int numDisplays = mService.mDisplayContents.size();
254 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
255 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
256 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
257 displayContent.mExitingTokens.get(i).hasVisible = false;
258 }
259 }
260
261 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
262 // Initialize state of exiting applications.
263 final AppTokenList exitingAppTokens =
264 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
265 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
266 exitingAppTokens.get(tokenNdx).hasVisible = false;
267 }
268 }
269
270 mHoldScreen = null;
271 mScreenBrightness = -1;
272 mButtonBrightness = -1;
273 mUserActivityTimeout = -1;
274 mObscureApplicationContentOnSecondaryDisplays = false;
275
276 mService.mTransactionSequence++;
277
278 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
279 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
280 final int defaultDw = defaultInfo.logicalWidth;
281 final int defaultDh = defaultInfo.logicalHeight;
282
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800283 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700284 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
285 SurfaceControl.openTransaction();
286 try {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700287 applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700288 } catch (RuntimeException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800289 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700290 } finally {
291 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800292 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700293 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
294 }
295
296 final WindowList defaultWindows = defaultDisplay.getWindowList();
297
298 // If we are ready to perform an app transition, check through
299 // all of the app tokens to be shown and see if they are ready
300 // to go.
301 if (mService.mAppTransition.isReady()) {
302 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
303 if (DEBUG_LAYOUT_REPEATS)
304 debugLayoutRepeats("after handleAppTransitionReadyLocked",
305 defaultDisplay.pendingLayoutChanges);
306 }
307
308 if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
309 // We have finished the animation of an app transition. To do
310 // this, we have delayed a lot of operations like showing and
311 // hiding apps, moving apps in Z-order, etc. The app token list
312 // reflects the correct Z-order, but the window list may now
313 // be out of sync with it. So here we will just rebuild the
314 // entire app window list. Fun!
315 defaultDisplay.pendingLayoutChanges |=
316 mService.handleAnimatingStoppedAndTransitionLocked();
317 if (DEBUG_LAYOUT_REPEATS)
318 debugLayoutRepeats("after handleAnimStopAndXitionLock",
319 defaultDisplay.pendingLayoutChanges);
320 }
321
322 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
323 && !mService.mAppTransition.isReady()) {
324 // At this point, there was a window with a wallpaper that
325 // was force hiding other windows behind it, but now it
326 // is going away. This may be simple -- just animate
327 // away the wallpaper and its window -- or it may be
328 // hard -- the wallpaper now needs to be shown behind
329 // something that was hidden.
330 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
331 if (DEBUG_LAYOUT_REPEATS)
332 debugLayoutRepeats("after animateAwayWallpaperLocked",
333 defaultDisplay.pendingLayoutChanges);
334 }
335 mWallpaperForceHidingChanged = false;
336
337 if (mWallpaperMayChange) {
338 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800339 Slog.v(TAG, "Wallpaper may change! Adjusting");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700340 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
341 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
342 defaultDisplay.pendingLayoutChanges);
343 }
344
345 if (mService.mFocusMayChange) {
346 mService.mFocusMayChange = false;
347 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
348 false /*updateInputWindows*/)) {
349 updateInputWindowsNeeded = true;
350 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
351 }
352 }
353
354 if (mService.needsLayout()) {
355 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
356 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
357 defaultDisplay.pendingLayoutChanges);
358 }
359
360 for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
361 WindowState win = mService.mResizingWindows.get(i);
362 if (win.mAppFreezing) {
363 // Don't remove this window until rotation has completed.
364 continue;
365 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700366 // Discard the saved surface if window size is changed, it can't be reused.
Chong Zhangbef461f2015-10-27 11:38:24 -0700367 if (win.mAppToken != null) {
368 win.mAppToken.destroySavedSurfaces();
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700369 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700370 win.reportResized();
371 mService.mResizingWindows.remove(i);
372 }
373
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800374 if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
375 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700376 if (mOrientationChangeComplete) {
377 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
378 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
379 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
380 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
381 }
382 mService.stopFreezingDisplayLocked();
383 }
384
385 // Destroy the surface of any windows that are no longer visible.
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800386 boolean wallpaperDestroyed = false;
387 i = mService.mDestroySurface.size();
388 if (i > 0) {
389 do {
390 i--;
391 WindowState win = mService.mDestroySurface.get(i);
392 win.mDestroying = false;
393 if (mService.mInputMethodWindow == win) {
394 mService.mInputMethodWindow = null;
395 }
396 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
397 wallpaperDestroyed = true;
398 }
Robert Carr13f7be9e2015-12-02 18:39:45 -0800399 win.destroyOrSaveSurface();
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800400 } while (i > 0);
401 mService.mDestroySurface.clear();
402 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700403
404 // Time to remove any exiting tokens?
405 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
406 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
407 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
408 for (i = exitingTokens.size() - 1; i >= 0; i--) {
409 WindowToken token = exitingTokens.get(i);
410 if (!token.hasVisible) {
411 exitingTokens.remove(i);
412 if (token.windowType == TYPE_WALLPAPER) {
413 mWallpaperControllerLocked.removeWallpaperToken(token);
414 }
415 }
416 }
417 }
418
419 // Time to remove any exiting applications?
420 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
421 // Initialize state of exiting applications.
422 final AppTokenList exitingAppTokens =
423 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
424 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
425 AppWindowToken token = exitingAppTokens.get(i);
426 if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
427 (!token.mIsExiting || token.allAppWindows.isEmpty())) {
428 // Make sure there is no animation running on this token,
429 // so any windows associated with it will be removed as
430 // soon as their animations are complete
431 token.mAppAnimator.clearAnimation();
432 token.mAppAnimator.animating = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800433 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
434 "performLayout: App token exiting now removed" + token);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700435 token.removeAppFromTaskLocked();
436 }
437 }
438 }
439
440 if (wallpaperDestroyed) {
441 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
442 defaultDisplay.layoutNeeded = true;
443 }
444
445 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
446 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
447 if (displayContent.pendingLayoutChanges != 0) {
448 displayContent.layoutNeeded = true;
449 }
450 }
451
452 // Finally update all input windows now that the window changes have stabilized.
453 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
454
455 mService.setHoldScreenLocked(mHoldScreen);
456 if (!mService.mDisplayFrozen) {
457 if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
458 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
459 } else {
460 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
461 toBrightnessOverride(mScreenBrightness));
462 }
463 if (mButtonBrightness < 0
464 || mButtonBrightness > 1.0f) {
465 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
466 } else {
467 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
468 toBrightnessOverride(mButtonBrightness));
469 }
470 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
471 mUserActivityTimeout);
472 }
473
474 if (mService.mTurnOnScreen) {
475 if (mService.mAllowTheaterModeWakeFromLayout
476 || Settings.Global.getInt(mService.mContext.getContentResolver(),
477 Settings.Global.THEATER_MODE_ON, 0) == 0) {
478 if (DEBUG_VISIBILITY || DEBUG_POWER) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800479 Slog.v(TAG, "Turning screen on after layout!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700480 }
481 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
482 "android.server.wm:TURN_ON");
483 }
484 mService.mTurnOnScreen = false;
485 }
486
487 if (mUpdateRotation) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800488 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700489 if (mService.updateRotationUncheckedLocked(false)) {
490 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
491 } else {
492 mUpdateRotation = false;
493 }
494 }
495
496 if (mService.mWaitingForDrawnCallback != null ||
497 (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
498 !mUpdateRotation)) {
499 mService.checkDrawnWindowsLocked();
500 }
501
502 final int N = mService.mPendingRemove.size();
503 if (N > 0) {
504 if (mService.mPendingRemoveTmp.length < N) {
505 mService.mPendingRemoveTmp = new WindowState[N+10];
506 }
507 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
508 mService.mPendingRemove.clear();
509 DisplayContentList displayList = new DisplayContentList();
510 for (i = 0; i < N; i++) {
511 WindowState w = mService.mPendingRemoveTmp[i];
512 mService.removeWindowInnerLocked(w);
513 final DisplayContent displayContent = w.getDisplayContent();
514 if (displayContent != null && !displayList.contains(displayContent)) {
515 displayList.add(displayContent);
516 }
517 }
518
519 for (DisplayContent displayContent : displayList) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800520 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700521 displayContent.layoutNeeded = true;
522 }
523 }
524
525 // Remove all deferred displays stacks, tasks, and activities.
526 for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
527 mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
528 }
529
530 if (updateInputWindowsNeeded) {
531 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
532 }
Chong Zhangb15758a2015-11-17 12:12:03 -0800533 mService.setFocusTaskRegionLocked();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700534
535 // Check to see if we are now in a state where the screen should
536 // be enabled, because the window obscured flags have changed.
537 mService.enableScreenIfNeededLocked();
538
539 mService.scheduleAnimationLocked();
540
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800541 if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
Wale Ogunwale69cf50f2015-11-13 11:08:36 -0800542 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700543 }
544
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700545 private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
546 int defaultDw, int defaultDh) {
547 if (mService.mWatermark != null) {
548 mService.mWatermark.positionSurface(defaultDw, defaultDh);
549 }
550 if (mService.mStrictModeFlash != null) {
551 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
552 }
553 if (mService.mCircularDisplayMask != null) {
554 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
555 mService.mRotation);
556 }
557 if (mService.mEmulatorDisplayOverlay != null) {
558 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
559 mService.mRotation);
560 }
561
562 boolean focusDisplayed = false;
563
564 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
565 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
566 boolean updateAllDrawn = false;
567 WindowList windows = displayContent.getWindowList();
568 DisplayInfo displayInfo = displayContent.getDisplayInfo();
569 final int displayId = displayContent.getDisplayId();
570 final int dw = displayInfo.logicalWidth;
571 final int dh = displayInfo.logicalHeight;
572 final int innerDw = displayInfo.appWidth;
573 final int innerDh = displayInfo.appHeight;
574 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
575
576 // Reset for each display.
577 mDisplayHasContent = false;
578 mPreferredRefreshRate = 0;
579 mPreferredModeId = 0;
580
581 int repeats = 0;
582 do {
583 repeats++;
584 if (repeats > 6) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800585 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700586 displayContent.layoutNeeded = false;
587 break;
588 }
589
590 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
591 "On entry to LockedInner", displayContent.pendingLayoutChanges);
592
593 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
594 mWallpaperControllerLocked.adjustWallpaperWindows()) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800595 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700596 displayContent.layoutNeeded = true;
597 }
598
599 if (isDefaultDisplay
600 && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800601 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700602 if (mService.updateOrientationFromAppTokensLocked(true)) {
603 displayContent.layoutNeeded = true;
604 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
605 }
606 }
607
608 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
609 displayContent.layoutNeeded = true;
610 }
611
612 // FIRST LOOP: Perform a layout, if needed.
613 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
614 performLayoutLockedInner(displayContent, repeats == 1,
615 false /* updateInputWindows */);
616 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800617 Slog.w(TAG, "Layout repeat skipped after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700618 }
619
620 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
621 // it is animating.
622 displayContent.pendingLayoutChanges = 0;
623
624 if (isDefaultDisplay) {
625 mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
626 for (int i = windows.size() - 1; i >= 0; i--) {
627 WindowState w = windows.get(i);
628 if (w.mHasSurface) {
629 mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
630 w.mAttachedWindow);
631 }
632 }
633 displayContent.pendingLayoutChanges |=
634 mService.mPolicy.finishPostLayoutPolicyLw();
635 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
636 displayContent.pendingLayoutChanges);
637 }
638 } while (displayContent.pendingLayoutChanges != 0);
639
640 mObscured = false;
641 mSyswin = false;
642 displayContent.resetDimming();
643
644 // Only used if default window
645 final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
646
647 for (int i = windows.size() - 1; i >= 0; i--) {
648 WindowState w = windows.get(i);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700649 final boolean obscuredChanged = w.mObscured != mObscured;
650
651 // Update effect.
652 w.mObscured = mObscured;
653 if (!mObscured) {
Chong Zhang0abb20f2015-11-19 14:17:31 -0800654 handleNotObscuredLocked(w, displayInfo);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700655 }
656
Chong Zhang112eb8c2015-11-02 11:17:00 -0800657 w.applyDimLayerIfNeeded();
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700658
659 if (isDefaultDisplay && obscuredChanged
660 && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
661 // This is the wallpaper target and its obscured state
662 // changed... make sure the current wallaper's visibility
663 // has been updated accordingly.
664 mWallpaperControllerLocked.updateWallpaperVisibility();
665 }
666
667 final WindowStateAnimator winAnimator = w.mWinAnimator;
668
669 // If the window has moved due to its containing content frame changing, then
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800670 // notify the listeners and optionally animate it. Simply checking a change of
671 // position is not enough, because being move due to dock divider is not a trigger
672 // for animation.
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700673 if (w.hasMoved()) {
674 // Frame has moved, containing content frame has also moved, and we're not
675 // currently animating... let's do something.
676 final int left = w.mFrame.left;
677 final int top = w.mFrame.top;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800678 final boolean adjustedForMinimizedDockedStack = w.getTask() != null &&
679 w.getTask().mStack.isAdjustedForMinimizedDockedStack();
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800680 if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800681 && !w.isDragResizing() && !adjustedForMinimizedDockedStack) {
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800682 winAnimator.setMoveAnimation(left, top);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700683 }
684
685 //TODO (multidisplay): Accessibility supported only for the default display.
686 if (mService.mAccessibilityController != null
687 && displayId == Display.DEFAULT_DISPLAY) {
688 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
689 }
690
691 try {
692 w.mClient.moved(left, top);
693 } catch (RemoteException e) {
694 }
695 }
696
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800697 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700698 w.mContentChanged = false;
Chong Zhangbd0d9372015-12-28 15:18:29 -0800699 w.mMovedByResize = false;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700700
701 // Moved from updateWindowsAndWallpaperLocked().
702 if (w.mHasSurface) {
703 // Take care of the window being ready to display.
704 final boolean committed = winAnimator.commitFinishDrawingLocked();
705 if (isDefaultDisplay && committed) {
706 if (w.mAttrs.type == TYPE_DREAM) {
707 // HACK: When a dream is shown, it may at that
708 // point hide the lock screen. So we need to
709 // redo the layout to let the phone window manager
710 // make this happen.
711 displayContent.pendingLayoutChanges |=
712 FINISH_LAYOUT_REDO_LAYOUT;
713 if (DEBUG_LAYOUT_REPEATS) {
714 debugLayoutRepeats("dream and commitFinishDrawingLocked true",
715 displayContent.pendingLayoutChanges);
716 }
717 }
718 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
719 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800720 Slog.v(TAG, "First draw done in potential wallpaper target " + w);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700721 mWallpaperMayChange = true;
722 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
723 if (DEBUG_LAYOUT_REPEATS) {
724 debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
725 displayContent.pendingLayoutChanges);
726 }
727 }
728 }
Filip Gruszczynskic46f41c2016-01-05 11:29:21 -0800729 if (!winAnimator.isAnimating()) {
730 // Updates the shown frame before we set up the surface. This is needed
731 // because the resizing could change the top-left position (in addition to
732 // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
733 // position the surface. We only apply it to windows that aren't animating,
734 // because we depend on the animation to calculate the correct shown frame
735 // on the next animation step.
736 winAnimator.computeShownFrameLocked();
737 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700738 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
739 }
740
741 final AppWindowToken atoken = w.mAppToken;
742 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800743 Slog.d(TAG, "updateWindows: starting " + w
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700744 + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
745 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
746 }
747 if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
748 if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
749 atoken.lastTransactionSequence = mService.mTransactionSequence;
750 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
751 atoken.startingDisplayed = false;
752 }
753 if ((w.isOnScreenIgnoringKeyguard()
754 || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800755 && !w.mAnimatingExit && !w.mDestroying) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700756 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800757 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700758 + w.isDrawnLw()
759 + ", isAnimating=" + winAnimator.isAnimating());
760 if (!w.isDrawnLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800761 Slog.v(TAG, "Not displayed: s="
Robert Carre6a83512015-11-03 16:09:21 -0800762 + winAnimator.mSurfaceController
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700763 + " pv=" + w.mPolicyVisibility
764 + " mDrawState=" + winAnimator.drawStateToString()
765 + " ah=" + w.mAttachedHidden
766 + " th=" + atoken.hiddenRequested
767 + " a=" + winAnimator.mAnimating);
768 }
769 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800770 if (w != atoken.startingWindow) {
771 if (!w.mAppDied &&
772 (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing)) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700773 atoken.numInterestingWindows++;
774 if (w.isDrawnLw()) {
775 atoken.numDrawnWindows++;
776 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800777 Slog.v(TAG, "tokenMayBeDrawn: " + atoken
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700778 + " freezingScreen="
779 + atoken.mAppAnimator.freezingScreen
780 + " mAppFreezing=" + w.mAppFreezing);
781 updateAllDrawn = true;
782 }
783 }
784 } else if (w.isDrawnLw()) {
785 atoken.startingDisplayed = true;
786 }
787 }
788 }
789
790 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
791 && w.isDisplayedLw()) {
792 focusDisplayed = true;
793 }
794
795 mService.updateResizingWindows(w);
796 }
797
798 mService.mDisplayManagerInternal.setDisplayProperties(displayId,
799 mDisplayHasContent,
800 mPreferredRefreshRate,
801 mPreferredModeId,
802 true /* inTraversal, must call performTraversalInTrans... below */);
803
804 mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
805
806 if (updateAllDrawn) {
807 updateAllDrawnLocked(displayContent);
808 }
809 }
810
811 if (focusDisplayed) {
812 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
813 }
814
815 // Give the display manager a chance to adjust properties
816 // like display rotation if it needs to.
817 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
818 }
819
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700820 boolean isInLayout() {
821 return mInLayout;
822 }
823
824 final void performLayoutLockedInner(final DisplayContent displayContent,
825 boolean initial, boolean updateInputWindows) {
826 if (!displayContent.layoutNeeded) {
827 return;
828 }
829 displayContent.layoutNeeded = false;
830 WindowList windows = displayContent.getWindowList();
831 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
832
833 DisplayInfo displayInfo = displayContent.getDisplayInfo();
834 final int dw = displayInfo.logicalWidth;
835 final int dh = displayInfo.logicalHeight;
836
837 if (mService.mInputConsumer != null) {
838 mService.mInputConsumer.layout(dw, dh);
839 }
840
841 final int N = windows.size();
842 int i;
843
844 if (DEBUG_LAYOUT) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800845 Slog.v(TAG, "-------------------------------------");
846 Slog.v(TAG, "performLayout: needed="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700847 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
848 }
849
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800850 mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
851 mService.mCurConfiguration.uiMode);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700852 if (isDefaultDisplay) {
853 // Not needed on non-default displays.
854 mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
855 mService.mScreenRect.set(0, 0, dw, dh);
856 }
857
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800858 mService.mPolicy.getContentRectLw(mTmpContentRect);
859 displayContent.resize(mTmpContentRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700860
861 int seq = mService.mLayoutSeq+1;
862 if (seq < 0) seq = 0;
863 mService.mLayoutSeq = seq;
864
865 boolean behindDream = false;
866
867 // First perform layout of any root windows (not attached
868 // to another window).
869 int topAttached = -1;
870 for (i = N-1; i >= 0; i--) {
871 final WindowState win = windows.get(i);
872
873 // Don't do layout of a window if it is not visible, or
874 // soon won't be visible, to avoid wasting time and funky
875 // changes while a window is animating away.
876 final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
877 || win.isGoneForLayoutLw();
878
879 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800880 Slog.v(TAG, "1ST PASS " + win
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700881 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
882 + " mLayoutAttached=" + win.mLayoutAttached
883 + " screen changed=" + win.isConfigChanged());
884 final AppWindowToken atoken = win.mAppToken;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800885 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700886 + win.mViewVisibility + " mRelayoutCalled="
887 + win.mRelayoutCalled + " hidden="
888 + win.mRootToken.hidden + " hiddenRequested="
889 + (atoken != null && atoken.hiddenRequested)
890 + " mAttachedHidden=" + win.mAttachedHidden);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800891 else Slog.v(TAG, " VIS: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700892 + win.mViewVisibility + " mRelayoutCalled="
893 + win.mRelayoutCalled + " hidden="
894 + win.mRootToken.hidden + " hiddenRequested="
895 + (atoken != null && atoken.hiddenRequested)
896 + " mAttachedHidden=" + win.mAttachedHidden);
897 }
898
899 // If this view is GONE, then skip it -- keep the current
900 // frame, and let the caller know so they can ignore it
901 // if they want. (We do the normal layout for INVISIBLE
902 // windows, since that means "perform layout as normal,
903 // just don't display").
904 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
905 || ((win.isConfigChanged() || win.setInsetsChanged()) &&
906 ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
907 (win.mHasSurface && win.mAppToken != null &&
908 win.mAppToken.layoutConfigChanges)))) {
909 if (!win.mLayoutAttached) {
910 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800911 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700912 win.mContentChanged = false;
913 }
914 if (win.mAttrs.type == TYPE_DREAM) {
915 // Don't layout windows behind a dream, so that if it
916 // does stuff like hide the status bar we won't get a
917 // bad transition when it goes away.
918 behindDream = true;
919 }
920 win.mLayoutNeeded = false;
921 win.prelayout();
922 mService.mPolicy.layoutWindowLw(win, null);
923 win.mLayoutSeq = seq;
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800924
925 // Window frames may have changed. Update dim layer with the new bounds.
926 final Task task = win.getTask();
927 if (task != null) {
928 displayContent.mDimLayerController.updateDimLayer(task);
929 }
930
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800931 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700932 " LAYOUT: mFrame="
933 + win.mFrame + " mContainingFrame="
934 + win.mContainingFrame + " mDisplayFrame="
935 + win.mDisplayFrame);
936 } else {
937 if (topAttached < 0) topAttached = i;
938 }
939 }
940 }
941
942 boolean attachedBehindDream = false;
943
944 // Now perform layout of attached windows, which usually
945 // depend on the position of the window they are attached to.
946 // XXX does not deal with windows that are attached to windows
947 // that are themselves attached.
948 for (i = topAttached; i >= 0; i--) {
949 final WindowState win = windows.get(i);
950
951 if (win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800952 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700953 "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
954 + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
955 // If this view is GONE, then skip it -- keep the current
956 // frame, and let the caller know so they can ignore it
957 // if they want. (We do the normal layout for INVISIBLE
958 // windows, since that means "perform layout as normal,
959 // just don't display").
960 if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
961 continue;
962 }
963 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
964 || !win.mHaveFrame || win.mLayoutNeeded) {
965 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800966 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700967 win.mContentChanged = false;
968 }
969 win.mLayoutNeeded = false;
970 win.prelayout();
971 mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
972 win.mLayoutSeq = seq;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800973 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700974 " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
975 + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
976 }
977 } else if (win.mAttrs.type == TYPE_DREAM) {
978 // Don't layout windows behind a dream, so that if it
979 // does stuff like hide the status bar we won't get a
980 // bad transition when it goes away.
981 attachedBehindDream = behindDream;
982 }
983 }
984
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800985 // Window frames may have changed. Tell the input dispatcher about it.
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700986 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
987 if (updateInputWindows) {
988 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
989 }
990
991 mService.mPolicy.finishLayoutLw();
Jorim Jaggi61f39a72015-10-29 16:54:18 +0100992 mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700993 }
994
995 /**
996 * @param windows List of windows on default display.
997 * @return bitmap indicating if another pass through layout must be made.
998 */
999 private int handleAppTransitionReadyLocked(WindowList windows) {
1000 int appsCount = mService.mOpeningApps.size();
1001 if (!transitionGoodToGo(appsCount)) {
1002 return 0;
1003 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001004 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001005 int transit = mService.mAppTransition.getAppTransition();
1006 if (mService.mSkipAppTransitionAnimation) {
1007 transit = AppTransition.TRANSIT_UNSET;
1008 }
1009 mService.mSkipAppTransitionAnimation = false;
1010 mService.mNoAnimationNotifyOnTransitionFinished.clear();
1011
1012 mService.mH.removeMessages(APP_TRANSITION_TIMEOUT);
1013
1014 mService.rebuildAppWindowListLocked();
1015
1016 mWallpaperMayChange = false;
1017
1018 // The top-most window will supply the layout params,
1019 // and we will determine it below.
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001020 LayoutParams animLp = null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001021 int bestAnimLayer = -1;
1022 boolean fullscreenAnim = false;
1023 boolean voiceInteraction = false;
1024
1025 final WindowState lowerWallpaperTarget =
1026 mWallpaperControllerLocked.getLowerWallpaperTarget();
1027 final WindowState upperWallpaperTarget =
1028 mWallpaperControllerLocked.getUpperWallpaperTarget();
1029
1030 boolean openingAppHasWallpaper = false;
1031 boolean closingAppHasWallpaper = false;
1032 final AppWindowToken lowerWallpaperAppToken;
1033 final AppWindowToken upperWallpaperAppToken;
1034 if (lowerWallpaperTarget == null) {
1035 lowerWallpaperAppToken = upperWallpaperAppToken = null;
1036 } else {
1037 lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
1038 upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
1039 }
1040
1041 int i;
1042 // Do a first pass through the tokens for two
1043 // things:
1044 // (1) Determine if both the closing and opening
1045 // app token sets are wallpaper targets, in which
1046 // case special animations are needed
1047 // (since the wallpaper needs to stay static
1048 // behind them).
1049 // (2) Find the layout params of the top-most
1050 // application window in the tokens, which is
1051 // what will control the animation theme.
1052 final int closingAppsCount = mService.mClosingApps.size();
1053 appsCount = closingAppsCount + mService.mOpeningApps.size();
1054 for (i = 0; i < appsCount; i++) {
1055 final AppWindowToken wtoken;
1056 if (i < closingAppsCount) {
1057 wtoken = mService.mClosingApps.valueAt(i);
1058 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1059 closingAppHasWallpaper = true;
1060 }
1061 } else {
1062 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
1063 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1064 openingAppHasWallpaper = true;
1065 }
1066 }
1067
1068 voiceInteraction |= wtoken.voiceInteraction;
1069
1070 if (wtoken.appFullscreen) {
1071 WindowState ws = wtoken.findMainWindow();
1072 if (ws != null) {
1073 animLp = ws.mAttrs;
1074 bestAnimLayer = ws.mLayer;
1075 fullscreenAnim = true;
1076 }
1077 } else if (!fullscreenAnim) {
1078 WindowState ws = wtoken.findMainWindow();
1079 if (ws != null) {
1080 if (ws.mLayer > bestAnimLayer) {
1081 animLp = ws.mAttrs;
1082 bestAnimLayer = ws.mLayer;
1083 }
1084 }
1085 }
1086 }
1087
1088 transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
1089 closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
1090
1091 // If all closing windows are obscured, then there is
1092 // no need to do an animation. This is the case, for
1093 // example, when this transition is being done behind
1094 // the lock screen.
1095 if (!mService.mPolicy.allowAppAnimationsLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001096 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001097 "Animations disallowed by keyguard or dream.");
1098 animLp = null;
1099 }
1100
1101 processApplicationsAnimatingInPlace(transit);
1102
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001103 mTmpLayerAndToken.token = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001104 handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
1105 final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
1106 final int topClosingLayer = mTmpLayerAndToken.layer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001107
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001108 final AppWindowToken topOpeningApp = handleOpeningApps(transit,
1109 animLp, voiceInteraction, topClosingLayer);
1110
1111 final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
1112 topOpeningApp.mAppAnimator;
1113 final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
1114 topClosingApp.mAppAnimator;
1115
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001116 mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
1117 mService.mOpeningApps, mService.mClosingApps);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001118 mService.mAppTransition.postAnimationCallback();
1119 mService.mAppTransition.clear();
1120
1121 mService.mOpeningApps.clear();
1122 mService.mClosingApps.clear();
1123
1124 // This has changed the visibility of windows, so perform
1125 // a new layout to get them all up-to-date.
1126 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1127
1128 // TODO(multidisplay): IMEs are only supported on the default display.
1129 if (windows == mService.getDefaultWindowListLocked()
1130 && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -08001131 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001132 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001133 mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1134 true /*updateInputWindows*/);
1135 mService.mFocusMayChange = false;
1136 mService.notifyActivityDrawnForKeyguard();
1137 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
1138 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001139
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001140 private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
1141 boolean voiceInteraction, int topClosingLayer) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001142 AppWindowToken topOpeningApp = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001143 final int appsCount = mService.mOpeningApps.size();
1144 for (int i = 0; i < appsCount; i++) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001145 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1146 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001147 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001148
1149 if (!appAnimator.usingTransferredAnimation) {
1150 appAnimator.clearThumbnail();
1151 appAnimator.animation = null;
1152 }
1153 wtoken.inPendingTransaction = false;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001154
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001155 if (!mService.setTokenVisibilityLocked(
1156 wtoken, animLp, true, transit, false, voiceInteraction)){
1157 // This token isn't going to be animating. Add it to the list of tokens to
1158 // be notified of app transition complete since the notification will not be
1159 // sent be the app window animator.
1160 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
1161 }
1162 wtoken.updateReportedVisibilityLocked();
1163 wtoken.waitingToShow = false;
1164
1165 appAnimator.mAllAppWinAnimators.clear();
1166 final int windowsCount = wtoken.allAppWindows.size();
1167 for (int j = 0; j < windowsCount; j++) {
1168 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1169 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001170 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001171 ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
1172 SurfaceControl.openTransaction();
1173 try {
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001174 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001175 } finally {
1176 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001177 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001178 "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
1179 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001180 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1181
1182 int topOpeningLayer = 0;
1183 if (animLp != null) {
1184 int layer = -1;
1185 for (int j = 0; j < wtoken.windows.size(); j++) {
Chong Zhangbef461f2015-10-27 11:38:24 -07001186 final WindowState win = wtoken.windows.get(j);
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001187 // Clearing the mAnimatingExit flag before entering animation. It will be set to true
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001188 // if app window is removed, or window relayout to invisible. We don't want to
1189 // clear it out for windows that get replaced, because the animation depends on
1190 // the flag to remove the replaced window.
Robert Carr7fed68d2016-01-19 21:24:57 -08001191 //
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001192 // We also don't clear the mAnimatingExit flag for windows which have the
Robert Carr7fed68d2016-01-19 21:24:57 -08001193 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
1194 // by the client. We should let animation proceed and not clear this flag or
1195 // they won't eventually be removed by WindowStateAnimator#finishExit.
1196 if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001197 win.mAnimatingExit = false;
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001198 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001199 if (win.mWinAnimator.mAnimLayer > layer) {
1200 layer = win.mWinAnimator.mAnimLayer;
1201 }
1202 }
1203 if (topOpeningApp == null || layer > topOpeningLayer) {
1204 topOpeningApp = wtoken;
1205 topOpeningLayer = layer;
1206 }
1207 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001208 if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
1209 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
1210 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001211 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001212 return topOpeningApp;
1213 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001214
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001215 private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
1216 LayerAndToken layerAndToken) {
1217 final int appsCount;
1218 appsCount = mService.mClosingApps.size();
1219 for (int i = 0; i < appsCount; i++) {
1220 AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
1221 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001222 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001223 appAnimator.clearThumbnail();
1224 appAnimator.animation = null;
1225 wtoken.inPendingTransaction = false;
1226 mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
1227 voiceInteraction);
1228 wtoken.updateReportedVisibilityLocked();
1229 // Force the allDrawn flag, because we want to start
1230 // this guy's animations regardless of whether it's
1231 // gotten drawn.
1232 wtoken.allDrawn = true;
1233 wtoken.deferClearAllDrawn = false;
1234 // Ensure that apps that are mid-starting are also scheduled to have their
1235 // starting windows removed after the animation is complete
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001236 if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001237 mService.scheduleRemoveStartingWindowLocked(wtoken);
1238 }
1239 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001240
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001241 if (animLp != null) {
1242 int layer = -1;
1243 for (int j = 0; j < wtoken.windows.size(); j++) {
1244 WindowState win = wtoken.windows.get(j);
1245 if (win.mWinAnimator.mAnimLayer > layer) {
1246 layer = win.mWinAnimator.mAnimLayer;
1247 }
1248 }
1249 if (layerAndToken.token == null || layer > layerAndToken.layer) {
1250 layerAndToken.token = wtoken;
1251 layerAndToken.layer = layer;
1252 }
1253 }
1254 if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
1255 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
1256 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001257 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001258 }
1259
1260 private boolean transitionGoodToGo(int appsCount) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001261 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001262 "Checking " + appsCount + " opening apps (frozen="
1263 + mService.mDisplayFrozen + " timeout="
1264 + mService.mAppTransition.isTimeout() + ")...");
1265 if (!mService.mAppTransition.isTimeout()) {
1266 for (int i = 0; i < appsCount; i++) {
1267 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001268 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001269 "Check opening app=" + wtoken + ": allDrawn="
1270 + wtoken.allDrawn + " startingDisplayed="
1271 + wtoken.startingDisplayed + " startingMoved="
1272 + wtoken.startingMoved);
Chong Zhangdb20b5f2015-10-23 14:01:43 -07001273
Chong Zhangbfc2f8f2016-01-29 15:50:34 -08001274 wtoken.restoreSavedSurfaces();
1275
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001276 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
1277 return false;
1278 }
1279 }
1280
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001281 // We also need to wait for the specs to be fetched, if needed.
1282 if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001283 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001284 return false;
1285 }
1286
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001287 // If the wallpaper is visible, we need to check it's ready too.
1288 return !mWallpaperControllerLocked.isWallpaperVisible() ||
1289 mWallpaperControllerLocked.wallpaperTransitionReady();
1290 }
1291 return true;
1292 }
1293
1294 private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
1295 boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
1296 WindowState upperWallpaperTarget) {
1297 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
1298 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
1299 final WindowState oldWallpaper =
1300 mWallpaperControllerLocked.isWallpaperTargetAnimating()
1301 ? null : wallpaperTarget;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001302 final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
1303 final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001304 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001305 "New wallpaper target=" + wallpaperTarget
1306 + ", oldWallpaper=" + oldWallpaper
1307 + ", lower target=" + lowerWallpaperTarget
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001308 + ", upper target=" + upperWallpaperTarget
1309 + ", openingApps=" + openingApps
1310 + ", closingApps=" + closingApps);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001311 mService.mAnimateWallpaperWithTarget = false;
1312 if (closingAppHasWallpaper && openingAppHasWallpaper) {
1313 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001314 Slog.v(TAG, "Wallpaper animation!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001315 switch (transit) {
1316 case AppTransition.TRANSIT_ACTIVITY_OPEN:
1317 case AppTransition.TRANSIT_TASK_OPEN:
1318 case AppTransition.TRANSIT_TASK_TO_FRONT:
1319 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
1320 break;
1321 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
1322 case AppTransition.TRANSIT_TASK_CLOSE:
1323 case AppTransition.TRANSIT_TASK_TO_BACK:
1324 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
1325 break;
1326 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001327 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001328 "New transit: " + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001329 } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
1330 && !openingApps.contains(oldWallpaper.mAppToken)
1331 && closingApps.contains(oldWallpaper.mAppToken)) {
1332 // We are transitioning from an activity with a wallpaper to one without.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001333 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001334 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001335 "New transit away from wallpaper: "
1336 + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001337 } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
1338 openingApps.contains(wallpaperTarget.mAppToken)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001339 // We are transitioning from an activity without
1340 // a wallpaper to now showing the wallpaper
1341 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001342 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001343 "New transit into wallpaper: "
1344 + AppTransition.appTransitionToString(transit));
1345 } else {
1346 mService.mAnimateWallpaperWithTarget = true;
1347 }
1348 return transit;
1349 }
1350
1351 /**
1352 * @param w WindowState this method is applied to.
Chong Zhang0abb20f2015-11-19 14:17:31 -08001353 * @param dispInfo info of the display that the window's obscuring state is checked against.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001354 */
Chong Zhang0abb20f2015-11-19 14:17:31 -08001355 private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001356 final LayoutParams attrs = w.mAttrs;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001357 final int attrFlags = attrs.flags;
1358 final boolean canBeSeen = w.isDisplayedLw();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001359
Chong Zhang0abb20f2015-11-19 14:17:31 -08001360 if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001361 // This window completely covers everything behind it,
1362 // so we want to leave all of them as undimmed (for
1363 // performance reasons).
1364 mObscured = true;
1365 }
1366
1367 if (w.mHasSurface) {
1368 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
1369 mHoldScreen = w.mSession;
1370 }
1371 if (!mSyswin && w.mAttrs.screenBrightness >= 0
1372 && mScreenBrightness < 0) {
1373 mScreenBrightness = w.mAttrs.screenBrightness;
1374 }
1375 if (!mSyswin && w.mAttrs.buttonBrightness >= 0
1376 && mButtonBrightness < 0) {
1377 mButtonBrightness = w.mAttrs.buttonBrightness;
1378 }
1379 if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
1380 && mUserActivityTimeout < 0) {
1381 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1382 }
1383
1384 final int type = attrs.type;
1385 if (canBeSeen
1386 && (type == TYPE_SYSTEM_DIALOG
1387 || type == TYPE_SYSTEM_ERROR
1388 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
1389 mSyswin = true;
1390 }
1391
1392 if (canBeSeen) {
1393 // This function assumes that the contents of the default display are
1394 // processed first before secondary displays.
1395 final DisplayContent displayContent = w.getDisplayContent();
1396 if (displayContent != null && displayContent.isDefaultDisplay) {
1397 // While a dream or keyguard is showing, obscure ordinary application
1398 // content on secondary displays (by forcibly enabling mirroring unless
1399 // there is other content we want to show) but still allow opaque
1400 // keyguard dialogs to be shown.
1401 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1402 mObscureApplicationContentOnSecondaryDisplays = true;
1403 }
1404 mDisplayHasContent = true;
1405 } else if (displayContent != null &&
1406 (!mObscureApplicationContentOnSecondaryDisplays
1407 || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1408 // Allow full screen keyguard presentation dialogs to be seen.
1409 mDisplayHasContent = true;
1410 }
1411 if (mPreferredRefreshRate == 0
1412 && w.mAttrs.preferredRefreshRate != 0) {
1413 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1414 }
1415 if (mPreferredModeId == 0
1416 && w.mAttrs.preferredDisplayModeId != 0) {
1417 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1418 }
1419 }
1420 }
1421 }
1422
1423 private void updateAllDrawnLocked(DisplayContent displayContent) {
1424 // See if any windows have been drawn, so they (and others
1425 // associated with them) can now be shown.
1426 ArrayList<TaskStack> stacks = displayContent.getStacks();
1427 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1428 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
1429 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1430 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1431 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
1432 final AppWindowToken wtoken = tokens.get(tokenNdx);
1433 if (!wtoken.allDrawn) {
1434 int numInteresting = wtoken.numInterestingWindows;
1435 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
1436 if (DEBUG_VISIBILITY)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001437 Slog.v(TAG, "allDrawn: " + wtoken
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001438 + " interesting=" + numInteresting
1439 + " drawn=" + wtoken.numDrawnWindows);
1440 wtoken.allDrawn = true;
1441 // Force an additional layout pass where WindowStateAnimator#
1442 // commitFinishDrawingLocked() will call performShowLocked().
1443 displayContent.layoutNeeded = true;
1444 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
1445 wtoken.token).sendToTarget();
1446 }
1447 }
1448 }
1449 }
1450 }
1451 }
1452
1453 private static int toBrightnessOverride(float value) {
1454 return (int)(value * PowerManager.BRIGHTNESS_ON);
1455 }
1456
1457 private void processApplicationsAnimatingInPlace(int transit) {
1458 if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
1459 // Find the focused window
1460 final WindowState win = mService.findFocusedWindowLocked(
1461 mService.getDefaultDisplayContentLocked());
1462 if (win != null) {
1463 final AppWindowToken wtoken = win.mAppToken;
1464 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1465 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001466 Slog.v(TAG, "Now animating app in place " + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001467 appAnimator.clearThumbnail();
1468 appAnimator.animation = null;
1469 mService.updateTokenInPlaceLocked(wtoken, transit);
1470 wtoken.updateReportedVisibilityLocked();
1471
1472 appAnimator.mAllAppWinAnimators.clear();
1473 final int N = wtoken.allAppWindows.size();
1474 for (int j = 0; j < N; j++) {
1475 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1476 }
1477 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001478 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001479 }
1480 }
1481 }
1482
1483 private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
1484 int openingLayer, int closingLayer) {
1485 AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
1486 if (openingAppAnimator == null || openingAppAnimator.animation == null) {
1487 return;
1488 }
1489 final int taskId = appToken.mTask.mTaskId;
1490 Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
1491 if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001492 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001493 return;
1494 }
1495 // This thumbnail animation is very special, we need to have
1496 // an extra surface with the thumbnail included with the animation.
1497 Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
1498 try {
1499 // TODO(multi-display): support other displays
1500 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1501 final Display display = displayContent.getDisplay();
1502 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1503
1504 // Create a new surface for the thumbnail
1505 SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
1506 "thumbnail anim", dirty.width(), dirty.height(),
1507 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
1508 surfaceControl.setLayerStack(display.getLayerStack());
1509 if (SHOW_TRANSACTIONS) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001510 Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001511 }
1512
1513 // Draw the thumbnail onto the surface
1514 Surface drawSurface = new Surface();
1515 drawSurface.copyFrom(surfaceControl);
1516 Canvas c = drawSurface.lockCanvas(dirty);
1517 c.drawBitmap(thumbnailHeader, 0, 0, null);
1518 drawSurface.unlockCanvasAndPost(c);
1519 drawSurface.release();
1520
1521 // Get the thumbnail animation
1522 Animation anim;
1523 if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
1524 // If this is a multi-window scenario, we use the windows frame as
1525 // destination of the thumbnail header animation. If this is a full screen
1526 // window scenario, we use the whole display as the target.
1527 WindowState win = appToken.findMainWindow();
1528 Rect appRect = win != null ? win.getContentFrameLw() :
1529 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
1530 // For the new aspect-scaled transition, we want it to always show
1531 // above the animating opening/closing window, and we want to
1532 // synchronize its thumbnail surface with the surface for the
1533 // open/close animation (only on the way down)
1534 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
1535 thumbnailHeader, taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001536 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
1537 openingAppAnimator.deferThumbnailDestruction =
1538 !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
1539 } else {
1540 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
1541 displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
1542 }
1543 anim.restrictDuration(MAX_ANIMATION_DURATION);
1544 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1545
1546 openingAppAnimator.thumbnail = surfaceControl;
1547 openingAppAnimator.thumbnailLayer = openingLayer;
1548 openingAppAnimator.thumbnailAnimation = anim;
1549 mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
1550 openingAppAnimator.thumbnailX = mTmpStartRect.left;
1551 openingAppAnimator.thumbnailY = mTmpStartRect.top;
1552 } catch (Surface.OutOfResourcesException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001553 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001554 + dirty.width() + " h=" + dirty.height(), e);
1555 openingAppAnimator.clearThumbnail();
1556 }
1557 }
1558
1559 boolean copyAnimToLayoutParamsLocked() {
1560 boolean doRequest = false;
1561
1562 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1563 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1564 mUpdateRotation = true;
1565 doRequest = true;
1566 }
1567 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1568 mWallpaperMayChange = true;
1569 doRequest = true;
1570 }
1571 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1572 mWallpaperForceHidingChanged = true;
1573 doRequest = true;
1574 }
1575 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1576 mOrientationChangeComplete = false;
1577 } else {
1578 mOrientationChangeComplete = true;
1579 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1580 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1581 doRequest = true;
1582 }
1583 }
1584 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1585 mService.mTurnOnScreen = true;
1586 }
1587 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1588 mWallpaperActionPending = true;
1589 }
1590
1591 return doRequest;
1592 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001593
1594 void requestTraversal() {
1595 if (!mTraversalScheduled) {
1596 mTraversalScheduled = true;
1597 mService.mH.sendEmptyMessage(DO_TRAVERSAL);
1598 }
1599 }
1600
1601 public void dump(PrintWriter pw, String prefix) {
1602 pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
1603 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001604}