DisplayContent.java revision 441e4494682144aec2ec7f19060464af3d29c319
1/* 2 * Copyright (C) 2012 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 17package com.android.server.wm; 18 19import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 20import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 21import static android.app.ActivityManager.StackId.HOME_STACK_ID; 22import static android.app.ActivityManager.StackId.PINNED_STACK_ID; 23import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; 24import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 25import static android.view.WindowManager.DOCKED_BOTTOM; 26import static android.view.WindowManager.DOCKED_INVALID; 27import static android.view.WindowManager.DOCKED_TOP; 28import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 29import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 30import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 31import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 32import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 33import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; 34import static android.view.WindowManager.LayoutParams.TYPE_TOAST; 35import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 36import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; 37import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY; 38import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; 39import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; 40import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; 41import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; 42import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; 43import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 44import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP; 45 46import android.annotation.NonNull; 47import android.app.ActivityManager.StackId; 48import android.content.res.Configuration; 49import android.graphics.Rect; 50import android.graphics.Region; 51import android.graphics.Region.Op; 52import android.hardware.display.DisplayManagerInternal; 53import android.os.Debug; 54import android.util.DisplayMetrics; 55import android.util.Slog; 56import android.view.Display; 57import android.view.DisplayInfo; 58import android.view.IWindow; 59import android.view.Surface; 60import com.android.internal.util.FastPrintWriter; 61 62import java.io.FileDescriptor; 63import java.io.PrintWriter; 64import java.io.StringWriter; 65import java.util.ArrayList; 66import java.util.Arrays; 67import java.util.List; 68 69class DisplayContentList extends ArrayList<DisplayContent> { 70} 71 72/** 73 * Utility class for keeping track of the WindowStates and other pertinent contents of a 74 * particular Display. 75 * 76 * IMPORTANT: No method from this class should ever be used without holding 77 * WindowManagerService.mWindowMap. 78 */ 79class DisplayContent extends WindowContainer<TaskStack> { 80 81 /** Unique identifier of this stack. */ 82 private final int mDisplayId; 83 84 /** Z-ordered (bottom-most first) list of all Window objects. Assigned to an element 85 * from mDisplayWindows; */ 86 private final WindowList mWindows = new WindowList(); 87 88 int mInitialDisplayWidth = 0; 89 int mInitialDisplayHeight = 0; 90 int mInitialDisplayDensity = 0; 91 int mBaseDisplayWidth = 0; 92 int mBaseDisplayHeight = 0; 93 int mBaseDisplayDensity = 0; 94 boolean mDisplayScalingDisabled; 95 private final DisplayInfo mDisplayInfo = new DisplayInfo(); 96 private final Display mDisplay; 97 private final DisplayMetrics mDisplayMetrics = new DisplayMetrics(); 98 99 Rect mBaseDisplayRect = new Rect(); 100 private Rect mContentRect = new Rect(); 101 102 // Accessed directly by all users. 103 boolean layoutNeeded; 104 int pendingLayoutChanges; 105 final boolean isDefaultDisplay; 106 107 /** Window tokens that are in the process of exiting, but still on screen for animations. */ 108 final ArrayList<WindowToken> mExitingTokens = new ArrayList<>(); 109 110 /** A special TaskStack with id==HOME_STACK_ID that moves to the bottom whenever any TaskStack 111 * (except a future lockscreen TaskStack) moves to the top. */ 112 private TaskStack mHomeStack = null; 113 114 /** Detect user tapping outside of current focused task bounds .*/ 115 TaskTapPointerEventListener mTapDetector; 116 117 /** Detect user tapping outside of current focused stack bounds .*/ 118 private Region mTouchExcludeRegion = new Region(); 119 120 /** Save allocating when calculating rects */ 121 private final Rect mTmpRect = new Rect(); 122 private final Rect mTmpRect2 = new Rect(); 123 private final Region mTmpRegion = new Region(); 124 125 final WindowManagerService mService; 126 127 /** Remove this display when animation on it has completed. */ 128 boolean mDeferredRemoval; 129 130 final DockedStackDividerController mDividerControllerLocked; 131 132 final DimLayerController mDimLayerController; 133 134 final ArrayList<WindowState> mTapExcludedWindows = new ArrayList<>(); 135 136 /** Used when rebuilding window list to keep track of windows that have been removed. */ 137 private WindowState[] mRebuildTmp = new WindowState[20]; 138 139 private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult = 140 new TaskForResizePointSearchResult(); 141 private final GetWindowOnDisplaySearchResult mTmpGetWindowOnDisplaySearchResult = 142 new GetWindowOnDisplaySearchResult(); 143 144 /** 145 * @param display May not be null. 146 * @param service You know. 147 */ 148 DisplayContent(Display display, WindowManagerService service) { 149 mDisplay = display; 150 mDisplayId = display.getDisplayId(); 151 display.getDisplayInfo(mDisplayInfo); 152 display.getMetrics(mDisplayMetrics); 153 isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY; 154 mService = service; 155 initializeDisplayBaseInfo(); 156 mDividerControllerLocked = new DockedStackDividerController(service, this); 157 mDimLayerController = new DimLayerController(this); 158 } 159 160 int getDisplayId() { 161 return mDisplayId; 162 } 163 164 WindowList getWindowList() { 165 return mWindows; 166 } 167 168 Display getDisplay() { 169 return mDisplay; 170 } 171 172 DisplayInfo getDisplayInfo() { 173 return mDisplayInfo; 174 } 175 176 DisplayMetrics getDisplayMetrics() { 177 return mDisplayMetrics; 178 } 179 180 DockedStackDividerController getDockedDividerController() { 181 return mDividerControllerLocked; 182 } 183 184 /** 185 * Returns true if the specified UID has access to this display. 186 */ 187 boolean hasAccess(int uid) { 188 return mDisplay.hasAccess(uid); 189 } 190 191 boolean isPrivate() { 192 return (mDisplay.getFlags() & Display.FLAG_PRIVATE) != 0; 193 } 194 195 TaskStack getHomeStack() { 196 if (mHomeStack == null && mDisplayId == Display.DEFAULT_DISPLAY) { 197 Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this); 198 } 199 return mHomeStack; 200 } 201 202 TaskStack getStackById(int stackId) { 203 for (int i = mChildren.size() - 1; i >= 0; --i) { 204 final TaskStack stack = mChildren.get(i); 205 if (stack.mStackId == stackId) { 206 return stack; 207 } 208 } 209 return null; 210 } 211 212 @Override 213 void onConfigurationChanged(Configuration newParentConfig) { 214 super.onConfigurationChanged(newParentConfig); 215 216 // The display size information is heavily dependent on the resources in the current 217 // configuration, so we need to reconfigure it every time the configuration changes. 218 // See {@link PhoneWindowManager#setInitialDisplaySize}...sigh... 219 mService.reconfigureDisplayLocked(this); 220 221 getDockedDividerController().onConfigurationChanged(); 222 } 223 224 /** 225 * Callback used to trigger bounds update after configuration change and get ids of stacks whose 226 * bounds were updated. 227 */ 228 void updateStackBoundsAfterConfigChange(@NonNull List<Integer> changedStackList) { 229 for (int i = mChildren.size() - 1; i >= 0; --i) { 230 final TaskStack stack = mChildren.get(i); 231 if (stack.updateBoundsAfterConfigChange()) { 232 changedStackList.add(stack.mStackId); 233 } 234 } 235 } 236 237 void checkAppWindowsReadyToShow() { 238 super.checkAppWindowsReadyToShow(mDisplayId); 239 } 240 241 void updateAllDrawn() { 242 super.updateAllDrawn(mDisplayId); 243 } 244 245 void stepAppWindowsAnimation(long currentTime) { 246 super.stepAppWindowsAnimation(currentTime, mDisplayId); 247 } 248 249 @Override 250 boolean fillsParent() { 251 return true; 252 } 253 254 @Override 255 boolean isVisible() { 256 return true; 257 } 258 259 @Override 260 void onAppTransitionDone() { 261 super.onAppTransitionDone(); 262 rebuildAppWindowList(); 263 } 264 265 @Override 266 int getOrientation() { 267 if (mService.isStackVisibleLocked(DOCKED_STACK_ID) 268 || mService.isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) { 269 // Apps and their containers are not allowed to specify an orientation while the docked 270 // or freeform stack is visible...except for the home stack/task if the docked stack is 271 // minimized and it actually set something. 272 if (mHomeStack != null && mHomeStack.isVisible() 273 && mDividerControllerLocked.isMinimizedDock()) { 274 final int orientation = mHomeStack.getOrientation(); 275 if (orientation != SCREEN_ORIENTATION_UNSET) { 276 return orientation; 277 } 278 } 279 return SCREEN_ORIENTATION_UNSPECIFIED; 280 } 281 282 final int orientation = super.getOrientation(); 283 if (orientation != SCREEN_ORIENTATION_UNSET) { 284 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, 285 "App is requesting an orientation, return " + orientation); 286 return orientation; 287 } 288 289 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, 290 "No app is requesting an orientation, return " + mService.mLastOrientation); 291 // The next app has not been requested to be visible, so we keep the current orientation 292 // to prevent freezing/unfreezing the display too early. 293 return mService.mLastOrientation; 294 } 295 296 void updateDisplayInfo() { 297 mDisplay.getDisplayInfo(mDisplayInfo); 298 mDisplay.getMetrics(mDisplayMetrics); 299 for (int i = mChildren.size() - 1; i >= 0; --i) { 300 mChildren.get(i).updateDisplayInfo(null); 301 } 302 } 303 304 void initializeDisplayBaseInfo() { 305 final DisplayManagerInternal displayManagerInternal = mService.mDisplayManagerInternal; 306 if (displayManagerInternal != null) { 307 // Bootstrap the default logical display from the display manager. 308 final DisplayInfo newDisplayInfo = displayManagerInternal.getDisplayInfo(mDisplayId); 309 if (newDisplayInfo != null) { 310 mDisplayInfo.copyFrom(newDisplayInfo); 311 } 312 } 313 314 mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth; 315 mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight; 316 mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi; 317 mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight); 318 } 319 320 void getLogicalDisplayRect(Rect out) { 321 // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked. 322 final int orientation = mDisplayInfo.rotation; 323 boolean rotated = (orientation == Surface.ROTATION_90 324 || orientation == Surface.ROTATION_270); 325 final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth; 326 final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight; 327 int width = mDisplayInfo.logicalWidth; 328 int left = (physWidth - width) / 2; 329 int height = mDisplayInfo.logicalHeight; 330 int top = (physHeight - height) / 2; 331 out.set(left, top, left + width, top + height); 332 } 333 334 void getContentRect(Rect out) { 335 out.set(mContentRect); 336 } 337 338 /** Refer to {@link WindowManagerService#attachStack(int, int, boolean)} */ 339 void attachStack(TaskStack stack, boolean onTop) { 340 if (stack.mStackId == HOME_STACK_ID) { 341 if (mHomeStack != null) { 342 throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first."); 343 } 344 mHomeStack = stack; 345 } 346 addChild(stack, onTop); 347 } 348 349 void moveStack(TaskStack stack, boolean toTop) { 350 if (StackId.isAlwaysOnTop(stack.mStackId) && !toTop) { 351 // This stack is always-on-top silly... 352 Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + stack + " to bottom"); 353 return; 354 } 355 356 if (!mChildren.contains(stack)) { 357 Slog.wtf(TAG_WM, "moving stack that was not added: " + stack, new Throwable()); 358 } 359 removeChild(stack); 360 addChild(stack, toTop); 361 } 362 363 private void addChild(TaskStack stack, boolean toTop) { 364 int addIndex = toTop ? mChildren.size() : 0; 365 366 if (toTop 367 && mService.isStackVisibleLocked(PINNED_STACK_ID) 368 && stack.mStackId != PINNED_STACK_ID) { 369 // The pinned stack is always the top most stack (always-on-top) when it is visible. 370 // So, stack is moved just below the pinned stack. 371 addIndex--; 372 TaskStack topStack = mChildren.get(addIndex); 373 if (topStack.mStackId != PINNED_STACK_ID) { 374 throw new IllegalStateException("Pinned stack isn't top stack??? " + mChildren); 375 } 376 } 377 addChild(stack, addIndex); 378 layoutNeeded = true; 379 } 380 381 /** 382 * Propagate the new bounds to all child stacks. 383 * @param contentRect The bounds to apply at the top level. 384 */ 385 void resize(Rect contentRect) { 386 mContentRect.set(contentRect); 387 } 388 389 int taskIdFromPoint(int x, int y) { 390 for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) { 391 final TaskStack stack = mChildren.get(stackNdx); 392 final int taskId = stack.taskIdFromPoint(x, y); 393 if (taskId != -1) { 394 return taskId; 395 } 396 } 397 return -1; 398 } 399 400 /** 401 * Find the task whose outside touch area (for resizing) (x, y) falls within. 402 * Returns null if the touch doesn't fall into a resizing area. 403 */ 404 Task findTaskForResizePoint(int x, int y) { 405 final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics); 406 mTmpTaskForResizePointSearchResult.reset(); 407 for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) { 408 TaskStack stack = mChildren.get(stackNdx); 409 if (!StackId.isTaskResizeAllowed(stack.mStackId)) { 410 return null; 411 } 412 413 stack.findTaskForResizePoint(x, y, delta, mTmpTaskForResizePointSearchResult); 414 if (mTmpTaskForResizePointSearchResult.searchDone) { 415 return mTmpTaskForResizePointSearchResult.taskForResize; 416 } 417 } 418 return null; 419 } 420 421 void setTouchExcludeRegion(Task focusedTask) { 422 mTouchExcludeRegion.set(mBaseDisplayRect); 423 final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics); 424 mTmpRect2.setEmpty(); 425 for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) { 426 final TaskStack stack = mChildren.get(stackNdx); 427 stack.setTouchExcludeRegion( 428 focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2); 429 } 430 // If we removed the focused task above, add it back and only leave its 431 // outside touch area in the exclusion. TapDectector is not interested in 432 // any touch inside the focused task itself. 433 if (!mTmpRect2.isEmpty()) { 434 mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION); 435 } 436 final WindowState inputMethod = mService.mInputMethodWindow; 437 if (inputMethod != null && inputMethod.isVisibleLw()) { 438 // If the input method is visible and the user is typing, we don't want these touch 439 // events to be intercepted and used to change focus. This would likely cause a 440 // disappearance of the input method. 441 inputMethod.getTouchableRegion(mTmpRegion); 442 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION); 443 } 444 for (int i = mTapExcludedWindows.size() - 1; i >= 0; i--) { 445 WindowState win = mTapExcludedWindows.get(i); 446 win.getTouchableRegion(mTmpRegion); 447 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION); 448 } 449 if (getDockedStackVisibleForUserLocked() != null) { 450 mDividerControllerLocked.getTouchRegion(mTmpRect); 451 mTmpRegion.set(mTmpRect); 452 mTouchExcludeRegion.op(mTmpRegion, Op.UNION); 453 } 454 if (mTapDetector != null) { 455 mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion); 456 } 457 } 458 459 void switchUser() { 460 final WindowList windows = getWindowList(); 461 for (int i = 0; i < windows.size(); i++) { 462 final WindowState win = windows.get(i); 463 if (win.isHiddenFromUserLocked()) { 464 if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + win 465 + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid); 466 win.hideLw(false); 467 } 468 } 469 470 for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) { 471 mChildren.get(stackNdx).switchUser(); 472 } 473 474 rebuildAppWindowList(); 475 } 476 477 void resetAnimationBackgroundAnimator() { 478 for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) { 479 mChildren.get(stackNdx).resetAnimationBackgroundAnimator(); 480 } 481 } 482 483 boolean animateDimLayers() { 484 return mDimLayerController.animateDimLayers(); 485 } 486 487 void resetDimming() { 488 mDimLayerController.resetDimming(); 489 } 490 491 boolean isDimming() { 492 return mDimLayerController.isDimming(); 493 } 494 495 void stopDimmingIfNeeded() { 496 mDimLayerController.stopDimmingIfNeeded(); 497 } 498 499 @Override 500 void removeIfPossible() { 501 if (isAnimating()) { 502 mDeferredRemoval = true; 503 return; 504 } 505 removeImmediately(); 506 } 507 508 @Override 509 void removeImmediately() { 510 super.removeImmediately(); 511 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this); 512 mDimLayerController.close(); 513 if (mDisplayId == Display.DEFAULT_DISPLAY) { 514 mService.unregisterPointerEventListener(mTapDetector); 515 mService.unregisterPointerEventListener(mService.mMousePositionTracker); 516 } 517 } 518 519 /** Returns true if a removal action is still being deferred. */ 520 @Override 521 boolean checkCompleteDeferredRemoval() { 522 final boolean stillDeferringRemoval = super.checkCompleteDeferredRemoval(); 523 524 if (!stillDeferringRemoval && mDeferredRemoval) { 525 removeImmediately(); 526 mService.onDisplayRemoved(mDisplayId); 527 return false; 528 } 529 return true; 530 } 531 532 boolean animateForIme(float interpolatedValue, float animationTarget, 533 float dividerAnimationTarget) { 534 boolean updated = false; 535 536 for (int i = mChildren.size() - 1; i >= 0; --i) { 537 final TaskStack stack = mChildren.get(i); 538 if (stack == null || !stack.isAdjustedForIme()) { 539 continue; 540 } 541 542 if (interpolatedValue >= 1f && animationTarget == 0f && dividerAnimationTarget == 0f) { 543 stack.resetAdjustedForIme(true /* adjustBoundsNow */); 544 updated = true; 545 } else { 546 mDividerControllerLocked.mLastAnimationProgress = 547 mDividerControllerLocked.getInterpolatedAnimationValue(interpolatedValue); 548 mDividerControllerLocked.mLastDividerProgress = 549 mDividerControllerLocked.getInterpolatedDividerValue(interpolatedValue); 550 updated |= stack.updateAdjustForIme( 551 mDividerControllerLocked.mLastAnimationProgress, 552 mDividerControllerLocked.mLastDividerProgress, 553 false /* force */); 554 } 555 if (interpolatedValue >= 1f) { 556 stack.endImeAdjustAnimation(); 557 } 558 } 559 560 return updated; 561 } 562 563 boolean clearImeAdjustAnimation() { 564 boolean changed = false; 565 for (int i = mChildren.size() - 1; i >= 0; --i) { 566 final TaskStack stack = mChildren.get(i); 567 if (stack != null && stack.isAdjustedForIme()) { 568 stack.resetAdjustedForIme(true /* adjustBoundsNow */); 569 changed = true; 570 } 571 } 572 return changed; 573 } 574 575 void beginImeAdjustAnimation() { 576 for (int i = mChildren.size() - 1; i >= 0; --i) { 577 final TaskStack stack = mChildren.get(i); 578 if (stack.isVisible() && stack.isAdjustedForIme()) { 579 stack.beginImeAdjustAnimation(); 580 } 581 } 582 } 583 584 void adjustForImeIfNeeded() { 585 final WindowState imeWin = mService.mInputMethodWindow; 586 final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw() 587 && !mDividerControllerLocked.isImeHideRequested(); 588 final boolean dockVisible = mService.isStackVisibleLocked(DOCKED_STACK_ID); 589 final TaskStack imeTargetStack = mService.getImeFocusStackLocked(); 590 final int imeDockSide = (dockVisible && imeTargetStack != null) ? 591 imeTargetStack.getDockSide() : DOCKED_INVALID; 592 final boolean imeOnTop = (imeDockSide == DOCKED_TOP); 593 final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM); 594 final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock(); 595 final int imeHeight = mService.mPolicy.getInputMethodWindowVisibleHeightLw(); 596 final boolean imeHeightChanged = imeVisible && 597 imeHeight != mDividerControllerLocked.getImeHeightAdjustedFor(); 598 599 // The divider could be adjusted for IME position, or be thinner than usual, 600 // or both. There are three possible cases: 601 // - If IME is visible, and focus is on top, divider is not moved for IME but thinner. 602 // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner. 603 // - If IME is not visible, divider is not moved and is normal width. 604 605 if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) { 606 for (int i = mChildren.size() - 1; i >= 0; --i) { 607 final TaskStack stack = mChildren.get(i); 608 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM; 609 if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)) { 610 stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged); 611 } else { 612 stack.resetAdjustedForIme(false); 613 } 614 } 615 mDividerControllerLocked.setAdjustedForIme( 616 imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight); 617 } else { 618 for (int i = mChildren.size() - 1; i >= 0; --i) { 619 final TaskStack stack = mChildren.get(i); 620 stack.resetAdjustedForIme(!dockVisible); 621 } 622 mDividerControllerLocked.setAdjustedForIme( 623 false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight); 624 } 625 } 626 627 void prepareFreezingTaskBounds() { 628 for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) { 629 final TaskStack stack = mChildren.get(stackNdx); 630 stack.prepareFreezingTaskBounds(); 631 } 632 } 633 634 void rotateBounds(int oldRotation, int newRotation, Rect bounds) { 635 final int rotationDelta = DisplayContent.deltaRotation(oldRotation, newRotation); 636 getLogicalDisplayRect(mTmpRect); 637 switch (rotationDelta) { 638 case Surface.ROTATION_0: 639 mTmpRect2.set(bounds); 640 break; 641 case Surface.ROTATION_90: 642 mTmpRect2.top = mTmpRect.bottom - bounds.right; 643 mTmpRect2.left = bounds.top; 644 mTmpRect2.right = mTmpRect2.left + bounds.height(); 645 mTmpRect2.bottom = mTmpRect2.top + bounds.width(); 646 break; 647 case Surface.ROTATION_180: 648 mTmpRect2.top = mTmpRect.bottom - bounds.bottom; 649 mTmpRect2.left = mTmpRect.right - bounds.right; 650 mTmpRect2.right = mTmpRect2.left + bounds.width(); 651 mTmpRect2.bottom = mTmpRect2.top + bounds.height(); 652 break; 653 case Surface.ROTATION_270: 654 mTmpRect2.top = bounds.left; 655 mTmpRect2.left = mTmpRect.right - bounds.bottom; 656 mTmpRect2.right = mTmpRect2.left + bounds.height(); 657 mTmpRect2.bottom = mTmpRect2.top + bounds.width(); 658 break; 659 } 660 bounds.set(mTmpRect2); 661 } 662 663 static int deltaRotation(int oldRotation, int newRotation) { 664 int delta = newRotation - oldRotation; 665 if (delta < 0) delta += 4; 666 return delta; 667 } 668 669 public void dump(String prefix, PrintWriter pw) { 670 pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId); 671 final String subPrefix = " " + prefix; 672 pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x"); 673 pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity); 674 pw.print("dpi"); 675 if (mInitialDisplayWidth != mBaseDisplayWidth 676 || mInitialDisplayHeight != mBaseDisplayHeight 677 || mInitialDisplayDensity != mBaseDisplayDensity) { 678 pw.print(" base="); 679 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight); 680 pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi"); 681 } 682 if (mDisplayScalingDisabled) { 683 pw.println(" noscale"); 684 } 685 pw.print(" cur="); 686 pw.print(mDisplayInfo.logicalWidth); 687 pw.print("x"); pw.print(mDisplayInfo.logicalHeight); 688 pw.print(" app="); 689 pw.print(mDisplayInfo.appWidth); 690 pw.print("x"); pw.print(mDisplayInfo.appHeight); 691 pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth); 692 pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight); 693 pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth); 694 pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight); 695 pw.print(subPrefix); pw.print("deferred="); pw.print(mDeferredRemoval); 696 pw.print(" layoutNeeded="); pw.println(layoutNeeded); 697 698 pw.println(); 699 pw.println(" Application tokens in top down Z order:"); 700 for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) { 701 final TaskStack stack = mChildren.get(stackNdx); 702 stack.dump(prefix + " ", pw); 703 } 704 705 pw.println(); 706 if (!mExitingTokens.isEmpty()) { 707 pw.println(); 708 pw.println(" Exiting tokens:"); 709 for (int i = mExitingTokens.size() - 1; i >= 0; i--) { 710 WindowToken token = mExitingTokens.get(i); 711 pw.print(" Exiting #"); pw.print(i); 712 pw.print(' '); pw.print(token); 713 pw.println(':'); 714 token.dump(pw, " "); 715 } 716 } 717 pw.println(); 718 mDimLayerController.dump(prefix + " ", pw); 719 pw.println(); 720 mDividerControllerLocked.dump(prefix + " ", pw); 721 } 722 723 @Override 724 public String toString() { 725 return getName() + " stacks=" + mChildren; 726 } 727 728 String getName() { 729 return "Display " + mDisplayId + " info=" + mDisplayInfo; 730 } 731 732 /** 733 * @return The docked stack, but only if it is visible, and {@code null} otherwise. 734 */ 735 TaskStack getDockedStackLocked() { 736 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID); 737 return (stack != null && stack.isVisible()) ? stack : null; 738 } 739 740 /** 741 * Like {@link #getDockedStackLocked}, but also returns the docked stack if it's currently not 742 * visible, as long as it's not hidden because the current user doesn't have any tasks there. 743 */ 744 TaskStack getDockedStackVisibleForUserLocked() { 745 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID); 746 return (stack != null && stack.isVisible(true /* ignoreKeyguard */)) ? stack : null; 747 } 748 749 /** Find the visible, touch-deliverable window under the given point */ 750 WindowState getTouchableWinAtPointLocked(float xf, float yf) { 751 WindowState touchedWin = null; 752 final int x = (int) xf; 753 final int y = (int) yf; 754 755 for (int i = mWindows.size() - 1; i >= 0; i--) { 756 WindowState window = mWindows.get(i); 757 final int flags = window.mAttrs.flags; 758 if (!window.isVisibleLw()) { 759 continue; 760 } 761 if ((flags & FLAG_NOT_TOUCHABLE) != 0) { 762 continue; 763 } 764 765 window.getVisibleBounds(mTmpRect); 766 if (!mTmpRect.contains(x, y)) { 767 continue; 768 } 769 770 window.getTouchableRegion(mTmpRegion); 771 772 final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL); 773 if (mTmpRegion.contains(x, y) || touchFlags == 0) { 774 touchedWin = window; 775 break; 776 } 777 } 778 779 return touchedWin; 780 } 781 782 boolean canAddToastWindowForUid(int uid) { 783 // We allow one toast window per UID being shown at a time. 784 WindowList windows = getWindowList(); 785 final int windowCount = windows.size(); 786 for (int i = 0; i < windowCount; i++) { 787 WindowState window = windows.get(i); 788 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == uid 789 && !window.mPermanentlyHidden && !window.mAnimatingExit) { 790 return false; 791 } 792 } 793 return true; 794 } 795 796 void scheduleToastWindowsTimeoutIfNeededLocked(WindowState oldFocus, 797 WindowState newFocus) { 798 if (oldFocus == null || (newFocus != null && newFocus.mOwnerUid == oldFocus.mOwnerUid)) { 799 return; 800 } 801 final int lostFocusUid = oldFocus.mOwnerUid; 802 WindowList windows = getWindowList(); 803 final int windowCount = windows.size(); 804 for (int i = 0; i < windowCount; i++) { 805 WindowState window = windows.get(i); 806 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == lostFocusUid) { 807 if (!mService.mH.hasMessages(WindowManagerService.H.WINDOW_HIDE_TIMEOUT, window)) { 808 mService.mH.sendMessageDelayed( 809 mService.mH.obtainMessage( 810 WindowManagerService.H.WINDOW_HIDE_TIMEOUT, window), 811 window.mAttrs.hideTimeoutMilliseconds); 812 } 813 } 814 } 815 } 816 817 WindowState findFocusedWindow() { 818 final AppWindowToken focusedApp = mService.mFocusedApp; 819 820 for (int i = mWindows.size() - 1; i >= 0; i--) { 821 final WindowState win = mWindows.get(i); 822 823 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + i + " = " + win 824 + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys()); 825 826 if (!win.canReceiveKeys()) { 827 continue; 828 } 829 830 final AppWindowToken wtoken = win.mAppToken; 831 832 // If this window's application has been removed, just skip it. 833 if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) { 834 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because " 835 + (wtoken.removed ? "removed" : "sendingToBottom")); 836 continue; 837 } 838 839 if (focusedApp == null) { 840 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null" 841 + " using new focus @ " + i + " = " + win); 842 return win; 843 } 844 845 if (!focusedApp.windowsAreFocusable()) { 846 // Current focused app windows aren't focusable... 847 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not" 848 + " focusable using new focus @ " + i + " = " + win); 849 return win; 850 } 851 852 // Descend through all of the app tokens and find the first that either matches 853 // win.mAppToken (return win) or mFocusedApp (return null). 854 if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) { 855 if (focusedApp.compareTo(wtoken) > 0) { 856 // App stack below focused app stack. No focus for you!!! 857 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, 858 "findFocusedWindow: Reached focused app=" + focusedApp); 859 return null; 860 } 861 } 862 863 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " 864 + i + " = " + win); 865 return win; 866 } 867 868 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows."); 869 return null; 870 } 871 872 int addAppWindowToWindowList(final WindowState win) { 873 final IWindow client = win.mClient; 874 875 WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken); 876 if (!tokenWindowList.isEmpty()) { 877 return addAppWindowExisting(win, tokenWindowList); 878 } 879 880 // No windows from this token on this display 881 if (mService.localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window " 882 + client.asBinder() + " (token=" + this + ")"); 883 884 final WindowToken wToken = win.mToken; 885 886 // Figure out where the window should go, based on the order of applications. 887 mTmpGetWindowOnDisplaySearchResult.reset(); 888 for (int i = mChildren.size() - 1; i >= 0; --i) { 889 final TaskStack stack = mChildren.get(i); 890 stack.getWindowOnDisplayBeforeToken(this, wToken, mTmpGetWindowOnDisplaySearchResult); 891 if (mTmpGetWindowOnDisplaySearchResult.reachedToken) { 892 // We have reach the token we are interested in. End search. 893 break; 894 } 895 } 896 897 WindowState pos = mTmpGetWindowOnDisplaySearchResult.foundWindow; 898 899 // We now know the index into the apps. If we found an app window above, that gives us the 900 // position; else we need to look some more. 901 if (pos != null) { 902 // Move behind any windows attached to this one. 903 final WindowToken atoken = mService.mTokenMap.get(pos.mClient.asBinder()); 904 if (atoken != null) { 905 tokenWindowList = getTokenWindowsOnDisplay(atoken); 906 final int NC = tokenWindowList.size(); 907 if (NC > 0) { 908 WindowState bottom = tokenWindowList.get(0); 909 if (bottom.mSubLayer < 0) { 910 pos = bottom; 911 } 912 } 913 } 914 addWindowToListBefore(win, pos); 915 return 0; 916 } 917 918 // Continue looking down until we find the first token that has windows on this display. 919 mTmpGetWindowOnDisplaySearchResult.reset(); 920 for (int i = mChildren.size() - 1; i >= 0; --i) { 921 final TaskStack stack = mChildren.get(i); 922 stack.getWindowOnDisplayAfterToken(this, wToken, mTmpGetWindowOnDisplaySearchResult); 923 if (mTmpGetWindowOnDisplaySearchResult.foundWindow != null) { 924 // We have found a window after the token. End search. 925 break; 926 } 927 } 928 929 pos = mTmpGetWindowOnDisplaySearchResult.foundWindow; 930 931 if (pos != null) { 932 // Move in front of any windows attached to this one. 933 final WindowToken atoken = mService.mTokenMap.get(pos.mClient.asBinder()); 934 if (atoken != null) { 935 final WindowState top = atoken.getTopWindow(); 936 if (top != null && top.mSubLayer >= 0) { 937 pos = top; 938 } 939 } 940 addWindowToListAfter(win, pos); 941 return 0; 942 } 943 944 // Just search for the start of this layer. 945 final int myLayer = win.mBaseLayer; 946 int i; 947 for (i = mWindows.size() - 1; i >= 0; --i) { 948 final WindowState w = mWindows.get(i); 949 // Dock divider shares the base layer with application windows, but we want to always 950 // keep it above the application windows. The sharing of the base layer is intended 951 // for window animations, which need to be above the dock divider for the duration 952 // of the animation. 953 if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) { 954 break; 955 } 956 } 957 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, 958 "Based on layer: Adding window " + win + " at " + (i + 1) + " of " 959 + mWindows.size()); 960 mWindows.add(i + 1, win); 961 mService.mWindowsChanged = true; 962 return 0; 963 } 964 965 /** Adds this non-app window to the window list. */ 966 void addNonAppWindowToWindowList(WindowState win) { 967 // Figure out where window should go, based on layer. 968 int i; 969 for (i = mWindows.size() - 1; i >= 0; i--) { 970 final WindowState otherWin = mWindows.get(i); 971 if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= win.mBaseLayer) { 972 // Wallpaper wanders through the window list, for example to position itself 973 // directly behind keyguard. Because of this it will break the ordering based on 974 // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and 975 // we don't want the new window to appear above them. An example of this is adding 976 // of the docked stack divider. Consider a scenario with the following ordering (top 977 // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider 978 // to land below the assist preview, so the dock divider must ignore the wallpaper, 979 // with which it shares the base layer. 980 break; 981 } 982 } 983 984 i++; 985 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, 986 "Free window: Adding window " + this + " at " + i + " of " + mWindows.size()); 987 mWindows.add(i, win); 988 mService.mWindowsChanged = true; 989 } 990 991 void addChildWindowToWindowList(WindowState win) { 992 final WindowState parentWindow = win.getParentWindow(); 993 994 WindowList windowsOnSameDisplay = getTokenWindowsOnDisplay(win.mToken); 995 996 // Figure out this window's ordering relative to the parent window. 997 final int wCount = windowsOnSameDisplay.size(); 998 final int sublayer = win.mSubLayer; 999 int largestSublayer = Integer.MIN_VALUE; 1000 WindowState windowWithLargestSublayer = null; 1001 int i; 1002 for (i = 0; i < wCount; i++) { 1003 WindowState w = windowsOnSameDisplay.get(i); 1004 final int wSublayer = w.mSubLayer; 1005 if (wSublayer >= largestSublayer) { 1006 largestSublayer = wSublayer; 1007 windowWithLargestSublayer = w; 1008 } 1009 if (sublayer < 0) { 1010 // For negative sublayers, we go below all windows in the same sublayer. 1011 if (wSublayer >= sublayer) { 1012 addWindowToListBefore(win, wSublayer >= 0 ? parentWindow : w); 1013 break; 1014 } 1015 } else { 1016 // For positive sublayers, we go above all windows in the same sublayer. 1017 if (wSublayer > sublayer) { 1018 addWindowToListBefore(win, w); 1019 break; 1020 } 1021 } 1022 } 1023 if (i >= wCount) { 1024 if (sublayer < 0) { 1025 addWindowToListBefore(win, parentWindow); 1026 } else { 1027 addWindowToListAfter(win, 1028 largestSublayer >= 0 ? windowWithLargestSublayer : parentWindow); 1029 } 1030 } 1031 } 1032 1033 /** 1034 * Z-orders the display window list so that: 1035 * <ul> 1036 * <li>Any windows that are currently below the wallpaper window stay below the wallpaper 1037 * window. 1038 * <li>Exiting application windows are at the bottom, but above the wallpaper window. 1039 * <li>All other application windows are above the exiting application windows and ordered based 1040 * on the ordering of their stacks and tasks on the display. 1041 * <li>Non-application windows are at the very top. 1042 * </ul> 1043 * <p> 1044 * NOTE: This isn't a complete picture of what the user see. Further manipulation of the window 1045 * surface layering is done in {@link WindowLayersController}. 1046 */ 1047 void rebuildAppWindowList() { 1048 int count = mWindows.size(); 1049 int i; 1050 int lastBelow = -1; 1051 int numRemoved = 0; 1052 1053 if (mRebuildTmp.length < count) { 1054 mRebuildTmp = new WindowState[count + 10]; 1055 } 1056 1057 // First remove all existing app windows. 1058 i = 0; 1059 while (i < count) { 1060 final WindowState w = mWindows.get(i); 1061 if (w.mAppToken != null) { 1062 final WindowState win = mWindows.remove(i); 1063 win.mRebuilding = true; 1064 mRebuildTmp[numRemoved] = win; 1065 mService.mWindowsChanged = true; 1066 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Rebuild removing window: " + win); 1067 count--; 1068 numRemoved++; 1069 continue; 1070 } else if (lastBelow == i-1) { 1071 if (w.mAttrs.type == TYPE_WALLPAPER) { 1072 lastBelow = i; 1073 } 1074 } 1075 i++; 1076 } 1077 1078 // Keep whatever windows were below the app windows still below, by skipping them. 1079 lastBelow++; 1080 i = lastBelow; 1081 1082 // First add all of the exiting app tokens... these are no longer in the main app list, 1083 // but still have windows shown. We put them in the back because now that the animation is 1084 // over we no longer will care about them. 1085 final int numStacks = mChildren.size(); 1086 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1087 AppTokenList exitingAppTokens = mChildren.get(stackNdx).mExitingAppTokens; 1088 int NT = exitingAppTokens.size(); 1089 for (int j = 0; j < NT; j++) { 1090 i = exitingAppTokens.get(j).rebuildWindowListUnchecked(this, i); 1091 } 1092 } 1093 1094 // And add in the still active app tokens in Z order. 1095 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 1096 i = mChildren.get(stackNdx).rebuildWindowList(this, i); 1097 } 1098 1099 i -= lastBelow; 1100 if (i != numRemoved) { 1101 layoutNeeded = true; 1102 Slog.w(TAG_WM, "On display=" + mDisplayId + " Rebuild removed " + numRemoved 1103 + " windows but added " + i + " rebuildAppWindowListLocked() " 1104 + " callers=" + Debug.getCallers(10)); 1105 for (i = 0; i < numRemoved; i++) { 1106 WindowState ws = mRebuildTmp[i]; 1107 if (ws.mRebuilding) { 1108 StringWriter sw = new StringWriter(); 1109 PrintWriter pw = new FastPrintWriter(sw, false, 1024); 1110 ws.dump(pw, "", true); 1111 pw.flush(); 1112 Slog.w(TAG_WM, "This window was lost: " + ws); 1113 Slog.w(TAG_WM, sw.toString()); 1114 ws.mWinAnimator.destroySurfaceLocked(); 1115 } 1116 } 1117 Slog.w(TAG_WM, "Current window hierarchy:"); 1118 dumpChildrenNames(); 1119 Slog.w(TAG_WM, "Final window list:"); 1120 dumpWindows(); 1121 } 1122 Arrays.fill(mRebuildTmp, null); 1123 } 1124 1125 /** Return the list of Windows on this display associated with the input token. */ 1126 WindowList getTokenWindowsOnDisplay(WindowToken token) { 1127 final WindowList windowList = new WindowList(); 1128 final int count = mWindows.size(); 1129 for (int i = 0; i < count; i++) { 1130 final WindowState win = mWindows.get(i); 1131 if (win.mToken == token) { 1132 windowList.add(win); 1133 } 1134 } 1135 return windowList; 1136 } 1137 1138 private int addAppWindowExisting(WindowState win, WindowList tokenWindowList) { 1139 1140 int tokenWindowsPos; 1141 // If this application has existing windows, we simply place the new window on top of 1142 // them... but keep the starting window on top. 1143 if (win.mAttrs.type == TYPE_BASE_APPLICATION) { 1144 // Base windows go behind everything else. 1145 final WindowState lowestWindow = tokenWindowList.get(0); 1146 addWindowToListBefore(win, lowestWindow); 1147 tokenWindowsPos = win.mToken.getWindowIndex(lowestWindow); 1148 } else { 1149 final AppWindowToken atoken = win.mAppToken; 1150 final int windowListPos = tokenWindowList.size(); 1151 final WindowState lastWindow = tokenWindowList.get(windowListPos - 1); 1152 if (atoken != null && lastWindow == atoken.startingWindow) { 1153 addWindowToListBefore(win, lastWindow); 1154 tokenWindowsPos = win.mToken.getWindowIndex(lastWindow); 1155 } else { 1156 int newIdx = findIdxBasedOnAppTokens(win); 1157 // There is a window above this one associated with the same apptoken note that the 1158 // window could be a floating window that was created later or a window at the top 1159 // of the list of windows associated with this token. 1160 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, 1161 "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of " 1162 + mWindows.size()); 1163 mWindows.add(newIdx + 1, win); 1164 if (newIdx < 0) { 1165 // No window from token found on win's display. 1166 tokenWindowsPos = 0; 1167 } else { 1168 tokenWindowsPos = win.mToken.getWindowIndex(mWindows.get(newIdx)) + 1; 1169 } 1170 mService.mWindowsChanged = true; 1171 } 1172 } 1173 return tokenWindowsPos; 1174 } 1175 1176 /** Places the first input window after the second input window in the window list. */ 1177 private void addWindowToListAfter(WindowState first, WindowState second) { 1178 final int i = mWindows.indexOf(second); 1179 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, 1180 "Adding window " + this + " at " + (i + 1) + " of " + mWindows.size() 1181 + " (after " + second + ")"); 1182 mWindows.add(i + 1, first); 1183 mService.mWindowsChanged = true; 1184 } 1185 1186 /** Places the first input window before the second input window in the window list. */ 1187 private void addWindowToListBefore(WindowState first, WindowState second) { 1188 int i = mWindows.indexOf(second); 1189 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, 1190 "Adding window " + this + " at " + i + " of " + mWindows.size() 1191 + " (before " + second + ")"); 1192 if (i < 0) { 1193 Slog.w(TAG_WM, "addWindowToListBefore: Unable to find " + second + " in " + mWindows); 1194 i = 0; 1195 } 1196 mWindows.add(i, first); 1197 mService.mWindowsChanged = true; 1198 } 1199 1200 /** 1201 * This method finds out the index of a window that has the same app token as win. used for z 1202 * ordering the windows in mWindows 1203 */ 1204 private int findIdxBasedOnAppTokens(WindowState win) { 1205 for(int j = mWindows.size() - 1; j >= 0; j--) { 1206 final WindowState wentry = mWindows.get(j); 1207 if(wentry.mAppToken == win.mAppToken) { 1208 return j; 1209 } 1210 } 1211 return -1; 1212 } 1213 1214 private void dumpChildrenNames() { 1215 StringBuilder output = new StringBuilder(); 1216 dumpChildrenNames(output, " "); 1217 Slog.v(TAG_WM, output.toString()); 1218 } 1219 1220 private void dumpWindows() { 1221 Slog.v(TAG_WM, " Display #" + mDisplayId); 1222 final WindowList windows = getWindowList(); 1223 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { 1224 Slog.v(TAG_WM, " #" + winNdx + ": " + windows.get(winNdx)); 1225 } 1226 } 1227 1228 static final class GetWindowOnDisplaySearchResult { 1229 boolean reachedToken; 1230 WindowState foundWindow; 1231 1232 void reset() { 1233 reachedToken = false; 1234 foundWindow = null; 1235 } 1236 } 1237 1238 static final class TaskForResizePointSearchResult { 1239 boolean searchDone; 1240 Task taskForResize; 1241 1242 void reset() { 1243 searchDone = false; 1244 taskForResize = null; 1245 } 1246 } 1247 1248 void enableSurfaceTrace(FileDescriptor fd) { 1249 for (int i = mWindows.size() - 1; i >= 0; i--) { 1250 final WindowState win = mWindows.get(i); 1251 win.mWinAnimator.enableSurfaceTrace(fd); 1252 } 1253 } 1254 1255 void disableSurfaceTrace() { 1256 for (int i = mWindows.size() - 1; i >= 0; i--) { 1257 final WindowState win = mWindows.get(i); 1258 win.mWinAnimator.disableSurfaceTrace(); 1259 } 1260 } 1261} 1262