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> { WindowList()111 WindowList() {} WindowList(WindowList 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 don’t 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 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, final DisplayContent displayContent)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 attach()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 getOwningUid()651 public int getOwningUid() { 652 return mOwnerUid; 653 } 654 655 @Override getOwningPackage()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 */ subtractInsets(Rect frame, Rect layoutFrame, Rect insetFrame, Rect displayFrame)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 computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf, Rect osf)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 getFrameLw()943 public Rect getFrameLw() { 944 return mFrame; 945 } 946 947 @Override getShownPositionLw()948 public Point getShownPositionLw() { 949 return mShownPosition; 950 } 951 952 @Override getDisplayFrameLw()953 public Rect getDisplayFrameLw() { 954 return mDisplayFrame; 955 } 956 957 @Override getOverscanFrameLw()958 public Rect getOverscanFrameLw() { 959 return mOverscanFrame; 960 } 961 962 @Override getContentFrameLw()963 public Rect getContentFrameLw() { 964 return mContentFrame; 965 } 966 967 @Override getVisibleFrameLw()968 public Rect getVisibleFrameLw() { 969 return mVisibleFrame; 970 } 971 972 @Override getGivenInsetsPendingLw()973 public boolean getGivenInsetsPendingLw() { 974 return mGivenInsetsPending; 975 } 976 977 @Override getGivenContentInsetsLw()978 public Rect getGivenContentInsetsLw() { 979 return mGivenContentInsets; 980 } 981 982 @Override getGivenVisibleInsetsLw()983 public Rect getGivenVisibleInsetsLw() { 984 return mGivenVisibleInsets; 985 } 986 987 @Override getAttrs()988 public WindowManager.LayoutParams getAttrs() { 989 return mAttrs; 990 } 991 992 @Override getNeedsMenuLw(WindowManagerPolicy.WindowState bottom)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 getSystemUiVisibility()1021 public int getSystemUiVisibility() { 1022 return mSystemUiVisibility; 1023 } 1024 1025 @Override getSurfaceLayer()1026 public int getSurfaceLayer() { 1027 return mLayer; 1028 } 1029 1030 @Override getBaseType()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 getAppToken()1040 public IApplicationToken getAppToken() { 1041 return mAppToken != null ? mAppToken.appToken : null; 1042 } 1043 1044 @Override isVoiceInteraction()1045 public boolean isVoiceInteraction() { 1046 return mAppToken != null && mAppToken.voiceInteraction; 1047 } 1048 setInsetsChanged()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 getDisplayContent()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 getDisplayInfo()1067 public DisplayInfo getDisplayInfo() { 1068 final DisplayContent displayContent = getDisplayContent(); 1069 return displayContent != null ? displayContent.getDisplayInfo() : null; 1070 } 1071 getDisplayId()1072 public int getDisplayId() { 1073 final DisplayContent displayContent = getDisplayContent(); 1074 if (displayContent == null) { 1075 return -1; 1076 } 1077 return displayContent.getDisplayId(); 1078 } 1079 getTask()1080 Task getTask() { 1081 return mAppToken != null ? mAppToken.mTask : null; 1082 } 1083 getStack()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 */ getVisibleBounds(Rect bounds)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 getInputDispatchingTimeoutNanos()1129 public long getInputDispatchingTimeoutNanos() { 1130 return mAppToken != null 1131 ? mAppToken.inputDispatchingTimeoutNanos 1132 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 1133 } 1134 1135 @Override hasAppShownWindows()1136 public boolean hasAppShownWindows() { 1137 return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed); 1138 } 1139 isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy)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 prelayout()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 */ isVisibleUnchecked()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 isVisibleLw()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 isVisibleOrBehindKeyguardLw()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 */ isWinVisibleLw()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 */ isVisibleNow()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 */ isPotentialDragTarget()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 */ isVisibleOrAdding()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 */ isOnScreen()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 */ isOnScreenIgnoringKeyguard()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 */ mightAffectAllDrawn(boolean visibleOnly)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 */ isInteresting()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 */ isReadyForDisplay()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 */ isReadyForDisplayIgnoringKeyguard()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 isDisplayedLw()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 isAnimatingLw()1339 public boolean isAnimatingLw() { 1340 return mWinAnimator.mAnimation != null 1341 || (mAppToken != null && mAppToken.mAppAnimator.animation != null); 1342 } 1343 1344 @Override isGoneForLayoutLw()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 */ isDrawFinishedLw()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 isDrawnLw()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 */ isOpaqueDrawn()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 */ hasMoved()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 isObscuringFullscreen(final DisplayInfo displayInfo)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 isFrameFullscreen(final DisplayInfo displayInfo)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 isConfigChanged()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 isAdjustedForMinimizedDock()1436 boolean isAdjustedForMinimizedDock() { 1437 return mAppToken != null && mAppToken.mTask != null 1438 && mAppToken.mTask.mStack.isAdjustedForMinimizedDock(); 1439 } 1440 removeLocked()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 setHasSurface(boolean hasSurface)1459 void setHasSurface(boolean hasSurface) { 1460 mHasSurface = hasSurface; 1461 } 1462 getAnimLayerAdjustment()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 scheduleAnimationIfDimming()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 */ notifyMovedInStack()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 */ hasJustMovedInStack()1508 boolean hasJustMovedInStack() { 1509 return mJustMovedInStack; 1510 } 1511 1512 /** 1513 * Resets that we just moved in the corresponding stack. See {@link #notifyMovedInStack}. 1514 */ resetJustMovedInStack()1515 void resetJustMovedInStack() { 1516 mJustMovedInStack = false; 1517 } 1518 1519 private final class DeadWindowEventReceiver extends InputEventReceiver { DeadWindowEventReceiver(InputChannel inputChannel)1520 DeadWindowEventReceiver(InputChannel inputChannel) { 1521 super(inputChannel, mService.mH.getLooper()); 1522 } 1523 @Override onInputEvent(InputEvent event)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 openInputChannel(InputChannel outInputChannel)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 disposeInputChannel()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 applyDimLayerIfNeeded()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 getDimLayerUser()1592 DimLayer.DimLayerUser getDimLayerUser() { 1593 Task task = getTask(); 1594 if (task != null) { 1595 return task; 1596 } 1597 return getStack(); 1598 } 1599 maybeRemoveReplacedWindow()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 setDisplayLayoutNeeded()1624 void setDisplayLayoutNeeded() { 1625 if (mDisplayContent != null) { 1626 mDisplayContent.layoutNeeded = true; 1627 } 1628 } 1629 inDockedWorkspace()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. inPinnedWorkspace()1636 boolean inPinnedWorkspace() { 1637 final Task task = getTask(); 1638 return task != null && task.inPinnedWorkspace(); 1639 } 1640 isDockedInEffect()1641 boolean isDockedInEffect() { 1642 final Task task = getTask(); 1643 return task != null && task.isDockedInEffect(); 1644 } 1645 applyScrollIfNeeded()1646 void applyScrollIfNeeded() { 1647 final Task task = getTask(); 1648 if (task != null) { 1649 task.applyScrollToWindowIfNeeded(this); 1650 } 1651 } 1652 applyAdjustForImeIfNeeded()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 getTouchableRegion(Region region, int flags)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 checkPolicyVisibilityChange()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 setRequestedSize(int requestedWidth, int requestedHeight)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 prepareWindowToDisplayDuringRelayout(Configuration outConfig)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 adjustStartingWindowFlags()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 setWindowScale(int requestedWidth, int requestedHeight)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 binderDied()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 */ shouldKeepVisibleDeadAppWindow()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. */ canReceiveKeys()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 hasDrawnLw()1840 public boolean hasDrawnLw() { 1841 return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN; 1842 } 1843 1844 @Override showLw(boolean doAnimation)1845 public boolean showLw(boolean doAnimation) { 1846 return showLw(doAnimation, true); 1847 } 1848 showLw(boolean doAnimation, boolean requestAnim)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 hideLw(boolean doAnimation)1886 public boolean hideLw(boolean doAnimation) { 1887 return hideLw(doAnimation, true); 1888 } 1889 hideLw(boolean doAnimation, boolean requestAnim)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 setAppOpVisibilityLw(boolean state)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 pokeDrawLockLw(long timeout)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 isAlive()1972 public boolean isAlive() { 1973 return mClient.asBinder().isBinderAlive(); 1974 } 1975 isClosing()1976 boolean isClosing() { 1977 return mAnimatingExit || (mService.mClosingApps.contains(mAppToken)); 1978 } 1979 isAnimatingWithSavedSurface()1980 boolean isAnimatingWithSavedSurface() { 1981 return mAnimatingWithSavedSurface; 1982 } 1983 isAnimatingInvisibleWithSavedSurface()1984 boolean isAnimatingInvisibleWithSavedSurface() { 1985 return mAnimatingWithSavedSurface 1986 && (mViewVisibility != View.VISIBLE || mWindowRemovalAllowed); 1987 } 1988 setVisibleBeforeClientHidden()1989 public void setVisibleBeforeClientHidden() { 1990 mWasVisibleBeforeClientHidden |= 1991 (mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface); 1992 } 1993 clearVisibleBeforeClientHidden()1994 public void clearVisibleBeforeClientHidden() { 1995 mWasVisibleBeforeClientHidden = false; 1996 } 1997 wasVisibleBeforeClientHidden()1998 public boolean wasVisibleBeforeClientHidden() { 1999 return mWasVisibleBeforeClientHidden; 2000 } 2001 shouldSaveSurface()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 destroyOrSaveSurface()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 destroySavedSurface()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 restoreSavedSurface()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 canRestoreSurface()2111 boolean canRestoreSurface() { 2112 return mWasVisibleBeforeClientHidden && mSurfaceSaved; 2113 } 2114 hasSavedSurface()2115 boolean hasSavedSurface() { 2116 return mSurfaceSaved; 2117 } 2118 clearHasSavedSurface()2119 void clearHasSavedSurface() { 2120 mSurfaceSaved = false; 2121 mAnimatingWithSavedSurface = false; 2122 if (mWasVisibleBeforeClientHidden) { 2123 mAppToken.destroySavedSurfaces(); 2124 } 2125 } 2126 clearAnimatingWithSavedSurface()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 isDefaultDisplay()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 isDimming()2150 public boolean isDimming() { 2151 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser(); 2152 return dimLayerUser != null && mDisplayContent != null && 2153 mDisplayContent.mDimLayerController.isDimming(dimLayerUser, mWinAnimator); 2154 } 2155 setShowToOwnerOnlyLocked(boolean showToOwnerOnly)2156 public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) { 2157 mShowToOwnerOnly = showToOwnerOnly; 2158 } 2159 isHiddenFromUserLocked()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 applyInsets(Region outRegion, Rect frame, Rect inset)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 getTouchableRegion(Region outRegion)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 cropRegionToStackBoundsIfNeeded(Region region)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 getWindowList()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 */ reportFocusChangedSerialized(boolean focused, boolean inTouchMode)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 */ updateConfiguration()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 getMergedConfig(Configuration outConfig)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 reportResized()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 getBackdropFrame(Rect frame)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 getStackId()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 dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig)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 registerFocusObserver(IWindowFocusObserver observer)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 unregisterFocusObserver(IWindowFocusObserver observer)2398 public void unregisterFocusObserver(IWindowFocusObserver observer) { 2399 synchronized(mService.mWindowMap) { 2400 if (mFocusCallbacks != null) { 2401 mFocusCallbacks.unregister(observer); 2402 } 2403 } 2404 } 2405 isFocused()2406 public boolean isFocused() { 2407 synchronized(mService.mWindowMap) { 2408 return mService.mCurrentFocus == this; 2409 } 2410 } 2411 inFreeformWorkspace()2412 boolean inFreeformWorkspace() { 2413 final Task task = getTask(); 2414 return task != null && task.inFreeformWorkspace(); 2415 } 2416 2417 @Override isInMultiWindowMode()2418 public boolean isInMultiWindowMode() { 2419 final Task task = getTask(); 2420 return task != null && !task.isFullscreen(); 2421 } 2422 isDragResizeChanged()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 */ isDragResizingChangeReported()2430 boolean isDragResizingChangeReported() { 2431 return mDragResizingChangeReported; 2432 } 2433 2434 /** 2435 * Resets the state whether we reported a drag resize change to the app. 2436 */ resetDragResizingChangeReported()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 */ setResizedWhileNotDragResizing(boolean resizedWhileNotDragResizing)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 */ isResizedWhileNotDragResizing()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 */ isResizedWhileNotDragResizingReported()2463 boolean isResizedWhileNotDragResizingReported() { 2464 return mResizedWhileNotDragResizingReported; 2465 } 2466 getResizeMode()2467 int getResizeMode() { 2468 return mResizeMode; 2469 } 2470 computeDragResizing()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 setDragResizing()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 isDragResizing()2511 boolean isDragResizing() { 2512 return mDragResizing; 2513 } 2514 isDockedResizing()2515 boolean isDockedResizing() { 2516 return mDragResizing && getResizeMode() == DRAG_RESIZE_MODE_DOCKED_DIVIDER; 2517 } 2518 dump(PrintWriter pw, String prefix, boolean dumpAll)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 makeInputChannelName()2709 String makeInputChannelName() { 2710 return Integer.toHexString(System.identityHashCode(this)) 2711 + " " + getWindowTag(); 2712 } 2713 getWindowTag()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 toString()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 transformClipRectFromScreenToSurfaceSpace(Rect clipRect)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 applyGravityAndUpdateFrame(Rect containingFrame, Rect displayFrame)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 isChildWindow()2831 boolean isChildWindow() { 2832 return mAttachedWindow != null; 2833 } 2834 layoutInParentFrame()2835 boolean layoutInParentFrame() { 2836 return isChildWindow() && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0; 2837 } 2838 setReplacing(boolean animate)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 resetReplacing()2852 void resetReplacing() { 2853 mWillReplaceWindow = false; 2854 mReplacingWindow = null; 2855 mAnimateReplacingWindow = false; 2856 } 2857 requestUpdateWallpaperIfNeeded()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 translateToWindowX(float x)2866 float translateToWindowX(float x) { 2867 float winX = x - mFrame.left; 2868 if (mEnforceSizeCompat) { 2869 winX *= mGlobalScale; 2870 } 2871 return winX; 2872 } 2873 translateToWindowY(float y)2874 float translateToWindowY(float y) { 2875 float winY = y - mFrame.top; 2876 if (mEnforceSizeCompat) { 2877 winY *= mGlobalScale; 2878 } 2879 return winY; 2880 } 2881 transferDimToReplacement()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. shouldBeReplacedWithChildren()2899 boolean shouldBeReplacedWithChildren() { 2900 return isChildWindow() || mAttrs.type == TYPE_APPLICATION; 2901 } 2902 } 2903