• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  */
16 
17 package com.android.server.wm;
18 
19 import android.content.res.Configuration;
20 import android.graphics.Rect;
21 import android.hardware.display.DisplayManager;
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.SystemClock;
33 import android.os.UserHandle;
34 import android.provider.Settings;
35 import android.util.ArraySet;
36 import android.util.EventLog;
37 import android.util.Slog;
38 import android.util.SparseIntArray;
39 import android.view.Display;
40 import android.view.DisplayInfo;
41 import android.view.WindowManager;
42 
43 import com.android.internal.os.SomeArgs;
44 import com.android.internal.util.ArrayUtils;
45 import com.android.server.EventLogTags;
46 
47 import java.io.FileDescriptor;
48 import java.io.PrintWriter;
49 import java.util.ArrayList;
50 import java.util.function.Consumer;
51 
52 import static android.app.AppOpsManager.MODE_ALLOWED;
53 import static android.app.AppOpsManager.MODE_DEFAULT;
54 import static android.app.AppOpsManager.OP_NONE;
55 import static android.view.Display.DEFAULT_DISPLAY;
56 import static android.view.Display.INVALID_DISPLAY;
57 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
58 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
59 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
60 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
61 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
62 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
63 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
64 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
65 
66 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
67 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
68 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
69 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
70 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
71 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
72 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
73 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
74 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
75 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
76 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
77 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
78 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
79 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
80 import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
81 import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
82 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
83 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
84 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
85 import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
86 import static com.android.server.wm.WindowManagerService.logSurface;
87 import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
88 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
89 import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN;
90 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
91 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
92 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
93 
94 /** Root {@link WindowContainer} for the device. */
95 class RootWindowContainer extends WindowContainer<DisplayContent> {
96     private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
97 
98     private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
99     private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
100 
101     WindowManagerService mService;
102 
103     private boolean mWallpaperForceHidingChanged = false;
104     private Object mLastWindowFreezeSource = null;
105     private Session mHoldScreen = null;
106     private float mScreenBrightness = -1;
107     private long mUserActivityTimeout = -1;
108     private boolean mUpdateRotation = false;
109     // Following variables are for debugging screen wakelock only.
110     // Last window that requires screen wakelock
111     WindowState mHoldScreenWindow = null;
112     // Last window that obscures all windows below
113     WindowState mObscuringWindow = null;
114     // Only set while traversing the default display based on its content.
115     // Affects the behavior of mirroring on secondary displays.
116     private boolean mObscureApplicationContentOnSecondaryDisplays = false;
117 
118     private boolean mSustainedPerformanceModeEnabled = false;
119     private boolean mSustainedPerformanceModeCurrent = false;
120 
121     boolean mWallpaperMayChange = false;
122     // During an orientation change, we track whether all windows have rendered
123     // at the new orientation, and this will be false from changing orientation until that occurs.
124     // For seamless rotation cases this always stays true, as the windows complete their orientation
125     // changes 1 by 1 without disturbing global state.
126     boolean mOrientationChangeComplete = true;
127     boolean mWallpaperActionPending = false;
128 
129     private final ArrayList<Integer> mChangedStackList = new ArrayList();
130 
131     // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
132     // instances will be replaced with an instance that writes a binary representation of all
133     // commands to mSurfaceTraceFd.
134     boolean mSurfaceTraceEnabled;
135     ParcelFileDescriptor mSurfaceTraceFd;
136     RemoteEventTrace mRemoteEventTrace;
137 
138     private final WindowLayersController mLayersController;
139     final WallpaperController mWallpaperController;
140 
141     private final Handler mHandler;
142 
143     private String mCloseSystemDialogsReason;
144     private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
145         if (w.mHasSurface) {
146             try {
147                 w.mClient.closeSystemDialogs(mCloseSystemDialogsReason);
148             } catch (RemoteException e) {
149             }
150         }
151     };
152 
153     private static final Consumer<WindowState> sRemoveReplacedWindowsConsumer = w -> {
154         final AppWindowToken aToken = w.mAppToken;
155         if (aToken != null) {
156             aToken.removeReplacedWindowIfNeeded(w);
157         }
158     };
159 
RootWindowContainer(WindowManagerService service)160     RootWindowContainer(WindowManagerService service) {
161         mService = service;
162         mHandler = new MyHandler(service.mH.getLooper());
163         mLayersController = new WindowLayersController(mService);
164         mWallpaperController = new WallpaperController(mService);
165     }
166 
computeFocusedWindow()167     WindowState computeFocusedWindow() {
168         // While the keyguard is showing, we must focus anything besides the main display.
169         // Otherwise we risk input not going to the keyguard when the user expects it to.
170         final boolean forceDefaultDisplay = mService.mPolicy.isKeyguardShowingAndNotOccluded();
171 
172         for (int i = mChildren.size() - 1; i >= 0; i--) {
173             final DisplayContent dc = mChildren.get(i);
174             final WindowState win = dc.findFocusedWindow();
175             if (win != null) {
176                 if (forceDefaultDisplay && !dc.isDefaultDisplay) {
177                     EventLog.writeEvent(0x534e4554, "71786287", win.mOwnerUid, "");
178                     continue;
179                 }
180                 return win;
181             }
182         }
183         return null;
184     }
185 
186     /**
187      * Get an array with display ids ordered by focus priority - last items should be given
188      * focus first. Sparse array just maps position to displayId.
189      */
getDisplaysInFocusOrder(SparseIntArray displaysInFocusOrder)190     void getDisplaysInFocusOrder(SparseIntArray displaysInFocusOrder) {
191         displaysInFocusOrder.clear();
192 
193         final int size = mChildren.size();
194         for (int i = 0; i < size; ++i) {
195             final DisplayContent displayContent = mChildren.get(i);
196             if (displayContent.isRemovalDeferred()) {
197                 // Don't report displays that are going to be removed soon.
198                 continue;
199             }
200             displaysInFocusOrder.put(i, displayContent.getDisplayId());
201         }
202     }
203 
204     /**
205      * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
206      * there is a Display for the displayId.
207      *
208      * @param displayId The display the caller is interested in.
209      * @return The DisplayContent associated with displayId or null if there is no Display for it.
210      */
getDisplayContentOrCreate(int displayId)211     DisplayContent getDisplayContentOrCreate(int displayId) {
212         DisplayContent dc = getDisplayContent(displayId);
213 
214         if (dc == null) {
215             final Display display = mService.mDisplayManager.getDisplay(displayId);
216             if (display != null) {
217                 final long callingIdentity = Binder.clearCallingIdentity();
218                 try {
219                     dc = createDisplayContent(display);
220                 } finally {
221                     Binder.restoreCallingIdentity(callingIdentity);
222                 }
223             }
224         }
225         return dc;
226     }
227 
getDisplayContent(int displayId)228     DisplayContent getDisplayContent(int displayId) {
229         for (int i = mChildren.size() - 1; i >= 0; --i) {
230             final DisplayContent current = mChildren.get(i);
231             if (current.getDisplayId() == displayId) {
232                 return current;
233             }
234         }
235         return null;
236     }
237 
createDisplayContent(final Display display)238     private DisplayContent createDisplayContent(final Display display) {
239         final DisplayContent dc = new DisplayContent(display, mService, mLayersController,
240                 mWallpaperController);
241         final int displayId = display.getDisplayId();
242 
243         if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
244 
245         final DisplayInfo displayInfo = dc.getDisplayInfo();
246         final Rect rect = new Rect();
247         mService.mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);
248         displayInfo.overscanLeft = rect.left;
249         displayInfo.overscanTop = rect.top;
250         displayInfo.overscanRight = rect.right;
251         displayInfo.overscanBottom = rect.bottom;
252         if (mService.mDisplayManagerInternal != null) {
253             mService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
254                     displayId, displayInfo);
255             mService.configureDisplayPolicyLocked(dc);
256 
257             // Tap Listeners are supported for:
258             // 1. All physical displays (multi-display).
259             // 2. VirtualDisplays that support virtual touch input. (Only VR for now)
260             // TODO(multi-display): Support VirtualDisplays with no virtual touch input.
261             if ((display.getType() != Display.TYPE_VIRTUAL
262                     || (display.getType() == Display.TYPE_VIRTUAL
263                         // Only VR VirtualDisplays
264                         && displayId == mService.mVr2dDisplayId))
265                     && mService.canDispatchPointerEvents()) {
266                 if (DEBUG_DISPLAY) {
267                     Slog.d(TAG,
268                             "Registering PointerEventListener for DisplayId: " + displayId);
269                 }
270                 dc.mTapDetector = new TaskTapPointerEventListener(mService, dc);
271                 mService.registerPointerEventListener(dc.mTapDetector);
272                 if (displayId == DEFAULT_DISPLAY) {
273                     mService.registerPointerEventListener(mService.mMousePositionTracker);
274                 }
275             }
276         }
277 
278         return dc;
279     }
280 
isLayoutNeeded()281     boolean isLayoutNeeded() {
282         final int numDisplays = mChildren.size();
283         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
284             final DisplayContent displayContent = mChildren.get(displayNdx);
285             if (displayContent.isLayoutNeeded()) {
286                 return true;
287             }
288         }
289         return false;
290     }
291 
getWindowsByName(ArrayList<WindowState> output, String name)292     void getWindowsByName(ArrayList<WindowState> output, String name) {
293         int objectId = 0;
294         // See if this is an object ID.
295         try {
296             objectId = Integer.parseInt(name, 16);
297             name = null;
298         } catch (RuntimeException e) {
299         }
300 
301         getWindowsByName(output, name, objectId);
302     }
303 
getWindowsByName(ArrayList<WindowState> output, String name, int objectId)304     private void getWindowsByName(ArrayList<WindowState> output, String name, int objectId) {
305         forAllWindows((w) -> {
306             if (name != null) {
307                 if (w.mAttrs.getTitle().toString().contains(name)) {
308                     output.add(w);
309                 }
310             } else if (System.identityHashCode(w) == objectId) {
311                 output.add(w);
312             }
313         }, true /* traverseTopToBottom */);
314     }
315 
316     /**
317      * Returns the app window token for the input binder if it exist in the system.
318      * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since
319      * AppWindowToken represents an activity which can only exist on one display.
320      */
getAppWindowToken(IBinder binder)321     AppWindowToken getAppWindowToken(IBinder binder) {
322         for (int i = mChildren.size() - 1; i >= 0; --i) {
323             final DisplayContent dc = mChildren.get(i);
324             final AppWindowToken atoken = dc.getAppWindowToken(binder);
325             if (atoken != null) {
326                 return atoken;
327             }
328         }
329         return null;
330     }
331 
332     /** Returns the display object the input window token is currently mapped on. */
getWindowTokenDisplay(WindowToken token)333     DisplayContent getWindowTokenDisplay(WindowToken token) {
334         if (token == null) {
335             return null;
336         }
337 
338         for (int i = mChildren.size() - 1; i >= 0; --i) {
339             final DisplayContent dc = mChildren.get(i);
340             final WindowToken current = dc.getWindowToken(token.token);
341             if (current == token) {
342                 return dc;
343             }
344         }
345 
346         return null;
347     }
348 
349     /**
350      * Set new display override config and return array of ids of stacks that were changed during
351      * update. If called for the default display, global configuration will also be updated.
352      */
setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, int displayId)353     int[] setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, int displayId) {
354         final DisplayContent displayContent = getDisplayContent(displayId);
355         if (displayContent == null) {
356             throw new IllegalArgumentException("Display not found for id: " + displayId);
357         }
358 
359         final Configuration currentConfig = displayContent.getOverrideConfiguration();
360         final boolean configChanged = currentConfig.diff(newConfiguration) != 0;
361         if (!configChanged) {
362             return null;
363         }
364         displayContent.onOverrideConfigurationChanged(newConfiguration);
365 
366         if (displayId == DEFAULT_DISPLAY) {
367             // Override configuration of the default display duplicates global config. In this case
368             // we also want to update the global config.
369             return setGlobalConfigurationIfNeeded(newConfiguration);
370         } else {
371             return updateStackBoundsAfterConfigChange(displayId);
372         }
373     }
374 
setGlobalConfigurationIfNeeded(Configuration newConfiguration)375     private int[] setGlobalConfigurationIfNeeded(Configuration newConfiguration) {
376         final boolean configChanged = getConfiguration().diff(newConfiguration) != 0;
377         if (!configChanged) {
378             return null;
379         }
380         onConfigurationChanged(newConfiguration);
381         return updateStackBoundsAfterConfigChange();
382     }
383 
384     @Override
onConfigurationChanged(Configuration newParentConfig)385     void onConfigurationChanged(Configuration newParentConfig) {
386         prepareFreezingTaskBounds();
387         super.onConfigurationChanged(newParentConfig);
388 
389         mService.mPolicy.onConfigurationChanged();
390     }
391 
392     /**
393      * Callback used to trigger bounds update after configuration change and get ids of stacks whose
394      * bounds were updated.
395      */
updateStackBoundsAfterConfigChange()396     private int[] updateStackBoundsAfterConfigChange() {
397         mChangedStackList.clear();
398 
399         final int numDisplays = mChildren.size();
400         for (int i = 0; i < numDisplays; ++i) {
401             final DisplayContent dc = mChildren.get(i);
402             dc.updateStackBoundsAfterConfigChange(mChangedStackList);
403         }
404 
405         return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
406     }
407 
408     /** Same as {@link #updateStackBoundsAfterConfigChange()} but only for a specific display. */
updateStackBoundsAfterConfigChange(int displayId)409     private int[] updateStackBoundsAfterConfigChange(int displayId) {
410         mChangedStackList.clear();
411 
412         final DisplayContent dc = getDisplayContent(displayId);
413         dc.updateStackBoundsAfterConfigChange(mChangedStackList);
414 
415         return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
416     }
417 
prepareFreezingTaskBounds()418     private void prepareFreezingTaskBounds() {
419         for (int i = mChildren.size() - 1; i >= 0; i--) {
420             mChildren.get(i).prepareFreezingTaskBounds();
421         }
422     }
423 
getStackById(int stackId)424     TaskStack getStackById(int stackId) {
425         for (int i = mChildren.size() - 1; i >= 0; i--) {
426             final DisplayContent dc = mChildren.get(i);
427             final TaskStack stack = dc.getStackById(stackId);
428             if (stack != null) {
429                 return stack;
430             }
431         }
432         return null;
433     }
434 
setSecureSurfaceState(int userId, boolean disabled)435     void setSecureSurfaceState(int userId, boolean disabled) {
436         forAllWindows((w) -> {
437             if (w.mHasSurface && userId == UserHandle.getUserId(w.mOwnerUid)) {
438                 w.mWinAnimator.setSecureLocked(disabled);
439             }
440         }, true /* traverseTopToBottom */);
441     }
442 
updateAppOpsState()443     void updateAppOpsState() {
444         forAllWindows((w) -> {
445             if (w.mAppOp == OP_NONE) {
446                 return;
447             }
448             final int mode = mService.mAppOps.checkOpNoThrow(w.mAppOp, w.getOwningUid(),
449                     w.getOwningPackage());
450             w.setAppOpVisibilityLw(mode == MODE_ALLOWED || mode == MODE_DEFAULT);
451         }, false /* traverseTopToBottom */);
452     }
453 
canShowStrictModeViolation(int pid)454     boolean canShowStrictModeViolation(int pid) {
455         final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisibleLw());
456         return win != null;
457     }
458 
closeSystemDialogs(String reason)459     void closeSystemDialogs(String reason) {
460         mCloseSystemDialogsReason = reason;
461         forAllWindows(mCloseSystemDialogsConsumer, false /* traverseTopToBottom */);
462     }
463 
removeReplacedWindows()464     void removeReplacedWindows() {
465         if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
466         mService.openSurfaceTransaction();
467         try {
468             forAllWindows(sRemoveReplacedWindowsConsumer, true /* traverseTopToBottom */);
469         } finally {
470             mService.closeSurfaceTransaction();
471             if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
472         }
473     }
474 
hasPendingLayoutChanges(WindowAnimator animator)475     boolean hasPendingLayoutChanges(WindowAnimator animator) {
476         boolean hasChanges = false;
477 
478         final int count = mChildren.size();
479         for (int i = 0; i < count; ++i) {
480             final DisplayContent dc = mChildren.get(i);
481             final int pendingChanges = animator.getPendingLayoutChanges(dc.getDisplayId());
482             if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
483                 animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
484             }
485             if (pendingChanges != 0) {
486                 hasChanges = true;
487             }
488         }
489 
490         return hasChanges;
491     }
492 
reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation, boolean secure)493     boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
494             boolean secure) {
495         final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
496         boolean leakedSurface = false;
497         boolean killedApps = false;
498 
499         EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
500                 winAnimator.mSession.mPid, operation);
501 
502         final long callingIdentity = Binder.clearCallingIdentity();
503         try {
504             // There was some problem...first, do a sanity check of the window list to make sure
505             // we haven't left any dangling surfaces around.
506 
507             Slog.i(TAG_WM, "Out of memory for surface!  Looking for leaks...");
508             final int numDisplays = mChildren.size();
509             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
510                 leakedSurface |= mChildren.get(displayNdx).destroyLeakedSurfaces();
511             }
512 
513             if (!leakedSurface) {
514                 Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
515                 final SparseIntArray pidCandidates = new SparseIntArray();
516                 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
517                     mChildren.get(displayNdx).forAllWindows((w) -> {
518                         if (mService.mForceRemoves.contains(w)) {
519                             return;
520                         }
521                         final WindowStateAnimator wsa = w.mWinAnimator;
522                         if (wsa.mSurfaceController != null) {
523                             pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
524                         }
525                     }, false /* traverseTopToBottom */);
526 
527                     if (pidCandidates.size() > 0) {
528                         int[] pids = new int[pidCandidates.size()];
529                         for (int i = 0; i < pids.length; i++) {
530                             pids[i] = pidCandidates.keyAt(i);
531                         }
532                         try {
533                             if (mService.mActivityManager.killPids(pids, "Free memory", secure)) {
534                                 killedApps = true;
535                             }
536                         } catch (RemoteException e) {
537                         }
538                     }
539                 }
540             }
541 
542             if (leakedSurface || killedApps) {
543                 // We managed to reclaim some memory, so get rid of the trouble surface and ask the
544                 // app to request another one.
545                 Slog.w(TAG_WM,
546                         "Looks like we have reclaimed some memory, clearing surface for retry.");
547                 if (surfaceController != null) {
548                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
549                             "RECOVER DESTROY", false);
550                     winAnimator.destroySurface();
551                     if (winAnimator.mWin.mAppToken != null
552                             && winAnimator.mWin.mAppToken.getController() != null) {
553                         winAnimator.mWin.mAppToken.getController().removeStartingWindow();
554                     }
555                 }
556 
557                 try {
558                     winAnimator.mWin.mClient.dispatchGetNewSurface();
559                 } catch (RemoteException e) {
560                 }
561             }
562         } finally {
563             Binder.restoreCallingIdentity(callingIdentity);
564         }
565 
566         return leakedSurface || killedApps;
567     }
568 
569     // "Something has changed!  Let's make it correct now."
570     // TODO: Super crazy long method that should be broken down...
performSurfacePlacement(boolean recoveringMemory)571     void performSurfacePlacement(boolean recoveringMemory) {
572         if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
573                 + Debug.getCallers(3));
574 
575         int i;
576         boolean updateInputWindowsNeeded = false;
577 
578         if (mService.mFocusMayChange) {
579             mService.mFocusMayChange = false;
580             updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
581                     UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
582         }
583 
584         // Initialize state of exiting tokens.
585         final int numDisplays = mChildren.size();
586         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
587             final DisplayContent displayContent = mChildren.get(displayNdx);
588             displayContent.setExitingTokensHasVisible(false);
589         }
590 
591         mHoldScreen = null;
592         mScreenBrightness = -1;
593         mUserActivityTimeout = -1;
594         mObscureApplicationContentOnSecondaryDisplays = false;
595         mSustainedPerformanceModeCurrent = false;
596         mService.mTransactionSequence++;
597 
598         // TODO(multi-display):
599         final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
600         final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
601         final int defaultDw = defaultInfo.logicalWidth;
602         final int defaultDh = defaultInfo.logicalHeight;
603 
604         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
605                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
606         mService.openSurfaceTransaction();
607         try {
608             applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
609         } catch (RuntimeException e) {
610             Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
611         } finally {
612             mService.closeSurfaceTransaction();
613             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
614                     "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
615         }
616 
617         final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
618 
619         // If we are ready to perform an app transition, check through all of the app tokens to be
620         // shown and see if they are ready to go.
621         if (mService.mAppTransition.isReady()) {
622             defaultDisplay.pendingLayoutChanges |=
623                     surfacePlacer.handleAppTransitionReadyLocked();
624             if (DEBUG_LAYOUT_REPEATS)
625                 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
626                         defaultDisplay.pendingLayoutChanges);
627         }
628 
629         if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
630             // We have finished the animation of an app transition. To do this, we have delayed a
631             // lot of operations like showing and hiding apps, moving apps in Z-order, etc. The app
632             // token list reflects the correct Z-order, but the window list may now be out of sync
633             // with it. So here we will just rebuild the entire app window list. Fun!
634             defaultDisplay.pendingLayoutChanges |=
635                     mService.handleAnimatingStoppedAndTransitionLocked();
636             if (DEBUG_LAYOUT_REPEATS)
637                 surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
638                         defaultDisplay.pendingLayoutChanges);
639         }
640 
641         if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
642                 && !mService.mAppTransition.isReady()) {
643             // At this point, there was a window with a wallpaper that was force hiding other
644             // windows behind it, but now it is going away. This may be simple -- just animate away
645             // the wallpaper and its window -- or it may be hard -- the wallpaper now needs to be
646             // shown behind something that was hidden.
647             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
648             if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
649                     "after animateAwayWallpaperLocked", defaultDisplay.pendingLayoutChanges);
650         }
651         mWallpaperForceHidingChanged = false;
652 
653         if (mWallpaperMayChange) {
654             if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change!  Adjusting");
655             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
656             if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("WallpaperMayChange",
657                     defaultDisplay.pendingLayoutChanges);
658         }
659 
660         if (mService.mFocusMayChange) {
661             mService.mFocusMayChange = false;
662             if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
663                     false /*updateInputWindows*/)) {
664                 updateInputWindowsNeeded = true;
665                 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
666             }
667         }
668 
669         if (isLayoutNeeded()) {
670             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
671             if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
672                     defaultDisplay.pendingLayoutChanges);
673         }
674 
675         final ArraySet<DisplayContent> touchExcludeRegionUpdateDisplays = handleResizingWindows();
676 
677         if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
678                 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
679         if (mOrientationChangeComplete) {
680             if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
681                 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
682                 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
683                 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
684             }
685             mService.stopFreezingDisplayLocked();
686         }
687 
688         // Destroy the surface of any windows that are no longer visible.
689         boolean wallpaperDestroyed = false;
690         i = mService.mDestroySurface.size();
691         if (i > 0) {
692             do {
693                 i--;
694                 WindowState win = mService.mDestroySurface.get(i);
695                 win.mDestroying = false;
696                 if (mService.mInputMethodWindow == win) {
697                     mService.setInputMethodWindowLocked(null);
698                 }
699                 if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) {
700                     wallpaperDestroyed = true;
701                 }
702                 win.destroyOrSaveSurfaceUnchecked();
703             } while (i > 0);
704             mService.mDestroySurface.clear();
705         }
706 
707         // Time to remove any exiting tokens?
708         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
709             final DisplayContent displayContent = mChildren.get(displayNdx);
710             displayContent.removeExistingTokensIfPossible();
711         }
712 
713         if (wallpaperDestroyed) {
714             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
715             defaultDisplay.setLayoutNeeded();
716         }
717 
718         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
719             final DisplayContent displayContent = mChildren.get(displayNdx);
720             if (displayContent.pendingLayoutChanges != 0) {
721                 displayContent.setLayoutNeeded();
722             }
723         }
724 
725         // Finally update all input windows now that the window changes have stabilized.
726         mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
727 
728         mService.setHoldScreenLocked(mHoldScreen);
729         if (!mService.mDisplayFrozen) {
730             final int brightness = mScreenBrightness < 0 || mScreenBrightness > 1.0f
731                     ? -1 : toBrightnessOverride(mScreenBrightness);
732 
733             // Post these on a handler such that we don't call into power manager service while
734             // holding the window manager lock to avoid lock contention with power manager lock.
735             mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, brightness, 0).sendToTarget();
736             mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget();
737         }
738 
739         if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
740             mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
741             mService.mPowerManagerInternal.powerHint(
742                     PowerHint.SUSTAINED_PERFORMANCE,
743                     (mSustainedPerformanceModeEnabled ? 1 : 0));
744         }
745 
746         if (mService.mTurnOnScreen) {
747             if (mService.mAllowTheaterModeWakeFromLayout
748                     || Settings.Global.getInt(mService.mContext.getContentResolver(),
749                     Settings.Global.THEATER_MODE_ON, 0) == 0) {
750                 if (DEBUG_VISIBILITY || DEBUG_POWER) {
751                     Slog.v(TAG, "Turning screen on after layout!");
752                 }
753                 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
754                         "android.server.wm:TURN_ON");
755             }
756             mService.mTurnOnScreen = false;
757         }
758 
759         if (mUpdateRotation) {
760             if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
761             // TODO(multi-display): Update rotation for different displays separately.
762             final int displayId = defaultDisplay.getDisplayId();
763             if (defaultDisplay.updateRotationUnchecked(false /* inTransaction */)) {
764                 mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget();
765             } else {
766                 mUpdateRotation = false;
767             }
768             // Update rotation of VR virtual display separately. Currently this is the only kind of
769             // secondary display that can be rotated because of the single-display limitations in
770             // PhoneWindowManager.
771             final DisplayContent vrDisplay = mService.mVr2dDisplayId != INVALID_DISPLAY
772                     ? getDisplayContent(mService.mVr2dDisplayId) : null;
773             if (vrDisplay != null && vrDisplay.updateRotationUnchecked(false /* inTransaction */)) {
774                 mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mService.mVr2dDisplayId)
775                         .sendToTarget();
776             }
777         }
778 
779         if (mService.mWaitingForDrawnCallback != null ||
780                 (mOrientationChangeComplete && !defaultDisplay.isLayoutNeeded()
781                         && !mUpdateRotation)) {
782             mService.checkDrawnWindowsLocked();
783         }
784 
785         final int N = mService.mPendingRemove.size();
786         if (N > 0) {
787             if (mService.mPendingRemoveTmp.length < N) {
788                 mService.mPendingRemoveTmp = new WindowState[N+10];
789             }
790             mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
791             mService.mPendingRemove.clear();
792             ArrayList<DisplayContent> displayList = new ArrayList();
793             for (i = 0; i < N; i++) {
794                 final WindowState w = mService.mPendingRemoveTmp[i];
795                 w.removeImmediately();
796                 final DisplayContent displayContent = w.getDisplayContent();
797                 if (displayContent != null && !displayList.contains(displayContent)) {
798                     displayList.add(displayContent);
799                 }
800             }
801 
802             for (int j = displayList.size() - 1; j >= 0; --j) {
803                 final DisplayContent dc = displayList.get(j);
804                 dc.assignWindowLayers(true /*setLayoutNeeded*/);
805             }
806         }
807 
808         // Remove all deferred displays stacks, tasks, and activities.
809         for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
810             mChildren.get(displayNdx).checkCompleteDeferredRemoval();
811         }
812 
813         if (updateInputWindowsNeeded) {
814             mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
815         }
816         mService.setFocusTaskRegionLocked(null);
817         if (touchExcludeRegionUpdateDisplays != null) {
818             final DisplayContent focusedDc = mService.mFocusedApp != null
819                     ? mService.mFocusedApp.getDisplayContent() : null;
820             for (DisplayContent dc : touchExcludeRegionUpdateDisplays) {
821                 // The focused DisplayContent was recalcuated in setFocusTaskRegionLocked
822                 if (focusedDc != dc) {
823                     dc.setTouchExcludeRegion(null /* focusedTask */);
824                 }
825             }
826         }
827 
828         // Check to see if we are now in a state where the screen should
829         // be enabled, because the window obscured flags have changed.
830         mService.enableScreenIfNeededLocked();
831 
832         mService.scheduleAnimationLocked();
833         mService.mWindowPlacerLocked.destroyPendingSurfaces();
834 
835         if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
836                 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
837     }
838 
applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw, int defaultDh)839     private void applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw,
840             int defaultDh) {
841         mHoldScreenWindow = null;
842         mObscuringWindow = null;
843 
844         // TODO(multi-display): Support these features on secondary screens.
845         if (mService.mWatermark != null) {
846             mService.mWatermark.positionSurface(defaultDw, defaultDh);
847         }
848         if (mService.mStrictModeFlash != null) {
849             mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
850         }
851         if (mService.mCircularDisplayMask != null) {
852             mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
853                     mService.getDefaultDisplayRotation());
854         }
855         if (mService.mEmulatorDisplayOverlay != null) {
856             mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
857                     mService.getDefaultDisplayRotation());
858         }
859 
860         boolean focusDisplayed = false;
861 
862         final int count = mChildren.size();
863         for (int j = 0; j < count; ++j) {
864             final DisplayContent dc = mChildren.get(j);
865             focusDisplayed |= dc.applySurfaceChangesTransaction(recoveringMemory);
866         }
867 
868         if (focusDisplayed) {
869             mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
870         }
871 
872         // Give the display manager a chance to adjust properties like display rotation if it needs
873         // to.
874         mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
875     }
876 
877     /**
878      * Handles resizing windows during surface placement.
879      *
880      * @return A set of any DisplayContent whose touch exclude region needs to be recalculated due
881      *         to a tap-exclude window resizing, or null if no such DisplayContents were found.
882      */
handleResizingWindows()883     private ArraySet<DisplayContent> handleResizingWindows() {
884         ArraySet<DisplayContent> touchExcludeRegionUpdateSet = null;
885         for (int i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
886             WindowState win = mService.mResizingWindows.get(i);
887             if (win.mAppFreezing) {
888                 // Don't remove this window until rotation has completed.
889                 continue;
890             }
891             // Discard the saved surface if window size is changed, it can't be reused.
892             if (win.mAppToken != null) {
893                 win.mAppToken.destroySavedSurfaces();
894             }
895             win.reportResized();
896             mService.mResizingWindows.remove(i);
897             if (WindowManagerService.excludeWindowTypeFromTapOutTask(win.mAttrs.type)) {
898                 final DisplayContent dc = win.getDisplayContent();
899                 if (touchExcludeRegionUpdateSet == null) {
900                     touchExcludeRegionUpdateSet = new ArraySet<>();
901                 }
902                 touchExcludeRegionUpdateSet.add(dc);
903             }
904         }
905         return touchExcludeRegionUpdateSet;
906     }
907 
908     /**
909      * @param w WindowState this method is applied to.
910      * @param obscured True if there is a window on top of this obscuring the display.
911      * @param syswin System window?
912      * @return True when the display contains content to show the user. When false, the display
913      *          manager may choose to mirror or blank the display.
914      */
handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin)915     boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) {
916         final WindowManager.LayoutParams attrs = w.mAttrs;
917         final int attrFlags = attrs.flags;
918         final boolean canBeSeen = w.isDisplayedLw();
919         final int privateflags = attrs.privateFlags;
920         boolean displayHasContent = false;
921 
922         if (w.mHasSurface && canBeSeen) {
923             if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
924                 mHoldScreen = w.mSession;
925                 mHoldScreenWindow = w;
926             } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
927                 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
928                         + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
929                         + Debug.getCallers(10));
930             }
931             if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
932                 mScreenBrightness = w.mAttrs.screenBrightness;
933             }
934             if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
935                 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
936             }
937 
938             final int type = attrs.type;
939             // This function assumes that the contents of the default display are processed first
940             // before secondary displays.
941             final DisplayContent displayContent = w.getDisplayContent();
942             if (displayContent != null && displayContent.isDefaultDisplay) {
943                 // While a dream or keyguard is showing, obscure ordinary application content on
944                 // secondary displays (by forcibly enabling mirroring unless there is other content
945                 // we want to show) but still allow opaque keyguard dialogs to be shown.
946                 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
947                     mObscureApplicationContentOnSecondaryDisplays = true;
948                 }
949                 displayHasContent = true;
950             } else if (displayContent != null &&
951                     (!mObscureApplicationContentOnSecondaryDisplays
952                             || (obscured && type == TYPE_KEYGUARD_DIALOG))) {
953                 // Allow full screen keyguard presentation dialogs to be seen.
954                 displayHasContent = true;
955             }
956             if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
957                 mSustainedPerformanceModeCurrent = true;
958             }
959         }
960 
961         return displayHasContent;
962     }
963 
copyAnimToLayoutParams()964     boolean copyAnimToLayoutParams() {
965         boolean doRequest = false;
966 
967         final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
968         if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
969             mUpdateRotation = true;
970             doRequest = true;
971         }
972         if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
973             mWallpaperMayChange = true;
974             doRequest = true;
975         }
976         if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
977             mWallpaperForceHidingChanged = true;
978             doRequest = true;
979         }
980         if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
981             mOrientationChangeComplete = false;
982         } else {
983             mOrientationChangeComplete = true;
984             mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
985             if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
986                 doRequest = true;
987             }
988         }
989         if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
990             mService.mTurnOnScreen = true;
991         }
992         if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
993             mWallpaperActionPending = true;
994         }
995 
996         return doRequest;
997     }
998 
toBrightnessOverride(float value)999     private static int toBrightnessOverride(float value) {
1000         return (int)(value * PowerManager.BRIGHTNESS_ON);
1001     }
1002 
1003     private final class MyHandler extends Handler {
1004 
MyHandler(Looper looper)1005         public MyHandler(Looper looper) {
1006             super(looper);
1007         }
1008 
1009         @Override
handleMessage(Message msg)1010         public void handleMessage(Message msg) {
1011             switch (msg.what) {
1012                 case SET_SCREEN_BRIGHTNESS_OVERRIDE:
1013                     mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
1014                             msg.arg1);
1015                     break;
1016                 case SET_USER_ACTIVITY_TIMEOUT:
1017                     mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
1018                             (Long) msg.obj);
1019                     break;
1020                 default:
1021                     break;
1022             }
1023         }
1024     }
1025 
enableSurfaceTrace(ParcelFileDescriptor pfd)1026     void enableSurfaceTrace(ParcelFileDescriptor pfd) {
1027         final FileDescriptor fd = pfd.getFileDescriptor();
1028         if (mSurfaceTraceEnabled) {
1029             disableSurfaceTrace();
1030         }
1031         mSurfaceTraceEnabled = true;
1032         mRemoteEventTrace = new RemoteEventTrace(mService, fd);
1033         mSurfaceTraceFd = pfd;
1034         for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
1035             final DisplayContent dc = mChildren.get(displayNdx);
1036             dc.enableSurfaceTrace(fd);
1037         }
1038     }
1039 
disableSurfaceTrace()1040     void disableSurfaceTrace() {
1041         mSurfaceTraceEnabled = false;
1042         mRemoteEventTrace = null;
1043         mSurfaceTraceFd = null;
1044         for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
1045             final DisplayContent dc = mChildren.get(displayNdx);
1046             dc.disableSurfaceTrace();
1047         }
1048     }
1049 
dumpDisplayContents(PrintWriter pw)1050     void dumpDisplayContents(PrintWriter pw) {
1051         pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
1052         if (mService.mDisplayReady) {
1053             final int count = mChildren.size();
1054             for (int i = 0; i < count; ++i) {
1055                 final DisplayContent displayContent = mChildren.get(i);
1056                 displayContent.dump("  ", pw);
1057             }
1058         } else {
1059             pw.println("  NO DISPLAY");
1060         }
1061     }
1062 
dumpLayoutNeededDisplayIds(PrintWriter pw)1063     void dumpLayoutNeededDisplayIds(PrintWriter pw) {
1064         if (!isLayoutNeeded()) {
1065             return;
1066         }
1067         pw.print("  mLayoutNeeded on displays=");
1068         final int count = mChildren.size();
1069         for (int displayNdx = 0; displayNdx < count; ++displayNdx) {
1070             final DisplayContent displayContent = mChildren.get(displayNdx);
1071             if (displayContent.isLayoutNeeded()) {
1072                 pw.print(displayContent.getDisplayId());
1073             }
1074         }
1075         pw.println();
1076     }
1077 
dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows)1078     void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
1079         final int[] index = new int[1];
1080         forAllWindows((w) -> {
1081             if (windows == null || windows.contains(w)) {
1082                 pw.println("  Window #" + index[0] + " " + w + ":");
1083                 w.dump(pw, "    ", dumpAll || windows != null);
1084                 index[0] = index[0] + 1;
1085             }
1086         }, true /* traverseTopToBottom */);
1087     }
1088 
dumpTokens(PrintWriter pw, boolean dumpAll)1089     void dumpTokens(PrintWriter pw, boolean dumpAll) {
1090         pw.println("  All tokens:");
1091         for (int i = mChildren.size() - 1; i >= 0; --i) {
1092             mChildren.get(i).dumpTokens(pw, dumpAll);
1093         }
1094     }
1095 
1096     @Override
getName()1097     String getName() {
1098         return "ROOT";
1099     }
1100 }
1101