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