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