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