1 /* 2 * Copyright (C) 2011 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.app.ActivityManager; 20 import android.app.AppOpsManager; 21 import android.content.Context; 22 import android.content.res.Configuration; 23 import android.graphics.Matrix; 24 import android.graphics.PixelFormat; 25 import android.graphics.Point; 26 import android.graphics.Rect; 27 import android.graphics.Region; 28 import android.os.IBinder; 29 import android.os.PowerManager; 30 import android.os.RemoteCallbackList; 31 import android.os.RemoteException; 32 import android.os.SystemClock; 33 import android.os.Trace; 34 import android.os.UserHandle; 35 import android.os.WorkSource; 36 import android.util.DisplayMetrics; 37 import android.util.Slog; 38 import android.util.TimeUtils; 39 import android.view.Display; 40 import android.view.DisplayInfo; 41 import android.view.Gravity; 42 import android.view.IApplicationToken; 43 import android.view.IWindow; 44 import android.view.IWindowFocusObserver; 45 import android.view.IWindowId; 46 import android.view.InputChannel; 47 import android.view.InputEvent; 48 import android.view.InputEventReceiver; 49 import android.view.View; 50 import android.view.ViewTreeObserver; 51 import android.view.WindowManager; 52 import android.view.WindowManagerPolicy; 53 54 import com.android.server.input.InputWindowHandle; 55 56 import java.io.PrintWriter; 57 import java.util.ArrayList; 58 59 import static android.app.ActivityManager.StackId; 60 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 61 import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 62 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; 63 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT; 64 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME; 65 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; 66 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE; 67 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 68 import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; 69 import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; 70 import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; 71 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; 72 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 73 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 74 import static android.view.WindowManager.LayoutParams.FLAG_SCALED; 75 import static android.view.WindowManager.LayoutParams.FLAG_SECURE; 76 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 77 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; 78 import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; 79 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; 80 import static android.view.WindowManager.LayoutParams.MATCH_PARENT; 81 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; 82 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; 83 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; 84 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH; 85 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 86 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; 87 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; 88 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 89 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 90 import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION; 91 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; 92 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 93 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 94 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 95 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 96 import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER; 97 import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM; 98 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; 99 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; 100 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; 101 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION; 102 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; 103 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT; 104 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; 105 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER; 106 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE; 107 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; 108 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 109 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 110 111 class WindowList extends ArrayList<WindowState> { WindowList()112 WindowList() {} WindowList(WindowList windowList)113 WindowList(WindowList windowList) { 114 super(windowList); 115 } 116 } 117 118 /** 119 * A window in the window manager. 120 */ 121 final class WindowState implements WindowManagerPolicy.WindowState { 122 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowState" : TAG_WM; 123 124 // The minimal size of a window within the usable area of the freeform stack. 125 // TODO(multi-window): fix the min sizes when we have mininum width/height support, 126 // use hard-coded min sizes for now. 127 static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48; 128 static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32; 129 130 // The thickness of a window resize handle outside the window bounds on the free form workspace 131 // to capture touch events in that area. 132 static final int RESIZE_HANDLE_WIDTH_IN_DP = 30; 133 134 static final boolean DEBUG_DISABLE_SAVING_SURFACES = false; 135 136 final WindowManagerService mService; 137 final WindowManagerPolicy mPolicy; 138 final Context mContext; 139 final Session mSession; 140 final IWindow mClient; 141 final int mAppOp; 142 // UserId and appId of the owner. Don't display windows of non-current user. 143 final int mOwnerUid; 144 final IWindowId mWindowId; 145 WindowToken mToken; 146 WindowToken mRootToken; 147 AppWindowToken mAppToken; 148 AppWindowToken mTargetAppToken; 149 150 // mAttrs.flags is tested in animation without being locked. If the bits tested are ever 151 // modified they will need to be locked. 152 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams(); 153 final DeathRecipient mDeathRecipient; 154 final WindowState mAttachedWindow; 155 final WindowList mChildWindows = new WindowList(); 156 final int mBaseLayer; 157 final int mSubLayer; 158 final boolean mLayoutAttached; 159 final boolean mIsImWindow; 160 final boolean mIsWallpaper; 161 final boolean mIsFloatingLayer; 162 int mSeq; 163 boolean mEnforceSizeCompat; 164 int mViewVisibility; 165 int mSystemUiVisibility; 166 boolean mPolicyVisibility = true; 167 boolean mPolicyVisibilityAfterAnim = true; 168 boolean mAppOpVisibility = true; 169 boolean mPermanentlyHidden; // the window should never be shown again 170 boolean mAppFreezing; 171 boolean mAttachedHidden; // is our parent window hidden? 172 boolean mWallpaperVisible; // for wallpaper, what was last vis report? 173 boolean mDragResizing; 174 boolean mDragResizingChangeReported; 175 int mResizeMode; 176 177 RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks; 178 179 /** 180 * The window size that was requested by the application. These are in 181 * the application's coordinate space (without compatibility scale applied). 182 */ 183 int mRequestedWidth; 184 int mRequestedHeight; 185 int mLastRequestedWidth; 186 int mLastRequestedHeight; 187 188 int mLayer; 189 boolean mHaveFrame; 190 boolean mObscured; 191 boolean mTurnOnScreen; 192 193 int mLayoutSeq = -1; 194 195 private final Configuration mTmpConfig = new Configuration(); 196 // Represents the changes from our override configuration applied 197 // to the global configuration. This is the only form of configuration 198 // which is suitable for delivery to the client. 199 private Configuration mMergedConfiguration = new Configuration(); 200 // Sticky answer to isConfigChanged(), remains true until new Configuration is assigned. 201 // Used only on {@link #TYPE_KEYGUARD}. 202 private boolean mConfigHasChanged; 203 204 /** 205 * Actual position of the surface shown on-screen (may be modified by animation). These are 206 * in the screen's coordinate space (WITH the compatibility scale applied). 207 */ 208 final Point mShownPosition = new Point(); 209 210 /** 211 * Insets that determine the actually visible area. These are in the application's 212 * coordinate space (without compatibility scale applied). 213 */ 214 final Rect mVisibleInsets = new Rect(); 215 final Rect mLastVisibleInsets = new Rect(); 216 boolean mVisibleInsetsChanged; 217 218 /** 219 * Insets that are covered by system windows (such as the status bar) and 220 * transient docking windows (such as the IME). These are in the application's 221 * coordinate space (without compatibility scale applied). 222 */ 223 final Rect mContentInsets = new Rect(); 224 final Rect mLastContentInsets = new Rect(); 225 boolean mContentInsetsChanged; 226 227 /** 228 * Insets that determine the area covered by the display overscan region. These are in the 229 * application's coordinate space (without compatibility scale applied). 230 */ 231 final Rect mOverscanInsets = new Rect(); 232 final Rect mLastOverscanInsets = new Rect(); 233 boolean mOverscanInsetsChanged; 234 235 /** 236 * Insets that determine the area covered by the stable system windows. These are in the 237 * application's coordinate space (without compatibility scale applied). 238 */ 239 final Rect mStableInsets = new Rect(); 240 final Rect mLastStableInsets = new Rect(); 241 boolean mStableInsetsChanged; 242 243 /** 244 * Outsets determine the area outside of the surface where we want to pretend that it's possible 245 * to draw anyway. 246 */ 247 final Rect mOutsets = new Rect(); 248 final Rect mLastOutsets = new Rect(); 249 boolean mOutsetsChanged = false; 250 251 /** 252 * Set to true if we are waiting for this window to receive its 253 * given internal insets before laying out other windows based on it. 254 */ 255 boolean mGivenInsetsPending; 256 257 /** 258 * These are the content insets that were given during layout for 259 * this window, to be applied to windows behind it. 260 */ 261 final Rect mGivenContentInsets = new Rect(); 262 263 /** 264 * These are the visible insets that were given during layout for 265 * this window, to be applied to windows behind it. 266 */ 267 final Rect mGivenVisibleInsets = new Rect(); 268 269 /** 270 * This is the given touchable area relative to the window frame, or null if none. 271 */ 272 final Region mGivenTouchableRegion = new Region(); 273 274 /** 275 * Flag indicating whether the touchable region should be adjusted by 276 * the visible insets; if false the area outside the visible insets is 277 * NOT touchable, so we must use those to adjust the frame during hit 278 * tests. 279 */ 280 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME; 281 282 // Current transformation being applied. 283 float mGlobalScale=1; 284 float mInvGlobalScale=1; 285 float mHScale=1, mVScale=1; 286 float mLastHScale=1, mLastVScale=1; 287 final Matrix mTmpMatrix = new Matrix(); 288 289 // "Real" frame that the application sees, in display coordinate space. 290 final Rect mFrame = new Rect(); 291 final Rect mLastFrame = new Rect(); 292 boolean mFrameSizeChanged = false; 293 // Frame that is scaled to the application's coordinate space when in 294 // screen size compatibility mode. 295 final Rect mCompatFrame = new Rect(); 296 297 final Rect mContainingFrame = new Rect(); 298 299 final Rect mParentFrame = new Rect(); 300 301 // The entire screen area of the {@link TaskStack} this window is in. Usually equal to the 302 // screen area of the device. 303 final Rect mDisplayFrame = new Rect(); 304 305 // The region of the display frame that the display type supports displaying content on. This 306 // is mostly a special case for TV where some displays don’t have the entire display usable. 307 // {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_OVERSCAN} flag can be used to allow 308 // window display contents to extend into the overscan region. 309 final Rect mOverscanFrame = new Rect(); 310 311 // The display frame minus the stable insets. This value is always constant regardless of if 312 // the status bar or navigation bar is visible. 313 final Rect mStableFrame = new Rect(); 314 315 // The area not occupied by the status and navigation bars. So, if both status and navigation 316 // bars are visible, the decor frame is equal to the stable frame. 317 final Rect mDecorFrame = new Rect(); 318 319 // Equal to the decor frame if the IME (e.g. keyboard) is not present. Equal to the decor frame 320 // minus the area occupied by the IME if the IME is present. 321 final Rect mContentFrame = new Rect(); 322 323 // Legacy stuff. Generally equal to the content frame expect when the IME for older apps 324 // displays hint text. 325 final Rect mVisibleFrame = new Rect(); 326 327 // Frame that includes dead area outside of the surface but where we want to pretend that it's 328 // possible to draw. 329 final Rect mOutsetFrame = new Rect(); 330 331 /** 332 * Usually empty. Set to the task's tempInsetFrame. See 333 *{@link android.app.IActivityManager#resizeDockedStack}. 334 */ 335 final Rect mInsetFrame = new Rect(); 336 337 private static final Rect sTmpRect = new Rect(); 338 339 boolean mContentChanged; 340 341 // If a window showing a wallpaper: the requested offset for the 342 // wallpaper; if a wallpaper window: the currently applied offset. 343 float mWallpaperX = -1; 344 float mWallpaperY = -1; 345 346 // If a window showing a wallpaper: what fraction of the offset 347 // range corresponds to a full virtual screen. 348 float mWallpaperXStep = -1; 349 float mWallpaperYStep = -1; 350 351 // If a window showing a wallpaper: a raw pixel offset to forcibly apply 352 // to its window; if a wallpaper window: not used. 353 int mWallpaperDisplayOffsetX = Integer.MIN_VALUE; 354 int mWallpaperDisplayOffsetY = Integer.MIN_VALUE; 355 356 // Wallpaper windows: pixels offset based on above variables. 357 int mXOffset; 358 int mYOffset; 359 360 /** 361 * This is set after IWindowSession.relayout() has been called at 362 * least once for the window. It allows us to detect the situation 363 * where we don't yet have a surface, but should have one soon, so 364 * we can give the window focus before waiting for the relayout. 365 */ 366 boolean mRelayoutCalled; 367 368 boolean mInRelayout; 369 370 /** 371 * If the application has called relayout() with changes that can 372 * impact its window's size, we need to perform a layout pass on it 373 * even if it is not currently visible for layout. This is set 374 * when in that case until the layout is done. 375 */ 376 boolean mLayoutNeeded; 377 378 /** Currently running an exit animation? */ 379 boolean mAnimatingExit; 380 381 /** Currently on the mDestroySurface list? */ 382 boolean mDestroying; 383 384 /** Completely remove from window manager after exit animation? */ 385 boolean mRemoveOnExit; 386 387 /** 388 * Whether the app died while it was visible, if true we might need 389 * to continue to show it until it's restarted. 390 */ 391 boolean mAppDied; 392 393 /** 394 * Set when the orientation is changing and this window has not yet 395 * been updated for the new orientation. 396 */ 397 boolean mOrientationChanging; 398 399 /** 400 * The orientation during the last visible call to relayout. If our 401 * current orientation is different, the window can't be ready 402 * to be shown. 403 */ 404 int mLastVisibleLayoutRotation = -1; 405 406 /** 407 * How long we last kept the screen frozen. 408 */ 409 int mLastFreezeDuration; 410 411 /** Is this window now (or just being) removed? */ 412 boolean mRemoved; 413 414 /** 415 * It is save to remove the window and destroy the surface because the client requested removal 416 * or some other higher level component said so (e.g. activity manager). 417 * TODO: We should either have different booleans for the removal reason or use a bit-field. 418 */ 419 boolean mWindowRemovalAllowed; 420 421 /** 422 * Temp for keeping track of windows that have been removed when 423 * rebuilding window list. 424 */ 425 boolean mRebuilding; 426 427 // Input channel and input window handle used by the input dispatcher. 428 final InputWindowHandle mInputWindowHandle; 429 InputChannel mInputChannel; 430 InputChannel mClientChannel; 431 432 // Used to improve performance of toString() 433 String mStringNameCache; 434 CharSequence mLastTitle; 435 boolean mWasExiting; 436 437 final WindowStateAnimator mWinAnimator; 438 439 boolean mHasSurface = false; 440 441 boolean mNotOnAppsDisplay = false; 442 DisplayContent mDisplayContent; 443 444 /** When true this window can be displayed on screens owther than mOwnerUid's */ 445 private boolean mShowToOwnerOnly; 446 447 // Whether the window has a saved surface from last pause, which can be 448 // used to start an entering animation earlier. 449 private boolean mSurfaceSaved = false; 450 451 // Whether we're performing an entering animation with a saved surface. This flag is 452 // true during the time we're showing a window with a previously saved surface. It's 453 // cleared when surface is destroyed, saved, or re-drawn by the app. 454 private boolean mAnimatingWithSavedSurface; 455 456 // Whether the window was visible when we set the app to invisible last time. WM uses 457 // this as a hint to restore the surface (if available) for early animation next time 458 // the app is brought visible. 459 boolean mWasVisibleBeforeClientHidden; 460 461 // This window will be replaced due to relaunch. This allows window manager 462 // to differentiate between simple removal of a window and replacement. In the latter case it 463 // will preserve the old window until the new one is drawn. 464 boolean mWillReplaceWindow = false; 465 // If true, the replaced window was already requested to be removed. 466 boolean mReplacingRemoveRequested = false; 467 // Whether the replacement of the window should trigger app transition animation. 468 boolean mAnimateReplacingWindow = false; 469 // If not null, the window that will be used to replace the old one. This is being set when 470 // the window is added and unset when this window reports its first draw. 471 WindowState mReplacingWindow = null; 472 // For the new window in the replacement transition, if we have 473 // requested to replace without animation, then we should 474 // make sure we also don't apply an enter animation for 475 // the new window. 476 boolean mSkipEnterAnimationForSeamlessReplacement = false; 477 // Whether this window is being moved via the resize API 478 boolean mMovedByResize; 479 480 /** 481 * Wake lock for drawing. 482 * Even though it's slightly more expensive to do so, we will use a separate wake lock 483 * for each app that is requesting to draw while dozing so that we can accurately track 484 * who is preventing the system from suspending. 485 * This lock is only acquired on first use. 486 */ 487 PowerManager.WakeLock mDrawLock; 488 489 final private Rect mTmpRect = new Rect(); 490 491 /** 492 * See {@link #notifyMovedInStack}. 493 */ 494 private boolean mJustMovedInStack; 495 496 /** 497 * Whether the window was resized by us while it was gone for layout. 498 */ 499 boolean mResizedWhileGone = false; 500 501 /** @see #isResizedWhileNotDragResizing(). */ 502 private boolean mResizedWhileNotDragResizing; 503 504 /** @see #isResizedWhileNotDragResizingReported(). */ 505 private boolean mResizedWhileNotDragResizingReported; 506 507 /** 508 * During seamless rotation we have two phases, first the old window contents 509 * are rotated to look as if they didn't move in the new coordinate system. Then we 510 * have to freeze updates to this layer (to preserve the transformation) until 511 * the resize actually occurs. This is true from when the transformation is set 512 * and false until the transaction to resize is sent. 513 */ 514 boolean mSeamlesslyRotated = false; 515 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, final DisplayContent displayContent)516 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, 517 WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a, 518 int viewVisibility, final DisplayContent displayContent) { 519 mService = service; 520 mSession = s; 521 mClient = c; 522 mAppOp = appOp; 523 mToken = token; 524 mOwnerUid = s.mUid; 525 mWindowId = new IWindowId.Stub() { 526 @Override 527 public void registerFocusObserver(IWindowFocusObserver observer) { 528 WindowState.this.registerFocusObserver(observer); 529 } 530 @Override 531 public void unregisterFocusObserver(IWindowFocusObserver observer) { 532 WindowState.this.unregisterFocusObserver(observer); 533 } 534 @Override 535 public boolean isFocused() { 536 return WindowState.this.isFocused(); 537 } 538 }; 539 mAttrs.copyFrom(a); 540 mViewVisibility = viewVisibility; 541 mDisplayContent = displayContent; 542 mPolicy = mService.mPolicy; 543 mContext = mService.mContext; 544 DeathRecipient deathRecipient = new DeathRecipient(); 545 mSeq = seq; 546 mEnforceSizeCompat = (mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0; 547 if (WindowManagerService.localLOGV) Slog.v( 548 TAG, "Window " + this + " client=" + c.asBinder() 549 + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a); 550 try { 551 c.asBinder().linkToDeath(deathRecipient, 0); 552 } catch (RemoteException e) { 553 mDeathRecipient = null; 554 mAttachedWindow = null; 555 mLayoutAttached = false; 556 mIsImWindow = false; 557 mIsWallpaper = false; 558 mIsFloatingLayer = false; 559 mBaseLayer = 0; 560 mSubLayer = 0; 561 mInputWindowHandle = null; 562 mWinAnimator = null; 563 return; 564 } 565 mDeathRecipient = deathRecipient; 566 567 if ((mAttrs.type >= FIRST_SUB_WINDOW && 568 mAttrs.type <= LAST_SUB_WINDOW)) { 569 // The multiplier here is to reserve space for multiple 570 // windows in the same type layer. 571 mBaseLayer = mPolicy.windowTypeToLayerLw( 572 attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER 573 + WindowManagerService.TYPE_LAYER_OFFSET; 574 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type); 575 mAttachedWindow = attachedWindow; 576 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow); 577 578 final WindowList childWindows = mAttachedWindow.mChildWindows; 579 final int numChildWindows = childWindows.size(); 580 if (numChildWindows == 0) { 581 childWindows.add(this); 582 } else { 583 boolean added = false; 584 for (int i = 0; i < numChildWindows; i++) { 585 final int childSubLayer = childWindows.get(i).mSubLayer; 586 if (mSubLayer < childSubLayer 587 || (mSubLayer == childSubLayer && childSubLayer < 0)) { 588 // We insert the child window into the list ordered by the sub-layer. For 589 // same sub-layers, the negative one should go below others; the positive 590 // one should go above others. 591 childWindows.add(i, this); 592 added = true; 593 break; 594 } 595 } 596 if (!added) { 597 childWindows.add(this); 598 } 599 } 600 601 mLayoutAttached = mAttrs.type != 602 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 603 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD 604 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 605 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER; 606 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 607 } else { 608 // The multiplier here is to reserve space for multiple 609 // windows in the same type layer. 610 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type) 611 * WindowManagerService.TYPE_LAYER_MULTIPLIER 612 + WindowManagerService.TYPE_LAYER_OFFSET; 613 mSubLayer = 0; 614 mAttachedWindow = null; 615 mLayoutAttached = false; 616 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD 617 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 618 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER; 619 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 620 } 621 622 WindowState appWin = this; 623 while (appWin.isChildWindow()) { 624 appWin = appWin.mAttachedWindow; 625 } 626 WindowToken appToken = appWin.mToken; 627 while (appToken.appWindowToken == null) { 628 WindowToken parent = mService.mTokenMap.get(appToken.token); 629 if (parent == null || appToken == parent) { 630 break; 631 } 632 appToken = parent; 633 } 634 mRootToken = appToken; 635 mAppToken = appToken.appWindowToken; 636 if (mAppToken != null) { 637 final DisplayContent appDisplay = getDisplayContent(); 638 mNotOnAppsDisplay = displayContent != appDisplay; 639 640 if (mAppToken.showForAllUsers) { 641 // Windows for apps that can show for all users should also show when the 642 // device is locked. 643 mAttrs.flags |= FLAG_SHOW_WHEN_LOCKED; 644 } 645 } 646 647 mWinAnimator = new WindowStateAnimator(this); 648 mWinAnimator.mAlpha = a.alpha; 649 650 mRequestedWidth = 0; 651 mRequestedHeight = 0; 652 mLastRequestedWidth = 0; 653 mLastRequestedHeight = 0; 654 mXOffset = 0; 655 mYOffset = 0; 656 mLayer = 0; 657 mInputWindowHandle = new InputWindowHandle( 658 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this, 659 displayContent.getDisplayId()); 660 } 661 attach()662 void attach() { 663 if (WindowManagerService.localLOGV) Slog.v( 664 TAG, "Attaching " + this + " token=" + mToken 665 + ", list=" + mToken.windows); 666 mSession.windowAddedLocked(); 667 } 668 669 @Override getOwningUid()670 public int getOwningUid() { 671 return mOwnerUid; 672 } 673 674 @Override getOwningPackage()675 public String getOwningPackage() { 676 return mAttrs.packageName; 677 } 678 679 /** 680 * Subtracts the insets calculated by intersecting {@param layoutFrame} with {@param insetFrame} 681 * from {@param frame}. In other words, it applies the insets that would result if 682 * {@param frame} would be shifted to {@param layoutFrame} and then applying the insets from 683 * {@param insetFrame}. Also it respects {@param displayFrame} in case window has minimum 684 * width/height applied and insets should be overridden. 685 */ subtractInsets(Rect frame, Rect layoutFrame, Rect insetFrame, Rect displayFrame)686 private void subtractInsets(Rect frame, Rect layoutFrame, Rect insetFrame, Rect displayFrame) { 687 final int left = Math.max(0, insetFrame.left - Math.max(layoutFrame.left, displayFrame.left)); 688 final int top = Math.max(0, insetFrame.top - Math.max(layoutFrame.top, displayFrame.top)); 689 final int right = Math.max(0, Math.min(layoutFrame.right, displayFrame.right) - insetFrame.right); 690 final int bottom = Math.max(0, Math.min(layoutFrame.bottom, displayFrame.bottom) - insetFrame.bottom); 691 frame.inset(left, top, right, bottom); 692 } 693 694 @Override computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf, Rect osf)695 public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf, 696 Rect osf) { 697 if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) { 698 // This window is being replaced and either already got information that it's being 699 // removed or we are still waiting for some information. Because of this we don't 700 // want to apply any more changes to it, so it remains in this state until new window 701 // appears. 702 return; 703 } 704 mHaveFrame = true; 705 706 final Task task = getTask(); 707 final boolean fullscreenTask = !isInMultiWindowMode(); 708 final boolean windowsAreFloating = task != null && task.isFloating(); 709 710 // If the task has temp inset bounds set, we have to make sure all its windows uses 711 // the temp inset frame. Otherwise different display frames get applied to the main 712 // window and the child window, making them misaligned. 713 if (fullscreenTask) { 714 mInsetFrame.setEmpty(); 715 } else { 716 task.getTempInsetBounds(mInsetFrame); 717 } 718 719 // Denotes the actual frame used to calculate the insets and to perform the layout. When 720 // resizing in docked mode, we'd like to freeze the layout, so we also need to freeze the 721 // insets temporarily. By the notion of a task having a different layout frame, we can 722 // achieve that while still moving the task around. 723 final Rect layoutContainingFrame; 724 final Rect layoutDisplayFrame; 725 726 // The offset from the layout containing frame to the actual containing frame. 727 final int layoutXDiff; 728 final int layoutYDiff; 729 if (fullscreenTask || layoutInParentFrame()) { 730 // We use the parent frame as the containing frame for fullscreen and child windows 731 mContainingFrame.set(pf); 732 mDisplayFrame.set(df); 733 layoutDisplayFrame = df; 734 layoutContainingFrame = pf; 735 layoutXDiff = 0; 736 layoutYDiff = 0; 737 } else { 738 task.getBounds(mContainingFrame); 739 if (mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) { 740 741 // If the bounds are frozen, we still want to translate the window freely and only 742 // freeze the size. 743 Rect frozen = mAppToken.mFrozenBounds.peek(); 744 mContainingFrame.right = mContainingFrame.left + frozen.width(); 745 mContainingFrame.bottom = mContainingFrame.top + frozen.height(); 746 } 747 final WindowState imeWin = mService.mInputMethodWindow; 748 // IME is up and obscuring this window. Adjust the window position so it is visible. 749 if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this) { 750 if (windowsAreFloating && mContainingFrame.bottom > cf.bottom) { 751 // In freeform we want to move the top up directly. 752 // TODO: Investigate why this is cf not pf. 753 mContainingFrame.top -= mContainingFrame.bottom - cf.bottom; 754 } else if (mContainingFrame.bottom > pf.bottom) { 755 // But in docked we want to behave like fullscreen 756 // and behave as if the task were given smaller bounds 757 // for the purposes of layout. 758 mContainingFrame.bottom = pf.bottom; 759 } 760 } 761 762 if (windowsAreFloating) { 763 // In floating modes (e.g. freeform, pinned) we have only to set the rectangle 764 // if it wasn't set already. No need to intersect it with the (visible) 765 // "content frame" since it is allowed to be outside the visible desktop. 766 if (mContainingFrame.isEmpty()) { 767 mContainingFrame.set(cf); 768 } 769 } 770 mDisplayFrame.set(mContainingFrame); 771 layoutXDiff = !mInsetFrame.isEmpty() ? mInsetFrame.left - mContainingFrame.left : 0; 772 layoutYDiff = !mInsetFrame.isEmpty() ? mInsetFrame.top - mContainingFrame.top : 0; 773 layoutContainingFrame = !mInsetFrame.isEmpty() ? mInsetFrame : mContainingFrame; 774 mTmpRect.set(0, 0, mDisplayContent.getDisplayInfo().logicalWidth, 775 mDisplayContent.getDisplayInfo().logicalHeight); 776 subtractInsets(mDisplayFrame, layoutContainingFrame, df, mTmpRect); 777 if (!layoutInParentFrame()) { 778 subtractInsets(mContainingFrame, layoutContainingFrame, pf, mTmpRect); 779 subtractInsets(mInsetFrame, layoutContainingFrame, pf, mTmpRect); 780 } 781 layoutDisplayFrame = df; 782 layoutDisplayFrame.intersect(layoutContainingFrame); 783 } 784 785 final int pw = mContainingFrame.width(); 786 final int ph = mContainingFrame.height(); 787 788 if (!mParentFrame.equals(pf)) { 789 //Slog.i(TAG_WM, "Window " + this + " content frame from " + mParentFrame 790 // + " to " + pf); 791 mParentFrame.set(pf); 792 mContentChanged = true; 793 } 794 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { 795 mLastRequestedWidth = mRequestedWidth; 796 mLastRequestedHeight = mRequestedHeight; 797 mContentChanged = true; 798 } 799 800 mOverscanFrame.set(of); 801 mContentFrame.set(cf); 802 mVisibleFrame.set(vf); 803 mDecorFrame.set(dcf); 804 mStableFrame.set(sf); 805 final boolean hasOutsets = osf != null; 806 if (hasOutsets) { 807 mOutsetFrame.set(osf); 808 } 809 810 final int fw = mFrame.width(); 811 final int fh = mFrame.height(); 812 813 applyGravityAndUpdateFrame(layoutContainingFrame, layoutDisplayFrame); 814 815 // Calculate the outsets before the content frame gets shrinked to the window frame. 816 if (hasOutsets) { 817 mOutsets.set(Math.max(mContentFrame.left - mOutsetFrame.left, 0), 818 Math.max(mContentFrame.top - mOutsetFrame.top, 0), 819 Math.max(mOutsetFrame.right - mContentFrame.right, 0), 820 Math.max(mOutsetFrame.bottom - mContentFrame.bottom, 0)); 821 } else { 822 mOutsets.set(0, 0, 0, 0); 823 } 824 825 // Make sure the content and visible frames are inside of the 826 // final window frame. 827 if (windowsAreFloating && !mFrame.isEmpty()) { 828 // Keep the frame out of the blocked system area, limit it in size to the content area 829 // and make sure that there is always a minimum visible so that the user can drag it 830 // into a usable area.. 831 final int height = Math.min(mFrame.height(), mContentFrame.height()); 832 final int width = Math.min(mContentFrame.width(), mFrame.width()); 833 final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); 834 final int minVisibleHeight = Math.min(height, WindowManagerService.dipToPixel( 835 MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics)); 836 final int minVisibleWidth = Math.min(width, WindowManagerService.dipToPixel( 837 MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics)); 838 final int top = Math.max(mContentFrame.top, 839 Math.min(mFrame.top, mContentFrame.bottom - minVisibleHeight)); 840 final int left = Math.max(mContentFrame.left + minVisibleWidth - width, 841 Math.min(mFrame.left, mContentFrame.right - minVisibleWidth)); 842 mFrame.set(left, top, left + width, top + height); 843 mContentFrame.set(mFrame); 844 mVisibleFrame.set(mContentFrame); 845 mStableFrame.set(mContentFrame); 846 } else if (mAttrs.type == TYPE_DOCK_DIVIDER) { 847 mDisplayContent.getDockedDividerController().positionDockedStackedDivider(mFrame); 848 mContentFrame.set(mFrame); 849 if (!mFrame.equals(mLastFrame)) { 850 mMovedByResize = true; 851 } 852 } else { 853 mContentFrame.set(Math.max(mContentFrame.left, mFrame.left), 854 Math.max(mContentFrame.top, mFrame.top), 855 Math.min(mContentFrame.right, mFrame.right), 856 Math.min(mContentFrame.bottom, mFrame.bottom)); 857 858 mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left), 859 Math.max(mVisibleFrame.top, mFrame.top), 860 Math.min(mVisibleFrame.right, mFrame.right), 861 Math.min(mVisibleFrame.bottom, mFrame.bottom)); 862 863 mStableFrame.set(Math.max(mStableFrame.left, mFrame.left), 864 Math.max(mStableFrame.top, mFrame.top), 865 Math.min(mStableFrame.right, mFrame.right), 866 Math.min(mStableFrame.bottom, mFrame.bottom)); 867 } 868 869 if (fullscreenTask && !windowsAreFloating) { 870 // Windows that are not fullscreen can be positioned outside of the display frame, 871 // but that is not a reason to provide them with overscan insets. 872 mOverscanInsets.set(Math.max(mOverscanFrame.left - layoutContainingFrame.left, 0), 873 Math.max(mOverscanFrame.top - layoutContainingFrame.top, 0), 874 Math.max(layoutContainingFrame.right - mOverscanFrame.right, 0), 875 Math.max(layoutContainingFrame.bottom - mOverscanFrame.bottom, 0)); 876 } 877 878 if (mAttrs.type == TYPE_DOCK_DIVIDER) { 879 // For the docked divider, we calculate the stable insets like a full-screen window 880 // so it can use it to calculate the snap positions. 881 mStableInsets.set(Math.max(mStableFrame.left - mDisplayFrame.left, 0), 882 Math.max(mStableFrame.top - mDisplayFrame.top, 0), 883 Math.max(mDisplayFrame.right - mStableFrame.right, 0), 884 Math.max(mDisplayFrame.bottom - mStableFrame.bottom, 0)); 885 886 // The divider doesn't care about insets in any case, so set it to empty so we don't 887 // trigger a relayout when moving it. 888 mContentInsets.setEmpty(); 889 mVisibleInsets.setEmpty(); 890 } else { 891 getDisplayContent().getLogicalDisplayRect(mTmpRect); 892 // Override right and/or bottom insets in case if the frame doesn't fit the screen in 893 // non-fullscreen mode. 894 boolean overrideRightInset = !fullscreenTask && mFrame.right > mTmpRect.right; 895 boolean overrideBottomInset = !fullscreenTask && mFrame.bottom > mTmpRect.bottom; 896 mContentInsets.set(mContentFrame.left - mFrame.left, 897 mContentFrame.top - mFrame.top, 898 overrideRightInset ? mTmpRect.right - mContentFrame.right 899 : mFrame.right - mContentFrame.right, 900 overrideBottomInset ? mTmpRect.bottom - mContentFrame.bottom 901 : mFrame.bottom - mContentFrame.bottom); 902 903 mVisibleInsets.set(mVisibleFrame.left - mFrame.left, 904 mVisibleFrame.top - mFrame.top, 905 overrideRightInset ? mTmpRect.right - mVisibleFrame.right 906 : mFrame.right - mVisibleFrame.right, 907 overrideBottomInset ? mTmpRect.bottom - mVisibleFrame.bottom 908 : mFrame.bottom - mVisibleFrame.bottom); 909 910 mStableInsets.set(Math.max(mStableFrame.left - mFrame.left, 0), 911 Math.max(mStableFrame.top - mFrame.top, 0), 912 overrideRightInset ? Math.max(mTmpRect.right - mStableFrame.right, 0) 913 : Math.max(mFrame.right - mStableFrame.right, 0), 914 overrideBottomInset ? Math.max(mTmpRect.bottom - mStableFrame.bottom, 0) 915 : Math.max(mFrame.bottom - mStableFrame.bottom, 0)); 916 } 917 918 // Offset the actual frame by the amount layout frame is off. 919 mFrame.offset(-layoutXDiff, -layoutYDiff); 920 mCompatFrame.offset(-layoutXDiff, -layoutYDiff); 921 mContentFrame.offset(-layoutXDiff, -layoutYDiff); 922 mVisibleFrame.offset(-layoutXDiff, -layoutYDiff); 923 mStableFrame.offset(-layoutXDiff, -layoutYDiff); 924 925 mCompatFrame.set(mFrame); 926 if (mEnforceSizeCompat) { 927 // If there is a size compatibility scale being applied to the 928 // window, we need to apply this to its insets so that they are 929 // reported to the app in its coordinate space. 930 mOverscanInsets.scale(mInvGlobalScale); 931 mContentInsets.scale(mInvGlobalScale); 932 mVisibleInsets.scale(mInvGlobalScale); 933 mStableInsets.scale(mInvGlobalScale); 934 mOutsets.scale(mInvGlobalScale); 935 936 // Also the scaled frame that we report to the app needs to be 937 // adjusted to be in its coordinate space. 938 mCompatFrame.scale(mInvGlobalScale); 939 } 940 941 if (mIsWallpaper && (fw != mFrame.width() || fh != mFrame.height())) { 942 final DisplayContent displayContent = getDisplayContent(); 943 if (displayContent != null) { 944 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 945 mService.mWallpaperControllerLocked.updateWallpaperOffset( 946 this, displayInfo.logicalWidth, displayInfo.logicalHeight, false); 947 } 948 } 949 950 if (DEBUG_LAYOUT || WindowManagerService.localLOGV) Slog.v(TAG, 951 "Resolving (mRequestedWidth=" 952 + mRequestedWidth + ", mRequestedheight=" 953 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph 954 + "): frame=" + mFrame.toShortString() 955 + " ci=" + mContentInsets.toShortString() 956 + " vi=" + mVisibleInsets.toShortString() 957 + " si=" + mStableInsets.toShortString() 958 + " of=" + mOutsets.toShortString()); 959 } 960 961 @Override getFrameLw()962 public Rect getFrameLw() { 963 return mFrame; 964 } 965 966 @Override getShownPositionLw()967 public Point getShownPositionLw() { 968 return mShownPosition; 969 } 970 971 @Override getDisplayFrameLw()972 public Rect getDisplayFrameLw() { 973 return mDisplayFrame; 974 } 975 976 @Override getOverscanFrameLw()977 public Rect getOverscanFrameLw() { 978 return mOverscanFrame; 979 } 980 981 @Override getContentFrameLw()982 public Rect getContentFrameLw() { 983 return mContentFrame; 984 } 985 986 @Override getVisibleFrameLw()987 public Rect getVisibleFrameLw() { 988 return mVisibleFrame; 989 } 990 991 @Override getGivenInsetsPendingLw()992 public boolean getGivenInsetsPendingLw() { 993 return mGivenInsetsPending; 994 } 995 996 @Override getGivenContentInsetsLw()997 public Rect getGivenContentInsetsLw() { 998 return mGivenContentInsets; 999 } 1000 1001 @Override getGivenVisibleInsetsLw()1002 public Rect getGivenVisibleInsetsLw() { 1003 return mGivenVisibleInsets; 1004 } 1005 1006 @Override getAttrs()1007 public WindowManager.LayoutParams getAttrs() { 1008 return mAttrs; 1009 } 1010 1011 @Override getNeedsMenuLw(WindowManagerPolicy.WindowState bottom)1012 public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) { 1013 int index = -1; 1014 WindowState ws = this; 1015 WindowList windows = getWindowList(); 1016 while (true) { 1017 if (ws.mAttrs.needsMenuKey != WindowManager.LayoutParams.NEEDS_MENU_UNSET) { 1018 return ws.mAttrs.needsMenuKey == WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE; 1019 } 1020 // If we reached the bottom of the range of windows we are considering, 1021 // assume no menu is needed. 1022 if (ws == bottom) { 1023 return false; 1024 } 1025 // The current window hasn't specified whether menu key is needed; 1026 // look behind it. 1027 // First, we may need to determine the starting position. 1028 if (index < 0) { 1029 index = windows.indexOf(ws); 1030 } 1031 index--; 1032 if (index < 0) { 1033 return false; 1034 } 1035 ws = windows.get(index); 1036 } 1037 } 1038 1039 @Override getSystemUiVisibility()1040 public int getSystemUiVisibility() { 1041 return mSystemUiVisibility; 1042 } 1043 1044 @Override getSurfaceLayer()1045 public int getSurfaceLayer() { 1046 return mLayer; 1047 } 1048 1049 @Override getBaseType()1050 public int getBaseType() { 1051 WindowState win = this; 1052 while (win.isChildWindow()) { 1053 win = win.mAttachedWindow; 1054 } 1055 return win.mAttrs.type; 1056 } 1057 1058 @Override getAppToken()1059 public IApplicationToken getAppToken() { 1060 return mAppToken != null ? mAppToken.appToken : null; 1061 } 1062 1063 @Override isVoiceInteraction()1064 public boolean isVoiceInteraction() { 1065 return mAppToken != null && mAppToken.voiceInteraction; 1066 } 1067 setReportResizeHints()1068 boolean setReportResizeHints() { 1069 mOverscanInsetsChanged |= !mLastOverscanInsets.equals(mOverscanInsets); 1070 mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets); 1071 mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets); 1072 mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets); 1073 mOutsetsChanged |= !mLastOutsets.equals(mOutsets); 1074 mFrameSizeChanged |= (mLastFrame.width() != mFrame.width()) || 1075 (mLastFrame.height() != mFrame.height()); 1076 return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged 1077 || mOutsetsChanged || mFrameSizeChanged; 1078 } 1079 getDisplayContent()1080 public DisplayContent getDisplayContent() { 1081 if (mAppToken == null || mNotOnAppsDisplay) { 1082 return mDisplayContent; 1083 } 1084 final TaskStack stack = getStack(); 1085 return stack == null ? mDisplayContent : stack.getDisplayContent(); 1086 } 1087 getDisplayInfo()1088 public DisplayInfo getDisplayInfo() { 1089 final DisplayContent displayContent = getDisplayContent(); 1090 return displayContent != null ? displayContent.getDisplayInfo() : null; 1091 } 1092 getDisplayId()1093 public int getDisplayId() { 1094 final DisplayContent displayContent = getDisplayContent(); 1095 if (displayContent == null) { 1096 return -1; 1097 } 1098 return displayContent.getDisplayId(); 1099 } 1100 getTask()1101 Task getTask() { 1102 return mAppToken != null ? mAppToken.mTask : null; 1103 } 1104 getStack()1105 TaskStack getStack() { 1106 Task task = getTask(); 1107 if (task != null) { 1108 if (task.mStack != null) { 1109 return task.mStack; 1110 } 1111 } 1112 // Some system windows (e.g. "Power off" dialog) don't have a task, but we would still 1113 // associate them with some stack to enable dimming. 1114 return mAttrs.type >= WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW 1115 && mDisplayContent != null ? mDisplayContent.getHomeStack() : null; 1116 } 1117 1118 /** 1119 * Retrieves the visible bounds of the window. 1120 * @param bounds The rect which gets the bounds. 1121 */ getVisibleBounds(Rect bounds)1122 void getVisibleBounds(Rect bounds) { 1123 final Task task = getTask(); 1124 boolean intersectWithStackBounds = task != null && task.cropWindowsToStackBounds(); 1125 bounds.setEmpty(); 1126 mTmpRect.setEmpty(); 1127 if (intersectWithStackBounds) { 1128 final TaskStack stack = task.mStack; 1129 if (stack != null) { 1130 stack.getDimBounds(mTmpRect); 1131 } else { 1132 intersectWithStackBounds = false; 1133 } 1134 } 1135 1136 bounds.set(mVisibleFrame); 1137 if (intersectWithStackBounds) { 1138 bounds.intersect(mTmpRect); 1139 } 1140 1141 if (bounds.isEmpty()) { 1142 bounds.set(mFrame); 1143 if (intersectWithStackBounds) { 1144 bounds.intersect(mTmpRect); 1145 } 1146 return; 1147 } 1148 } 1149 getInputDispatchingTimeoutNanos()1150 public long getInputDispatchingTimeoutNanos() { 1151 return mAppToken != null 1152 ? mAppToken.inputDispatchingTimeoutNanos 1153 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 1154 } 1155 1156 @Override hasAppShownWindows()1157 public boolean hasAppShownWindows() { 1158 return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed); 1159 } 1160 isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy)1161 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 1162 if (dsdx < .99999f || dsdx > 1.00001f) return false; 1163 if (dtdy < .99999f || dtdy > 1.00001f) return false; 1164 if (dtdx < -.000001f || dtdx > .000001f) return false; 1165 if (dsdy < -.000001f || dsdy > .000001f) return false; 1166 return true; 1167 } 1168 prelayout()1169 void prelayout() { 1170 if (mEnforceSizeCompat) { 1171 mGlobalScale = mService.mCompatibleScreenScale; 1172 mInvGlobalScale = 1/mGlobalScale; 1173 } else { 1174 mGlobalScale = mInvGlobalScale = 1; 1175 } 1176 } 1177 1178 /** 1179 * Does the minimal check for visibility. Callers generally want to use one of the public 1180 * methods as they perform additional checks on the app token. 1181 * TODO: See if there are other places we can use this check below instead of duplicating... 1182 */ isVisibleUnchecked()1183 private boolean isVisibleUnchecked() { 1184 return mHasSurface && mPolicyVisibility && !mAttachedHidden 1185 && !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible); 1186 } 1187 1188 /** 1189 * Is this window visible? It is not visible if there is no surface, or we are in the process 1190 * of running an exit animation that will remove the surface, or its app token has been hidden. 1191 */ 1192 @Override isVisibleLw()1193 public boolean isVisibleLw() { 1194 return (mAppToken == null || !mAppToken.hiddenRequested) && isVisibleUnchecked(); 1195 } 1196 1197 /** 1198 * Like {@link #isVisibleLw}, but also counts a window that is currently "hidden" behind the 1199 * keyguard as visible. This allows us to apply things like window flags that impact the 1200 * keyguard. XXX I am starting to think we need to have ANOTHER visibility flag for this 1201 * "hidden behind keyguard" state rather than overloading mPolicyVisibility. Ungh. 1202 */ 1203 @Override isVisibleOrBehindKeyguardLw()1204 public boolean isVisibleOrBehindKeyguardLw() { 1205 if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { 1206 return false; 1207 } 1208 final AppWindowToken atoken = mAppToken; 1209 final boolean animating = atoken != null && atoken.mAppAnimator.animation != null; 1210 return mHasSurface && !mDestroying && !mAnimatingExit 1211 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested) 1212 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden) 1213 || mWinAnimator.mAnimation != null || animating); 1214 } 1215 1216 /** 1217 * Is this window visible, ignoring its app token? It is not visible if there is no surface, 1218 * or we are in the process of running an exit animation that will remove the surface. 1219 */ isWinVisibleLw()1220 public boolean isWinVisibleLw() { 1221 return (mAppToken == null || !mAppToken.hiddenRequested || mAppToken.mAppAnimator.animating) 1222 && isVisibleUnchecked(); 1223 } 1224 1225 /** 1226 * The same as isVisible(), but follows the current hidden state of the associated app token, 1227 * not the pending requested hidden state. 1228 */ isVisibleNow()1229 boolean isVisibleNow() { 1230 return (!mRootToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING) 1231 && isVisibleUnchecked(); 1232 } 1233 1234 /** 1235 * Can this window possibly be a drag/drop target? The test here is 1236 * a combination of the above "visible now" with the check that the 1237 * Input Manager uses when discarding windows from input consideration. 1238 */ isPotentialDragTarget()1239 boolean isPotentialDragTarget() { 1240 return isVisibleNow() && !mRemoved 1241 && mInputChannel != null && mInputWindowHandle != null; 1242 } 1243 1244 /** 1245 * Same as isVisible(), but we also count it as visible between the 1246 * call to IWindowSession.add() and the first relayout(). 1247 */ isVisibleOrAdding()1248 boolean isVisibleOrAdding() { 1249 final AppWindowToken atoken = mAppToken; 1250 return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE)) 1251 && mPolicyVisibility && !mAttachedHidden 1252 && (atoken == null || !atoken.hiddenRequested) 1253 && !mAnimatingExit && !mDestroying; 1254 } 1255 1256 /** 1257 * Is this window currently on-screen? It is on-screen either if it 1258 * is visible or it is currently running an animation before no longer 1259 * being visible. 1260 */ isOnScreen()1261 boolean isOnScreen() { 1262 return mPolicyVisibility && isOnScreenIgnoringKeyguard(); 1263 } 1264 1265 /** 1266 * Like isOnScreen(), but ignores any force hiding of the window due 1267 * to the keyguard. 1268 */ isOnScreenIgnoringKeyguard()1269 boolean isOnScreenIgnoringKeyguard() { 1270 if (!mHasSurface || mDestroying) { 1271 return false; 1272 } 1273 final AppWindowToken atoken = mAppToken; 1274 if (atoken != null) { 1275 return ((!mAttachedHidden && !atoken.hiddenRequested) 1276 || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null); 1277 } 1278 return !mAttachedHidden || mWinAnimator.mAnimation != null; 1279 } 1280 1281 /** 1282 * Whether this window's drawn state might affect the drawn states of the app token. 1283 * 1284 * @param visibleOnly Whether we should consider only the windows that's currently 1285 * visible in layout. If true, windows that has not relayout to VISIBLE 1286 * would always return false. 1287 * 1288 * @return true if the window should be considered while evaluating allDrawn flags. 1289 */ mightAffectAllDrawn(boolean visibleOnly)1290 boolean mightAffectAllDrawn(boolean visibleOnly) { 1291 final boolean isViewVisible = (mAppToken == null || !mAppToken.clientHidden) 1292 && (mViewVisibility == View.VISIBLE) && !mWindowRemovalAllowed; 1293 return (isOnScreenIgnoringKeyguard() && (!visibleOnly || isViewVisible) 1294 || mWinAnimator.mAttrType == TYPE_BASE_APPLICATION 1295 || mWinAnimator.mAttrType == TYPE_DRAWN_APPLICATION) 1296 && !mAnimatingExit && !mDestroying; 1297 } 1298 1299 /** 1300 * Whether this window is "interesting" when evaluating allDrawn. If it's interesting, 1301 * it must be drawn before allDrawn can become true. 1302 */ isInteresting()1303 boolean isInteresting() { 1304 return mAppToken != null && !mAppDied 1305 && (!mAppToken.mAppAnimator.freezingScreen || !mAppFreezing); 1306 } 1307 1308 /** 1309 * Like isOnScreen(), but we don't return true if the window is part 1310 * of a transition that has not yet been started. 1311 */ isReadyForDisplay()1312 boolean isReadyForDisplay() { 1313 if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { 1314 return false; 1315 } 1316 return mHasSurface && mPolicyVisibility && !mDestroying 1317 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden) 1318 || mWinAnimator.mAnimation != null 1319 || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null))); 1320 } 1321 1322 /** 1323 * Like isReadyForDisplay(), but ignores any force hiding of the window due 1324 * to the keyguard. 1325 */ isReadyForDisplayIgnoringKeyguard()1326 boolean isReadyForDisplayIgnoringKeyguard() { 1327 if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { 1328 return false; 1329 } 1330 final AppWindowToken atoken = mAppToken; 1331 if (atoken == null && !mPolicyVisibility) { 1332 // If this is not an app window, and the policy has asked to force 1333 // hide, then we really do want to hide. 1334 return false; 1335 } 1336 return mHasSurface && !mDestroying 1337 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden) 1338 || mWinAnimator.mAnimation != null 1339 || ((atoken != null) && (atoken.mAppAnimator.animation != null) 1340 && !mWinAnimator.isDummyAnimation()) 1341 || isAnimatingWithSavedSurface()); 1342 } 1343 1344 /** 1345 * Like isOnScreen, but returns false if the surface hasn't yet 1346 * been drawn. 1347 */ 1348 @Override isDisplayedLw()1349 public boolean isDisplayedLw() { 1350 final AppWindowToken atoken = mAppToken; 1351 return isDrawnLw() && mPolicyVisibility 1352 && ((!mAttachedHidden && 1353 (atoken == null || !atoken.hiddenRequested)) 1354 || mWinAnimator.mAnimating 1355 || (atoken != null && atoken.mAppAnimator.animation != null)); 1356 } 1357 1358 /** 1359 * Return true if this window or its app token is currently animating. 1360 */ 1361 @Override isAnimatingLw()1362 public boolean isAnimatingLw() { 1363 return mWinAnimator.mAnimation != null 1364 || (mAppToken != null && mAppToken.mAppAnimator.animation != null); 1365 } 1366 1367 @Override isGoneForLayoutLw()1368 public boolean isGoneForLayoutLw() { 1369 final AppWindowToken atoken = mAppToken; 1370 return mViewVisibility == View.GONE 1371 || !mRelayoutCalled 1372 || (atoken == null && mRootToken.hidden) 1373 || (atoken != null && atoken.hiddenRequested) 1374 || mAttachedHidden 1375 || (mAnimatingExit && !isAnimatingLw()) 1376 || mDestroying; 1377 } 1378 1379 /** 1380 * Returns true if the window has a surface that it has drawn a 1381 * complete UI in to. 1382 */ isDrawFinishedLw()1383 public boolean isDrawFinishedLw() { 1384 return mHasSurface && !mDestroying && 1385 (mWinAnimator.mDrawState == WindowStateAnimator.COMMIT_DRAW_PENDING 1386 || mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW 1387 || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN); 1388 } 1389 1390 /** 1391 * Returns true if the window has a surface that it has drawn a 1392 * complete UI in to. 1393 */ 1394 @Override isDrawnLw()1395 public boolean isDrawnLw() { 1396 return mHasSurface && !mDestroying && 1397 (mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW 1398 || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN); 1399 } 1400 1401 /** 1402 * Return true if the window is opaque and fully drawn. This indicates 1403 * it may obscure windows behind it. 1404 */ isOpaqueDrawn()1405 boolean isOpaqueDrawn() { 1406 // When there is keyguard, wallpaper could be placed over the secure app 1407 // window but invisible. We need to check wallpaper visibility explicitly 1408 // to determine if it's occluding apps. 1409 return ((!mIsWallpaper && mAttrs.format == PixelFormat.OPAQUE) 1410 || (mIsWallpaper && mWallpaperVisible)) 1411 && isDrawnLw() && mWinAnimator.mAnimation == null 1412 && (mAppToken == null || mAppToken.mAppAnimator.animation == null); 1413 } 1414 1415 /** 1416 * Return whether this window has moved. (Only makes 1417 * sense to call from performLayoutAndPlaceSurfacesLockedInner().) 1418 */ hasMoved()1419 boolean hasMoved() { 1420 return mHasSurface && (mContentChanged || mMovedByResize) 1421 && !mAnimatingExit 1422 && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left) 1423 && (mAttachedWindow == null || !mAttachedWindow.hasMoved()); 1424 } 1425 isObscuringFullscreen(final DisplayInfo displayInfo)1426 boolean isObscuringFullscreen(final DisplayInfo displayInfo) { 1427 Task task = getTask(); 1428 if (task != null && task.mStack != null && !task.mStack.isFullscreen()) { 1429 return false; 1430 } 1431 if (!isOpaqueDrawn() || !isFrameFullscreen(displayInfo)) { 1432 return false; 1433 } 1434 return true; 1435 } 1436 isFrameFullscreen(final DisplayInfo displayInfo)1437 boolean isFrameFullscreen(final DisplayInfo displayInfo) { 1438 return mFrame.left <= 0 && mFrame.top <= 0 1439 && mFrame.right >= displayInfo.appWidth && mFrame.bottom >= displayInfo.appHeight; 1440 } 1441 isConfigChanged()1442 boolean isConfigChanged() { 1443 getMergedConfig(mTmpConfig); 1444 1445 // If the merged configuration is still empty, it means that we haven't issues the 1446 // configuration to the client yet and we need to return true so the configuration updates. 1447 boolean configChanged = mMergedConfiguration.equals(Configuration.EMPTY) 1448 || mTmpConfig.diff(mMergedConfiguration) != 0; 1449 1450 if ((mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 1451 // Retain configuration changed status until resetConfiguration called. 1452 mConfigHasChanged |= configChanged; 1453 configChanged = mConfigHasChanged; 1454 } 1455 1456 return configChanged; 1457 } 1458 isAdjustedForMinimizedDock()1459 boolean isAdjustedForMinimizedDock() { 1460 return mAppToken != null && mAppToken.mTask != null 1461 && mAppToken.mTask.mStack.isAdjustedForMinimizedDock(); 1462 } 1463 removeLocked()1464 void removeLocked() { 1465 disposeInputChannel(); 1466 1467 if (isChildWindow()) { 1468 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow); 1469 mAttachedWindow.mChildWindows.remove(this); 1470 } 1471 mWinAnimator.destroyDeferredSurfaceLocked(); 1472 mWinAnimator.destroySurfaceLocked(); 1473 mSession.windowRemovedLocked(); 1474 try { 1475 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0); 1476 } catch (RuntimeException e) { 1477 // Ignore if it has already been removed (usually because 1478 // we are doing this as part of processing a death note.) 1479 } 1480 } 1481 setHasSurface(boolean hasSurface)1482 void setHasSurface(boolean hasSurface) { 1483 mHasSurface = hasSurface; 1484 } 1485 getAnimLayerAdjustment()1486 int getAnimLayerAdjustment() { 1487 if (mTargetAppToken != null) { 1488 return mTargetAppToken.mAppAnimator.animLayerAdjustment; 1489 } else if (mAppToken != null) { 1490 return mAppToken.mAppAnimator.animLayerAdjustment; 1491 } else { 1492 // Nothing is animating, so there is no animation adjustment. 1493 return 0; 1494 } 1495 } 1496 scheduleAnimationIfDimming()1497 void scheduleAnimationIfDimming() { 1498 if (mDisplayContent == null) { 1499 return; 1500 } 1501 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser(); 1502 if (dimLayerUser != null && mDisplayContent.mDimLayerController.isDimming( 1503 dimLayerUser, mWinAnimator)) { 1504 // Force an animation pass just to update the mDimLayer layer. 1505 mService.scheduleAnimationLocked(); 1506 } 1507 } 1508 1509 /** 1510 * Notifies this window that the corresponding task has just moved in the stack. 1511 * <p> 1512 * This is used to fix the following: If we moved in the stack, and if the last clip rect was 1513 * empty, meaning that our task was completely offscreen, we need to keep it invisible because 1514 * the actual app transition that updates the visibility is delayed by a few transactions. 1515 * Instead of messing around with the ordering and timing how transitions and transactions are 1516 * executed, we introduce this little hack which prevents this window of getting visible again 1517 * with the wrong bounds until the app transitions has started. 1518 * <p> 1519 * This method notifies the window about that we just moved in the stack so we can apply this 1520 * logic in {@link WindowStateAnimator#updateSurfaceWindowCrop} 1521 */ notifyMovedInStack()1522 void notifyMovedInStack() { 1523 mJustMovedInStack = true; 1524 } 1525 1526 /** 1527 * See {@link #notifyMovedInStack}. 1528 * 1529 * @return Whether we just got moved in the corresponding stack. 1530 */ hasJustMovedInStack()1531 boolean hasJustMovedInStack() { 1532 return mJustMovedInStack; 1533 } 1534 1535 /** 1536 * Resets that we just moved in the corresponding stack. See {@link #notifyMovedInStack}. 1537 */ resetJustMovedInStack()1538 void resetJustMovedInStack() { 1539 mJustMovedInStack = false; 1540 } 1541 1542 private final class DeadWindowEventReceiver extends InputEventReceiver { DeadWindowEventReceiver(InputChannel inputChannel)1543 DeadWindowEventReceiver(InputChannel inputChannel) { 1544 super(inputChannel, mService.mH.getLooper()); 1545 } 1546 @Override onInputEvent(InputEvent event)1547 public void onInputEvent(InputEvent event) { 1548 finishInputEvent(event, true); 1549 } 1550 } 1551 /** 1552 * Dummy event receiver for windows that died visible. 1553 */ 1554 private DeadWindowEventReceiver mDeadWindowEventReceiver; 1555 openInputChannel(InputChannel outInputChannel)1556 void openInputChannel(InputChannel outInputChannel) { 1557 if (mInputChannel != null) { 1558 throw new IllegalStateException("Window already has an input channel."); 1559 } 1560 String name = makeInputChannelName(); 1561 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); 1562 mInputChannel = inputChannels[0]; 1563 mClientChannel = inputChannels[1]; 1564 mInputWindowHandle.inputChannel = inputChannels[0]; 1565 if (outInputChannel != null) { 1566 mClientChannel.transferTo(outInputChannel); 1567 mClientChannel.dispose(); 1568 mClientChannel = null; 1569 } else { 1570 // If the window died visible, we setup a dummy input channel, so that taps 1571 // can still detected by input monitor channel, and we can relaunch the app. 1572 // Create dummy event receiver that simply reports all events as handled. 1573 mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel); 1574 } 1575 mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle); 1576 } 1577 disposeInputChannel()1578 void disposeInputChannel() { 1579 if (mDeadWindowEventReceiver != null) { 1580 mDeadWindowEventReceiver.dispose(); 1581 mDeadWindowEventReceiver = null; 1582 } 1583 1584 // unregister server channel first otherwise it complains about broken channel 1585 if (mInputChannel != null) { 1586 mService.mInputManager.unregisterInputChannel(mInputChannel); 1587 mInputChannel.dispose(); 1588 mInputChannel = null; 1589 } 1590 if (mClientChannel != null) { 1591 mClientChannel.dispose(); 1592 mClientChannel = null; 1593 } 1594 mInputWindowHandle.inputChannel = null; 1595 } 1596 applyDimLayerIfNeeded()1597 void applyDimLayerIfNeeded() { 1598 // When the app is terminated (eg. from Recents), the task might have already been 1599 // removed with the window pending removal. Don't apply dim in such cases, as there 1600 // will be no more updateDimLayer() calls, which leaves the dimlayer invalid. 1601 final AppWindowToken token = mAppToken; 1602 if (token != null && token.removed) { 1603 return; 1604 } 1605 1606 if (!mAnimatingExit && mAppDied) { 1607 // If app died visible, apply a dim over the window to indicate that it's inactive 1608 mDisplayContent.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator); 1609 } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0 1610 && mDisplayContent != null && !mAnimatingExit && isVisibleUnchecked()) { 1611 mDisplayContent.mDimLayerController.applyDimBehind(getDimLayerUser(), mWinAnimator); 1612 } 1613 } 1614 getDimLayerUser()1615 DimLayer.DimLayerUser getDimLayerUser() { 1616 Task task = getTask(); 1617 if (task != null) { 1618 return task; 1619 } 1620 return getStack(); 1621 } 1622 maybeRemoveReplacedWindow()1623 void maybeRemoveReplacedWindow() { 1624 if (mAppToken == null) { 1625 return; 1626 } 1627 for (int i = mAppToken.allAppWindows.size() - 1; i >= 0; i--) { 1628 final WindowState win = mAppToken.allAppWindows.get(i); 1629 if (win.mWillReplaceWindow && win.mReplacingWindow == this && hasDrawnLw()) { 1630 if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replaced window: " + win); 1631 if (win.isDimming()) { 1632 win.transferDimToReplacement(); 1633 } 1634 win.mWillReplaceWindow = false; 1635 final boolean animateReplacingWindow = win.mAnimateReplacingWindow; 1636 win.mAnimateReplacingWindow = false; 1637 win.mReplacingRemoveRequested = false; 1638 win.mReplacingWindow = null; 1639 mSkipEnterAnimationForSeamlessReplacement = false; 1640 if (win.mAnimatingExit || !animateReplacingWindow) { 1641 mService.removeWindowInnerLocked(win); 1642 } 1643 } 1644 } 1645 } 1646 setDisplayLayoutNeeded()1647 void setDisplayLayoutNeeded() { 1648 if (mDisplayContent != null) { 1649 mDisplayContent.layoutNeeded = true; 1650 } 1651 } 1652 inDockedWorkspace()1653 boolean inDockedWorkspace() { 1654 final Task task = getTask(); 1655 return task != null && task.inDockedWorkspace(); 1656 } 1657 1658 // TODO: Strange usage of word workspace here and above. inPinnedWorkspace()1659 boolean inPinnedWorkspace() { 1660 final Task task = getTask(); 1661 return task != null && task.inPinnedWorkspace(); 1662 } 1663 isDockedInEffect()1664 boolean isDockedInEffect() { 1665 final Task task = getTask(); 1666 return task != null && task.isDockedInEffect(); 1667 } 1668 applyScrollIfNeeded()1669 void applyScrollIfNeeded() { 1670 final Task task = getTask(); 1671 if (task != null) { 1672 task.applyScrollToWindowIfNeeded(this); 1673 } 1674 } 1675 applyAdjustForImeIfNeeded()1676 void applyAdjustForImeIfNeeded() { 1677 final Task task = getTask(); 1678 if (task != null && task.mStack != null && task.mStack.isAdjustedForIme()) { 1679 task.mStack.applyAdjustForImeIfNeeded(task); 1680 } 1681 } 1682 getTouchableRegion(Region region, int flags)1683 int getTouchableRegion(Region region, int flags) { 1684 final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0; 1685 if (modal && mAppToken != null) { 1686 // Limit the outer touch to the activity stack region. 1687 flags |= FLAG_NOT_TOUCH_MODAL; 1688 // If this is a modal window we need to dismiss it if it's not full screen and the 1689 // touch happens outside of the frame that displays the content. This means we 1690 // need to intercept touches outside of that window. The dim layer user 1691 // associated with the window (task or stack) will give us the good bounds, as 1692 // they would be used to display the dim layer. 1693 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser(); 1694 if (dimLayerUser != null) { 1695 dimLayerUser.getDimBounds(mTmpRect); 1696 } else { 1697 getVisibleBounds(mTmpRect); 1698 } 1699 if (inFreeformWorkspace()) { 1700 // For freeform windows we the touch region to include the whole surface for the 1701 // shadows. 1702 final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); 1703 final int delta = WindowManagerService.dipToPixel( 1704 RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics); 1705 mTmpRect.inset(-delta, -delta); 1706 } 1707 region.set(mTmpRect); 1708 cropRegionToStackBoundsIfNeeded(region); 1709 } else { 1710 // Not modal or full screen modal 1711 getTouchableRegion(region); 1712 } 1713 return flags; 1714 } 1715 checkPolicyVisibilityChange()1716 void checkPolicyVisibilityChange() { 1717 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) { 1718 if (DEBUG_VISIBILITY) { 1719 Slog.v(TAG, "Policy visibility changing after anim in " + 1720 mWinAnimator + ": " + mPolicyVisibilityAfterAnim); 1721 } 1722 mPolicyVisibility = mPolicyVisibilityAfterAnim; 1723 setDisplayLayoutNeeded(); 1724 if (!mPolicyVisibility) { 1725 if (mService.mCurrentFocus == this) { 1726 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, 1727 "setAnimationLocked: setting mFocusMayChange true"); 1728 mService.mFocusMayChange = true; 1729 } 1730 // Window is no longer visible -- make sure if we were waiting 1731 // for it to be displayed before enabling the display, that 1732 // we allow the display to be enabled now. 1733 mService.enableScreenIfNeededLocked(); 1734 } 1735 } 1736 } 1737 setRequestedSize(int requestedWidth, int requestedHeight)1738 void setRequestedSize(int requestedWidth, int requestedHeight) { 1739 if ((mRequestedWidth != requestedWidth || mRequestedHeight != requestedHeight)) { 1740 mLayoutNeeded = true; 1741 mRequestedWidth = requestedWidth; 1742 mRequestedHeight = requestedHeight; 1743 } 1744 } 1745 prepareWindowToDisplayDuringRelayout(Configuration outConfig)1746 void prepareWindowToDisplayDuringRelayout(Configuration outConfig) { 1747 if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST) 1748 == SOFT_INPUT_ADJUST_RESIZE) { 1749 mLayoutNeeded = true; 1750 } 1751 if (isDrawnLw() && mService.okToDisplay()) { 1752 mWinAnimator.applyEnterAnimationLocked(); 1753 } 1754 if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) { 1755 if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this); 1756 mTurnOnScreen = true; 1757 } 1758 if (isConfigChanged()) { 1759 final Configuration newConfig = updateConfiguration(); 1760 if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: " 1761 + newConfig); 1762 outConfig.setTo(newConfig); 1763 } 1764 } 1765 adjustStartingWindowFlags()1766 void adjustStartingWindowFlags() { 1767 if (mAttrs.type == TYPE_BASE_APPLICATION && mAppToken != null 1768 && mAppToken.startingWindow != null) { 1769 // Special handling of starting window over the base 1770 // window of the app: propagate lock screen flags to it, 1771 // to provide the correct semantics while starting. 1772 final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD 1773 | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; 1774 WindowManager.LayoutParams sa = mAppToken.startingWindow.mAttrs; 1775 sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask); 1776 } 1777 } 1778 setWindowScale(int requestedWidth, int requestedHeight)1779 void setWindowScale(int requestedWidth, int requestedHeight) { 1780 final boolean scaledWindow = (mAttrs.flags & FLAG_SCALED) != 0; 1781 1782 if (scaledWindow) { 1783 // requested{Width|Height} Surface's physical size 1784 // attrs.{width|height} Size on screen 1785 // TODO: We don't check if attrs != null here. Is it implicitly checked? 1786 mHScale = (mAttrs.width != requestedWidth) ? 1787 (mAttrs.width / (float)requestedWidth) : 1.0f; 1788 mVScale = (mAttrs.height != requestedHeight) ? 1789 (mAttrs.height / (float)requestedHeight) : 1.0f; 1790 } else { 1791 mHScale = mVScale = 1; 1792 } 1793 } 1794 1795 private class DeathRecipient implements IBinder.DeathRecipient { 1796 @Override binderDied()1797 public void binderDied() { 1798 try { 1799 synchronized(mService.mWindowMap) { 1800 WindowState win = mService.windowForClientLocked(mSession, mClient, false); 1801 Slog.i(TAG, "WIN DEATH: " + win); 1802 if (win != null) { 1803 mService.removeWindowLocked(win, shouldKeepVisibleDeadAppWindow()); 1804 if (win.mAttrs.type == TYPE_DOCK_DIVIDER) { 1805 // The owner of the docked divider died :( We reset the docked stack, 1806 // just in case they have the divider at an unstable position. Better 1807 // also reset drag resizing state, because the owner can't do it 1808 // anymore. 1809 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID); 1810 if (stack != null) { 1811 stack.resetDockedStackToMiddle(); 1812 } 1813 mService.setDockedStackResizing(false); 1814 } 1815 } else if (mHasSurface) { 1816 Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid."); 1817 mService.removeWindowLocked(WindowState.this); 1818 } 1819 } 1820 } catch (IllegalArgumentException ex) { 1821 // This will happen if the window has already been removed. 1822 } 1823 } 1824 } 1825 1826 /** 1827 * Returns true if this window is visible and belongs to a dead app and shouldn't be removed, 1828 * because we want to preserve its location on screen to be re-activated later when the user 1829 * interacts with it. 1830 */ shouldKeepVisibleDeadAppWindow()1831 boolean shouldKeepVisibleDeadAppWindow() { 1832 if (!isWinVisibleLw() || mAppToken == null || mAppToken.clientHidden) { 1833 // Not a visible app window or the app isn't dead. 1834 return false; 1835 } 1836 1837 if (mAttrs.token != mClient.asBinder()) { 1838 // The window was add by a client using another client's app token. We don't want to 1839 // keep the dead window around for this case since this is meant for 'real' apps. 1840 return false; 1841 } 1842 1843 if (mAttrs.type == TYPE_APPLICATION_STARTING) { 1844 // We don't keep starting windows since they were added by the window manager before 1845 // the app even launched. 1846 return false; 1847 } 1848 1849 final TaskStack stack = getStack(); 1850 return stack != null && StackId.keepVisibleDeadAppWindowOnScreen(stack.mStackId); 1851 } 1852 1853 /** @return true if this window desires key events. */ canReceiveKeys()1854 boolean canReceiveKeys() { 1855 return isVisibleOrAdding() 1856 && (mViewVisibility == View.VISIBLE) && !mRemoveOnExit 1857 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0) 1858 && (mAppToken == null || mAppToken.windowsAreFocusable()) 1859 && !isAdjustedForMinimizedDock(); 1860 } 1861 1862 @Override hasDrawnLw()1863 public boolean hasDrawnLw() { 1864 return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN; 1865 } 1866 1867 @Override showLw(boolean doAnimation)1868 public boolean showLw(boolean doAnimation) { 1869 return showLw(doAnimation, true); 1870 } 1871 showLw(boolean doAnimation, boolean requestAnim)1872 boolean showLw(boolean doAnimation, boolean requestAnim) { 1873 if (isHiddenFromUserLocked()) { 1874 return false; 1875 } 1876 if (!mAppOpVisibility) { 1877 // Being hidden due to app op request. 1878 return false; 1879 } 1880 if (mPermanentlyHidden) { 1881 // Permanently hidden until the app exists as apps aren't prepared 1882 // to handle their windows being removed from under them. 1883 return false; 1884 } 1885 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) { 1886 // Already showing. 1887 return false; 1888 } 1889 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this); 1890 if (doAnimation) { 1891 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility=" 1892 + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation); 1893 if (!mService.okToDisplay()) { 1894 doAnimation = false; 1895 } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) { 1896 // Check for the case where we are currently visible and 1897 // not animating; we do not want to do animation at such a 1898 // point to become visible when we already are. 1899 doAnimation = false; 1900 } 1901 } 1902 mPolicyVisibility = true; 1903 mPolicyVisibilityAfterAnim = true; 1904 if (doAnimation) { 1905 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true); 1906 } 1907 if (requestAnim) { 1908 mService.scheduleAnimationLocked(); 1909 } 1910 return true; 1911 } 1912 1913 @Override hideLw(boolean doAnimation)1914 public boolean hideLw(boolean doAnimation) { 1915 return hideLw(doAnimation, true); 1916 } 1917 hideLw(boolean doAnimation, boolean requestAnim)1918 boolean hideLw(boolean doAnimation, boolean requestAnim) { 1919 if (doAnimation) { 1920 if (!mService.okToDisplay()) { 1921 doAnimation = false; 1922 } 1923 } 1924 boolean current = doAnimation ? mPolicyVisibilityAfterAnim 1925 : mPolicyVisibility; 1926 if (!current) { 1927 // Already hiding. 1928 return false; 1929 } 1930 if (doAnimation) { 1931 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false); 1932 if (mWinAnimator.mAnimation == null) { 1933 doAnimation = false; 1934 } 1935 } 1936 if (doAnimation) { 1937 mPolicyVisibilityAfterAnim = false; 1938 } else { 1939 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this); 1940 mPolicyVisibilityAfterAnim = false; 1941 mPolicyVisibility = false; 1942 // Window is no longer visible -- make sure if we were waiting 1943 // for it to be displayed before enabling the display, that 1944 // we allow the display to be enabled now. 1945 mService.enableScreenIfNeededLocked(); 1946 if (mService.mCurrentFocus == this) { 1947 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, 1948 "WindowState.hideLw: setting mFocusMayChange true"); 1949 mService.mFocusMayChange = true; 1950 } 1951 } 1952 if (requestAnim) { 1953 mService.scheduleAnimationLocked(); 1954 } 1955 return true; 1956 } 1957 setAppOpVisibilityLw(boolean state)1958 public void setAppOpVisibilityLw(boolean state) { 1959 if (mAppOpVisibility != state) { 1960 mAppOpVisibility = state; 1961 if (state) { 1962 // If the policy visibility had last been to hide, then this 1963 // will incorrectly show at this point since we lost that 1964 // information. Not a big deal -- for the windows that have app 1965 // ops modifies they should only be hidden by policy due to the 1966 // lock screen, and the user won't be changing this if locked. 1967 // Plus it will quickly be fixed the next time we do a layout. 1968 showLw(true, true); 1969 } else { 1970 hideLw(true, true); 1971 } 1972 } 1973 } 1974 hidePermanentlyLw()1975 public void hidePermanentlyLw() { 1976 if (!mPermanentlyHidden) { 1977 mPermanentlyHidden = true; 1978 hideLw(true, true); 1979 } 1980 } 1981 pokeDrawLockLw(long timeout)1982 public void pokeDrawLockLw(long timeout) { 1983 if (isVisibleOrAdding()) { 1984 if (mDrawLock == null) { 1985 // We want the tag name to be somewhat stable so that it is easier to correlate 1986 // in wake lock statistics. So in particular, we don't want to include the 1987 // window's hash code as in toString(). 1988 final CharSequence tag = getWindowTag(); 1989 mDrawLock = mService.mPowerManager.newWakeLock( 1990 PowerManager.DRAW_WAKE_LOCK, "Window:" + tag); 1991 mDrawLock.setReferenceCounted(false); 1992 mDrawLock.setWorkSource(new WorkSource(mOwnerUid, mAttrs.packageName)); 1993 } 1994 // Each call to acquire resets the timeout. 1995 if (DEBUG_POWER) { 1996 Slog.d(TAG, "pokeDrawLock: poking draw lock on behalf of visible window owned by " 1997 + mAttrs.packageName); 1998 } 1999 mDrawLock.acquire(timeout); 2000 } else if (DEBUG_POWER) { 2001 Slog.d(TAG, "pokeDrawLock: suppressed draw lock request for invisible window " 2002 + "owned by " + mAttrs.packageName); 2003 } 2004 } 2005 2006 @Override isAlive()2007 public boolean isAlive() { 2008 return mClient.asBinder().isBinderAlive(); 2009 } 2010 isClosing()2011 boolean isClosing() { 2012 return mAnimatingExit || (mService.mClosingApps.contains(mAppToken)); 2013 } 2014 isAnimatingWithSavedSurface()2015 boolean isAnimatingWithSavedSurface() { 2016 return mAnimatingWithSavedSurface; 2017 } 2018 isAnimatingInvisibleWithSavedSurface()2019 boolean isAnimatingInvisibleWithSavedSurface() { 2020 return mAnimatingWithSavedSurface 2021 && (mViewVisibility != View.VISIBLE || mWindowRemovalAllowed); 2022 } 2023 setVisibleBeforeClientHidden()2024 public void setVisibleBeforeClientHidden() { 2025 mWasVisibleBeforeClientHidden |= 2026 (mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface); 2027 } 2028 clearVisibleBeforeClientHidden()2029 public void clearVisibleBeforeClientHidden() { 2030 mWasVisibleBeforeClientHidden = false; 2031 } 2032 wasVisibleBeforeClientHidden()2033 public boolean wasVisibleBeforeClientHidden() { 2034 return mWasVisibleBeforeClientHidden; 2035 } 2036 shouldSaveSurface()2037 private boolean shouldSaveSurface() { 2038 if (mWinAnimator.mSurfaceController == null) { 2039 // Don't bother if the surface controller is gone for any reason. 2040 return false; 2041 } 2042 2043 if (!mWasVisibleBeforeClientHidden) { 2044 return false; 2045 } 2046 2047 if ((mAttrs.flags & FLAG_SECURE) != 0) { 2048 // We don't save secure surfaces since their content shouldn't be shown while the app 2049 // isn't on screen and content might leak through during the transition animation with 2050 // saved surface. 2051 return false; 2052 } 2053 2054 if (ActivityManager.isLowRamDeviceStatic()) { 2055 // Don't save surfaces on Svelte devices. 2056 return false; 2057 } 2058 2059 Task task = getTask(); 2060 if (task == null || task.inHomeStack()) { 2061 // Don't save surfaces for home stack apps. These usually resume and draw 2062 // first frame very fast. Saving surfaces are mostly a waste of memory. 2063 return false; 2064 } 2065 2066 final AppWindowToken taskTop = task.getTopVisibleAppToken(); 2067 if (taskTop != null && taskTop != mAppToken) { 2068 // Don't save if the window is not the topmost window. 2069 return false; 2070 } 2071 2072 if (mResizedWhileGone) { 2073 // Somebody resized our window while we were gone for layout, which means that the 2074 // client got an old size, so we have an outdated surface here. 2075 return false; 2076 } 2077 2078 if (DEBUG_DISABLE_SAVING_SURFACES) { 2079 return false; 2080 } 2081 2082 return mAppToken.shouldSaveSurface(); 2083 } 2084 2085 static final Region sEmptyRegion = new Region(); 2086 destroyOrSaveSurface()2087 void destroyOrSaveSurface() { 2088 mSurfaceSaved = shouldSaveSurface(); 2089 if (mSurfaceSaved) { 2090 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { 2091 Slog.v(TAG, "Saving surface: " + this); 2092 } 2093 // Previous user of the surface may have set a transparent region signaling a portion 2094 // doesn't need to be composited, so reset to default empty state. 2095 mSession.setTransparentRegion(mClient, sEmptyRegion); 2096 2097 mWinAnimator.hide("saved surface"); 2098 mWinAnimator.mDrawState = WindowStateAnimator.NO_SURFACE; 2099 setHasSurface(false); 2100 // The client should have disconnected at this point, but if it doesn't, 2101 // we need to make sure it's disconnected. Otherwise when we reuse the surface 2102 // the client can't reconnect to the buffer queue, and rendering will fail. 2103 if (mWinAnimator.mSurfaceController != null) { 2104 mWinAnimator.mSurfaceController.disconnectInTransaction(); 2105 } 2106 mAnimatingWithSavedSurface = false; 2107 } else { 2108 mWinAnimator.destroySurfaceLocked(); 2109 } 2110 // Clear animating flags now, since the surface is now gone. (Note this is true even 2111 // if the surface is saved, to outside world the surface is still NO_SURFACE.) 2112 mAnimatingExit = false; 2113 } 2114 destroySavedSurface()2115 void destroySavedSurface() { 2116 if (mSurfaceSaved) { 2117 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { 2118 Slog.v(TAG, "Destroying saved surface: " + this); 2119 } 2120 mWinAnimator.destroySurfaceLocked(); 2121 mSurfaceSaved = false; 2122 } 2123 mWasVisibleBeforeClientHidden = false; 2124 } 2125 restoreSavedSurface()2126 void restoreSavedSurface() { 2127 if (!mSurfaceSaved) { 2128 return; 2129 } 2130 2131 // Sometimes we save surfaces due to layout invisible 2132 // directly after rotation occurs. However this means 2133 // the surface was never laid out in the new orientation. 2134 // We can only restore to the last rotation we were 2135 // laid out as visible in. 2136 if (mLastVisibleLayoutRotation != mService.mRotation) { 2137 destroySavedSurface(); 2138 return; 2139 } 2140 mSurfaceSaved = false; 2141 2142 if (mWinAnimator.mSurfaceController != null) { 2143 setHasSurface(true); 2144 mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW; 2145 mAnimatingWithSavedSurface = true; 2146 2147 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { 2148 Slog.v(TAG, "Restoring saved surface: " + this); 2149 } 2150 } else { 2151 // mSurfaceController shouldn't be null if mSurfaceSaved was still true at 2152 // this point. Even if we destroyed the saved surface because of rotation 2153 // or resize, mSurfaceSaved flag should have been cleared. So this is a wtf. 2154 Slog.wtf(TAG, "Failed to restore saved surface: surface gone! " + this); 2155 } 2156 } 2157 canRestoreSurface()2158 boolean canRestoreSurface() { 2159 return mWasVisibleBeforeClientHidden && mSurfaceSaved; 2160 } 2161 hasSavedSurface()2162 boolean hasSavedSurface() { 2163 return mSurfaceSaved; 2164 } 2165 clearHasSavedSurface()2166 void clearHasSavedSurface() { 2167 mSurfaceSaved = false; 2168 mAnimatingWithSavedSurface = false; 2169 if (mWasVisibleBeforeClientHidden) { 2170 mAppToken.destroySavedSurfaces(); 2171 } 2172 } 2173 clearAnimatingWithSavedSurface()2174 boolean clearAnimatingWithSavedSurface() { 2175 if (mAnimatingWithSavedSurface) { 2176 // App has drawn something to its windows, we're no longer animating with 2177 // the saved surfaces. 2178 if (DEBUG_ANIM) Slog.d(TAG, 2179 "clearAnimatingWithSavedSurface(): win=" + this); 2180 mAnimatingWithSavedSurface = false; 2181 return true; 2182 } 2183 return false; 2184 } 2185 2186 @Override isDefaultDisplay()2187 public boolean isDefaultDisplay() { 2188 final DisplayContent displayContent = getDisplayContent(); 2189 if (displayContent == null) { 2190 // Only a window that was on a non-default display can be detached from it. 2191 return false; 2192 } 2193 return displayContent.isDefaultDisplay; 2194 } 2195 2196 @Override isDimming()2197 public boolean isDimming() { 2198 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser(); 2199 return dimLayerUser != null && mDisplayContent != null && 2200 mDisplayContent.mDimLayerController.isDimming(dimLayerUser, mWinAnimator); 2201 } 2202 setShowToOwnerOnlyLocked(boolean showToOwnerOnly)2203 public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) { 2204 mShowToOwnerOnly = showToOwnerOnly; 2205 } 2206 isHiddenFromUserLocked()2207 boolean isHiddenFromUserLocked() { 2208 // Attached windows are evaluated based on the window that they are attached to. 2209 WindowState win = this; 2210 while (win.isChildWindow()) { 2211 win = win.mAttachedWindow; 2212 } 2213 if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW 2214 && win.mAppToken != null && win.mAppToken.showForAllUsers) { 2215 2216 // All window frames that are fullscreen extend above status bar, but some don't extend 2217 // below navigation bar. Thus, check for display frame for top/left and stable frame for 2218 // bottom right. 2219 if (win.mFrame.left <= win.mDisplayFrame.left 2220 && win.mFrame.top <= win.mDisplayFrame.top 2221 && win.mFrame.right >= win.mStableFrame.right 2222 && win.mFrame.bottom >= win.mStableFrame.bottom) { 2223 // Is a fullscreen window, like the clock alarm. Show to everyone. 2224 return false; 2225 } 2226 } 2227 2228 return win.mShowToOwnerOnly 2229 && !mService.isCurrentProfileLocked(UserHandle.getUserId(win.mOwnerUid)); 2230 } 2231 applyInsets(Region outRegion, Rect frame, Rect inset)2232 private static void applyInsets(Region outRegion, Rect frame, Rect inset) { 2233 outRegion.set( 2234 frame.left + inset.left, frame.top + inset.top, 2235 frame.right - inset.right, frame.bottom - inset.bottom); 2236 } 2237 getTouchableRegion(Region outRegion)2238 void getTouchableRegion(Region outRegion) { 2239 final Rect frame = mFrame; 2240 switch (mTouchableInsets) { 2241 default: 2242 case TOUCHABLE_INSETS_FRAME: 2243 outRegion.set(frame); 2244 break; 2245 case TOUCHABLE_INSETS_CONTENT: 2246 applyInsets(outRegion, frame, mGivenContentInsets); 2247 break; 2248 case TOUCHABLE_INSETS_VISIBLE: 2249 applyInsets(outRegion, frame, mGivenVisibleInsets); 2250 break; 2251 case TOUCHABLE_INSETS_REGION: { 2252 final Region givenTouchableRegion = mGivenTouchableRegion; 2253 outRegion.set(givenTouchableRegion); 2254 outRegion.translate(frame.left, frame.top); 2255 break; 2256 } 2257 } 2258 cropRegionToStackBoundsIfNeeded(outRegion); 2259 } 2260 cropRegionToStackBoundsIfNeeded(Region region)2261 void cropRegionToStackBoundsIfNeeded(Region region) { 2262 final Task task = getTask(); 2263 if (task == null || !task.cropWindowsToStackBounds()) { 2264 return; 2265 } 2266 2267 final TaskStack stack = task.mStack; 2268 if (stack == null) { 2269 return; 2270 } 2271 2272 stack.getDimBounds(mTmpRect); 2273 region.op(mTmpRect, Region.Op.INTERSECT); 2274 } 2275 getWindowList()2276 WindowList getWindowList() { 2277 final DisplayContent displayContent = getDisplayContent(); 2278 return displayContent == null ? null : displayContent.getWindowList(); 2279 } 2280 2281 /** 2282 * Report a focus change. Must be called with no locks held, and consistently 2283 * from the same serialized thread (such as dispatched from a handler). 2284 */ reportFocusChangedSerialized(boolean focused, boolean inTouchMode)2285 public void reportFocusChangedSerialized(boolean focused, boolean inTouchMode) { 2286 try { 2287 mClient.windowFocusChanged(focused, inTouchMode); 2288 } catch (RemoteException e) { 2289 } 2290 if (mFocusCallbacks != null) { 2291 final int N = mFocusCallbacks.beginBroadcast(); 2292 for (int i=0; i<N; i++) { 2293 IWindowFocusObserver obs = mFocusCallbacks.getBroadcastItem(i); 2294 try { 2295 if (focused) { 2296 obs.focusGained(mWindowId.asBinder()); 2297 } else { 2298 obs.focusLost(mWindowId.asBinder()); 2299 } 2300 } catch (RemoteException e) { 2301 } 2302 } 2303 mFocusCallbacks.finishBroadcast(); 2304 } 2305 } 2306 2307 /** 2308 * Update our current configurations, based on task configuration. 2309 * 2310 * @return A configuration suitable for sending to the client. 2311 */ updateConfiguration()2312 private Configuration updateConfiguration() { 2313 final boolean configChanged = isConfigChanged(); 2314 getMergedConfig(mMergedConfiguration); 2315 mConfigHasChanged = false; 2316 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) { 2317 Slog.i(TAG, "Sending new config to window " + this + ": " + 2318 " / mergedConfig=" + mMergedConfiguration); 2319 } 2320 return mMergedConfiguration; 2321 } 2322 getMergedConfig(Configuration outConfig)2323 private void getMergedConfig(Configuration outConfig) { 2324 if (mAppToken != null && mAppToken.mFrozenMergedConfig.size() > 0) { 2325 outConfig.setTo(mAppToken.mFrozenMergedConfig.peek()); 2326 return; 2327 } 2328 final Task task = getTask(); 2329 final Configuration overrideConfig = task != null 2330 ? task.mOverrideConfig 2331 : Configuration.EMPTY; 2332 final Configuration serviceConfig = mService.mCurConfiguration; 2333 outConfig.setTo(serviceConfig); 2334 if (overrideConfig != Configuration.EMPTY) { 2335 outConfig.updateFrom(overrideConfig); 2336 } 2337 } 2338 reportResized()2339 void reportResized() { 2340 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag()); 2341 try { 2342 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this 2343 + ": " + mCompatFrame); 2344 final Configuration newConfig = isConfigChanged() ? updateConfiguration() : null; 2345 if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) 2346 Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING"); 2347 2348 final Rect frame = mFrame; 2349 final Rect overscanInsets = mLastOverscanInsets; 2350 final Rect contentInsets = mLastContentInsets; 2351 final Rect visibleInsets = mLastVisibleInsets; 2352 final Rect stableInsets = mLastStableInsets; 2353 final Rect outsets = mLastOutsets; 2354 final boolean reportDraw = mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING; 2355 if (mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_STARTING 2356 && mClient instanceof IWindow.Stub) { 2357 // To prevent deadlock simulate one-way call if win.mClient is a local object. 2358 mService.mH.post(new Runnable() { 2359 @Override 2360 public void run() { 2361 try { 2362 dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, 2363 stableInsets, outsets, reportDraw, newConfig); 2364 } catch (RemoteException e) { 2365 // Not a remote call, RemoteException won't be raised. 2366 } 2367 } 2368 }); 2369 } else { 2370 dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, 2371 outsets, reportDraw, newConfig); 2372 } 2373 2374 //TODO (multidisplay): Accessibility supported only for the default display. 2375 if (mService.mAccessibilityController != null 2376 && getDisplayId() == Display.DEFAULT_DISPLAY) { 2377 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(); 2378 } 2379 2380 mOverscanInsetsChanged = false; 2381 mContentInsetsChanged = false; 2382 mVisibleInsetsChanged = false; 2383 mStableInsetsChanged = false; 2384 mOutsetsChanged = false; 2385 mFrameSizeChanged = false; 2386 mResizedWhileNotDragResizingReported = true; 2387 mWinAnimator.mSurfaceResized = false; 2388 } catch (RemoteException e) { 2389 mOrientationChanging = false; 2390 mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() 2391 - mService.mDisplayFreezeTime); 2392 // We are assuming the hosting process is dead or in a zombie state. 2393 Slog.w(TAG, "Failed to report 'resized' to the client of " + this 2394 + ", removing this window."); 2395 mService.mPendingRemove.add(this); 2396 mService.mWindowPlacerLocked.requestTraversal(); 2397 } 2398 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 2399 } 2400 getBackdropFrame(Rect frame)2401 Rect getBackdropFrame(Rect frame) { 2402 // When the task is docked, we send fullscreen sized backDropFrame as soon as resizing 2403 // start even if we haven't received the relayout window, so that the client requests 2404 // the relayout sooner. When dragging stops, backDropFrame needs to stay fullscreen 2405 // until the window to small size, otherwise the multithread renderer will shift last 2406 // one or more frame to wrong offset. So here we send fullscreen backdrop if either 2407 // isDragResizing() or isDragResizeChanged() is true. 2408 boolean resizing = isDragResizing() || isDragResizeChanged(); 2409 if (StackId.useWindowFrameForBackdrop(getStackId()) || !resizing) { 2410 return frame; 2411 } 2412 DisplayInfo displayInfo = getDisplayInfo(); 2413 mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); 2414 return mTmpRect; 2415 } 2416 2417 @Override getStackId()2418 public int getStackId() { 2419 final TaskStack stack = getStack(); 2420 if (stack == null) { 2421 return INVALID_STACK_ID; 2422 } 2423 return stack.mStackId; 2424 } 2425 dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig)2426 private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, 2427 Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, 2428 Configuration newConfig) throws RemoteException { 2429 final boolean forceRelayout = isDragResizeChanged() || mResizedWhileNotDragResizing; 2430 2431 mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets, 2432 reportDraw, newConfig, getBackdropFrame(frame), 2433 forceRelayout, mPolicy.isNavBarForcedShownLw(this)); 2434 mDragResizingChangeReported = true; 2435 } 2436 registerFocusObserver(IWindowFocusObserver observer)2437 public void registerFocusObserver(IWindowFocusObserver observer) { 2438 synchronized(mService.mWindowMap) { 2439 if (mFocusCallbacks == null) { 2440 mFocusCallbacks = new RemoteCallbackList<IWindowFocusObserver>(); 2441 } 2442 mFocusCallbacks.register(observer); 2443 } 2444 } 2445 unregisterFocusObserver(IWindowFocusObserver observer)2446 public void unregisterFocusObserver(IWindowFocusObserver observer) { 2447 synchronized(mService.mWindowMap) { 2448 if (mFocusCallbacks != null) { 2449 mFocusCallbacks.unregister(observer); 2450 } 2451 } 2452 } 2453 isFocused()2454 public boolean isFocused() { 2455 synchronized(mService.mWindowMap) { 2456 return mService.mCurrentFocus == this; 2457 } 2458 } 2459 inFreeformWorkspace()2460 boolean inFreeformWorkspace() { 2461 final Task task = getTask(); 2462 return task != null && task.inFreeformWorkspace(); 2463 } 2464 2465 @Override isInMultiWindowMode()2466 public boolean isInMultiWindowMode() { 2467 final Task task = getTask(); 2468 return task != null && !task.isFullscreen(); 2469 } 2470 isDragResizeChanged()2471 boolean isDragResizeChanged() { 2472 return mDragResizing != computeDragResizing(); 2473 } 2474 2475 /** 2476 * @return Whether we reported a drag resize change to the application or not already. 2477 */ isDragResizingChangeReported()2478 boolean isDragResizingChangeReported() { 2479 return mDragResizingChangeReported; 2480 } 2481 2482 /** 2483 * Resets the state whether we reported a drag resize change to the app. 2484 */ resetDragResizingChangeReported()2485 void resetDragResizingChangeReported() { 2486 mDragResizingChangeReported = false; 2487 } 2488 2489 /** 2490 * Set whether we got resized but drag resizing flag was false. 2491 * @see #isResizedWhileNotDragResizing(). 2492 */ setResizedWhileNotDragResizing(boolean resizedWhileNotDragResizing)2493 void setResizedWhileNotDragResizing(boolean resizedWhileNotDragResizing) { 2494 mResizedWhileNotDragResizing = resizedWhileNotDragResizing; 2495 mResizedWhileNotDragResizingReported = !resizedWhileNotDragResizing; 2496 } 2497 2498 /** 2499 * Indicates whether we got resized but drag resizing flag was false. In this case, we also 2500 * need to recreate the surface and defer surface bound updates in order to make sure the 2501 * buffer contents and the positioning/size stay in sync. 2502 */ isResizedWhileNotDragResizing()2503 boolean isResizedWhileNotDragResizing() { 2504 return mResizedWhileNotDragResizing; 2505 } 2506 2507 /** 2508 * @return Whether we reported "resize while not drag resizing" to the application. 2509 * @see #isResizedWhileNotDragResizing() 2510 */ isResizedWhileNotDragResizingReported()2511 boolean isResizedWhileNotDragResizingReported() { 2512 return mResizedWhileNotDragResizingReported; 2513 } 2514 getResizeMode()2515 int getResizeMode() { 2516 return mResizeMode; 2517 } 2518 computeDragResizing()2519 boolean computeDragResizing() { 2520 final Task task = getTask(); 2521 if (task == null) { 2522 return false; 2523 } 2524 if (mAttrs.width != MATCH_PARENT || mAttrs.height != MATCH_PARENT) { 2525 2526 // Floating windows never enter drag resize mode. 2527 return false; 2528 } 2529 if (task.isDragResizing()) { 2530 return true; 2531 } 2532 2533 // If the bounds are currently frozen, it means that the layout size that the app sees 2534 // and the bounds we clip this window to might be different. In order to avoid holes, we 2535 // simulate that we are still resizing so the app fills the hole with the resizing 2536 // background. 2537 return (mDisplayContent.mDividerControllerLocked.isResizing() 2538 || mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) && 2539 !task.inFreeformWorkspace() && !isGoneForLayoutLw(); 2540 2541 } 2542 setDragResizing()2543 void setDragResizing() { 2544 final boolean resizing = computeDragResizing(); 2545 if (resizing == mDragResizing) { 2546 return; 2547 } 2548 mDragResizing = resizing; 2549 final Task task = getTask(); 2550 if (task != null && task.isDragResizing()) { 2551 mResizeMode = task.getDragResizeMode(); 2552 } else { 2553 mResizeMode = mDragResizing && mDisplayContent.mDividerControllerLocked.isResizing() 2554 ? DRAG_RESIZE_MODE_DOCKED_DIVIDER 2555 : DRAG_RESIZE_MODE_FREEFORM; 2556 } 2557 } 2558 isDragResizing()2559 boolean isDragResizing() { 2560 return mDragResizing; 2561 } 2562 isDockedResizing()2563 boolean isDockedResizing() { 2564 return mDragResizing && getResizeMode() == DRAG_RESIZE_MODE_DOCKED_DIVIDER; 2565 } 2566 dump(PrintWriter pw, String prefix, boolean dumpAll)2567 void dump(PrintWriter pw, String prefix, boolean dumpAll) { 2568 final TaskStack stack = getStack(); 2569 pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId()); 2570 if (stack != null) { 2571 pw.print(" stackId="); pw.print(stack.mStackId); 2572 } 2573 if (mNotOnAppsDisplay) { 2574 pw.print(" mNotOnAppsDisplay="); pw.print(mNotOnAppsDisplay); 2575 } 2576 pw.print(" mSession="); pw.print(mSession); 2577 pw.print(" mClient="); pw.println(mClient.asBinder()); 2578 pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid); 2579 pw.print(" mShowToOwnerOnly="); pw.print(mShowToOwnerOnly); 2580 pw.print(" package="); pw.print(mAttrs.packageName); 2581 pw.print(" appop="); pw.println(AppOpsManager.opToName(mAppOp)); 2582 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs); 2583 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth); 2584 pw.print(" h="); pw.print(mRequestedHeight); 2585 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq); 2586 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { 2587 pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth); 2588 pw.print(" h="); pw.println(mLastRequestedHeight); 2589 } 2590 if (isChildWindow() || mLayoutAttached) { 2591 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow); 2592 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached); 2593 } 2594 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) { 2595 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow); 2596 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper); 2597 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer); 2598 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible); 2599 } 2600 if (dumpAll) { 2601 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer); 2602 pw.print(" mSubLayer="); pw.print(mSubLayer); 2603 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+"); 2604 pw.print((mTargetAppToken != null ? 2605 mTargetAppToken.mAppAnimator.animLayerAdjustment 2606 : (mAppToken != null ? mAppToken.mAppAnimator.animLayerAdjustment : 0))); 2607 pw.print("="); pw.print(mWinAnimator.mAnimLayer); 2608 pw.print(" mLastLayer="); pw.println(mWinAnimator.mLastLayer); 2609 } 2610 if (dumpAll) { 2611 pw.print(prefix); pw.print("mToken="); pw.println(mToken); 2612 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken); 2613 if (mAppToken != null) { 2614 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken); 2615 pw.print(prefix); pw.print(" isAnimatingWithSavedSurface()="); 2616 pw.print(isAnimatingWithSavedSurface()); 2617 pw.print(" mAppDied=");pw.println(mAppDied); 2618 } 2619 if (mTargetAppToken != null) { 2620 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken); 2621 } 2622 pw.print(prefix); pw.print("mViewVisibility=0x"); 2623 pw.print(Integer.toHexString(mViewVisibility)); 2624 pw.print(" mHaveFrame="); pw.print(mHaveFrame); 2625 pw.print(" mObscured="); pw.println(mObscured); 2626 pw.print(prefix); pw.print("mSeq="); pw.print(mSeq); 2627 pw.print(" mSystemUiVisibility=0x"); 2628 pw.println(Integer.toHexString(mSystemUiVisibility)); 2629 } 2630 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || !mAppOpVisibility 2631 || mAttachedHidden || mPermanentlyHidden) { 2632 pw.print(prefix); pw.print("mPolicyVisibility="); 2633 pw.print(mPolicyVisibility); 2634 pw.print(" mPolicyVisibilityAfterAnim="); 2635 pw.print(mPolicyVisibilityAfterAnim); 2636 pw.print(" mAppOpVisibility="); 2637 pw.print(mAppOpVisibility); 2638 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden); 2639 pw.print(" mPermanentlyHidden="); pw.println(mPermanentlyHidden); 2640 } 2641 if (!mRelayoutCalled || mLayoutNeeded) { 2642 pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled); 2643 pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded); 2644 } 2645 if (mXOffset != 0 || mYOffset != 0) { 2646 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset); 2647 pw.print(" y="); pw.println(mYOffset); 2648 } 2649 if (dumpAll) { 2650 pw.print(prefix); pw.print("mGivenContentInsets="); 2651 mGivenContentInsets.printShortString(pw); 2652 pw.print(" mGivenVisibleInsets="); 2653 mGivenVisibleInsets.printShortString(pw); 2654 pw.println(); 2655 if (mTouchableInsets != 0 || mGivenInsetsPending) { 2656 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets); 2657 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending); 2658 Region region = new Region(); 2659 getTouchableRegion(region); 2660 pw.print(prefix); pw.print("touchable region="); pw.println(region); 2661 } 2662 pw.print(prefix); pw.print("mMergedConfiguration="); pw.println(mMergedConfiguration); 2663 } 2664 pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface); 2665 pw.print(" mShownPosition="); mShownPosition.printShortString(pw); 2666 pw.print(" isReadyForDisplay()="); pw.print(isReadyForDisplay()); 2667 pw.print(" hasSavedSurface()="); pw.print(hasSavedSurface()); 2668 pw.print(" mWindowRemovalAllowed="); pw.println(mWindowRemovalAllowed); 2669 if (dumpAll) { 2670 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw); 2671 pw.print(" last="); mLastFrame.printShortString(pw); 2672 pw.println(); 2673 } 2674 if (mEnforceSizeCompat) { 2675 pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw); 2676 pw.println(); 2677 } 2678 if (dumpAll) { 2679 pw.print(prefix); pw.print("Frames: containing="); 2680 mContainingFrame.printShortString(pw); 2681 pw.print(" parent="); mParentFrame.printShortString(pw); 2682 pw.println(); 2683 pw.print(prefix); pw.print(" display="); mDisplayFrame.printShortString(pw); 2684 pw.print(" overscan="); mOverscanFrame.printShortString(pw); 2685 pw.println(); 2686 pw.print(prefix); pw.print(" content="); mContentFrame.printShortString(pw); 2687 pw.print(" visible="); mVisibleFrame.printShortString(pw); 2688 pw.println(); 2689 pw.print(prefix); pw.print(" decor="); mDecorFrame.printShortString(pw); 2690 pw.println(); 2691 pw.print(prefix); pw.print(" outset="); mOutsetFrame.printShortString(pw); 2692 pw.println(); 2693 pw.print(prefix); pw.print("Cur insets: overscan="); 2694 mOverscanInsets.printShortString(pw); 2695 pw.print(" content="); mContentInsets.printShortString(pw); 2696 pw.print(" visible="); mVisibleInsets.printShortString(pw); 2697 pw.print(" stable="); mStableInsets.printShortString(pw); 2698 pw.print(" surface="); mAttrs.surfaceInsets.printShortString(pw); 2699 pw.print(" outsets="); mOutsets.printShortString(pw); 2700 pw.println(); 2701 pw.print(prefix); pw.print("Lst insets: overscan="); 2702 mLastOverscanInsets.printShortString(pw); 2703 pw.print(" content="); mLastContentInsets.printShortString(pw); 2704 pw.print(" visible="); mLastVisibleInsets.printShortString(pw); 2705 pw.print(" stable="); mLastStableInsets.printShortString(pw); 2706 pw.print(" physical="); mLastOutsets.printShortString(pw); 2707 pw.print(" outset="); mLastOutsets.printShortString(pw); 2708 pw.println(); 2709 } 2710 pw.print(prefix); pw.print(mWinAnimator); pw.println(":"); 2711 mWinAnimator.dump(pw, prefix + " ", dumpAll); 2712 if (mAnimatingExit || mRemoveOnExit || mDestroying || mRemoved) { 2713 pw.print(prefix); pw.print("mAnimatingExit="); pw.print(mAnimatingExit); 2714 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit); 2715 pw.print(" mDestroying="); pw.print(mDestroying); 2716 pw.print(" mRemoved="); pw.println(mRemoved); 2717 } 2718 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) { 2719 pw.print(prefix); pw.print("mOrientationChanging="); 2720 pw.print(mOrientationChanging); 2721 pw.print(" mAppFreezing="); pw.print(mAppFreezing); 2722 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen); 2723 } 2724 if (mLastFreezeDuration != 0) { 2725 pw.print(prefix); pw.print("mLastFreezeDuration="); 2726 TimeUtils.formatDuration(mLastFreezeDuration, pw); pw.println(); 2727 } 2728 if (mHScale != 1 || mVScale != 1) { 2729 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale); 2730 pw.print(" mVScale="); pw.println(mVScale); 2731 } 2732 if (mWallpaperX != -1 || mWallpaperY != -1) { 2733 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX); 2734 pw.print(" mWallpaperY="); pw.println(mWallpaperY); 2735 } 2736 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) { 2737 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep); 2738 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep); 2739 } 2740 if (mWallpaperDisplayOffsetX != Integer.MIN_VALUE 2741 || mWallpaperDisplayOffsetY != Integer.MIN_VALUE) { 2742 pw.print(prefix); pw.print("mWallpaperDisplayOffsetX="); 2743 pw.print(mWallpaperDisplayOffsetX); 2744 pw.print(" mWallpaperDisplayOffsetY="); 2745 pw.println(mWallpaperDisplayOffsetY); 2746 } 2747 if (mDrawLock != null) { 2748 pw.print(prefix); pw.println("mDrawLock=" + mDrawLock); 2749 } 2750 if (isDragResizing()) { 2751 pw.print(prefix); pw.println("isDragResizing=" + isDragResizing()); 2752 } 2753 if (computeDragResizing()) { 2754 pw.print(prefix); pw.println("computeDragResizing=" + computeDragResizing()); 2755 } 2756 } 2757 makeInputChannelName()2758 String makeInputChannelName() { 2759 return Integer.toHexString(System.identityHashCode(this)) 2760 + " " + getWindowTag(); 2761 } 2762 getWindowTag()2763 CharSequence getWindowTag() { 2764 CharSequence tag = mAttrs.getTitle(); 2765 if (tag == null || tag.length() <= 0) { 2766 tag = mAttrs.packageName; 2767 } 2768 return tag; 2769 } 2770 2771 @Override toString()2772 public String toString() { 2773 final CharSequence title = getWindowTag(); 2774 if (mStringNameCache == null || mLastTitle != title || mWasExiting != mAnimatingExit) { 2775 mLastTitle = title; 2776 mWasExiting = mAnimatingExit; 2777 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) 2778 + " u" + UserHandle.getUserId(mSession.mUid) 2779 + " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}"); 2780 } 2781 return mStringNameCache; 2782 } 2783 transformClipRectFromScreenToSurfaceSpace(Rect clipRect)2784 void transformClipRectFromScreenToSurfaceSpace(Rect clipRect) { 2785 if (mHScale >= 0) { 2786 clipRect.left = (int) (clipRect.left / mHScale); 2787 clipRect.right = (int) Math.ceil(clipRect.right / mHScale); 2788 } 2789 if (mVScale >= 0) { 2790 clipRect.top = (int) (clipRect.top / mVScale); 2791 clipRect.bottom = (int) Math.ceil(clipRect.bottom / mVScale); 2792 } 2793 } 2794 applyGravityAndUpdateFrame(Rect containingFrame, Rect displayFrame)2795 void applyGravityAndUpdateFrame(Rect containingFrame, Rect displayFrame) { 2796 final int pw = containingFrame.width(); 2797 final int ph = containingFrame.height(); 2798 final Task task = getTask(); 2799 final boolean nonFullscreenTask = isInMultiWindowMode(); 2800 final boolean noLimits = (mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) != 0; 2801 2802 // We need to fit it to the display if either 2803 // a) The task is fullscreen, or we don't have a task (we assume fullscreen for the taskless 2804 // windows) 2805 // b) If it's a child window, we also need to fit it to the display unless 2806 // FLAG_LAYOUT_NO_LIMITS is set. This is so we place Popup and similar windows on screen, 2807 // but SurfaceViews want to be always at a specific location so we don't fit it to the 2808 // display. 2809 final boolean fitToDisplay = (task == null || !nonFullscreenTask) 2810 || (isChildWindow() && !noLimits); 2811 float x, y; 2812 int w,h; 2813 2814 if ((mAttrs.flags & FLAG_SCALED) != 0) { 2815 if (mAttrs.width < 0) { 2816 w = pw; 2817 } else if (mEnforceSizeCompat) { 2818 w = (int)(mAttrs.width * mGlobalScale + .5f); 2819 } else { 2820 w = mAttrs.width; 2821 } 2822 if (mAttrs.height < 0) { 2823 h = ph; 2824 } else if (mEnforceSizeCompat) { 2825 h = (int)(mAttrs.height * mGlobalScale + .5f); 2826 } else { 2827 h = mAttrs.height; 2828 } 2829 } else { 2830 if (mAttrs.width == MATCH_PARENT) { 2831 w = pw; 2832 } else if (mEnforceSizeCompat) { 2833 w = (int)(mRequestedWidth * mGlobalScale + .5f); 2834 } else { 2835 w = mRequestedWidth; 2836 } 2837 if (mAttrs.height == MATCH_PARENT) { 2838 h = ph; 2839 } else if (mEnforceSizeCompat) { 2840 h = (int)(mRequestedHeight * mGlobalScale + .5f); 2841 } else { 2842 h = mRequestedHeight; 2843 } 2844 } 2845 2846 if (mEnforceSizeCompat) { 2847 x = mAttrs.x * mGlobalScale; 2848 y = mAttrs.y * mGlobalScale; 2849 } else { 2850 x = mAttrs.x; 2851 y = mAttrs.y; 2852 } 2853 2854 if (nonFullscreenTask && !layoutInParentFrame()) { 2855 // Make sure window fits in containing frame since it is in a non-fullscreen task as 2856 // required by {@link Gravity#apply} call. 2857 w = Math.min(w, pw); 2858 h = Math.min(h, ph); 2859 } 2860 2861 // Set mFrame 2862 Gravity.apply(mAttrs.gravity, w, h, containingFrame, 2863 (int) (x + mAttrs.horizontalMargin * pw), 2864 (int) (y + mAttrs.verticalMargin * ph), mFrame); 2865 2866 // Now make sure the window fits in the overall display frame. 2867 if (fitToDisplay) { 2868 Gravity.applyDisplay(mAttrs.gravity, displayFrame, mFrame); 2869 } 2870 2871 // We need to make sure we update the CompatFrame as it is used for 2872 // cropping decisions, etc, on systems where we lack a decor layer. 2873 mCompatFrame.set(mFrame); 2874 if (mEnforceSizeCompat) { 2875 // See comparable block in computeFrameLw. 2876 mCompatFrame.scale(mInvGlobalScale); 2877 } 2878 } 2879 isChildWindow()2880 boolean isChildWindow() { 2881 return mAttachedWindow != null; 2882 } 2883 layoutInParentFrame()2884 boolean layoutInParentFrame() { 2885 return isChildWindow() && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0; 2886 } 2887 setReplacing(boolean animate)2888 void setReplacing(boolean animate) { 2889 if ((mAttrs.privateFlags & PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH) != 0 2890 || mAttrs.type == TYPE_APPLICATION_STARTING) { 2891 // We don't set replacing on starting windows since they are added by window manager and 2892 // not the client so won't be replaced by the client. 2893 return; 2894 } 2895 2896 mWillReplaceWindow = true; 2897 mReplacingWindow = null; 2898 mAnimateReplacingWindow = animate; 2899 } 2900 resetReplacing()2901 void resetReplacing() { 2902 mWillReplaceWindow = false; 2903 mReplacingWindow = null; 2904 mAnimateReplacingWindow = false; 2905 } 2906 requestUpdateWallpaperIfNeeded()2907 void requestUpdateWallpaperIfNeeded() { 2908 if (mDisplayContent != null && (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) { 2909 mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 2910 mDisplayContent.layoutNeeded = true; 2911 mService.mWindowPlacerLocked.requestTraversal(); 2912 } 2913 } 2914 translateToWindowX(float x)2915 float translateToWindowX(float x) { 2916 float winX = x - mFrame.left; 2917 if (mEnforceSizeCompat) { 2918 winX *= mGlobalScale; 2919 } 2920 return winX; 2921 } 2922 translateToWindowY(float y)2923 float translateToWindowY(float y) { 2924 float winY = y - mFrame.top; 2925 if (mEnforceSizeCompat) { 2926 winY *= mGlobalScale; 2927 } 2928 return winY; 2929 } 2930 transferDimToReplacement()2931 void transferDimToReplacement() { 2932 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser(); 2933 if (dimLayerUser != null && mDisplayContent != null) { 2934 mDisplayContent.mDimLayerController.applyDim(dimLayerUser, 2935 mReplacingWindow.mWinAnimator, 2936 (mAttrs.flags & FLAG_DIM_BEHIND) != 0 ? true : false); 2937 } 2938 } 2939 2940 // During activity relaunch due to resize, we sometimes use window replacement 2941 // for only child windows (as the main window is handled by window preservation) 2942 // and the big surface. 2943 // 2944 // Though windows of TYPE_APPLICATION or TYPE_DRAWN_APPLICATION (as opposed to 2945 // TYPE_BASE_APPLICATION) are not children in the sense of an attached window, 2946 // we also want to replace them at such phases, as they won't be covered by window 2947 // preservation, and in general we expect them to return following relaunch. shouldBeReplacedWithChildren()2948 boolean shouldBeReplacedWithChildren() { 2949 return isChildWindow() || mAttrs.type == TYPE_APPLICATION 2950 || mAttrs.type == TYPE_DRAWN_APPLICATION; 2951 } 2952 getRotationAnimationHint()2953 public int getRotationAnimationHint() { 2954 if (mAppToken != null) { 2955 return mAppToken.mRotationAnimationHint; 2956 } else { 2957 return -1; 2958 } 2959 } 2960 isRtl()2961 public boolean isRtl() { 2962 return mMergedConfiguration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; 2963 } 2964 isRemovedOrHidden()2965 public boolean isRemovedOrHidden() { 2966 return mPermanentlyHidden || mAnimatingExit 2967 || mRemoveOnExit || mWindowRemovalAllowed 2968 || mViewVisibility == View.GONE; 2969 } 2970 } 2971