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