• Home
  • History
  • Annotate
  • 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