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.content.res.Configuration;
20 import android.graphics.Rect;
21 import android.hardware.power.V1_0.PowerHint;
22 import android.os.Binder;
23 import android.os.Debug;
24 import android.os.Handler;
25 import android.os.IBinder;
26 import android.os.Looper;
27 import android.os.Message;
28 import android.os.ParcelFileDescriptor;
29 import android.os.PowerManager;
30 import android.os.RemoteException;
31 import android.os.SystemClock;
32 import android.os.UserHandle;
33 import android.provider.Settings;
34 import android.util.EventLog;
35 import android.util.Slog;
36 import android.util.SparseIntArray;
37 import android.view.Display;
38 import android.view.DisplayInfo;
39 import android.view.WindowManager;
41 import com.android.internal.os.SomeArgs;
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.function.Consumer;
50 import static android.app.AppOpsManager.MODE_ALLOWED;
51 import static android.app.AppOpsManager.MODE_DEFAULT;
52 import static android.app.AppOpsManager.OP_NONE;
53 import static android.view.Display.DEFAULT_DISPLAY;
54 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
55 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
56 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
57 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
58 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
59 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
60 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
61 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
63 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
64 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
65 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
66 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
67 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
68 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
69 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
70 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
71 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
72 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
73 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
74 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
75 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
76 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
77 import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
78 import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
79 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
80 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
81 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
82 import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
83 import static com.android.server.wm.WindowManagerService.logSurface;
84 import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
85 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
86 import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN;
87 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
88 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
89 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
91 /** Root {@link WindowContainer} for the device. */
92 class RootWindowContainer extends WindowContainer<DisplayContent> {
93 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
95 private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
96 private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
98 WindowManagerService mService;
100 private boolean mWallpaperForceHidingChanged = false;
101 private Object mLastWindowFreezeSource = null;
102 private Session mHoldScreen = null;
103 private float mScreenBrightness = -1;
104 private long mUserActivityTimeout = -1;
105 private boolean mUpdateRotation = false;
106 // Following variables are for debugging screen wakelock only.
107 // Last window that requires screen wakelock
108 WindowState mHoldScreenWindow = null;
109 // Last window that obscures all windows below
110 WindowState mObscuringWindow = null;
111 // Only set while traversing the default display based on its content.
112 // Affects the behavior of mirroring on secondary displays.
113 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
115 private boolean mSustainedPerformanceModeEnabled = false;
116 private boolean mSustainedPerformanceModeCurrent = false;
118 boolean mWallpaperMayChange = false;
119 // During an orientation change, we track whether all windows have rendered
120 // at the new orientation, and this will be false from changing orientation until that occurs.
121 // For seamless rotation cases this always stays true, as the windows complete their orientation
122 // changes 1 by 1 without disturbing global state.
123 boolean mOrientationChangeComplete = true;
124 boolean mWallpaperActionPending = false;
126 private final ArrayList<Integer> mChangedStackList = new ArrayList();
128 // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
129 // instances will be replaced with an instance that writes a binary representation of all
130 // commands to mSurfaceTraceFd.
131 boolean mSurfaceTraceEnabled;
132 ParcelFileDescriptor mSurfaceTraceFd;
133 RemoteEventTrace mRemoteEventTrace;
135 private final WindowLayersController mLayersController;
136 final WallpaperController mWallpaperController;
138 private final Handler mHandler;
140 private String mCloseSystemDialogsReason;
141 private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
144 w.mClient.closeSystemDialogs(mCloseSystemDialogsReason);
145 } catch (RemoteException e) {
150 private static final Consumer<WindowState> sRemoveReplacedWindowsConsumer = w -> {
151 final AppWindowToken aToken = w.mAppToken;
152 if (aToken != null) {
153 aToken.removeReplacedWindowIfNeeded(w);
157 RootWindowContainer(WindowManagerService service) {
159 mHandler = new MyHandler(service.mH.getLooper());
160 mLayersController = new WindowLayersController(mService);
161 mWallpaperController = new WallpaperController(mService);
164 WindowState computeFocusedWindow() {
165 for (int i = mChildren.size() - 1; i >= 0; i--) {
166 final DisplayContent dc = mChildren.get(i);
167 final WindowState win = dc.findFocusedWindow();
176 * Get an array with display ids ordered by focus priority - last items should be given
177 * focus first. Sparse array just maps position to displayId.
179 void getDisplaysInFocusOrder(SparseIntArray displaysInFocusOrder) {
180 displaysInFocusOrder.clear();
182 final int size = mChildren.size();
183 for (int i = 0; i < size; ++i) {
184 final DisplayContent displayContent = mChildren.get(i);
185 if (displayContent.isRemovalDeferred()) {
186 // Don't report displays that are going to be removed soon.
189 displaysInFocusOrder.put(i, displayContent.getDisplayId());
194 * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
195 * there is a Display for the displayId.
197 * @param displayId The display the caller is interested in.
198 * @return The DisplayContent associated with displayId or null if there is no Display for it.
200 DisplayContent getDisplayContentOrCreate(int displayId) {
201 DisplayContent dc = getDisplayContent(displayId);
204 final Display display = mService.mDisplayManager.getDisplay(displayId);
205 if (display != null) {
206 final long callingIdentity = Binder.clearCallingIdentity();
208 dc = createDisplayContent(display);
210 Binder.restoreCallingIdentity(callingIdentity);
217 DisplayContent getDisplayContent(int displayId) {
218 for (int i = mChildren.size() - 1; i >= 0; --i) {
219 final DisplayContent current = mChildren.get(i);
220 if (current.getDisplayId() == displayId) {
227 private DisplayContent createDisplayContent(final Display display) {
228 final DisplayContent dc = new DisplayContent(display, mService, mLayersController,
229 mWallpaperController);
230 final int displayId = display.getDisplayId();
232 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
234 final DisplayInfo displayInfo = dc.getDisplayInfo();
235 final Rect rect = new Rect();
236 mService.mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);
237 displayInfo.overscanLeft = rect.left;
238 displayInfo.overscanTop = rect.top;
239 displayInfo.overscanRight = rect.right;
240 displayInfo.overscanBottom = rect.bottom;
241 if (mService.mDisplayManagerInternal != null) {
242 mService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
243 displayId, displayInfo);
244 mService.configureDisplayPolicyLocked(dc);
246 // TODO(multi-display): Create an input channel for each display with touch capability.
247 if (displayId == DEFAULT_DISPLAY && mService.canDispatchPointerEvents()) {
248 dc.mTapDetector = new TaskTapPointerEventListener(
250 mService.registerPointerEventListener(dc.mTapDetector);
251 mService.registerPointerEventListener(mService.mMousePositionTracker);
258 boolean isLayoutNeeded() {
259 final int numDisplays = mChildren.size();
260 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
261 final DisplayContent displayContent = mChildren.get(displayNdx);
262 if (displayContent.isLayoutNeeded()) {
269 void getWindowsByName(ArrayList<WindowState> output, String name) {
271 // See if this is an object ID.
273 objectId = Integer.parseInt(name, 16);
275 } catch (RuntimeException e) {
278 getWindowsByName(output, name, objectId);
281 private void getWindowsByName(ArrayList<WindowState> output, String name, int objectId) {
282 forAllWindows((w) -> {
284 if (w.mAttrs.getTitle().toString().contains(name)) {
287 } else if (System.identityHashCode(w) == objectId) {
290 }, true /* traverseTopToBottom */);
294 * Returns the app window token for the input binder if it exist in the system.
295 * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since
296 * AppWindowToken represents an activity which can only exist on one display.
298 AppWindowToken getAppWindowToken(IBinder binder) {
299 for (int i = mChildren.size() - 1; i >= 0; --i) {
300 final DisplayContent dc = mChildren.get(i);
301 final AppWindowToken atoken = dc.getAppWindowToken(binder);
302 if (atoken != null) {
309 /** Returns the display object the input window token is currently mapped on. */
310 DisplayContent getWindowTokenDisplay(WindowToken token) {
315 for (int i = mChildren.size() - 1; i >= 0; --i) {
316 final DisplayContent dc = mChildren.get(i);
317 final WindowToken current = dc.getWindowToken(token.token);
318 if (current == token) {
327 * Set new display override config and return array of ids of stacks that were changed during
328 * update. If called for the default display, global configuration will also be updated.
330 int[] setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, int displayId) {
331 final DisplayContent displayContent = getDisplayContent(displayId);
332 if (displayContent == null) {
333 throw new IllegalArgumentException("Display not found for id: " + displayId);
336 final Configuration currentConfig = displayContent.getOverrideConfiguration();
337 final boolean configChanged = currentConfig.diff(newConfiguration) != 0;
338 if (!configChanged) {
341 displayContent.onOverrideConfigurationChanged(newConfiguration);
343 if (displayId == DEFAULT_DISPLAY) {
344 // Override configuration of the default display duplicates global config. In this case
345 // we also want to update the global config.
346 return setGlobalConfigurationIfNeeded(newConfiguration);
348 return updateStackBoundsAfterConfigChange(displayId);
352 private int[] setGlobalConfigurationIfNeeded(Configuration newConfiguration) {
353 final boolean configChanged = getConfiguration().diff(newConfiguration) != 0;
354 if (!configChanged) {
357 onConfigurationChanged(newConfiguration);
358 return updateStackBoundsAfterConfigChange();
362 void onConfigurationChanged(Configuration newParentConfig) {
363 prepareFreezingTaskBounds();
364 super.onConfigurationChanged(newParentConfig);
366 mService.mPolicy.onConfigurationChanged();
370 * Callback used to trigger bounds update after configuration change and get ids of stacks whose
371 * bounds were updated.
373 private int[] updateStackBoundsAfterConfigChange() {
374 mChangedStackList.clear();
376 final int numDisplays = mChildren.size();
377 for (int i = 0; i < numDisplays; ++i) {
378 final DisplayContent dc = mChildren.get(i);
379 dc.updateStackBoundsAfterConfigChange(mChangedStackList);
382 return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
385 /** Same as {@link #updateStackBoundsAfterConfigChange()} but only for a specific display. */
386 private int[] updateStackBoundsAfterConfigChange(int displayId) {
387 mChangedStackList.clear();
389 final DisplayContent dc = getDisplayContent(displayId);
390 dc.updateStackBoundsAfterConfigChange(mChangedStackList);
392 return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
395 private void prepareFreezingTaskBounds() {
396 for (int i = mChildren.size() - 1; i >= 0; i--) {
397 mChildren.get(i).prepareFreezingTaskBounds();
401 TaskStack getStackById(int stackId) {
402 for (int i = mChildren.size() - 1; i >= 0; i--) {
403 final DisplayContent dc = mChildren.get(i);
404 final TaskStack stack = dc.getStackById(stackId);
412 void setSecureSurfaceState(int userId, boolean disabled) {
413 forAllWindows((w) -> {
414 if (w.mHasSurface && userId == UserHandle.getUserId(w.mOwnerUid)) {
415 w.mWinAnimator.setSecureLocked(disabled);
417 }, true /* traverseTopToBottom */);
420 void updateAppOpsState() {
421 forAllWindows((w) -> {
422 if (w.mAppOp == OP_NONE) {
425 final int mode = mService.mAppOps.checkOpNoThrow(w.mAppOp, w.getOwningUid(),
426 w.getOwningPackage());
427 w.setAppOpVisibilityLw(mode == MODE_ALLOWED || mode == MODE_DEFAULT);
428 }, false /* traverseTopToBottom */);
431 boolean canShowStrictModeViolation(int pid) {
432 final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisibleLw());
436 void closeSystemDialogs(String reason) {
437 mCloseSystemDialogsReason = reason;
438 forAllWindows(mCloseSystemDialogsConsumer, false /* traverseTopToBottom */);
441 void removeReplacedWindows() {
442 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
443 mService.openSurfaceTransaction();
445 forAllWindows(sRemoveReplacedWindowsConsumer, true /* traverseTopToBottom */);
447 mService.closeSurfaceTransaction();
448 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
452 boolean hasPendingLayoutChanges(WindowAnimator animator) {
453 boolean hasChanges = false;
455 final int count = mChildren.size();
456 for (int i = 0; i < count; ++i) {
457 final DisplayContent dc = mChildren.get(i);
458 final int pendingChanges = animator.getPendingLayoutChanges(dc.getDisplayId());
459 if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
460 animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
462 if (pendingChanges != 0) {
470 boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
472 final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
473 boolean leakedSurface = false;
474 boolean killedApps = false;
476 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
477 winAnimator.mSession.mPid, operation);
479 final long callingIdentity = Binder.clearCallingIdentity();
481 // There was some problem...first, do a sanity check of the window list to make sure
482 // we haven't left any dangling surfaces around.
484 Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
485 final int numDisplays = mChildren.size();
486 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
487 leakedSurface |= mChildren.get(displayNdx).destroyLeakedSurfaces();
490 if (!leakedSurface) {
491 Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
492 final SparseIntArray pidCandidates = new SparseIntArray();
493 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
494 mChildren.get(displayNdx).forAllWindows((w) -> {
495 if (mService.mForceRemoves.contains(w)) {
498 final WindowStateAnimator wsa = w.mWinAnimator;
499 if (wsa.mSurfaceController != null) {
500 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
502 }, false /* traverseTopToBottom */);
504 if (pidCandidates.size() > 0) {
505 int[] pids = new int[pidCandidates.size()];
506 for (int i = 0; i < pids.length; i++) {
507 pids[i] = pidCandidates.keyAt(i);
510 if (mService.mActivityManager.killPids(pids, "Free memory", secure)) {
513 } catch (RemoteException e) {
519 if (leakedSurface || killedApps) {
520 // We managed to reclaim some memory, so get rid of the trouble surface and ask the
521 // app to request another one.
523 "Looks like we have reclaimed some memory, clearing surface for retry.");
524 if (surfaceController != null) {
525 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
526 "RECOVER DESTROY", false);
527 winAnimator.destroySurface();
528 if (winAnimator.mWin.mAppToken != null
529 && winAnimator.mWin.mAppToken.getController() != null) {
530 winAnimator.mWin.mAppToken.getController().removeStartingWindow();
535 winAnimator.mWin.mClient.dispatchGetNewSurface();
536 } catch (RemoteException e) {
540 Binder.restoreCallingIdentity(callingIdentity);
543 return leakedSurface || killedApps;
546 // "Something has changed! Let's make it correct now."
547 // TODO: Super crazy long method that should be broken down...
548 void performSurfacePlacement(boolean recoveringMemory) {
549 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
550 + Debug.getCallers(3));
553 boolean updateInputWindowsNeeded = false;
555 if (mService.mFocusMayChange) {
556 mService.mFocusMayChange = false;
557 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
558 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
561 // Initialize state of exiting tokens.
562 final int numDisplays = mChildren.size();
563 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
564 final DisplayContent displayContent = mChildren.get(displayNdx);
565 displayContent.setExitingTokensHasVisible(false);
569 mScreenBrightness = -1;
570 mUserActivityTimeout = -1;
571 mObscureApplicationContentOnSecondaryDisplays = false;
572 mSustainedPerformanceModeCurrent = false;
573 mService.mTransactionSequence++;
575 // TODO(multi-display):
576 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
577 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
578 final int defaultDw = defaultInfo.logicalWidth;
579 final int defaultDh = defaultInfo.logicalHeight;
581 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
582 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
583 mService.openSurfaceTransaction();
585 applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
586 } catch (RuntimeException e) {
587 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
589 mService.closeSurfaceTransaction();
590 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
591 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
594 final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
596 // If we are ready to perform an app transition, check through all of the app tokens to be
597 // shown and see if they are ready to go.
598 if (mService.mAppTransition.isReady()) {
599 defaultDisplay.pendingLayoutChanges |=
600 surfacePlacer.handleAppTransitionReadyLocked();
601 if (DEBUG_LAYOUT_REPEATS)
602 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
603 defaultDisplay.pendingLayoutChanges);
606 if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
607 // We have finished the animation of an app transition. To do this, we have delayed a
608 // lot of operations like showing and hiding apps, moving apps in Z-order, etc. The app
609 // token list reflects the correct Z-order, but the window list may now be out of sync
610 // with it. So here we will just rebuild the entire app window list. Fun!
611 defaultDisplay.pendingLayoutChanges |=
612 mService.handleAnimatingStoppedAndTransitionLocked();
613 if (DEBUG_LAYOUT_REPEATS)
614 surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
615 defaultDisplay.pendingLayoutChanges);
618 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
619 && !mService.mAppTransition.isReady()) {
620 // At this point, there was a window with a wallpaper that was force hiding other
621 // windows behind it, but now it is going away. This may be simple -- just animate away
622 // the wallpaper and its window -- or it may be hard -- the wallpaper now needs to be
623 // shown behind something that was hidden.
624 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
625 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
626 "after animateAwayWallpaperLocked", defaultDisplay.pendingLayoutChanges);
628 mWallpaperForceHidingChanged = false;
630 if (mWallpaperMayChange) {
631 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
632 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
633 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("WallpaperMayChange",
634 defaultDisplay.pendingLayoutChanges);
637 if (mService.mFocusMayChange) {
638 mService.mFocusMayChange = false;
639 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
640 false /*updateInputWindows*/)) {
641 updateInputWindowsNeeded = true;
642 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
646 if (isLayoutNeeded()) {
647 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
648 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
649 defaultDisplay.pendingLayoutChanges);
652 for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
653 WindowState win = mService.mResizingWindows.get(i);
654 if (win.mAppFreezing) {
655 // Don't remove this window until rotation has completed.
658 // Discard the saved surface if window size is changed, it can't be reused.
659 if (win.mAppToken != null) {
660 win.mAppToken.destroySavedSurfaces();
663 mService.mResizingWindows.remove(i);
666 if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
667 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
668 if (mOrientationChangeComplete) {
669 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
670 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
671 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
672 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
674 mService.stopFreezingDisplayLocked();
677 // Destroy the surface of any windows that are no longer visible.
678 boolean wallpaperDestroyed = false;
679 i = mService.mDestroySurface.size();
683 WindowState win = mService.mDestroySurface.get(i);
684 win.mDestroying = false;
685 if (mService.mInputMethodWindow == win) {
686 mService.setInputMethodWindowLocked(null);
688 if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) {
689 wallpaperDestroyed = true;
691 win.destroyOrSaveSurfaceUnchecked();
693 mService.mDestroySurface.clear();
696 // Time to remove any exiting tokens?
697 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
698 final DisplayContent displayContent = mChildren.get(displayNdx);
699 displayContent.removeExistingTokensIfPossible();
702 if (wallpaperDestroyed) {
703 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
704 defaultDisplay.setLayoutNeeded();
707 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
708 final DisplayContent displayContent = mChildren.get(displayNdx);
709 if (displayContent.pendingLayoutChanges != 0) {
710 displayContent.setLayoutNeeded();
714 // Finally update all input windows now that the window changes have stabilized.
715 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
717 mService.setHoldScreenLocked(mHoldScreen);
718 if (!mService.mDisplayFrozen) {
719 final int brightness = mScreenBrightness < 0 || mScreenBrightness > 1.0f
720 ? -1 : toBrightnessOverride(mScreenBrightness);
722 // Post these on a handler such that we don't call into power manager service while
723 // holding the window manager lock to avoid lock contention with power manager lock.
724 mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, brightness, 0).sendToTarget();
725 mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget();
728 if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
729 mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
730 mService.mPowerManagerInternal.powerHint(
731 PowerHint.SUSTAINED_PERFORMANCE,
732 (mSustainedPerformanceModeEnabled ? 1 : 0));
735 if (mService.mTurnOnScreen) {
736 if (mService.mAllowTheaterModeWakeFromLayout
737 || Settings.Global.getInt(mService.mContext.getContentResolver(),
738 Settings.Global.THEATER_MODE_ON, 0) == 0) {
739 if (DEBUG_VISIBILITY || DEBUG_POWER) {
740 Slog.v(TAG, "Turning screen on after layout!");
742 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
743 "android.server.wm:TURN_ON");
745 mService.mTurnOnScreen = false;
748 if (mUpdateRotation) {
749 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
750 // TODO(multi-display): Update rotation for different displays separately.
751 final int displayId = defaultDisplay.getDisplayId();
752 if (defaultDisplay.updateRotationUnchecked(false /* inTransaction */)) {
753 mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget();
755 mUpdateRotation = false;
759 if (mService.mWaitingForDrawnCallback != null ||
760 (mOrientationChangeComplete && !defaultDisplay.isLayoutNeeded()
761 && !mUpdateRotation)) {
762 mService.checkDrawnWindowsLocked();
765 final int N = mService.mPendingRemove.size();
767 if (mService.mPendingRemoveTmp.length < N) {
768 mService.mPendingRemoveTmp = new WindowState[N+10];
770 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
771 mService.mPendingRemove.clear();
772 ArrayList<DisplayContent> displayList = new ArrayList();
773 for (i = 0; i < N; i++) {
774 final WindowState w = mService.mPendingRemoveTmp[i];
775 w.removeImmediately();
776 final DisplayContent displayContent = w.getDisplayContent();
777 if (displayContent != null && !displayList.contains(displayContent)) {
778 displayList.add(displayContent);
782 for (int j = displayList.size() - 1; j >= 0; --j) {
783 final DisplayContent dc = displayList.get(j);
784 dc.assignWindowLayers(true /*setLayoutNeeded*/);
788 // Remove all deferred displays stacks, tasks, and activities.
789 for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
790 mChildren.get(displayNdx).checkCompleteDeferredRemoval();
793 if (updateInputWindowsNeeded) {
794 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
796 mService.setFocusTaskRegionLocked(null);
798 // Check to see if we are now in a state where the screen should
799 // be enabled, because the window obscured flags have changed.
800 mService.enableScreenIfNeededLocked();
802 mService.scheduleAnimationLocked();
803 mService.mWindowPlacerLocked.destroyPendingSurfaces();
805 if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
806 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
809 private void applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw,
811 mHoldScreenWindow = null;
812 mObscuringWindow = null;
814 // TODO(multi-display): Support these features on secondary screens.
815 if (mService.mWatermark != null) {
816 mService.mWatermark.positionSurface(defaultDw, defaultDh);
818 if (mService.mStrictModeFlash != null) {
819 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
821 if (mService.mCircularDisplayMask != null) {
822 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
823 mService.getDefaultDisplayRotation());
825 if (mService.mEmulatorDisplayOverlay != null) {
826 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
827 mService.getDefaultDisplayRotation());
830 boolean focusDisplayed = false;
832 final int count = mChildren.size();
833 for (int j = 0; j < count; ++j) {
834 final DisplayContent dc = mChildren.get(j);
835 focusDisplayed |= dc.applySurfaceChangesTransaction(recoveringMemory);
838 if (focusDisplayed) {
839 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
842 // Give the display manager a chance to adjust properties like display rotation if it needs
844 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
848 * @param w WindowState this method is applied to.
849 * @param obscured True if there is a window on top of this obscuring the display.
850 * @param syswin System window?
851 * @return True when the display contains content to show the user. When false, the display
852 * manager may choose to mirror or blank the display.
854 boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) {
855 final WindowManager.LayoutParams attrs = w.mAttrs;
856 final int attrFlags = attrs.flags;
857 final boolean canBeSeen = w.isDisplayedLw();
858 final int privateflags = attrs.privateFlags;
859 boolean displayHasContent = false;
861 if (w.mHasSurface && canBeSeen) {
862 if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
863 mHoldScreen = w.mSession;
864 mHoldScreenWindow = w;
865 } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
866 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
867 + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
868 + Debug.getCallers(10));
870 if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
871 mScreenBrightness = w.mAttrs.screenBrightness;
873 if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
874 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
877 final int type = attrs.type;
878 // This function assumes that the contents of the default display are processed first
879 // before secondary displays.
880 final DisplayContent displayContent = w.getDisplayContent();
881 if (displayContent != null && displayContent.isDefaultDisplay) {
882 // While a dream or keyguard is showing, obscure ordinary application content on
883 // secondary displays (by forcibly enabling mirroring unless there is other content
884 // we want to show) but still allow opaque keyguard dialogs to be shown.
885 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
886 mObscureApplicationContentOnSecondaryDisplays = true;
888 displayHasContent = true;
889 } else if (displayContent != null &&
890 (!mObscureApplicationContentOnSecondaryDisplays
891 || (obscured && type == TYPE_KEYGUARD_DIALOG))) {
892 // Allow full screen keyguard presentation dialogs to be seen.
893 displayHasContent = true;
895 if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
896 mSustainedPerformanceModeCurrent = true;
900 return displayHasContent;
903 boolean copyAnimToLayoutParams() {
904 boolean doRequest = false;
906 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
907 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
908 mUpdateRotation = true;
911 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
912 mWallpaperMayChange = true;
915 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
916 mWallpaperForceHidingChanged = true;
919 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
920 mOrientationChangeComplete = false;
922 mOrientationChangeComplete = true;
923 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
924 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
928 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
929 mService.mTurnOnScreen = true;
931 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
932 mWallpaperActionPending = true;
938 private static int toBrightnessOverride(float value) {
939 return (int)(value * PowerManager.BRIGHTNESS_ON);
942 private final class MyHandler extends Handler {
944 public MyHandler(Looper looper) {
949 public void handleMessage(Message msg) {
951 case SET_SCREEN_BRIGHTNESS_OVERRIDE:
952 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
955 case SET_USER_ACTIVITY_TIMEOUT:
956 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
965 void enableSurfaceTrace(ParcelFileDescriptor pfd) {
966 final FileDescriptor fd = pfd.getFileDescriptor();
967 if (mSurfaceTraceEnabled) {
968 disableSurfaceTrace();
970 mSurfaceTraceEnabled = true;
971 mRemoteEventTrace = new RemoteEventTrace(mService, fd);
972 mSurfaceTraceFd = pfd;
973 for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
974 final DisplayContent dc = mChildren.get(displayNdx);
975 dc.enableSurfaceTrace(fd);
979 void disableSurfaceTrace() {
980 mSurfaceTraceEnabled = false;
981 mRemoteEventTrace = null;
982 mSurfaceTraceFd = null;
983 for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
984 final DisplayContent dc = mChildren.get(displayNdx);
985 dc.disableSurfaceTrace();
989 void dumpDisplayContents(PrintWriter pw) {
990 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
991 if (mService.mDisplayReady) {
992 final int count = mChildren.size();
993 for (int i = 0; i < count; ++i) {
994 final DisplayContent displayContent = mChildren.get(i);
995 displayContent.dump(" ", pw);
998 pw.println(" NO DISPLAY");
1002 void dumpLayoutNeededDisplayIds(PrintWriter pw) {
1003 if (!isLayoutNeeded()) {
1006 pw.print(" mLayoutNeeded on displays=");
1007 final int count = mChildren.size();
1008 for (int displayNdx = 0; displayNdx < count; ++displayNdx) {
1009 final DisplayContent displayContent = mChildren.get(displayNdx);
1010 if (displayContent.isLayoutNeeded()) {
1011 pw.print(displayContent.getDisplayId());
1017 void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
1018 final int[] index = new int[1];
1019 forAllWindows((w) -> {
1020 if (windows == null || windows.contains(w)) {
1021 pw.println(" Window #" + index[0] + " " + w + ":");
1022 w.dump(pw, " ", dumpAll || windows != null);
1023 index[0] = index[0] + 1;
1025 }, true /* traverseTopToBottom */);
1028 void dumpTokens(PrintWriter pw, boolean dumpAll) {
1029 pw.println(" All tokens:");
1030 for (int i = mChildren.size() - 1; i >= 0; --i) {
1031 mChildren.get(i).dumpTokens(pw, dumpAll);