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