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