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