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