blob: 160c97f1e62b9ac52134bb806631876f221a9864 [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;
10import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
11import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
12import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
13import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
14import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
15import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
16import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
17import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080018import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
19import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
20import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
21import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
22import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
23import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
24import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
25import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
26import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
27import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
28import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
29import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
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 {
70 private final WindowManagerService mService;
71 private final WallpaperController mWallpaperControllerLocked;
72
73 private boolean mInLayout = false;
74
75 /** Only do a maximum of 6 repeated layouts. After that quit */
76 private int mLayoutRepeatCount;
77
78 static final int SET_UPDATE_ROTATION = 1 << 0;
79 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
80 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
81 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
82 static final int SET_TURN_ON_SCREEN = 1 << 4;
83 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
84
85 boolean mWallpaperMayChange = false;
86 boolean mOrientationChangeComplete = true;
87 boolean mWallpaperActionPending = false;
88
89 private boolean mWallpaperForceHidingChanged = false;
90 private Object mLastWindowFreezeSource = null;
91 private Session mHoldScreen = null;
92 private boolean mObscured = false;
93 private boolean mSyswin = false;
94 private float mScreenBrightness = -1;
95 private float mButtonBrightness = -1;
96 private long mUserActivityTimeout = -1;
97 private boolean mUpdateRotation = false;
98 private final Rect mTmpStartRect = new Rect();
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -080099 private final Rect mTmpContentRect = new Rect();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700100
101 // Set to true when the display contains content to show the user.
102 // When false, the display manager may choose to mirror or blank the display.
103 private boolean mDisplayHasContent = false;
104
105 // Only set while traversing the default display based on its content.
106 // Affects the behavior of mirroring on secondary displays.
107 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
108
109 private float mPreferredRefreshRate = 0;
110
111 private int mPreferredModeId = 0;
112
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700113 private boolean mTraversalScheduled;
Jorim Jaggic4025202015-10-22 16:43:34 +0200114 private int mDeferDepth = 0;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700115
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800116 private static final class LayerAndToken {
117 public int layer;
118 public AppWindowToken token;
119 }
120 private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
121
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700122 public WindowSurfacePlacer(WindowManagerService service) {
123 mService = service;
124 mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
125 }
126
Jorim Jaggic4025202015-10-22 16:43:34 +0200127 /**
128 * See {@link WindowManagerService#deferSurfaceLayout()}
129 */
130 void deferLayout() {
131 mDeferDepth++;
132 }
133
134 /**
135 * See {@link WindowManagerService#continueSurfaceLayout()}
136 */
137 void continueLayout() {
138 mDeferDepth--;
139 if (mDeferDepth <= 0) {
140 performSurfacePlacement();
141 }
142 }
143
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700144 final void performSurfacePlacement() {
Jorim Jaggic4025202015-10-22 16:43:34 +0200145 if (mDeferDepth > 0) {
146 return;
147 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700148 int loopCount = 6;
149 do {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700150 mTraversalScheduled = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700151 performSurfacePlacementLoop();
152 mService.mH.removeMessages(DO_TRAVERSAL);
153 loopCount--;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700154 } while (mTraversalScheduled && loopCount > 0);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700155 mWallpaperActionPending = false;
156 }
157
158 private void performSurfacePlacementLoop() {
159 if (mInLayout) {
160 if (DEBUG) {
161 throw new RuntimeException("Recursive call!");
162 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800163 Slog.w(TAG_WM, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700164 + Debug.getCallers(3));
165 return;
166 }
167
168 if (mService.mWaitingForConfig) {
169 // Our configuration has changed (most likely rotation), but we
170 // don't yet have the complete configuration to report to
171 // applications. Don't do any window layout until we have it.
172 return;
173 }
174
175 if (!mService.mDisplayReady) {
176 // Not yet initialized, nothing to do.
177 return;
178 }
179
180 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
181 mInLayout = true;
182
183 boolean recoveringMemory = false;
184 if (!mService.mForceRemoves.isEmpty()) {
185 recoveringMemory = true;
186 // Wait a little bit for things to settle down, and off we go.
187 while (!mService.mForceRemoves.isEmpty()) {
188 WindowState ws = mService.mForceRemoves.remove(0);
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800189 Slog.i(TAG_WM, "Force removing: " + ws);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700190 mService.removeWindowInnerLocked(ws);
191 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800192 Slog.w(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700193 "Due to memory failure, waiting a bit for next layout");
194 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 Gruszczynski0bd180d2015-12-07 15:43:52 -0800212 Slog.e(TAG_WM, "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 Gruszczynski0bd180d2015-12-07 15:43:52 -0800225 Slog.wtf(TAG_WM, "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 Gruszczynski0bd180d2015-12-07 15:43:52 -0800233 Slog.v(TAG_WM, "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) {
240 if (DEBUG_WINDOW_TRACE) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800241 Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700242 "performSurfacePlacementInner: entry. Called by "
243 + Debug.getCallers(3));
244 }
245
246 int i;
247 boolean updateInputWindowsNeeded = false;
248
249 if (mService.mFocusMayChange) {
250 mService.mFocusMayChange = false;
251 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
252 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
253 }
254
255 // Initialize state of exiting tokens.
256 final int numDisplays = mService.mDisplayContents.size();
257 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
258 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
259 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
260 displayContent.mExitingTokens.get(i).hasVisible = false;
261 }
262 }
263
264 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
265 // Initialize state of exiting applications.
266 final AppTokenList exitingAppTokens =
267 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
268 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
269 exitingAppTokens.get(tokenNdx).hasVisible = false;
270 }
271 }
272
273 mHoldScreen = null;
274 mScreenBrightness = -1;
275 mButtonBrightness = -1;
276 mUserActivityTimeout = -1;
277 mObscureApplicationContentOnSecondaryDisplays = false;
278
279 mService.mTransactionSequence++;
280
281 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
282 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
283 final int defaultDw = defaultInfo.logicalWidth;
284 final int defaultDh = defaultInfo.logicalHeight;
285
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800286 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700287 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
288 SurfaceControl.openTransaction();
289 try {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700290 applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700291 } catch (RuntimeException e) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800292 Slog.wtf(TAG_WM, "Unhandled exception in Window Manager", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700293 } finally {
294 SurfaceControl.closeTransaction();
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800295 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700296 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
297 }
298
299 final WindowList defaultWindows = defaultDisplay.getWindowList();
300
301 // If we are ready to perform an app transition, check through
302 // all of the app tokens to be shown and see if they are ready
303 // to go.
304 if (mService.mAppTransition.isReady()) {
305 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
306 if (DEBUG_LAYOUT_REPEATS)
307 debugLayoutRepeats("after handleAppTransitionReadyLocked",
308 defaultDisplay.pendingLayoutChanges);
309 }
310
311 if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
312 // We have finished the animation of an app transition. To do
313 // this, we have delayed a lot of operations like showing and
314 // hiding apps, moving apps in Z-order, etc. The app token list
315 // reflects the correct Z-order, but the window list may now
316 // be out of sync with it. So here we will just rebuild the
317 // entire app window list. Fun!
318 defaultDisplay.pendingLayoutChanges |=
319 mService.handleAnimatingStoppedAndTransitionLocked();
320 if (DEBUG_LAYOUT_REPEATS)
321 debugLayoutRepeats("after handleAnimStopAndXitionLock",
322 defaultDisplay.pendingLayoutChanges);
323 }
324
325 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
326 && !mService.mAppTransition.isReady()) {
327 // At this point, there was a window with a wallpaper that
328 // was force hiding other windows behind it, but now it
329 // is going away. This may be simple -- just animate
330 // away the wallpaper and its window -- or it may be
331 // hard -- the wallpaper now needs to be shown behind
332 // something that was hidden.
333 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
334 if (DEBUG_LAYOUT_REPEATS)
335 debugLayoutRepeats("after animateAwayWallpaperLocked",
336 defaultDisplay.pendingLayoutChanges);
337 }
338 mWallpaperForceHidingChanged = false;
339
340 if (mWallpaperMayChange) {
341 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800342 Slog.v(TAG_WM, "Wallpaper may change! Adjusting");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700343 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
344 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
345 defaultDisplay.pendingLayoutChanges);
346 }
347
348 if (mService.mFocusMayChange) {
349 mService.mFocusMayChange = false;
350 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
351 false /*updateInputWindows*/)) {
352 updateInputWindowsNeeded = true;
353 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
354 }
355 }
356
357 if (mService.needsLayout()) {
358 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
359 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
360 defaultDisplay.pendingLayoutChanges);
361 }
362
363 for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
364 WindowState win = mService.mResizingWindows.get(i);
365 if (win.mAppFreezing) {
366 // Don't remove this window until rotation has completed.
367 continue;
368 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700369 // Discard the saved surface if window size is changed, it can't be reused.
Chong Zhangbef461f2015-10-27 11:38:24 -0700370 if (win.mAppToken != null) {
371 win.mAppToken.destroySavedSurfaces();
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700372 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700373 win.reportResized();
374 mService.mResizingWindows.remove(i);
375 }
376
377 if (DEBUG_ORIENTATION && mService.mDisplayFrozen)
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800378 Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700379 "With display frozen, orientationChangeComplete="
380 + mOrientationChangeComplete);
381 if (mOrientationChangeComplete) {
382 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
383 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
384 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
385 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
386 }
387 mService.stopFreezingDisplayLocked();
388 }
389
390 // Destroy the surface of any windows that are no longer visible.
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800391 boolean wallpaperDestroyed = false;
392 i = mService.mDestroySurface.size();
393 if (i > 0) {
394 do {
395 i--;
396 WindowState win = mService.mDestroySurface.get(i);
397 win.mDestroying = false;
398 if (mService.mInputMethodWindow == win) {
399 mService.mInputMethodWindow = null;
400 }
401 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
402 wallpaperDestroyed = true;
403 }
Robert Carr13f7be9e2015-12-02 18:39:45 -0800404 win.destroyOrSaveSurface();
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800405 } while (i > 0);
406 mService.mDestroySurface.clear();
407 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700408
409 // Time to remove any exiting tokens?
410 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
411 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
412 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
413 for (i = exitingTokens.size() - 1; i >= 0; i--) {
414 WindowToken token = exitingTokens.get(i);
415 if (!token.hasVisible) {
416 exitingTokens.remove(i);
417 if (token.windowType == TYPE_WALLPAPER) {
418 mWallpaperControllerLocked.removeWallpaperToken(token);
419 }
420 }
421 }
422 }
423
424 // Time to remove any exiting applications?
425 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
426 // Initialize state of exiting applications.
427 final AppTokenList exitingAppTokens =
428 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
429 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
430 AppWindowToken token = exitingAppTokens.get(i);
431 if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
432 (!token.mIsExiting || token.allAppWindows.isEmpty())) {
433 // Make sure there is no animation running on this token,
434 // so any windows associated with it will be removed as
435 // soon as their animations are complete
436 token.mAppAnimator.clearAnimation();
437 token.mAppAnimator.animating = false;
438 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT)
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800439 Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700440 "performLayout: App token exiting now removed" + token);
441 token.removeAppFromTaskLocked();
442 }
443 }
444 }
445
446 if (wallpaperDestroyed) {
447 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
448 defaultDisplay.layoutNeeded = true;
449 }
450
451 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
452 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
453 if (displayContent.pendingLayoutChanges != 0) {
454 displayContent.layoutNeeded = true;
455 }
456 }
457
458 // Finally update all input windows now that the window changes have stabilized.
459 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
460
461 mService.setHoldScreenLocked(mHoldScreen);
462 if (!mService.mDisplayFrozen) {
463 if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
464 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
465 } else {
466 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
467 toBrightnessOverride(mScreenBrightness));
468 }
469 if (mButtonBrightness < 0
470 || mButtonBrightness > 1.0f) {
471 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
472 } else {
473 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
474 toBrightnessOverride(mButtonBrightness));
475 }
476 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
477 mUserActivityTimeout);
478 }
479
480 if (mService.mTurnOnScreen) {
481 if (mService.mAllowTheaterModeWakeFromLayout
482 || Settings.Global.getInt(mService.mContext.getContentResolver(),
483 Settings.Global.THEATER_MODE_ON, 0) == 0) {
484 if (DEBUG_VISIBILITY || DEBUG_POWER) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800485 Slog.v(TAG_WM, "Turning screen on after layout!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700486 }
487 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
488 "android.server.wm:TURN_ON");
489 }
490 mService.mTurnOnScreen = false;
491 }
492
493 if (mUpdateRotation) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800494 if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700495 "Performing post-rotate rotation");
496 if (mService.updateRotationUncheckedLocked(false)) {
497 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
498 } else {
499 mUpdateRotation = false;
500 }
501 }
502
503 if (mService.mWaitingForDrawnCallback != null ||
504 (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
505 !mUpdateRotation)) {
506 mService.checkDrawnWindowsLocked();
507 }
508
509 final int N = mService.mPendingRemove.size();
510 if (N > 0) {
511 if (mService.mPendingRemoveTmp.length < N) {
512 mService.mPendingRemoveTmp = new WindowState[N+10];
513 }
514 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
515 mService.mPendingRemove.clear();
516 DisplayContentList displayList = new DisplayContentList();
517 for (i = 0; i < N; i++) {
518 WindowState w = mService.mPendingRemoveTmp[i];
519 mService.removeWindowInnerLocked(w);
520 final DisplayContent displayContent = w.getDisplayContent();
521 if (displayContent != null && !displayList.contains(displayContent)) {
522 displayList.add(displayContent);
523 }
524 }
525
526 for (DisplayContent displayContent : displayList) {
527 mService.assignLayersLocked(displayContent.getWindowList());
528 displayContent.layoutNeeded = true;
529 }
530 }
531
532 // Remove all deferred displays stacks, tasks, and activities.
533 for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
534 mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
535 }
536
537 if (updateInputWindowsNeeded) {
538 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
539 }
Chong Zhangb15758a2015-11-17 12:12:03 -0800540 mService.setFocusTaskRegionLocked();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700541
542 // Check to see if we are now in a state where the screen should
543 // be enabled, because the window obscured flags have changed.
544 mService.enableScreenIfNeededLocked();
545
546 mService.scheduleAnimationLocked();
547
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800548 if (DEBUG_WINDOW_TRACE) Slog.e(TAG_WM,
Wale Ogunwale69cf50f2015-11-13 11:08:36 -0800549 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700550 }
551
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700552 private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
553 int defaultDw, int defaultDh) {
554 if (mService.mWatermark != null) {
555 mService.mWatermark.positionSurface(defaultDw, defaultDh);
556 }
557 if (mService.mStrictModeFlash != null) {
558 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
559 }
560 if (mService.mCircularDisplayMask != null) {
561 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
562 mService.mRotation);
563 }
564 if (mService.mEmulatorDisplayOverlay != null) {
565 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
566 mService.mRotation);
567 }
568
569 boolean focusDisplayed = false;
570
571 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
572 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
573 boolean updateAllDrawn = false;
574 WindowList windows = displayContent.getWindowList();
575 DisplayInfo displayInfo = displayContent.getDisplayInfo();
576 final int displayId = displayContent.getDisplayId();
577 final int dw = displayInfo.logicalWidth;
578 final int dh = displayInfo.logicalHeight;
579 final int innerDw = displayInfo.appWidth;
580 final int innerDh = displayInfo.appHeight;
581 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
582
583 // Reset for each display.
584 mDisplayHasContent = false;
585 mPreferredRefreshRate = 0;
586 mPreferredModeId = 0;
587
588 int repeats = 0;
589 do {
590 repeats++;
591 if (repeats > 6) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800592 Slog.w(TAG_WM, "Animation repeat aborted after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700593 displayContent.layoutNeeded = false;
594 break;
595 }
596
597 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
598 "On entry to LockedInner", displayContent.pendingLayoutChanges);
599
600 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
601 mWallpaperControllerLocked.adjustWallpaperWindows()) {
602 mService.assignLayersLocked(windows);
603 displayContent.layoutNeeded = true;
604 }
605
606 if (isDefaultDisplay
607 && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800608 if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Computing new config from layout");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700609 if (mService.updateOrientationFromAppTokensLocked(true)) {
610 displayContent.layoutNeeded = true;
611 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
612 }
613 }
614
615 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
616 displayContent.layoutNeeded = true;
617 }
618
619 // FIRST LOOP: Perform a layout, if needed.
620 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
621 performLayoutLockedInner(displayContent, repeats == 1,
622 false /* updateInputWindows */);
623 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800624 Slog.w(TAG_WM, "Layout repeat skipped after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700625 }
626
627 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
628 // it is animating.
629 displayContent.pendingLayoutChanges = 0;
630
631 if (isDefaultDisplay) {
632 mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
633 for (int i = windows.size() - 1; i >= 0; i--) {
634 WindowState w = windows.get(i);
635 if (w.mHasSurface) {
636 mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
637 w.mAttachedWindow);
638 }
639 }
640 displayContent.pendingLayoutChanges |=
641 mService.mPolicy.finishPostLayoutPolicyLw();
642 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
643 displayContent.pendingLayoutChanges);
644 }
645 } while (displayContent.pendingLayoutChanges != 0);
646
647 mObscured = false;
648 mSyswin = false;
649 displayContent.resetDimming();
650
651 // Only used if default window
652 final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
653
654 for (int i = windows.size() - 1; i >= 0; i--) {
655 WindowState w = windows.get(i);
Wale Ogunwale5a2f2cb2015-09-17 12:31:55 -0700656 Task task = w.getTask();
657 if (task == null && w.getDisplayContent().getHomeStack() == null
658 && w.getAttrs().type != TYPE_PRIVATE_PRESENTATION) {
659 // TODO: Understand what the use case is here and see if the conditions can be
660 // simplified.
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700661 continue;
662 }
663
664 final boolean obscuredChanged = w.mObscured != mObscured;
665
666 // Update effect.
667 w.mObscured = mObscured;
668 if (!mObscured) {
Chong Zhang0abb20f2015-11-19 14:17:31 -0800669 handleNotObscuredLocked(w, displayInfo);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700670 }
671
Chong Zhang112eb8c2015-11-02 11:17:00 -0800672 w.applyDimLayerIfNeeded();
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700673
674 if (isDefaultDisplay && obscuredChanged
675 && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
676 // This is the wallpaper target and its obscured state
677 // changed... make sure the current wallaper's visibility
678 // has been updated accordingly.
679 mWallpaperControllerLocked.updateWallpaperVisibility();
680 }
681
682 final WindowStateAnimator winAnimator = w.mWinAnimator;
683
684 // If the window has moved due to its containing content frame changing, then
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800685 // notify the listeners and optionally animate it. Simply checking a change of
686 // position is not enough, because being move due to dock divider is not a trigger
687 // for animation.
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700688 if (w.hasMoved()) {
689 // Frame has moved, containing content frame has also moved, and we're not
690 // currently animating... let's do something.
691 final int left = w.mFrame.left;
692 final int top = w.mFrame.top;
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800693 if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
694 && !w.isDragResizing()) {
695 winAnimator.setMoveAnimation(left, top);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700696 }
697
698 //TODO (multidisplay): Accessibility supported only for the default display.
699 if (mService.mAccessibilityController != null
700 && displayId == Display.DEFAULT_DISPLAY) {
701 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
702 }
703
704 try {
705 w.mClient.moved(left, top);
706 } catch (RemoteException e) {
707 }
708 }
709
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800710 //Slog.i(TAG_WM, "Window " + this + " clearing mContentChanged - done placing");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700711 w.mContentChanged = false;
712
713 // Moved from updateWindowsAndWallpaperLocked().
714 if (w.mHasSurface) {
715 // Take care of the window being ready to display.
716 final boolean committed = winAnimator.commitFinishDrawingLocked();
717 if (isDefaultDisplay && committed) {
718 if (w.mAttrs.type == TYPE_DREAM) {
719 // HACK: When a dream is shown, it may at that
720 // point hide the lock screen. So we need to
721 // redo the layout to let the phone window manager
722 // make this happen.
723 displayContent.pendingLayoutChanges |=
724 FINISH_LAYOUT_REDO_LAYOUT;
725 if (DEBUG_LAYOUT_REPEATS) {
726 debugLayoutRepeats("dream and commitFinishDrawingLocked true",
727 displayContent.pendingLayoutChanges);
728 }
729 }
730 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
731 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800732 Slog.v(TAG_WM, "First draw done in potential wallpaper target " + w);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700733 mWallpaperMayChange = true;
734 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
735 if (DEBUG_LAYOUT_REPEATS) {
736 debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
737 displayContent.pendingLayoutChanges);
738 }
739 }
740 }
Chong Zhang09b21ef2015-09-14 10:20:21 -0700741 /*
742 * Updates the shown frame before we set up the surface. This is needed because
743 * the resizing could change the top-left position (in addition to size) of the
Filip Gruszczynski2a6a2c22015-10-14 12:00:53 -0700744 * window. setSurfaceBoundariesLocked uses mShownPosition to position the
745 * surface.
Chong Zhang09b21ef2015-09-14 10:20:21 -0700746 */
747 winAnimator.computeShownFrameLocked();
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700748 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
749 }
750
751 final AppWindowToken atoken = w.mAppToken;
752 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800753 Slog.d(TAG_WM, "updateWindows: starting " + w
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700754 + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
755 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
756 }
757 if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
758 if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
759 atoken.lastTransactionSequence = mService.mTransactionSequence;
760 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
761 atoken.startingDisplayed = false;
762 }
763 if ((w.isOnScreenIgnoringKeyguard()
764 || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
765 && !w.mExiting && !w.mDestroying) {
766 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800767 Slog.v(TAG_WM, "Eval win " + w + ": isDrawn="
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700768 + w.isDrawnLw()
769 + ", isAnimating=" + winAnimator.isAnimating());
770 if (!w.isDrawnLw()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800771 Slog.v(TAG_WM, "Not displayed: s="
Robert Carre6a83512015-11-03 16:09:21 -0800772 + winAnimator.mSurfaceController
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700773 + " pv=" + w.mPolicyVisibility
774 + " mDrawState=" + winAnimator.drawStateToString()
775 + " ah=" + w.mAttachedHidden
776 + " th=" + atoken.hiddenRequested
777 + " a=" + winAnimator.mAnimating);
778 }
779 }
Chong Zhang112eb8c2015-11-02 11:17:00 -0800780 if (w != atoken.startingWindow && !w.mAppDied) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700781 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
782 atoken.numInterestingWindows++;
783 if (w.isDrawnLw()) {
784 atoken.numDrawnWindows++;
785 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800786 Slog.v(TAG_WM, "tokenMayBeDrawn: " + atoken
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700787 + " freezingScreen="
788 + atoken.mAppAnimator.freezingScreen
789 + " mAppFreezing=" + w.mAppFreezing);
790 updateAllDrawn = true;
791 }
792 }
793 } else if (w.isDrawnLw()) {
794 atoken.startingDisplayed = true;
795 }
796 }
797 }
798
799 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
800 && w.isDisplayedLw()) {
801 focusDisplayed = true;
802 }
803
804 mService.updateResizingWindows(w);
805 }
806
807 mService.mDisplayManagerInternal.setDisplayProperties(displayId,
808 mDisplayHasContent,
809 mPreferredRefreshRate,
810 mPreferredModeId,
811 true /* inTraversal, must call performTraversalInTrans... below */);
812
813 mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
814
815 if (updateAllDrawn) {
816 updateAllDrawnLocked(displayContent);
817 }
818 }
819
820 if (focusDisplayed) {
821 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
822 }
823
824 // Give the display manager a chance to adjust properties
825 // like display rotation if it needs to.
826 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
827 }
828
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700829 boolean isInLayout() {
830 return mInLayout;
831 }
832
833 final void performLayoutLockedInner(final DisplayContent displayContent,
834 boolean initial, boolean updateInputWindows) {
835 if (!displayContent.layoutNeeded) {
836 return;
837 }
838 displayContent.layoutNeeded = false;
839 WindowList windows = displayContent.getWindowList();
840 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
841
842 DisplayInfo displayInfo = displayContent.getDisplayInfo();
843 final int dw = displayInfo.logicalWidth;
844 final int dh = displayInfo.logicalHeight;
845
846 if (mService.mInputConsumer != null) {
847 mService.mInputConsumer.layout(dw, dh);
848 }
849
850 final int N = windows.size();
851 int i;
852
853 if (DEBUG_LAYOUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800854 Slog.v(TAG_WM, "-------------------------------------");
855 Slog.v(TAG_WM, "performLayout: needed="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700856 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
857 }
858
859 mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation);
860 if (isDefaultDisplay) {
861 // Not needed on non-default displays.
862 mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
863 mService.mScreenRect.set(0, 0, dw, dh);
864 }
865
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800866 mService.mPolicy.getContentRectLw(mTmpContentRect);
867 displayContent.resize(mTmpContentRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700868
869 int seq = mService.mLayoutSeq+1;
870 if (seq < 0) seq = 0;
871 mService.mLayoutSeq = seq;
872
873 boolean behindDream = false;
874
875 // First perform layout of any root windows (not attached
876 // to another window).
877 int topAttached = -1;
878 for (i = N-1; i >= 0; i--) {
879 final WindowState win = windows.get(i);
880
881 // Don't do layout of a window if it is not visible, or
882 // soon won't be visible, to avoid wasting time and funky
883 // changes while a window is animating away.
884 final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
885 || win.isGoneForLayoutLw();
886
887 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800888 Slog.v(TAG_WM, "1ST PASS " + win
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700889 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
890 + " mLayoutAttached=" + win.mLayoutAttached
891 + " screen changed=" + win.isConfigChanged());
892 final AppWindowToken atoken = win.mAppToken;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800893 if (gone) Slog.v(TAG_WM, " GONE: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700894 + win.mViewVisibility + " mRelayoutCalled="
895 + win.mRelayoutCalled + " hidden="
896 + win.mRootToken.hidden + " hiddenRequested="
897 + (atoken != null && atoken.hiddenRequested)
898 + " mAttachedHidden=" + win.mAttachedHidden);
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800899 else Slog.v(TAG_WM, " VIS: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700900 + win.mViewVisibility + " mRelayoutCalled="
901 + win.mRelayoutCalled + " hidden="
902 + win.mRootToken.hidden + " hiddenRequested="
903 + (atoken != null && atoken.hiddenRequested)
904 + " mAttachedHidden=" + win.mAttachedHidden);
905 }
906
907 // If this view is GONE, then skip it -- keep the current
908 // frame, and let the caller know so they can ignore it
909 // if they want. (We do the normal layout for INVISIBLE
910 // windows, since that means "perform layout as normal,
911 // just don't display").
912 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
913 || ((win.isConfigChanged() || win.setInsetsChanged()) &&
914 ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
915 (win.mHasSurface && win.mAppToken != null &&
916 win.mAppToken.layoutConfigChanges)))) {
917 if (!win.mLayoutAttached) {
918 if (initial) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800919 //Slog.i(TAG_WM, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700920 win.mContentChanged = false;
921 }
922 if (win.mAttrs.type == TYPE_DREAM) {
923 // Don't layout windows behind a dream, so that if it
924 // does stuff like hide the status bar we won't get a
925 // bad transition when it goes away.
926 behindDream = true;
927 }
928 win.mLayoutNeeded = false;
929 win.prelayout();
930 mService.mPolicy.layoutWindowLw(win, null);
931 win.mLayoutSeq = seq;
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800932
933 // Window frames may have changed. Update dim layer with the new bounds.
934 final Task task = win.getTask();
935 if (task != null) {
936 displayContent.mDimLayerController.updateDimLayer(task);
937 }
938
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800939 if (DEBUG_LAYOUT) Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700940 " LAYOUT: mFrame="
941 + win.mFrame + " mContainingFrame="
942 + win.mContainingFrame + " mDisplayFrame="
943 + win.mDisplayFrame);
944 } else {
945 if (topAttached < 0) topAttached = i;
946 }
947 }
948 }
949
950 boolean attachedBehindDream = false;
951
952 // Now perform layout of attached windows, which usually
953 // depend on the position of the window they are attached to.
954 // XXX does not deal with windows that are attached to windows
955 // that are themselves attached.
956 for (i = topAttached; i >= 0; i--) {
957 final WindowState win = windows.get(i);
958
959 if (win.mLayoutAttached) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800960 if (DEBUG_LAYOUT) Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700961 "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
962 + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
963 // If this view is GONE, then skip it -- keep the current
964 // frame, and let the caller know so they can ignore it
965 // if they want. (We do the normal layout for INVISIBLE
966 // windows, since that means "perform layout as normal,
967 // just don't display").
968 if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
969 continue;
970 }
971 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
972 || !win.mHaveFrame || win.mLayoutNeeded) {
973 if (initial) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800974 //Slog.i(TAG_WM, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700975 win.mContentChanged = false;
976 }
977 win.mLayoutNeeded = false;
978 win.prelayout();
979 mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
980 win.mLayoutSeq = seq;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800981 if (DEBUG_LAYOUT) Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700982 " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
983 + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
984 }
985 } else if (win.mAttrs.type == TYPE_DREAM) {
986 // Don't layout windows behind a dream, so that if it
987 // does stuff like hide the status bar we won't get a
988 // bad transition when it goes away.
989 attachedBehindDream = behindDream;
990 }
991 }
992
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800993 // Window frames may have changed. Tell the input dispatcher about it.
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700994 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
995 if (updateInputWindows) {
996 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
997 }
998
999 mService.mPolicy.finishLayoutLw();
Jorim Jaggi61f39a72015-10-29 16:54:18 +01001000 mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001001 }
1002
1003 /**
1004 * @param windows List of windows on default display.
1005 * @return bitmap indicating if another pass through layout must be made.
1006 */
1007 private int handleAppTransitionReadyLocked(WindowList windows) {
1008 int appsCount = mService.mOpeningApps.size();
1009 if (!transitionGoodToGo(appsCount)) {
1010 return 0;
1011 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001012 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "**** GOOD TO GO");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001013 int transit = mService.mAppTransition.getAppTransition();
1014 if (mService.mSkipAppTransitionAnimation) {
1015 transit = AppTransition.TRANSIT_UNSET;
1016 }
1017 mService.mSkipAppTransitionAnimation = false;
1018 mService.mNoAnimationNotifyOnTransitionFinished.clear();
1019
1020 mService.mH.removeMessages(APP_TRANSITION_TIMEOUT);
1021
1022 mService.rebuildAppWindowListLocked();
1023
1024 mWallpaperMayChange = false;
1025
1026 // The top-most window will supply the layout params,
1027 // and we will determine it below.
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001028 LayoutParams animLp = null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001029 int bestAnimLayer = -1;
1030 boolean fullscreenAnim = false;
1031 boolean voiceInteraction = false;
1032
1033 final WindowState lowerWallpaperTarget =
1034 mWallpaperControllerLocked.getLowerWallpaperTarget();
1035 final WindowState upperWallpaperTarget =
1036 mWallpaperControllerLocked.getUpperWallpaperTarget();
1037
1038 boolean openingAppHasWallpaper = false;
1039 boolean closingAppHasWallpaper = false;
1040 final AppWindowToken lowerWallpaperAppToken;
1041 final AppWindowToken upperWallpaperAppToken;
1042 if (lowerWallpaperTarget == null) {
1043 lowerWallpaperAppToken = upperWallpaperAppToken = null;
1044 } else {
1045 lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
1046 upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
1047 }
1048
1049 int i;
1050 // Do a first pass through the tokens for two
1051 // things:
1052 // (1) Determine if both the closing and opening
1053 // app token sets are wallpaper targets, in which
1054 // case special animations are needed
1055 // (since the wallpaper needs to stay static
1056 // behind them).
1057 // (2) Find the layout params of the top-most
1058 // application window in the tokens, which is
1059 // what will control the animation theme.
1060 final int closingAppsCount = mService.mClosingApps.size();
1061 appsCount = closingAppsCount + mService.mOpeningApps.size();
1062 for (i = 0; i < appsCount; i++) {
1063 final AppWindowToken wtoken;
1064 if (i < closingAppsCount) {
1065 wtoken = mService.mClosingApps.valueAt(i);
1066 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1067 closingAppHasWallpaper = true;
1068 }
1069 } else {
1070 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
1071 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1072 openingAppHasWallpaper = true;
1073 }
1074 }
1075
1076 voiceInteraction |= wtoken.voiceInteraction;
1077
1078 if (wtoken.appFullscreen) {
1079 WindowState ws = wtoken.findMainWindow();
1080 if (ws != null) {
1081 animLp = ws.mAttrs;
1082 bestAnimLayer = ws.mLayer;
1083 fullscreenAnim = true;
1084 }
1085 } else if (!fullscreenAnim) {
1086 WindowState ws = wtoken.findMainWindow();
1087 if (ws != null) {
1088 if (ws.mLayer > bestAnimLayer) {
1089 animLp = ws.mAttrs;
1090 bestAnimLayer = ws.mLayer;
1091 }
1092 }
1093 }
1094 }
1095
1096 transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
1097 closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
1098
1099 // If all closing windows are obscured, then there is
1100 // no need to do an animation. This is the case, for
1101 // example, when this transition is being done behind
1102 // the lock screen.
1103 if (!mService.mPolicy.allowAppAnimationsLw()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001104 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001105 "Animations disallowed by keyguard or dream.");
1106 animLp = null;
1107 }
1108
1109 processApplicationsAnimatingInPlace(transit);
1110
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001111 handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
1112 final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
1113 final int topClosingLayer = mTmpLayerAndToken.layer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001114
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001115 final AppWindowToken topOpeningApp = handleOpeningApps(transit,
1116 animLp, voiceInteraction, topClosingLayer);
1117
1118 final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
1119 topOpeningApp.mAppAnimator;
1120 final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
1121 topClosingApp.mAppAnimator;
1122
1123 mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
1124 mService.mAppTransition.postAnimationCallback();
1125 mService.mAppTransition.clear();
1126
1127 mService.mOpeningApps.clear();
1128 mService.mClosingApps.clear();
1129
1130 // This has changed the visibility of windows, so perform
1131 // a new layout to get them all up-to-date.
1132 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1133
1134 // TODO(multidisplay): IMEs are only supported on the default display.
1135 if (windows == mService.getDefaultWindowListLocked()
1136 && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
1137 mService.assignLayersLocked(windows);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001138 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001139 mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1140 true /*updateInputWindows*/);
1141 mService.mFocusMayChange = false;
1142 mService.notifyActivityDrawnForKeyguard();
1143 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
1144 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001145
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001146 private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
1147 boolean voiceInteraction, int topClosingLayer) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001148 AppWindowToken topOpeningApp = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001149 final int appsCount = mService.mOpeningApps.size();
1150 for (int i = 0; i < appsCount; i++) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001151 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1152 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001153 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Now opening app" + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001154
1155 if (!appAnimator.usingTransferredAnimation) {
1156 appAnimator.clearThumbnail();
1157 appAnimator.animation = null;
1158 }
1159 wtoken.inPendingTransaction = false;
1160 if (!mService.setTokenVisibilityLocked(
1161 wtoken, animLp, true, transit, false, voiceInteraction)){
1162 // This token isn't going to be animating. Add it to the list of tokens to
1163 // be notified of app transition complete since the notification will not be
1164 // sent be the app window animator.
1165 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
1166 }
1167 wtoken.updateReportedVisibilityLocked();
1168 wtoken.waitingToShow = false;
1169
1170 appAnimator.mAllAppWinAnimators.clear();
1171 final int windowsCount = wtoken.allAppWindows.size();
1172 for (int j = 0; j < windowsCount; j++) {
1173 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1174 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001175 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001176 ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
1177 SurfaceControl.openTransaction();
1178 try {
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001179 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001180 } finally {
1181 SurfaceControl.closeTransaction();
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001182 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001183 "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
1184 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001185 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1186
1187 int topOpeningLayer = 0;
1188 if (animLp != null) {
1189 int layer = -1;
1190 for (int j = 0; j < wtoken.windows.size(); j++) {
Chong Zhangbef461f2015-10-27 11:38:24 -07001191 final WindowState win = wtoken.windows.get(j);
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001192 // Clearing the mExiting flag before entering animation. It will be set to true
1193 // if app window is removed, or window relayout to invisible. We don't want to
1194 // clear it out for windows that get replaced, because the animation depends on
1195 // the flag to remove the replaced window.
Robert Carra1eb4392015-12-10 12:43:51 -08001196 if (!win.mWillReplaceWindow) {
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001197 win.mExiting = false;
1198 }
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 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -07001211
Chong Zhangbef461f2015-10-27 11:38:24 -07001212 wtoken.restoreSavedSurfaces();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001213 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001214 return topOpeningApp;
1215 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001216
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001217 private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
1218 LayerAndToken layerAndToken) {
1219 final int appsCount;
1220 appsCount = mService.mClosingApps.size();
1221 for (int i = 0; i < appsCount; i++) {
1222 AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
1223 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1224 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Now closing app " + wtoken);
1225 appAnimator.clearThumbnail();
1226 appAnimator.animation = null;
1227 wtoken.inPendingTransaction = false;
1228 mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
1229 voiceInteraction);
1230 wtoken.updateReportedVisibilityLocked();
1231 // Force the allDrawn flag, because we want to start
1232 // this guy's animations regardless of whether it's
1233 // gotten drawn.
1234 wtoken.allDrawn = true;
1235 wtoken.deferClearAllDrawn = false;
1236 // Ensure that apps that are mid-starting are also scheduled to have their
1237 // starting windows removed after the animation is complete
1238 if (wtoken.startingWindow != null && !wtoken.startingWindow.mExiting) {
1239 mService.scheduleRemoveStartingWindowLocked(wtoken);
1240 }
1241 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001242
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001243 if (animLp != null) {
1244 int layer = -1;
1245 for (int j = 0; j < wtoken.windows.size(); j++) {
1246 WindowState win = wtoken.windows.get(j);
1247 if (win.mWinAnimator.mAnimLayer > layer) {
1248 layer = win.mWinAnimator.mAnimLayer;
1249 }
1250 }
1251 if (layerAndToken.token == null || layer > layerAndToken.layer) {
1252 layerAndToken.token = wtoken;
1253 layerAndToken.layer = layer;
1254 }
1255 }
1256 if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
1257 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
1258 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001259 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001260 }
1261
1262 private boolean transitionGoodToGo(int appsCount) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001263 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001264 "Checking " + appsCount + " opening apps (frozen="
1265 + mService.mDisplayFrozen + " timeout="
1266 + mService.mAppTransition.isTimeout() + ")...");
1267 if (!mService.mAppTransition.isTimeout()) {
1268 for (int i = 0; i < appsCount; i++) {
1269 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001270 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001271 "Check opening app=" + wtoken + ": allDrawn="
1272 + wtoken.allDrawn + " startingDisplayed="
1273 + wtoken.startingDisplayed + " startingMoved="
1274 + wtoken.startingMoved);
Chong Zhangdb20b5f2015-10-23 14:01:43 -07001275
Robert Carr13f7be9e2015-12-02 18:39:45 -08001276 if (wtoken.hasSavedSurface() || wtoken.mAnimatingWithSavedSurface) {
Chong Zhangdb20b5f2015-10-23 14:01:43 -07001277 continue;
1278 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001279 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
1280 return false;
1281 }
1282 }
1283
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001284 // We also need to wait for the specs to be fetched, if needed.
1285 if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001286 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "isFetchingAppTransitionSpecs=true");
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001287 return false;
1288 }
1289
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001290 // If the wallpaper is visible, we need to check it's ready too.
1291 return !mWallpaperControllerLocked.isWallpaperVisible() ||
1292 mWallpaperControllerLocked.wallpaperTransitionReady();
1293 }
1294 return true;
1295 }
1296
1297 private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
1298 boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
1299 WindowState upperWallpaperTarget) {
1300 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
1301 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
1302 final WindowState oldWallpaper =
1303 mWallpaperControllerLocked.isWallpaperTargetAnimating()
1304 ? null : wallpaperTarget;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001305 final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
1306 final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001307 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001308 "New wallpaper target=" + wallpaperTarget
1309 + ", oldWallpaper=" + oldWallpaper
1310 + ", lower target=" + lowerWallpaperTarget
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001311 + ", upper target=" + upperWallpaperTarget
1312 + ", openingApps=" + openingApps
1313 + ", closingApps=" + closingApps);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001314 mService.mAnimateWallpaperWithTarget = false;
1315 if (closingAppHasWallpaper && openingAppHasWallpaper) {
1316 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001317 Slog.v(TAG_WM, "Wallpaper animation!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001318 switch (transit) {
1319 case AppTransition.TRANSIT_ACTIVITY_OPEN:
1320 case AppTransition.TRANSIT_TASK_OPEN:
1321 case AppTransition.TRANSIT_TASK_TO_FRONT:
1322 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
1323 break;
1324 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
1325 case AppTransition.TRANSIT_TASK_CLOSE:
1326 case AppTransition.TRANSIT_TASK_TO_BACK:
1327 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
1328 break;
1329 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001330 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001331 "New transit: " + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001332 } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
1333 && !openingApps.contains(oldWallpaper.mAppToken)
1334 && closingApps.contains(oldWallpaper.mAppToken)) {
1335 // We are transitioning from an activity with a wallpaper to one without.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001336 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001337 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001338 "New transit away from wallpaper: "
1339 + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001340 } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
1341 openingApps.contains(wallpaperTarget.mAppToken)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001342 // We are transitioning from an activity without
1343 // a wallpaper to now showing the wallpaper
1344 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001345 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001346 "New transit into wallpaper: "
1347 + AppTransition.appTransitionToString(transit));
1348 } else {
1349 mService.mAnimateWallpaperWithTarget = true;
1350 }
1351 return transit;
1352 }
1353
1354 /**
1355 * @param w WindowState this method is applied to.
Chong Zhang0abb20f2015-11-19 14:17:31 -08001356 * @param dispInfo info of the display that the window's obscuring state is checked against.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001357 */
Chong Zhang0abb20f2015-11-19 14:17:31 -08001358 private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001359 final LayoutParams attrs = w.mAttrs;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001360 final int attrFlags = attrs.flags;
1361 final boolean canBeSeen = w.isDisplayedLw();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001362
Chong Zhang0abb20f2015-11-19 14:17:31 -08001363 if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001364 // This window completely covers everything behind it,
1365 // so we want to leave all of them as undimmed (for
1366 // performance reasons).
1367 mObscured = true;
1368 }
1369
1370 if (w.mHasSurface) {
1371 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
1372 mHoldScreen = w.mSession;
1373 }
1374 if (!mSyswin && w.mAttrs.screenBrightness >= 0
1375 && mScreenBrightness < 0) {
1376 mScreenBrightness = w.mAttrs.screenBrightness;
1377 }
1378 if (!mSyswin && w.mAttrs.buttonBrightness >= 0
1379 && mButtonBrightness < 0) {
1380 mButtonBrightness = w.mAttrs.buttonBrightness;
1381 }
1382 if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
1383 && mUserActivityTimeout < 0) {
1384 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1385 }
1386
1387 final int type = attrs.type;
1388 if (canBeSeen
1389 && (type == TYPE_SYSTEM_DIALOG
1390 || type == TYPE_SYSTEM_ERROR
1391 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
1392 mSyswin = true;
1393 }
1394
1395 if (canBeSeen) {
1396 // This function assumes that the contents of the default display are
1397 // processed first before secondary displays.
1398 final DisplayContent displayContent = w.getDisplayContent();
1399 if (displayContent != null && displayContent.isDefaultDisplay) {
1400 // While a dream or keyguard is showing, obscure ordinary application
1401 // content on secondary displays (by forcibly enabling mirroring unless
1402 // there is other content we want to show) but still allow opaque
1403 // keyguard dialogs to be shown.
1404 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1405 mObscureApplicationContentOnSecondaryDisplays = true;
1406 }
1407 mDisplayHasContent = true;
1408 } else if (displayContent != null &&
1409 (!mObscureApplicationContentOnSecondaryDisplays
1410 || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1411 // Allow full screen keyguard presentation dialogs to be seen.
1412 mDisplayHasContent = true;
1413 }
1414 if (mPreferredRefreshRate == 0
1415 && w.mAttrs.preferredRefreshRate != 0) {
1416 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1417 }
1418 if (mPreferredModeId == 0
1419 && w.mAttrs.preferredDisplayModeId != 0) {
1420 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1421 }
1422 }
1423 }
1424 }
1425
1426 private void updateAllDrawnLocked(DisplayContent displayContent) {
1427 // See if any windows have been drawn, so they (and others
1428 // associated with them) can now be shown.
1429 ArrayList<TaskStack> stacks = displayContent.getStacks();
1430 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1431 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
1432 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1433 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1434 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
1435 final AppWindowToken wtoken = tokens.get(tokenNdx);
1436 if (!wtoken.allDrawn) {
1437 int numInteresting = wtoken.numInterestingWindows;
1438 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
1439 if (DEBUG_VISIBILITY)
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001440 Slog.v(TAG_WM, "allDrawn: " + wtoken
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001441 + " interesting=" + numInteresting
1442 + " drawn=" + wtoken.numDrawnWindows);
1443 wtoken.allDrawn = true;
1444 // Force an additional layout pass where WindowStateAnimator#
1445 // commitFinishDrawingLocked() will call performShowLocked().
1446 displayContent.layoutNeeded = true;
1447 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
1448 wtoken.token).sendToTarget();
1449 }
1450 }
1451 }
1452 }
1453 }
1454 }
1455
1456 private static int toBrightnessOverride(float value) {
1457 return (int)(value * PowerManager.BRIGHTNESS_ON);
1458 }
1459
1460 private void processApplicationsAnimatingInPlace(int transit) {
1461 if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
1462 // Find the focused window
1463 final WindowState win = mService.findFocusedWindowLocked(
1464 mService.getDefaultDisplayContentLocked());
1465 if (win != null) {
1466 final AppWindowToken wtoken = win.mAppToken;
1467 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1468 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001469 Slog.v(TAG_WM, "Now animating app in place " + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001470 appAnimator.clearThumbnail();
1471 appAnimator.animation = null;
1472 mService.updateTokenInPlaceLocked(wtoken, transit);
1473 wtoken.updateReportedVisibilityLocked();
1474
1475 appAnimator.mAllAppWinAnimators.clear();
1476 final int N = wtoken.allAppWindows.size();
1477 for (int j = 0; j < N; j++) {
1478 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1479 }
1480 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001481 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001482 }
1483 }
1484 }
1485
1486 private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
1487 int openingLayer, int closingLayer) {
1488 AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
1489 if (openingAppAnimator == null || openingAppAnimator.animation == null) {
1490 return;
1491 }
1492 final int taskId = appToken.mTask.mTaskId;
1493 Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
1494 if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001495 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "No thumbnail header bitmap for: " + taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001496 return;
1497 }
1498 // This thumbnail animation is very special, we need to have
1499 // an extra surface with the thumbnail included with the animation.
1500 Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
1501 try {
1502 // TODO(multi-display): support other displays
1503 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1504 final Display display = displayContent.getDisplay();
1505 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1506
1507 // Create a new surface for the thumbnail
1508 SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
1509 "thumbnail anim", dirty.width(), dirty.height(),
1510 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
1511 surfaceControl.setLayerStack(display.getLayerStack());
1512 if (SHOW_TRANSACTIONS) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001513 Slog.i(TAG_WM, " THUMBNAIL " + surfaceControl + ": CREATE");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001514 }
1515
1516 // Draw the thumbnail onto the surface
1517 Surface drawSurface = new Surface();
1518 drawSurface.copyFrom(surfaceControl);
1519 Canvas c = drawSurface.lockCanvas(dirty);
1520 c.drawBitmap(thumbnailHeader, 0, 0, null);
1521 drawSurface.unlockCanvasAndPost(c);
1522 drawSurface.release();
1523
1524 // Get the thumbnail animation
1525 Animation anim;
1526 if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
1527 // If this is a multi-window scenario, we use the windows frame as
1528 // destination of the thumbnail header animation. If this is a full screen
1529 // window scenario, we use the whole display as the target.
1530 WindowState win = appToken.findMainWindow();
1531 Rect appRect = win != null ? win.getContentFrameLw() :
1532 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
1533 // For the new aspect-scaled transition, we want it to always show
1534 // above the animating opening/closing window, and we want to
1535 // synchronize its thumbnail surface with the surface for the
1536 // open/close animation (only on the way down)
1537 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
1538 thumbnailHeader, taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001539 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
1540 openingAppAnimator.deferThumbnailDestruction =
1541 !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
1542 } else {
1543 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
1544 displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
1545 }
1546 anim.restrictDuration(MAX_ANIMATION_DURATION);
1547 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1548
1549 openingAppAnimator.thumbnail = surfaceControl;
1550 openingAppAnimator.thumbnailLayer = openingLayer;
1551 openingAppAnimator.thumbnailAnimation = anim;
1552 mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
1553 openingAppAnimator.thumbnailX = mTmpStartRect.left;
1554 openingAppAnimator.thumbnailY = mTmpStartRect.top;
1555 } catch (Surface.OutOfResourcesException e) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -08001556 Slog.e(TAG_WM, "Can't allocate thumbnail/Canvas surface w="
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001557 + dirty.width() + " h=" + dirty.height(), e);
1558 openingAppAnimator.clearThumbnail();
1559 }
1560 }
1561
1562 boolean copyAnimToLayoutParamsLocked() {
1563 boolean doRequest = false;
1564
1565 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1566 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1567 mUpdateRotation = true;
1568 doRequest = true;
1569 }
1570 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1571 mWallpaperMayChange = true;
1572 doRequest = true;
1573 }
1574 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1575 mWallpaperForceHidingChanged = true;
1576 doRequest = true;
1577 }
1578 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1579 mOrientationChangeComplete = false;
1580 } else {
1581 mOrientationChangeComplete = true;
1582 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1583 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1584 doRequest = true;
1585 }
1586 }
1587 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1588 mService.mTurnOnScreen = true;
1589 }
1590 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1591 mWallpaperActionPending = true;
1592 }
1593
1594 return doRequest;
1595 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001596
1597 void requestTraversal() {
1598 if (!mTraversalScheduled) {
1599 mTraversalScheduled = true;
1600 mService.mH.sendEmptyMessage(DO_TRAVERSAL);
1601 }
1602 }
1603
1604 public void dump(PrintWriter pw, String prefix) {
1605 pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
1606 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001607}