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