2 * Copyright (C) 2016 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
17 package com.android.server.wm;
19 import android.annotation.CallSuper;
20 import android.content.res.Configuration;
21 import android.graphics.Rect;
22 import android.hardware.power.V1_0.PowerHint;
23 import android.os.Binder;
24 import android.os.Debug;
25 import android.os.Handler;
26 import android.os.IBinder;
27 import android.os.Looper;
28 import android.os.Message;
29 import android.os.ParcelFileDescriptor;
30 import android.os.PowerManager;
31 import android.os.RemoteException;
32 import android.os.UserHandle;
33 import android.util.ArraySet;
34 import android.util.EventLog;
35 import android.util.Slog;
36 import android.util.SparseIntArray;
37 import android.util.proto.ProtoOutputStream;
38 import android.view.Display;
39 import android.view.DisplayInfo;
40 import android.view.WindowManager;
42 import com.android.internal.util.ArrayUtils;
43 import com.android.server.EventLogTags;
45 import java.io.FileDescriptor;
46 import java.io.PrintWriter;
47 import java.util.ArrayList;
48 import java.util.List;
49 import java.util.function.Consumer;
51 import static android.view.Display.DEFAULT_DISPLAY;
52 import static android.view.Display.INVALID_DISPLAY;
53 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
54 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
55 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
56 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
57 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
59 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
60 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
61 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
62 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
63 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
64 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
65 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
66 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
67 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
68 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
69 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
70 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
71 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
72 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
73 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
74 import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
75 import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
76 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
77 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
78 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
79 import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
80 import static com.android.server.wm.WindowManagerService.logSurface;
81 import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
82 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
83 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
84 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
85 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
86 import static com.android.server.wm.proto.RootWindowContainerProto.DISPLAYS;
87 import static com.android.server.wm.proto.RootWindowContainerProto.WINDOWS;
88 import static com.android.server.wm.proto.RootWindowContainerProto.WINDOW_CONTAINER;
90 /** Root {@link WindowContainer} for the device. */
91 class RootWindowContainer extends WindowContainer<DisplayContent> {
92 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
94 private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
95 private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
97 private boolean mWallpaperForceHidingChanged = false;
98 private Object mLastWindowFreezeSource = null;
99 private Session mHoldScreen = null;
100 private float mScreenBrightness = -1;
101 private long mUserActivityTimeout = -1;
102 private boolean mUpdateRotation = false;
103 // Following variables are for debugging screen wakelock only.
104 // Last window that requires screen wakelock
105 WindowState mHoldScreenWindow = null;
106 // Last window that obscures all windows below
107 WindowState mObscuringWindow = null;
108 // Only set while traversing the default display based on its content.
109 // Affects the behavior of mirroring on secondary displays.
110 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
112 private boolean mSustainedPerformanceModeEnabled = false;
113 private boolean mSustainedPerformanceModeCurrent = false;
115 boolean mWallpaperMayChange = false;
116 // During an orientation change, we track whether all windows have rendered
117 // at the new orientation, and this will be false from changing orientation until that occurs.
118 // For seamless rotation cases this always stays true, as the windows complete their orientation
119 // changes 1 by 1 without disturbing global state.
120 boolean mOrientationChangeComplete = true;
121 boolean mWallpaperActionPending = false;
123 private final ArrayList<TaskStack> mTmpStackList = new ArrayList();
124 private final ArrayList<Integer> mTmpStackIds = new ArrayList<>();
126 final WallpaperController mWallpaperController;
128 private final Handler mHandler;
130 private String mCloseSystemDialogsReason;
131 private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
134 w.mClient.closeSystemDialogs(mCloseSystemDialogsReason);
135 } catch (RemoteException e) {
140 private static final Consumer<WindowState> sRemoveReplacedWindowsConsumer = w -> {
141 final AppWindowToken aToken = w.mAppToken;
142 if (aToken != null) {
143 aToken.removeReplacedWindowIfNeeded(w);
147 RootWindowContainer(WindowManagerService service) {
149 mHandler = new MyHandler(service.mH.getLooper());
150 mWallpaperController = new WallpaperController(mService);
153 WindowState computeFocusedWindow() {
154 for (int i = mChildren.size() - 1; i >= 0; i--) {
155 final DisplayContent dc = mChildren.get(i);
156 final WindowState win = dc.findFocusedWindow();
165 * Get an array with display ids ordered by focus priority - last items should be given
166 * focus first. Sparse array just maps position to displayId.
168 void getDisplaysInFocusOrder(SparseIntArray displaysInFocusOrder) {
169 displaysInFocusOrder.clear();
171 final int size = mChildren.size();
172 for (int i = 0; i < size; ++i) {
173 final DisplayContent displayContent = mChildren.get(i);
174 if (displayContent.isRemovalDeferred()) {
175 // Don't report displays that are going to be removed soon.
178 displaysInFocusOrder.put(i, displayContent.getDisplayId());
182 DisplayContent getDisplayContent(int displayId) {
183 for (int i = mChildren.size() - 1; i >= 0; --i) {
184 final DisplayContent current = mChildren.get(i);
185 if (current.getDisplayId() == displayId) {
192 DisplayContent createDisplayContent(final Display display, DisplayWindowController controller) {
193 final int displayId = display.getDisplayId();
195 // In select scenarios, it is possible that a DisplayContent will be created on demand
196 // rather than waiting for the controller. In this case, associate the controller and return
197 // the existing display.
198 final DisplayContent existing = getDisplayContent(displayId);
200 if (existing != null) {
201 existing.setController(controller);
205 final DisplayContent dc =
206 new DisplayContent(display, mService, mWallpaperController, controller);
208 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
210 final DisplayInfo displayInfo = dc.getDisplayInfo();
211 final Rect rect = new Rect();
212 mService.mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);
213 displayInfo.overscanLeft = rect.left;
214 displayInfo.overscanTop = rect.top;
215 displayInfo.overscanRight = rect.right;
216 displayInfo.overscanBottom = rect.bottom;
217 if (mService.mDisplayManagerInternal != null) {
218 mService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
219 displayId, displayInfo);
220 dc.configureDisplayPolicy();
222 // Tap Listeners are supported for:
223 // 1. All physical displays (multi-display).
224 // 2. VirtualDisplays on VR, AA (and everything else).
225 if (mService.canDispatchPointerEvents()) {
228 "Registering PointerEventListener for DisplayId: " + displayId);
230 dc.mTapDetector = new TaskTapPointerEventListener(mService, dc);
231 mService.registerPointerEventListener(dc.mTapDetector);
232 if (displayId == DEFAULT_DISPLAY) {
233 mService.registerPointerEventListener(mService.mMousePositionTracker);
241 boolean isLayoutNeeded() {
242 final int numDisplays = mChildren.size();
243 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
244 final DisplayContent displayContent = mChildren.get(displayNdx);
245 if (displayContent.isLayoutNeeded()) {
252 void getWindowsByName(ArrayList<WindowState> output, String name) {
254 // See if this is an object ID.
256 objectId = Integer.parseInt(name, 16);
258 } catch (RuntimeException e) {
261 getWindowsByName(output, name, objectId);
264 private void getWindowsByName(ArrayList<WindowState> output, String name, int objectId) {
265 forAllWindows((w) -> {
267 if (w.mAttrs.getTitle().toString().contains(name)) {
270 } else if (System.identityHashCode(w) == objectId) {
273 }, true /* traverseTopToBottom */);
277 * Returns the app window token for the input binder if it exist in the system.
278 * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since
279 * AppWindowToken represents an activity which can only exist on one display.
281 AppWindowToken getAppWindowToken(IBinder binder) {
282 for (int i = mChildren.size() - 1; i >= 0; --i) {
283 final DisplayContent dc = mChildren.get(i);
284 final AppWindowToken atoken = dc.getAppWindowToken(binder);
285 if (atoken != null) {
292 /** Returns the display object the input window token is currently mapped on. */
293 DisplayContent getWindowTokenDisplay(WindowToken token) {
298 for (int i = mChildren.size() - 1; i >= 0; --i) {
299 final DisplayContent dc = mChildren.get(i);
300 final WindowToken current = dc.getWindowToken(token.token);
301 if (current == token) {
310 * Set new display override config and return array of ids of stacks that were changed during
311 * update. If called for the default display, global configuration will also be updated. Stacks
312 * that are marked for deferred removal are excluded from the returned array.
314 int[] setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, int displayId) {
315 final DisplayContent displayContent = getDisplayContent(displayId);
316 if (displayContent == null) {
317 throw new IllegalArgumentException("Display not found for id: " + displayId);
320 final Configuration currentConfig = displayContent.getOverrideConfiguration();
321 final boolean configChanged = currentConfig.diff(newConfiguration) != 0;
322 if (!configChanged) {
326 displayContent.onOverrideConfigurationChanged(newConfiguration);
328 mTmpStackList.clear();
329 if (displayId == DEFAULT_DISPLAY) {
330 // Override configuration of the default display duplicates global config. In this case
331 // we also want to update the global config.
332 setGlobalConfigurationIfNeeded(newConfiguration, mTmpStackList);
334 updateStackBoundsAfterConfigChange(displayId, mTmpStackList);
337 mTmpStackIds.clear();
338 final int stackCount = mTmpStackList.size();
340 for (int i = 0; i < stackCount; ++i) {
341 final TaskStack stack = mTmpStackList.get(i);
343 // We only include stacks that are not marked for removal as they do not exist outside
344 // of WindowManager at this point.
345 if (!stack.mDeferRemoval) {
346 mTmpStackIds.add(stack.mStackId);
350 return mTmpStackIds.isEmpty() ? null : ArrayUtils.convertToIntArray(mTmpStackIds);
353 private void setGlobalConfigurationIfNeeded(Configuration newConfiguration,
354 List<TaskStack> changedStacks) {
355 final boolean configChanged = getConfiguration().diff(newConfiguration) != 0;
356 if (!configChanged) {
359 onConfigurationChanged(newConfiguration);
360 updateStackBoundsAfterConfigChange(changedStacks);
364 public void onConfigurationChanged(Configuration newParentConfig) {
365 prepareFreezingTaskBounds();
366 super.onConfigurationChanged(newParentConfig);
368 mService.mPolicy.onConfigurationChanged();
372 * Callback used to trigger bounds update after configuration change and get ids of stacks whose
373 * bounds were updated.
375 private void updateStackBoundsAfterConfigChange(List<TaskStack> changedStacks) {
376 final int numDisplays = mChildren.size();
377 for (int i = 0; i < numDisplays; ++i) {
378 final DisplayContent dc = mChildren.get(i);
379 dc.updateStackBoundsAfterConfigChange(changedStacks);
383 /** Same as {@link #updateStackBoundsAfterConfigChange()} but only for a specific display. */
384 private void updateStackBoundsAfterConfigChange(int displayId, List<TaskStack> changedStacks) {
385 final DisplayContent dc = getDisplayContent(displayId);
386 dc.updateStackBoundsAfterConfigChange(changedStacks);
389 private void prepareFreezingTaskBounds() {
390 for (int i = mChildren.size() - 1; i >= 0; i--) {
391 mChildren.get(i).prepareFreezingTaskBounds();
395 TaskStack getStack(int windowingMode, int activityType) {
396 for (int i = mChildren.size() - 1; i >= 0; i--) {
397 final DisplayContent dc = mChildren.get(i);
398 final TaskStack stack = dc.getStack(windowingMode, activityType);
406 void setSecureSurfaceState(int userId, boolean disabled) {
407 forAllWindows((w) -> {
408 if (w.mHasSurface && userId == UserHandle.getUserId(w.mOwnerUid)) {
409 w.mWinAnimator.setSecureLocked(disabled);
411 }, true /* traverseTopToBottom */);
414 void updateAppOpsState() {
415 forAllWindows((w) -> {
416 w.updateAppOpsState();
417 }, false /* traverseTopToBottom */);
420 boolean canShowStrictModeViolation(int pid) {
421 final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisibleLw());
425 void closeSystemDialogs(String reason) {
426 mCloseSystemDialogsReason = reason;
427 forAllWindows(mCloseSystemDialogsConsumer, false /* traverseTopToBottom */);
430 void removeReplacedWindows() {
431 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
432 mService.openSurfaceTransaction();
434 forAllWindows(sRemoveReplacedWindowsConsumer, true /* traverseTopToBottom */);
436 mService.closeSurfaceTransaction("removeReplacedWindows");
437 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
441 boolean hasPendingLayoutChanges(WindowAnimator animator) {
442 boolean hasChanges = false;
444 final int count = mChildren.size();
445 for (int i = 0; i < count; ++i) {
446 final DisplayContent dc = mChildren.get(i);
447 final int pendingChanges = animator.getPendingLayoutChanges(dc.getDisplayId());
448 if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
449 animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
451 if (pendingChanges != 0) {
459 boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
461 final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
462 boolean leakedSurface = false;
463 boolean killedApps = false;
465 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
466 winAnimator.mSession.mPid, operation);
468 final long callingIdentity = Binder.clearCallingIdentity();
470 // There was some problem...first, do a sanity check of the window list to make sure
471 // we haven't left any dangling surfaces around.
473 Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
474 final int numDisplays = mChildren.size();
475 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
476 leakedSurface |= mChildren.get(displayNdx).destroyLeakedSurfaces();
479 if (!leakedSurface) {
480 Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
481 final SparseIntArray pidCandidates = new SparseIntArray();
482 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
483 mChildren.get(displayNdx).forAllWindows((w) -> {
484 if (mService.mForceRemoves.contains(w)) {
487 final WindowStateAnimator wsa = w.mWinAnimator;
488 if (wsa.mSurfaceController != null) {
489 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
491 }, false /* traverseTopToBottom */);
493 if (pidCandidates.size() > 0) {
494 int[] pids = new int[pidCandidates.size()];
495 for (int i = 0; i < pids.length; i++) {
496 pids[i] = pidCandidates.keyAt(i);
499 if (mService.mActivityManager.killPids(pids, "Free memory", secure)) {
502 } catch (RemoteException e) {
508 if (leakedSurface || killedApps) {
509 // We managed to reclaim some memory, so get rid of the trouble surface and ask the
510 // app to request another one.
512 "Looks like we have reclaimed some memory, clearing surface for retry.");
513 if (surfaceController != null) {
514 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
515 "RECOVER DESTROY", false);
516 winAnimator.destroySurface();
517 if (winAnimator.mWin.mAppToken != null
518 && winAnimator.mWin.mAppToken.getController() != null) {
519 winAnimator.mWin.mAppToken.getController().removeStartingWindow();
524 winAnimator.mWin.mClient.dispatchGetNewSurface();
525 } catch (RemoteException e) {
529 Binder.restoreCallingIdentity(callingIdentity);
532 return leakedSurface || killedApps;
535 // "Something has changed! Let's make it correct now."
536 // TODO: Super crazy long method that should be broken down...
537 void performSurfacePlacement(boolean recoveringMemory) {
538 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
539 + Debug.getCallers(3));
542 boolean updateInputWindowsNeeded = false;
544 if (mService.mFocusMayChange) {
545 mService.mFocusMayChange = false;
546 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
547 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
550 // Initialize state of exiting tokens.
551 final int numDisplays = mChildren.size();
552 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
553 final DisplayContent displayContent = mChildren.get(displayNdx);
554 displayContent.setExitingTokensHasVisible(false);
558 mScreenBrightness = -1;
559 mUserActivityTimeout = -1;
560 mObscureApplicationContentOnSecondaryDisplays = false;
561 mSustainedPerformanceModeCurrent = false;
562 mService.mTransactionSequence++;
564 // TODO(multi-display):
565 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
566 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
567 final int defaultDw = defaultInfo.logicalWidth;
568 final int defaultDh = defaultInfo.logicalHeight;
570 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
571 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
572 mService.openSurfaceTransaction();
574 applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
575 } catch (RuntimeException e) {
576 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
578 mService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
579 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
580 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
583 mService.mAnimator.executeAfterPrepareSurfacesRunnables();
585 final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
587 // If we are ready to perform an app transition, check through all of the app tokens to be
588 // shown and see if they are ready to go.
589 if (mService.mAppTransition.isReady()) {
590 // This needs to be split into two expressions, as handleAppTransitionReadyLocked may
591 // modify dc.pendingLayoutChanges, which would get lost when writing
592 // defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked()
593 final int layoutChanges = surfacePlacer.handleAppTransitionReadyLocked();
594 defaultDisplay.pendingLayoutChanges |= layoutChanges;
595 if (DEBUG_LAYOUT_REPEATS)
596 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
597 defaultDisplay.pendingLayoutChanges);
600 if (!isAppAnimating() && mService.mAppTransition.isRunning()) {
601 // We have finished the animation of an app transition. To do this, we have delayed a
602 // lot of operations like showing and hiding apps, moving apps in Z-order, etc. The app
603 // token list reflects the correct Z-order, but the window list may now be out of sync
604 // with it. So here we will just rebuild the entire app window list. Fun!
605 defaultDisplay.pendingLayoutChanges |=
606 mService.handleAnimatingStoppedAndTransitionLocked();
607 if (DEBUG_LAYOUT_REPEATS)
608 surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
609 defaultDisplay.pendingLayoutChanges);
612 // Defer starting the recents animation until the wallpaper has drawn
613 final RecentsAnimationController recentsAnimationController =
614 mService.getRecentsAnimationController();
615 if (recentsAnimationController != null) {
616 recentsAnimationController.checkAnimationReady(mWallpaperController);
619 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
620 && !mService.mAppTransition.isReady()) {
621 // At this point, there was a window with a wallpaper that was force hiding other
622 // windows behind it, but now it is going away. This may be simple -- just animate away
623 // the wallpaper and its window -- or it may be hard -- the wallpaper now needs to be
624 // shown behind something that was hidden.
625 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
626 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
627 "after animateAwayWallpaperLocked", defaultDisplay.pendingLayoutChanges);
629 mWallpaperForceHidingChanged = false;
631 if (mWallpaperMayChange) {
632 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
633 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
634 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("WallpaperMayChange",
635 defaultDisplay.pendingLayoutChanges);
638 if (mService.mFocusMayChange) {
639 mService.mFocusMayChange = false;
640 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
641 false /*updateInputWindows*/)) {
642 updateInputWindowsNeeded = true;
643 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
647 if (isLayoutNeeded()) {
648 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
649 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
650 defaultDisplay.pendingLayoutChanges);
653 final ArraySet<DisplayContent> touchExcludeRegionUpdateDisplays = handleResizingWindows();
655 if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
656 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
657 if (mOrientationChangeComplete) {
658 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
659 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
660 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
661 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
663 mService.stopFreezingDisplayLocked();
666 // Destroy the surface of any windows that are no longer visible.
667 boolean wallpaperDestroyed = false;
668 i = mService.mDestroySurface.size();
672 WindowState win = mService.mDestroySurface.get(i);
673 win.mDestroying = false;
674 if (mService.mInputMethodWindow == win) {
675 mService.setInputMethodWindowLocked(null);
677 if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) {
678 wallpaperDestroyed = true;
680 win.destroySurfaceUnchecked();
682 mService.mDestroySurface.clear();
685 // Time to remove any exiting tokens?
686 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
687 final DisplayContent displayContent = mChildren.get(displayNdx);
688 displayContent.removeExistingTokensIfPossible();
691 if (wallpaperDestroyed) {
692 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
693 defaultDisplay.setLayoutNeeded();
696 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
697 final DisplayContent displayContent = mChildren.get(displayNdx);
698 if (displayContent.pendingLayoutChanges != 0) {
699 displayContent.setLayoutNeeded();
703 // Finally update all input windows now that the window changes have stabilized.
704 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
706 mService.setHoldScreenLocked(mHoldScreen);
707 if (!mService.mDisplayFrozen) {
708 final int brightness = mScreenBrightness < 0 || mScreenBrightness > 1.0f
709 ? -1 : toBrightnessOverride(mScreenBrightness);
711 // Post these on a handler such that we don't call into power manager service while
712 // holding the window manager lock to avoid lock contention with power manager lock.
713 mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, brightness, 0).sendToTarget();
714 mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget();
717 if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
718 mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
719 mService.mPowerManagerInternal.powerHint(
720 PowerHint.SUSTAINED_PERFORMANCE,
721 (mSustainedPerformanceModeEnabled ? 1 : 0));
724 if (mUpdateRotation) {
725 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
726 // TODO(multi-display): Update rotation for different displays separately.
727 final int displayId = defaultDisplay.getDisplayId();
728 if (defaultDisplay.updateRotationUnchecked(false /* inTransaction */)) {
729 mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget();
731 mUpdateRotation = false;
733 // Update rotation of VR virtual display separately. Currently this is the only kind of
734 // secondary display that can be rotated because of the single-display limitations in
735 // PhoneWindowManager.
736 final DisplayContent vrDisplay = mService.mVr2dDisplayId != INVALID_DISPLAY
737 ? getDisplayContent(mService.mVr2dDisplayId) : null;
738 if (vrDisplay != null && vrDisplay.updateRotationUnchecked(false /* inTransaction */)) {
739 mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mService.mVr2dDisplayId)
744 if (mService.mWaitingForDrawnCallback != null ||
745 (mOrientationChangeComplete && !defaultDisplay.isLayoutNeeded()
746 && !mUpdateRotation)) {
747 mService.checkDrawnWindowsLocked();
750 final int N = mService.mPendingRemove.size();
752 if (mService.mPendingRemoveTmp.length < N) {
753 mService.mPendingRemoveTmp = new WindowState[N+10];
755 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
756 mService.mPendingRemove.clear();
757 ArrayList<DisplayContent> displayList = new ArrayList();
758 for (i = 0; i < N; i++) {
759 final WindowState w = mService.mPendingRemoveTmp[i];
760 w.removeImmediately();
761 final DisplayContent displayContent = w.getDisplayContent();
762 if (displayContent != null && !displayList.contains(displayContent)) {
763 displayList.add(displayContent);
767 for (int j = displayList.size() - 1; j >= 0; --j) {
768 final DisplayContent dc = displayList.get(j);
769 dc.assignWindowLayers(true /*setLayoutNeeded*/);
773 // Remove all deferred displays stacks, tasks, and activities.
774 for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
775 mChildren.get(displayNdx).checkCompleteDeferredRemoval();
778 if (updateInputWindowsNeeded) {
779 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
781 mService.setFocusTaskRegionLocked(null);
782 if (touchExcludeRegionUpdateDisplays != null) {
783 final DisplayContent focusedDc = mService.mFocusedApp != null
784 ? mService.mFocusedApp.getDisplayContent() : null;
785 for (DisplayContent dc : touchExcludeRegionUpdateDisplays) {
786 // The focused DisplayContent was recalcuated in setFocusTaskRegionLocked
787 if (focusedDc != dc) {
788 dc.setTouchExcludeRegion(null /* focusedTask */);
793 // Check to see if we are now in a state where the screen should
794 // be enabled, because the window obscured flags have changed.
795 mService.enableScreenIfNeededLocked();
797 mService.scheduleAnimationLocked();
798 mService.mWindowPlacerLocked.destroyPendingSurfaces();
800 if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
801 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
804 private void applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw,
806 mHoldScreenWindow = null;
807 mObscuringWindow = null;
809 // TODO(multi-display): Support these features on secondary screens.
810 if (mService.mWatermark != null) {
811 mService.mWatermark.positionSurface(defaultDw, defaultDh);
813 if (mService.mStrictModeFlash != null) {
814 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
816 if (mService.mCircularDisplayMask != null) {
817 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
818 mService.getDefaultDisplayRotation());
820 if (mService.mEmulatorDisplayOverlay != null) {
821 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
822 mService.getDefaultDisplayRotation());
825 boolean focusDisplayed = false;
827 final int count = mChildren.size();
828 for (int j = 0; j < count; ++j) {
829 final DisplayContent dc = mChildren.get(j);
830 focusDisplayed |= dc.applySurfaceChangesTransaction(recoveringMemory);
833 if (focusDisplayed) {
834 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
837 // Give the display manager a chance to adjust properties like display rotation if it needs
839 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
843 * Handles resizing windows during surface placement.
845 * @return A set of any DisplayContent whose touch exclude region needs to be recalculated due
846 * to a tap-exclude window resizing, or null if no such DisplayContents were found.
848 private ArraySet<DisplayContent> handleResizingWindows() {
849 ArraySet<DisplayContent> touchExcludeRegionUpdateSet = null;
850 for (int i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
851 WindowState win = mService.mResizingWindows.get(i);
852 if (win.mAppFreezing) {
853 // Don't remove this window until rotation has completed.
857 mService.mResizingWindows.remove(i);
858 if (WindowManagerService.excludeWindowTypeFromTapOutTask(win.mAttrs.type)) {
859 final DisplayContent dc = win.getDisplayContent();
860 if (touchExcludeRegionUpdateSet == null) {
861 touchExcludeRegionUpdateSet = new ArraySet<>();
863 touchExcludeRegionUpdateSet.add(dc);
866 return touchExcludeRegionUpdateSet;
870 * @param w WindowState this method is applied to.
871 * @param obscured True if there is a window on top of this obscuring the display.
872 * @param syswin System window?
873 * @return True when the display contains content to show the user. When false, the display
874 * manager may choose to mirror or blank the display.
876 boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) {
877 final WindowManager.LayoutParams attrs = w.mAttrs;
878 final int attrFlags = attrs.flags;
879 final boolean onScreen = w.isOnScreen();
880 final boolean canBeSeen = w.isDisplayedLw();
881 final int privateflags = attrs.privateFlags;
882 boolean displayHasContent = false;
884 if (DEBUG_KEEP_SCREEN_ON) {
885 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked w: " + w
886 + ", w.mHasSurface: " + w.mHasSurface
887 + ", w.isOnScreen(): " + onScreen
888 + ", w.isDisplayedLw(): " + w.isDisplayedLw()
889 + ", w.mAttrs.userActivityTimeout: " + w.mAttrs.userActivityTimeout);
891 if (w.mHasSurface && onScreen) {
892 if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
893 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
894 if (DEBUG_KEEP_SCREEN_ON) {
895 Slog.d(TAG, "mUserActivityTimeout set to " + mUserActivityTimeout);
899 if (w.mHasSurface && canBeSeen) {
900 if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
901 mHoldScreen = w.mSession;
902 mHoldScreenWindow = w;
903 } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
904 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
905 + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
906 + Debug.getCallers(10));
908 if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
909 mScreenBrightness = w.mAttrs.screenBrightness;
912 final int type = attrs.type;
913 // This function assumes that the contents of the default display are processed first
914 // before secondary displays.
915 final DisplayContent displayContent = w.getDisplayContent();
916 if (displayContent != null && displayContent.isDefaultDisplay) {
917 // While a dream or keyguard is showing, obscure ordinary application content on
918 // secondary displays (by forcibly enabling mirroring unless there is other content
919 // we want to show) but still allow opaque keyguard dialogs to be shown.
920 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
921 mObscureApplicationContentOnSecondaryDisplays = true;
923 displayHasContent = true;
924 } else if (displayContent != null &&
925 (!mObscureApplicationContentOnSecondaryDisplays
926 || (obscured && type == TYPE_KEYGUARD_DIALOG))) {
927 // Allow full screen keyguard presentation dialogs to be seen.
928 displayHasContent = true;
930 if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
931 mSustainedPerformanceModeCurrent = true;
935 return displayHasContent;
938 boolean copyAnimToLayoutParams() {
939 boolean doRequest = false;
941 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
942 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
943 mUpdateRotation = true;
946 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
947 mWallpaperMayChange = true;
950 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
951 mWallpaperForceHidingChanged = true;
954 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
955 mOrientationChangeComplete = false;
957 mOrientationChangeComplete = true;
958 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
959 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
964 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
965 mWallpaperActionPending = true;
971 private static int toBrightnessOverride(float value) {
972 return (int)(value * PowerManager.BRIGHTNESS_ON);
975 private final class MyHandler extends Handler {
977 public MyHandler(Looper looper) {
982 public void handleMessage(Message msg) {
984 case SET_SCREEN_BRIGHTNESS_OVERRIDE:
985 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
988 case SET_USER_ACTIVITY_TIMEOUT:
989 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
998 void dumpDisplayContents(PrintWriter pw) {
999 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
1000 if (mService.mDisplayReady) {
1001 final int count = mChildren.size();
1002 for (int i = 0; i < count; ++i) {
1003 final DisplayContent displayContent = mChildren.get(i);
1004 displayContent.dump(pw, " ", true /* dumpAll */);
1007 pw.println(" NO DISPLAY");
1011 void dumpLayoutNeededDisplayIds(PrintWriter pw) {
1012 if (!isLayoutNeeded()) {
1015 pw.print(" mLayoutNeeded on displays=");
1016 final int count = mChildren.size();
1017 for (int displayNdx = 0; displayNdx < count; ++displayNdx) {
1018 final DisplayContent displayContent = mChildren.get(displayNdx);
1019 if (displayContent.isLayoutNeeded()) {
1020 pw.print(displayContent.getDisplayId());
1026 void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
1027 final int[] index = new int[1];
1028 forAllWindows((w) -> {
1029 if (windows == null || windows.contains(w)) {
1030 pw.println(" Window #" + index[0] + " " + w + ":");
1031 w.dump(pw, " ", dumpAll || windows != null);
1032 index[0] = index[0] + 1;
1034 }, true /* traverseTopToBottom */);
1037 void dumpTokens(PrintWriter pw, boolean dumpAll) {
1038 pw.println(" All tokens:");
1039 for (int i = mChildren.size() - 1; i >= 0; --i) {
1040 mChildren.get(i).dumpTokens(pw, dumpAll);
1046 public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
1047 final long token = proto.start(fieldId);
1048 super.writeToProto(proto, WINDOW_CONTAINER, trim);
1049 if (mService.mDisplayReady) {
1050 final int count = mChildren.size();
1051 for (int i = 0; i < count; ++i) {
1052 final DisplayContent displayContent = mChildren.get(i);
1053 displayContent.writeToProto(proto, DISPLAYS, trim);
1057 forAllWindows((w) -> {
1058 w.writeIdentifierToProto(proto, WINDOWS);
1070 void scheduleAnimation() {
1071 mService.scheduleAnimationLocked();