WindowState.java revision 84cc5e320df461f6b7f2173833e62880ecc5af8e
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 static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; 20import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 21import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; 22import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; 23import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; 24import static android.view.WindowManager.LayoutParams.FLAG_SCALED; 25import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; 26import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; 27import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; 28import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; 29import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; 30import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 31import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; 32import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 33import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 34import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; 35import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 36import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 37import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 38import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE; 39import static com.android.server.wm.WindowManagerService.DEBUG_ANIM; 40import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS; 41import static com.android.server.wm.WindowManagerService.DEBUG_CONFIGURATION; 42import static com.android.server.wm.WindowManagerService.DEBUG_FOCUS_LIGHT; 43import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT; 44import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION; 45import static com.android.server.wm.WindowManagerService.DEBUG_POWER; 46import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE; 47import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY; 48 49import android.app.ActivityManager; 50import android.app.AppOpsManager; 51import android.graphics.Point; 52import android.os.PowerManager; 53import android.os.RemoteCallbackList; 54import android.os.SystemClock; 55import android.os.Trace; 56import android.os.WorkSource; 57import android.util.DisplayMetrics; 58import android.util.TimeUtils; 59import android.view.Display; 60import android.view.IWindowFocusObserver; 61import android.view.IWindowId; 62 63import com.android.server.input.InputWindowHandle; 64 65import android.content.Context; 66import android.content.res.Configuration; 67import android.graphics.Matrix; 68import android.graphics.PixelFormat; 69import android.graphics.Rect; 70import android.graphics.Region; 71import android.os.IBinder; 72import android.os.RemoteException; 73import android.os.UserHandle; 74import android.util.Slog; 75import android.view.DisplayInfo; 76import android.view.Gravity; 77import android.view.IApplicationToken; 78import android.view.IWindow; 79import android.view.InputChannel; 80import android.view.InputEvent; 81import android.view.InputEventReceiver; 82import android.view.View; 83import android.view.ViewTreeObserver; 84import android.view.WindowManager; 85import android.view.WindowManagerPolicy; 86 87import java.io.PrintWriter; 88import java.util.ArrayList; 89 90class WindowList extends ArrayList<WindowState> { 91} 92 93/** 94 * A window in the window manager. 95 */ 96final class WindowState implements WindowManagerPolicy.WindowState { 97 static final String TAG = "WindowState"; 98 99 // The minimal size of a window within the usable area of the freeform stack. 100 // TODO(multi-window): fix the min sizes when we have mininum width/height support, 101 // use hard-coded min sizes for now. 102 static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48; 103 static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32; 104 105 // The thickness of a window resize handle outside the window bounds on the free form workspace 106 // to capture touch events in that area. 107 static final int RESIZE_HANDLE_WIDTH_IN_DP = 30; 108 109 static final boolean BOUNDS_FOR_TOUCH = true; 110 111 final WindowManagerService mService; 112 final WindowManagerPolicy mPolicy; 113 final Context mContext; 114 final Session mSession; 115 final IWindow mClient; 116 final int mAppOp; 117 // UserId and appId of the owner. Don't display windows of non-current user. 118 final int mOwnerUid; 119 final IWindowId mWindowId; 120 WindowToken mToken; 121 WindowToken mRootToken; 122 AppWindowToken mAppToken; 123 AppWindowToken mTargetAppToken; 124 125 // mAttrs.flags is tested in animation without being locked. If the bits tested are ever 126 // modified they will need to be locked. 127 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams(); 128 final DeathRecipient mDeathRecipient; 129 final WindowState mAttachedWindow; 130 final WindowList mChildWindows = new WindowList(); 131 final int mBaseLayer; 132 final int mSubLayer; 133 final boolean mLayoutAttached; 134 final boolean mIsImWindow; 135 final boolean mIsWallpaper; 136 final boolean mIsFloatingLayer; 137 int mSeq; 138 boolean mEnforceSizeCompat; 139 int mViewVisibility; 140 int mSystemUiVisibility; 141 boolean mPolicyVisibility = true; 142 boolean mPolicyVisibilityAfterAnim = true; 143 boolean mAppOpVisibility = true; 144 boolean mAppFreezing; 145 boolean mAttachedHidden; // is our parent window hidden? 146 boolean mWallpaperVisible; // for wallpaper, what was last vis report? 147 boolean mDragResizing; 148 149 RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks; 150 151 /** 152 * The window size that was requested by the application. These are in 153 * the application's coordinate space (without compatibility scale applied). 154 */ 155 int mRequestedWidth; 156 int mRequestedHeight; 157 int mLastRequestedWidth; 158 int mLastRequestedHeight; 159 160 int mLayer; 161 boolean mHaveFrame; 162 boolean mObscured; 163 boolean mTurnOnScreen; 164 165 int mLayoutSeq = -1; 166 167 private Configuration mConfiguration = Configuration.EMPTY; 168 private Configuration mOverrideConfig = Configuration.EMPTY; 169 // Sticky answer to isConfigChanged(), remains true until new Configuration is assigned. 170 // Used only on {@link #TYPE_KEYGUARD}. 171 private boolean mConfigHasChanged; 172 173 /** 174 * Actual position of the surface shown on-screen (may be modified by animation). These are 175 * in the screen's coordinate space (WITH the compatibility scale applied). 176 */ 177 final Point mShownPosition = new Point(); 178 179 /** 180 * Insets that determine the actually visible area. These are in the application's 181 * coordinate space (without compatibility scale applied). 182 */ 183 final Rect mVisibleInsets = new Rect(); 184 final Rect mLastVisibleInsets = new Rect(); 185 boolean mVisibleInsetsChanged; 186 187 /** 188 * Insets that are covered by system windows (such as the status bar) and 189 * transient docking windows (such as the IME). These are in the application's 190 * coordinate space (without compatibility scale applied). 191 */ 192 final Rect mContentInsets = new Rect(); 193 final Rect mLastContentInsets = new Rect(); 194 boolean mContentInsetsChanged; 195 196 /** 197 * Insets that determine the area covered by the display overscan region. These are in the 198 * application's coordinate space (without compatibility scale applied). 199 */ 200 final Rect mOverscanInsets = new Rect(); 201 final Rect mLastOverscanInsets = new Rect(); 202 boolean mOverscanInsetsChanged; 203 204 /** 205 * Insets that determine the area covered by the stable system windows. These are in the 206 * application's coordinate space (without compatibility scale applied). 207 */ 208 final Rect mStableInsets = new Rect(); 209 final Rect mLastStableInsets = new Rect(); 210 boolean mStableInsetsChanged; 211 212 /** 213 * Outsets determine the area outside of the surface where we want to pretend that it's possible 214 * to draw anyway. 215 */ 216 final Rect mOutsets = new Rect(); 217 final Rect mLastOutsets = new Rect(); 218 boolean mOutsetsChanged = false; 219 220 /** 221 * Set to true if we are waiting for this window to receive its 222 * given internal insets before laying out other windows based on it. 223 */ 224 boolean mGivenInsetsPending; 225 226 /** 227 * These are the content insets that were given during layout for 228 * this window, to be applied to windows behind it. 229 */ 230 final Rect mGivenContentInsets = new Rect(); 231 232 /** 233 * These are the visible insets that were given during layout for 234 * this window, to be applied to windows behind it. 235 */ 236 final Rect mGivenVisibleInsets = new Rect(); 237 238 /** 239 * This is the given touchable area relative to the window frame, or null if none. 240 */ 241 final Region mGivenTouchableRegion = new Region(); 242 243 /** 244 * Flag indicating whether the touchable region should be adjusted by 245 * the visible insets; if false the area outside the visible insets is 246 * NOT touchable, so we must use those to adjust the frame during hit 247 * tests. 248 */ 249 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME; 250 251 /** 252 * This is rectangle of the window's surface that is not covered by 253 * system decorations. 254 */ 255 final Rect mSystemDecorRect = new Rect(); 256 final Rect mLastSystemDecorRect = new Rect(); 257 258 // Current transformation being applied. 259 float mGlobalScale=1; 260 float mInvGlobalScale=1; 261 float mHScale=1, mVScale=1; 262 float mLastHScale=1, mLastVScale=1; 263 final Matrix mTmpMatrix = new Matrix(); 264 265 // "Real" frame that the application sees, in display coordinate space. 266 final Rect mFrame = new Rect(); 267 final Rect mLastFrame = new Rect(); 268 // Frame that is scaled to the application's coordinate space when in 269 // screen size compatibility mode. 270 final Rect mCompatFrame = new Rect(); 271 272 final Rect mContainingFrame = new Rect(); 273 274 final Rect mParentFrame = new Rect(); 275 276 // The entire screen area of the {@link TaskStack} this window is in. Usually equal to the 277 // screen area of the device. 278 final Rect mDisplayFrame = new Rect(); 279 280 // The region of the display frame that the display type supports displaying content on. This 281 // is mostly a special case for TV where some displays don’t have the entire display usable. 282 // {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_OVERSCAN} flag can be used to allow 283 // window display contents to extend into the overscan region. 284 final Rect mOverscanFrame = new Rect(); 285 286 // The display frame minus the stable insets. This value is always constant regardless of if 287 // the status bar or navigation bar is visible. 288 final Rect mStableFrame = new Rect(); 289 290 // The area not occupied by the status and navigation bars. So, if both status and navigation 291 // bars are visible, the decor frame is equal to the stable frame. 292 final Rect mDecorFrame = new Rect(); 293 294 // Equal to the decor frame if the IME (e.g. keyboard) is not present. Equal to the decor frame 295 // minus the area occupied by the IME if the IME is present. 296 final Rect mContentFrame = new Rect(); 297 298 // Legacy stuff. Generally equal to the content frame expect when the IME for older apps 299 // displays hint text. 300 final Rect mVisibleFrame = new Rect(); 301 302 // Frame that includes dead area outside of the surface but where we want to pretend that it's 303 // possible to draw. 304 final Rect mOutsetFrame = new Rect(); 305 306 boolean mContentChanged; 307 308 // If a window showing a wallpaper: the requested offset for the 309 // wallpaper; if a wallpaper window: the currently applied offset. 310 float mWallpaperX = -1; 311 float mWallpaperY = -1; 312 313 // If a window showing a wallpaper: what fraction of the offset 314 // range corresponds to a full virtual screen. 315 float mWallpaperXStep = -1; 316 float mWallpaperYStep = -1; 317 318 // If a window showing a wallpaper: a raw pixel offset to forcibly apply 319 // to its window; if a wallpaper window: not used. 320 int mWallpaperDisplayOffsetX = Integer.MIN_VALUE; 321 int mWallpaperDisplayOffsetY = Integer.MIN_VALUE; 322 323 // Wallpaper windows: pixels offset based on above variables. 324 int mXOffset; 325 int mYOffset; 326 327 /** 328 * This is set after IWindowSession.relayout() has been called at 329 * least once for the window. It allows us to detect the situation 330 * where we don't yet have a surface, but should have one soon, so 331 * we can give the window focus before waiting for the relayout. 332 */ 333 boolean mRelayoutCalled; 334 335 /** 336 * If the application has called relayout() with changes that can 337 * impact its window's size, we need to perform a layout pass on it 338 * even if it is not currently visible for layout. This is set 339 * when in that case until the layout is done. 340 */ 341 boolean mLayoutNeeded; 342 343 /** Currently running an exit animation? */ 344 boolean mExiting; 345 346 /** Currently on the mDestroySurface list? */ 347 boolean mDestroying; 348 349 /** Completely remove from window manager after exit animation? */ 350 boolean mRemoveOnExit; 351 352 /** 353 * Whether the app died while it was visible, if true we might need 354 * to continue to show it until it's restarted. 355 */ 356 boolean mAppDied; 357 358 /** 359 * Set when the orientation is changing and this window has not yet 360 * been updated for the new orientation. 361 */ 362 boolean mOrientationChanging; 363 364 /** 365 * How long we last kept the screen frozen. 366 */ 367 int mLastFreezeDuration; 368 369 /** Is this window now (or just being) removed? */ 370 boolean mRemoved; 371 372 /** 373 * Temp for keeping track of windows that have been removed when 374 * rebuilding window list. 375 */ 376 boolean mRebuilding; 377 378 // Input channel and input window handle used by the input dispatcher. 379 final InputWindowHandle mInputWindowHandle; 380 InputChannel mInputChannel; 381 InputChannel mClientChannel; 382 383 // Used to improve performance of toString() 384 String mStringNameCache; 385 CharSequence mLastTitle; 386 boolean mWasExiting; 387 388 final WindowStateAnimator mWinAnimator; 389 390 boolean mHasSurface = false; 391 392 boolean mNotOnAppsDisplay = false; 393 DisplayContent mDisplayContent; 394 395 /** When true this window can be displayed on screens owther than mOwnerUid's */ 396 private boolean mShowToOwnerOnly; 397 398 /** 399 * Wake lock for drawing. 400 * Even though it's slightly more expensive to do so, we will use a separate wake lock 401 * for each app that is requesting to draw while dozing so that we can accurately track 402 * who is preventing the system from suspending. 403 * This lock is only acquired on first use. 404 */ 405 PowerManager.WakeLock mDrawLock; 406 407 final private Rect mTmpRect = new Rect(); 408 409 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, 410 WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a, 411 int viewVisibility, final DisplayContent displayContent) { 412 mService = service; 413 mSession = s; 414 mClient = c; 415 mAppOp = appOp; 416 mToken = token; 417 mOwnerUid = s.mUid; 418 mWindowId = new IWindowId.Stub() { 419 @Override 420 public void registerFocusObserver(IWindowFocusObserver observer) { 421 WindowState.this.registerFocusObserver(observer); 422 } 423 @Override 424 public void unregisterFocusObserver(IWindowFocusObserver observer) { 425 WindowState.this.unregisterFocusObserver(observer); 426 } 427 @Override 428 public boolean isFocused() { 429 return WindowState.this.isFocused(); 430 } 431 }; 432 mAttrs.copyFrom(a); 433 mViewVisibility = viewVisibility; 434 mDisplayContent = displayContent; 435 mPolicy = mService.mPolicy; 436 mContext = mService.mContext; 437 DeathRecipient deathRecipient = new DeathRecipient(); 438 mSeq = seq; 439 mEnforceSizeCompat = (mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0; 440 if (WindowManagerService.localLOGV) Slog.v( 441 TAG, "Window " + this + " client=" + c.asBinder() 442 + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a); 443 try { 444 c.asBinder().linkToDeath(deathRecipient, 0); 445 } catch (RemoteException e) { 446 mDeathRecipient = null; 447 mAttachedWindow = null; 448 mLayoutAttached = false; 449 mIsImWindow = false; 450 mIsWallpaper = false; 451 mIsFloatingLayer = false; 452 mBaseLayer = 0; 453 mSubLayer = 0; 454 mInputWindowHandle = null; 455 mWinAnimator = null; 456 return; 457 } 458 mDeathRecipient = deathRecipient; 459 460 if ((mAttrs.type >= FIRST_SUB_WINDOW && 461 mAttrs.type <= LAST_SUB_WINDOW)) { 462 // The multiplier here is to reserve space for multiple 463 // windows in the same type layer. 464 mBaseLayer = mPolicy.windowTypeToLayerLw( 465 attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER 466 + WindowManagerService.TYPE_LAYER_OFFSET; 467 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type); 468 mAttachedWindow = attachedWindow; 469 if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " 470 + mAttachedWindow); 471 472 final WindowList childWindows = mAttachedWindow.mChildWindows; 473 final int numChildWindows = childWindows.size(); 474 if (numChildWindows == 0) { 475 childWindows.add(this); 476 } else { 477 boolean added = false; 478 for (int i = 0; i < numChildWindows; i++) { 479 final int childSubLayer = childWindows.get(i).mSubLayer; 480 if (mSubLayer < childSubLayer 481 || (mSubLayer == childSubLayer && childSubLayer < 0)) { 482 // We insert the child window into the list ordered by the sub-layer. For 483 // same sub-layers, the negative one should go below others; the positive 484 // one should go above others. 485 childWindows.add(i, this); 486 added = true; 487 break; 488 } 489 } 490 if (!added) { 491 childWindows.add(this); 492 } 493 } 494 495 mLayoutAttached = mAttrs.type != 496 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 497 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD 498 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 499 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER; 500 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 501 } else { 502 // The multiplier here is to reserve space for multiple 503 // windows in the same type layer. 504 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type) 505 * WindowManagerService.TYPE_LAYER_MULTIPLIER 506 + WindowManagerService.TYPE_LAYER_OFFSET; 507 mSubLayer = 0; 508 mAttachedWindow = null; 509 mLayoutAttached = false; 510 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD 511 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 512 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER; 513 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 514 } 515 516 WindowState appWin = this; 517 while (appWin.mAttachedWindow != null) { 518 appWin = appWin.mAttachedWindow; 519 } 520 WindowToken appToken = appWin.mToken; 521 while (appToken.appWindowToken == null) { 522 WindowToken parent = mService.mTokenMap.get(appToken.token); 523 if (parent == null || appToken == parent) { 524 break; 525 } 526 appToken = parent; 527 } 528 mRootToken = appToken; 529 mAppToken = appToken.appWindowToken; 530 if (mAppToken != null) { 531 final DisplayContent appDisplay = getDisplayContent(); 532 mNotOnAppsDisplay = displayContent != appDisplay; 533 534 if (mAppToken.showForAllUsers) { 535 // Windows for apps that can show for all users should also show when the 536 // device is locked. 537 mAttrs.flags |= FLAG_SHOW_WHEN_LOCKED; 538 } 539 } 540 541 mWinAnimator = new WindowStateAnimator(this); 542 mWinAnimator.mAlpha = a.alpha; 543 544 mRequestedWidth = 0; 545 mRequestedHeight = 0; 546 mLastRequestedWidth = 0; 547 mLastRequestedHeight = 0; 548 mXOffset = 0; 549 mYOffset = 0; 550 mLayer = 0; 551 mInputWindowHandle = new InputWindowHandle( 552 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this, 553 displayContent.getDisplayId()); 554 } 555 556 void attach() { 557 if (WindowManagerService.localLOGV) Slog.v( 558 TAG, "Attaching " + this + " token=" + mToken 559 + ", list=" + mToken.windows); 560 mSession.windowAddedLocked(); 561 } 562 563 @Override 564 public int getOwningUid() { 565 return mOwnerUid; 566 } 567 568 @Override 569 public String getOwningPackage() { 570 return mAttrs.packageName; 571 } 572 573 @Override 574 public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf, 575 Rect osf) { 576 if (mAppToken != null && mAppToken.mWillReplaceWindow 577 && (mExiting || !mAppToken.mReplacingRemoveRequested)) { 578 // This window is being replaced and either already got information that it's being 579 // removed or we are still waiting for some information. Because of this we don't 580 // want to apply any more changes to it, so it remains in this state until new window 581 // appears. 582 return; 583 } 584 mHaveFrame = true; 585 586 final Task task = getTask(); 587 final boolean nonFullscreenTask = task != null && !task.isFullscreen(); 588 final boolean freeformWorkspace = task != null && task.inFreeformWorkspace(); 589 if (nonFullscreenTask) { 590 task.getBounds(mContainingFrame); 591 final WindowState imeWin = mService.mInputMethodWindow; 592 if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this 593 && mContainingFrame.bottom > cf.bottom) { 594 // IME is up and obscuring this window. Adjust the window position so it is visible. 595 mContainingFrame.top -= mContainingFrame.bottom - cf.bottom; 596 } 597 598 if (freeformWorkspace) { 599 // In free form mode we have only to set the rectangle if it wasn't set already. No 600 // need to intersect it with the (visible) "content frame" since it is allowed to 601 // be outside the visible desktop. 602 if (mContainingFrame.isEmpty()) { 603 mContainingFrame.set(cf); 604 } 605 } 606 mDisplayFrame.set(mContainingFrame); 607 } else { 608 mContainingFrame.set(pf); 609 mDisplayFrame.set(df); 610 } 611 612 final int pw = mContainingFrame.width(); 613 final int ph = mContainingFrame.height(); 614 615 int w,h; 616 if ((mAttrs.flags & FLAG_SCALED) != 0) { 617 if (mAttrs.width < 0) { 618 w = pw; 619 } else if (mEnforceSizeCompat) { 620 w = (int)(mAttrs.width * mGlobalScale + .5f); 621 } else { 622 w = mAttrs.width; 623 } 624 if (mAttrs.height < 0) { 625 h = ph; 626 } else if (mEnforceSizeCompat) { 627 h = (int)(mAttrs.height * mGlobalScale + .5f); 628 } else { 629 h = mAttrs.height; 630 } 631 } else { 632 if (mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT) { 633 w = pw; 634 } else if (mEnforceSizeCompat) { 635 w = (int)(mRequestedWidth * mGlobalScale + .5f); 636 } else { 637 w = mRequestedWidth; 638 } 639 if (mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT) { 640 h = ph; 641 } else if (mEnforceSizeCompat) { 642 h = (int)(mRequestedHeight * mGlobalScale + .5f); 643 } else { 644 h = mRequestedHeight; 645 } 646 } 647 648 if (!mParentFrame.equals(pf)) { 649 //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame 650 // + " to " + pf); 651 mParentFrame.set(pf); 652 mContentChanged = true; 653 } 654 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { 655 mLastRequestedWidth = mRequestedWidth; 656 mLastRequestedHeight = mRequestedHeight; 657 mContentChanged = true; 658 } 659 660 mOverscanFrame.set(of); 661 mContentFrame.set(cf); 662 mVisibleFrame.set(vf); 663 mDecorFrame.set(dcf); 664 mStableFrame.set(sf); 665 final boolean hasOutsets = osf != null; 666 if (hasOutsets) { 667 mOutsetFrame.set(osf); 668 } 669 670 final int fw = mFrame.width(); 671 final int fh = mFrame.height(); 672 673 float x, y; 674 if (mEnforceSizeCompat) { 675 x = mAttrs.x * mGlobalScale; 676 y = mAttrs.y * mGlobalScale; 677 } else { 678 x = mAttrs.x; 679 y = mAttrs.y; 680 } 681 682 if (nonFullscreenTask) { 683 // Make sure window fits in containing frame since it is in a non-fullscreen stack as 684 // required by {@link Gravity#apply} call. 685 w = Math.min(w, pw); 686 h = Math.min(h, ph); 687 } 688 689 Gravity.apply(mAttrs.gravity, w, h, mContainingFrame, 690 (int) (x + mAttrs.horizontalMargin * pw), 691 (int) (y + mAttrs.verticalMargin * ph), mFrame); 692 693 // Now make sure the window fits in the overall display frame. 694 Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame); 695 696 // Calculate the outsets before the content frame gets shrinked to the window frame. 697 if (hasOutsets) { 698 mOutsets.set(Math.max(mContentFrame.left - mOutsetFrame.left, 0), 699 Math.max(mContentFrame.top - mOutsetFrame.top, 0), 700 Math.max(mOutsetFrame.right - mContentFrame.right, 0), 701 Math.max(mOutsetFrame.bottom - mContentFrame.bottom, 0)); 702 } else { 703 mOutsets.set(0, 0, 0, 0); 704 } 705 706 // Make sure the content and visible frames are inside of the 707 // final window frame. 708 if (freeformWorkspace && !mFrame.isEmpty()) { 709 // Keep the frame out of the blocked system area, limit it in size to the content area 710 // and make sure that there is always a minimum visible so that the user can drag it 711 // into a usable area.. 712 final int height = Math.min(mFrame.height(), mContentFrame.height()); 713 final int width = Math.min(mContentFrame.width(), mFrame.width()); 714 final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); 715 final int minVisibleHeight = WindowManagerService.dipToPixel( 716 MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics); 717 final int minVisibleWidth = WindowManagerService.dipToPixel( 718 MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics); 719 final int top = Math.max(mContentFrame.top, 720 Math.min(mFrame.top, mContentFrame.bottom - minVisibleHeight)); 721 final int left = Math.max(mContentFrame.left + minVisibleWidth - width, 722 Math.min(mFrame.left, mContentFrame.right - minVisibleWidth)); 723 mFrame.set(left, top, left + width, top + height); 724 mContentFrame.set(mFrame); 725 mVisibleFrame.set(mContentFrame); 726 mStableFrame.set(mContentFrame); 727 } else if (mAttrs.type == TYPE_DOCK_DIVIDER) { 728 mDisplayContent.mDividerControllerLocked.positionDockedStackedDivider(mFrame); 729 mContentFrame.set(mFrame); 730 } else { 731 mContentFrame.set(Math.max(mContentFrame.left, mFrame.left), 732 Math.max(mContentFrame.top, mFrame.top), 733 Math.min(mContentFrame.right, mFrame.right), 734 Math.min(mContentFrame.bottom, mFrame.bottom)); 735 736 mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left), 737 Math.max(mVisibleFrame.top, mFrame.top), 738 Math.min(mVisibleFrame.right, mFrame.right), 739 Math.min(mVisibleFrame.bottom, mFrame.bottom)); 740 741 mStableFrame.set(Math.max(mStableFrame.left, mFrame.left), 742 Math.max(mStableFrame.top, mFrame.top), 743 Math.min(mStableFrame.right, mFrame.right), 744 Math.min(mStableFrame.bottom, mFrame.bottom)); 745 } 746 747 mOverscanInsets.set(Math.max(mOverscanFrame.left - mFrame.left, 0), 748 Math.max(mOverscanFrame.top - mFrame.top, 0), 749 Math.max(mFrame.right - mOverscanFrame.right, 0), 750 Math.max(mFrame.bottom - mOverscanFrame.bottom, 0)); 751 752 mContentInsets.set(mContentFrame.left - mFrame.left, 753 mContentFrame.top - mFrame.top, 754 mFrame.right - mContentFrame.right, 755 mFrame.bottom - mContentFrame.bottom); 756 757 mVisibleInsets.set(mVisibleFrame.left - mFrame.left, 758 mVisibleFrame.top - mFrame.top, 759 mFrame.right - mVisibleFrame.right, 760 mFrame.bottom - mVisibleFrame.bottom); 761 762 mStableInsets.set(Math.max(mStableFrame.left - mFrame.left, 0), 763 Math.max(mStableFrame.top - mFrame.top, 0), 764 Math.max(mFrame.right - mStableFrame.right, 0), 765 Math.max(mFrame.bottom - mStableFrame.bottom, 0)); 766 767 mCompatFrame.set(mFrame); 768 if (mEnforceSizeCompat) { 769 // If there is a size compatibility scale being applied to the 770 // window, we need to apply this to its insets so that they are 771 // reported to the app in its coordinate space. 772 mOverscanInsets.scale(mInvGlobalScale); 773 mContentInsets.scale(mInvGlobalScale); 774 mVisibleInsets.scale(mInvGlobalScale); 775 mStableInsets.scale(mInvGlobalScale); 776 mOutsets.scale(mInvGlobalScale); 777 778 // Also the scaled frame that we report to the app needs to be 779 // adjusted to be in its coordinate space. 780 mCompatFrame.scale(mInvGlobalScale); 781 } 782 783 if (mIsWallpaper && (fw != mFrame.width() || fh != mFrame.height())) { 784 final DisplayContent displayContent = getDisplayContent(); 785 if (displayContent != null) { 786 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 787 mService.mWallpaperControllerLocked.updateWallpaperOffset( 788 this, displayInfo.logicalWidth, displayInfo.logicalHeight, false); 789 } 790 } 791 792 if (DEBUG_LAYOUT || WindowManagerService.localLOGV) Slog.v(TAG, 793 "Resolving (mRequestedWidth=" 794 + mRequestedWidth + ", mRequestedheight=" 795 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph 796 + "): frame=" + mFrame.toShortString() 797 + " ci=" + mContentInsets.toShortString() 798 + " vi=" + mVisibleInsets.toShortString() 799 + " vi=" + mStableInsets.toShortString() 800 + " of=" + mOutsets.toShortString()); 801 } 802 803 @Override 804 public Rect getFrameLw() { 805 return mFrame; 806 } 807 808 @Override 809 public Point getShownPositionLw() { 810 return mShownPosition; 811 } 812 813 @Override 814 public Rect getDisplayFrameLw() { 815 return mDisplayFrame; 816 } 817 818 @Override 819 public Rect getOverscanFrameLw() { 820 return mOverscanFrame; 821 } 822 823 @Override 824 public Rect getContentFrameLw() { 825 return mContentFrame; 826 } 827 828 @Override 829 public Rect getVisibleFrameLw() { 830 return mVisibleFrame; 831 } 832 833 @Override 834 public boolean getGivenInsetsPendingLw() { 835 return mGivenInsetsPending; 836 } 837 838 @Override 839 public Rect getGivenContentInsetsLw() { 840 return mGivenContentInsets; 841 } 842 843 @Override 844 public Rect getGivenVisibleInsetsLw() { 845 return mGivenVisibleInsets; 846 } 847 848 @Override 849 public WindowManager.LayoutParams getAttrs() { 850 return mAttrs; 851 } 852 853 @Override 854 public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) { 855 int index = -1; 856 WindowState ws = this; 857 WindowList windows = getWindowList(); 858 while (true) { 859 if (ws.mAttrs.needsMenuKey != WindowManager.LayoutParams.NEEDS_MENU_UNSET) { 860 return ws.mAttrs.needsMenuKey == WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE; 861 } 862 // If we reached the bottom of the range of windows we are considering, 863 // assume no menu is needed. 864 if (ws == bottom) { 865 return false; 866 } 867 // The current window hasn't specified whether menu key is needed; 868 // look behind it. 869 // First, we may need to determine the starting position. 870 if (index < 0) { 871 index = windows.indexOf(ws); 872 } 873 index--; 874 if (index < 0) { 875 return false; 876 } 877 ws = windows.get(index); 878 } 879 } 880 881 @Override 882 public int getSystemUiVisibility() { 883 return mSystemUiVisibility; 884 } 885 886 @Override 887 public int getSurfaceLayer() { 888 return mLayer; 889 } 890 891 @Override 892 public int getBaseType() { 893 WindowState win = this; 894 while (win.mAttachedWindow != null) { 895 win = win.mAttachedWindow; 896 } 897 return win.mAttrs.type; 898 } 899 900 @Override 901 public IApplicationToken getAppToken() { 902 return mAppToken != null ? mAppToken.appToken : null; 903 } 904 905 @Override 906 public boolean isVoiceInteraction() { 907 return mAppToken != null && mAppToken.voiceInteraction; 908 } 909 910 boolean setInsetsChanged() { 911 mOverscanInsetsChanged |= !mLastOverscanInsets.equals(mOverscanInsets); 912 mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets); 913 mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets); 914 mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets); 915 mOutsetsChanged |= !mLastOutsets.equals(mOutsets); 916 return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged 917 || mOutsetsChanged; 918 } 919 920 public DisplayContent getDisplayContent() { 921 if (mAppToken == null || mNotOnAppsDisplay) { 922 return mDisplayContent; 923 } 924 final TaskStack stack = getStack(); 925 return stack == null ? mDisplayContent : stack.getDisplayContent(); 926 } 927 928 public DisplayInfo getDisplayInfo() { 929 final DisplayContent displayContent = getDisplayContent(); 930 return displayContent != null ? displayContent.getDisplayInfo() : null; 931 } 932 933 public int getDisplayId() { 934 final DisplayContent displayContent = getDisplayContent(); 935 if (displayContent == null) { 936 return -1; 937 } 938 return displayContent.getDisplayId(); 939 } 940 941 Task getTask() { 942 return mAppToken != null ? mAppToken.mTask : null; 943 } 944 945 TaskStack getStack() { 946 Task task = getTask(); 947 if (task != null) { 948 if (task.mStack != null) { 949 return task.mStack; 950 } 951 } 952 // Some system windows (e.g. "Power off" dialog) don't have a task, but we would still 953 // associate them with some stack to enable dimming. 954 return mAttrs.type >= WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW 955 && mDisplayContent != null ? mDisplayContent.getHomeStack() : null; 956 } 957 958 /** 959 * Retrieves the visible bounds of the window. 960 * @param bounds The rect which gets the bounds. 961 * @param forTouch Pass in BOUNDS_FOR_TOUCH to get touch related bounds, otherwise visible 962 * bounds will be returned. 963 */ 964 void getVisibleBounds(Rect bounds, boolean forTouch) { 965 boolean intersectWithStackBounds = mAppToken != null && mAppToken.mCropWindowsToStack; 966 bounds.setEmpty(); 967 mTmpRect.setEmpty(); 968 if (intersectWithStackBounds) { 969 final TaskStack stack = getStack(); 970 if (stack != null) { 971 stack.getBounds(mTmpRect); 972 } else { 973 intersectWithStackBounds = false; 974 } 975 } 976 977 bounds.set(mVisibleFrame); 978 if (intersectWithStackBounds) { 979 bounds.intersect(mTmpRect); 980 } 981 982 if (bounds.isEmpty()) { 983 bounds.set(mFrame); 984 if (intersectWithStackBounds) { 985 bounds.intersect(mTmpRect); 986 } 987 return; 988 } 989 if (forTouch && inFreeformWorkspace()) { 990 final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); 991 final int delta = WindowManagerService.dipToPixel( 992 RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics); 993 bounds.inset(-delta, -delta); 994 } 995 } 996 997 public long getInputDispatchingTimeoutNanos() { 998 return mAppToken != null 999 ? mAppToken.inputDispatchingTimeoutNanos 1000 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 1001 } 1002 1003 @Override 1004 public boolean hasAppShownWindows() { 1005 return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed); 1006 } 1007 1008 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 1009 if (dsdx < .99999f || dsdx > 1.00001f) return false; 1010 if (dtdy < .99999f || dtdy > 1.00001f) return false; 1011 if (dtdx < -.000001f || dtdx > .000001f) return false; 1012 if (dsdy < -.000001f || dsdy > .000001f) return false; 1013 return true; 1014 } 1015 1016 void prelayout() { 1017 if (mEnforceSizeCompat) { 1018 mGlobalScale = mService.mCompatibleScreenScale; 1019 mInvGlobalScale = 1/mGlobalScale; 1020 } else { 1021 mGlobalScale = mInvGlobalScale = 1; 1022 } 1023 } 1024 1025 /** 1026 * Is this window visible? It is not visible if there is no 1027 * surface, or we are in the process of running an exit animation 1028 * that will remove the surface, or its app token has been hidden. 1029 */ 1030 @Override 1031 public boolean isVisibleLw() { 1032 final AppWindowToken atoken = mAppToken; 1033 return mHasSurface && mPolicyVisibility && !mAttachedHidden 1034 && (atoken == null || !atoken.hiddenRequested) 1035 && !mExiting && !mDestroying; 1036 } 1037 1038 /** 1039 * Like {@link #isVisibleLw}, but also counts a window that is currently 1040 * "hidden" behind the keyguard as visible. This allows us to apply 1041 * things like window flags that impact the keyguard. 1042 * XXX I am starting to think we need to have ANOTHER visibility flag 1043 * for this "hidden behind keyguard" state rather than overloading 1044 * mPolicyVisibility. Ungh. 1045 */ 1046 @Override 1047 public boolean isVisibleOrBehindKeyguardLw() { 1048 if (mRootToken.waitingToShow && 1049 mService.mAppTransition.isTransitionSet()) { 1050 return false; 1051 } 1052 final AppWindowToken atoken = mAppToken; 1053 final boolean animating = atoken != null && atoken.mAppAnimator.animation != null; 1054 return mHasSurface && !mDestroying && !mExiting 1055 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested) 1056 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE 1057 && !mRootToken.hidden) 1058 || mWinAnimator.mAnimation != null || animating); 1059 } 1060 1061 /** 1062 * Is this window visible, ignoring its app token? It is not visible 1063 * if there is no surface, or we are in the process of running an exit animation 1064 * that will remove the surface. 1065 */ 1066 public boolean isWinVisibleLw() { 1067 final AppWindowToken atoken = mAppToken; 1068 return mHasSurface && mPolicyVisibility && !mAttachedHidden 1069 && (atoken == null || !atoken.hiddenRequested || atoken.mAppAnimator.animating) 1070 && !mExiting && !mDestroying; 1071 } 1072 1073 /** 1074 * The same as isVisible(), but follows the current hidden state of 1075 * the associated app token, not the pending requested hidden state. 1076 */ 1077 boolean isVisibleNow() { 1078 return mHasSurface && mPolicyVisibility && !mAttachedHidden 1079 && (!mRootToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING) 1080 && !mExiting && !mDestroying; 1081 } 1082 1083 /** 1084 * Can this window possibly be a drag/drop target? The test here is 1085 * a combination of the above "visible now" with the check that the 1086 * Input Manager uses when discarding windows from input consideration. 1087 */ 1088 boolean isPotentialDragTarget() { 1089 return isVisibleNow() && !mRemoved 1090 && mInputChannel != null && mInputWindowHandle != null; 1091 } 1092 1093 /** 1094 * Same as isVisible(), but we also count it as visible between the 1095 * call to IWindowSession.add() and the first relayout(). 1096 */ 1097 boolean isVisibleOrAdding() { 1098 final AppWindowToken atoken = mAppToken; 1099 return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE)) 1100 && mPolicyVisibility && !mAttachedHidden 1101 && (atoken == null || !atoken.hiddenRequested) 1102 && !mExiting && !mDestroying; 1103 } 1104 1105 /** 1106 * Is this window currently on-screen? It is on-screen either if it 1107 * is visible or it is currently running an animation before no longer 1108 * being visible. 1109 */ 1110 boolean isOnScreen() { 1111 return mPolicyVisibility && isOnScreenIgnoringKeyguard(); 1112 } 1113 1114 /** 1115 * Like isOnScreen(), but ignores any force hiding of the window due 1116 * to the keyguard. 1117 */ 1118 boolean isOnScreenIgnoringKeyguard() { 1119 if (!mHasSurface || mDestroying) { 1120 return false; 1121 } 1122 final AppWindowToken atoken = mAppToken; 1123 if (atoken != null) { 1124 return ((!mAttachedHidden && !atoken.hiddenRequested) 1125 || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null); 1126 } 1127 return !mAttachedHidden || mWinAnimator.mAnimation != null; 1128 } 1129 1130 /** 1131 * Like isOnScreen(), but we don't return true if the window is part 1132 * of a transition that has not yet been started. 1133 */ 1134 boolean isReadyForDisplay() { 1135 if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { 1136 return false; 1137 } 1138 return mHasSurface && mPolicyVisibility && !mDestroying 1139 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE 1140 && !mRootToken.hidden) 1141 || mWinAnimator.mAnimation != null 1142 || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null))); 1143 } 1144 1145 /** 1146 * Like isReadyForDisplay(), but ignores any force hiding of the window due 1147 * to the keyguard. 1148 */ 1149 boolean isReadyForDisplayIgnoringKeyguard() { 1150 if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { 1151 return false; 1152 } 1153 final AppWindowToken atoken = mAppToken; 1154 if (atoken == null && !mPolicyVisibility) { 1155 // If this is not an app window, and the policy has asked to force 1156 // hide, then we really do want to hide. 1157 return false; 1158 } 1159 return mHasSurface && !mDestroying 1160 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE 1161 && !mRootToken.hidden) 1162 || mWinAnimator.mAnimation != null 1163 || ((atoken != null) && (atoken.mAppAnimator.animation != null) 1164 && !mWinAnimator.isDummyAnimation())); 1165 } 1166 1167 /** 1168 * Like isOnScreen, but returns false if the surface hasn't yet 1169 * been drawn. 1170 */ 1171 @Override 1172 public boolean isDisplayedLw() { 1173 final AppWindowToken atoken = mAppToken; 1174 return isDrawnLw() && mPolicyVisibility 1175 && ((!mAttachedHidden && 1176 (atoken == null || !atoken.hiddenRequested)) 1177 || mWinAnimator.mAnimating 1178 || (atoken != null && atoken.mAppAnimator.animation != null)); 1179 } 1180 1181 /** 1182 * Return true if this window or its app token is currently animating. 1183 */ 1184 @Override 1185 public boolean isAnimatingLw() { 1186 return mWinAnimator.mAnimation != null 1187 || (mAppToken != null && mAppToken.mAppAnimator.animation != null); 1188 } 1189 1190 @Override 1191 public boolean isGoneForLayoutLw() { 1192 final AppWindowToken atoken = mAppToken; 1193 return mViewVisibility == View.GONE 1194 || !mRelayoutCalled 1195 || (atoken == null && mRootToken.hidden) 1196 || (atoken != null && (atoken.hiddenRequested || atoken.hidden)) 1197 || mAttachedHidden 1198 || (mExiting && !isAnimatingLw()) 1199 || mDestroying; 1200 } 1201 1202 /** 1203 * Returns true if the window has a surface that it has drawn a 1204 * complete UI in to. 1205 */ 1206 public boolean isDrawFinishedLw() { 1207 return mHasSurface && !mDestroying && 1208 (mWinAnimator.mDrawState == WindowStateAnimator.COMMIT_DRAW_PENDING 1209 || mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW 1210 || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN); 1211 } 1212 1213 /** 1214 * Returns true if the window has a surface that it has drawn a 1215 * complete UI in to. 1216 */ 1217 @Override 1218 public boolean isDrawnLw() { 1219 return mHasSurface && !mDestroying && 1220 (mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW 1221 || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN); 1222 } 1223 1224 /** 1225 * Return true if the window is opaque and fully drawn. This indicates 1226 * it may obscure windows behind it. 1227 */ 1228 boolean isOpaqueDrawn() { 1229 return (mAttrs.format == PixelFormat.OPAQUE 1230 || mAttrs.type == TYPE_WALLPAPER) 1231 && isDrawnLw() && mWinAnimator.mAnimation == null 1232 && (mAppToken == null || mAppToken.mAppAnimator.animation == null); 1233 } 1234 1235 /** 1236 * Return whether this window has moved. (Only makes 1237 * sense to call from performLayoutAndPlaceSurfacesLockedInner().) 1238 */ 1239 boolean hasMoved() { 1240 return mHasSurface && mContentChanged && !mExiting && !mWinAnimator.mLastHidden 1241 && mService.okToDisplay() && (mFrame.top != mLastFrame.top 1242 || mFrame.left != mLastFrame.left) 1243 && (mAttachedWindow == null || !mAttachedWindow.hasMoved()); 1244 } 1245 1246 boolean isFullscreen(int screenWidth, int screenHeight) { 1247 return mFrame.left <= 0 && mFrame.top <= 0 && 1248 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight; 1249 } 1250 1251 boolean isConfigChanged() { 1252 final Task task = getTask(); 1253 final Configuration overrideConfig = 1254 (task != null) ? task.mOverrideConfig : Configuration.EMPTY; 1255 final Configuration serviceConfig = mService.mCurConfiguration; 1256 boolean configChanged = 1257 (mConfiguration != serviceConfig && mConfiguration.diff(serviceConfig) != 0) 1258 || (mOverrideConfig != overrideConfig && !mOverrideConfig.equals(overrideConfig)); 1259 1260 if ((mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 1261 // Retain configuration changed status until resetConfiguration called. 1262 mConfigHasChanged |= configChanged; 1263 configChanged = mConfigHasChanged; 1264 } 1265 1266 return configChanged; 1267 } 1268 1269 void removeLocked() { 1270 disposeInputChannel(); 1271 1272 if (mAttachedWindow != null) { 1273 if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow); 1274 mAttachedWindow.mChildWindows.remove(this); 1275 } 1276 mWinAnimator.destroyDeferredSurfaceLocked(); 1277 mWinAnimator.destroySurfaceLocked(); 1278 mSession.windowRemovedLocked(); 1279 try { 1280 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0); 1281 } catch (RuntimeException e) { 1282 // Ignore if it has already been removed (usually because 1283 // we are doing this as part of processing a death note.) 1284 } 1285 } 1286 1287 private void setConfiguration( 1288 final Configuration newConfig, final Configuration newOverrideConfig) { 1289 mConfiguration = newConfig; 1290 mOverrideConfig = newOverrideConfig; 1291 mConfigHasChanged = false; 1292 } 1293 1294 private final class DeadWindowEventReceiver extends InputEventReceiver { 1295 DeadWindowEventReceiver(InputChannel inputChannel) { 1296 super(inputChannel, mService.mH.getLooper()); 1297 } 1298 @Override 1299 public void onInputEvent(InputEvent event) { 1300 finishInputEvent(event, true); 1301 } 1302 } 1303 /** 1304 * Dummy event receiver for windows that died visible. 1305 */ 1306 private DeadWindowEventReceiver mDeadWindowEventReceiver; 1307 1308 void openInputChannel(InputChannel outInputChannel) { 1309 if (mInputChannel != null) { 1310 throw new IllegalStateException("Window already has an input channel."); 1311 } 1312 String name = makeInputChannelName(); 1313 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); 1314 mInputChannel = inputChannels[0]; 1315 mClientChannel = inputChannels[1]; 1316 mInputWindowHandle.inputChannel = inputChannels[0]; 1317 if (outInputChannel != null) { 1318 mClientChannel.transferTo(outInputChannel); 1319 mClientChannel.dispose(); 1320 mClientChannel = null; 1321 } else { 1322 // If the window died visible, we setup a dummy input channel, so that taps 1323 // can still detected by input monitor channel, and we can relaunch the app. 1324 // Create dummy event receiver that simply reports all events as handled. 1325 mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel); 1326 } 1327 mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle); 1328 } 1329 1330 void disposeInputChannel() { 1331 if (mDeadWindowEventReceiver != null) { 1332 mDeadWindowEventReceiver.dispose(); 1333 mDeadWindowEventReceiver = null; 1334 } 1335 1336 // unregister server channel first otherwise it complains about broken channel 1337 if (mInputChannel != null) { 1338 mService.mInputManager.unregisterInputChannel(mInputChannel); 1339 mInputChannel.dispose(); 1340 mInputChannel = null; 1341 } 1342 if (mClientChannel != null) { 1343 mClientChannel.dispose(); 1344 mClientChannel = null; 1345 } 1346 mInputWindowHandle.inputChannel = null; 1347 } 1348 1349 void applyDimLayerIfNeeded() { 1350 if (!mExiting && mAppDied) { 1351 // If app died visible, apply a dim over the window to indicate that it's inactive 1352 mDisplayContent.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator); 1353 } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0 1354 && mDisplayContent != null && !mExiting && isDisplayedLw()) { 1355 mDisplayContent.mDimLayerController.applyDimBehind(getDimLayerUser(), mWinAnimator); 1356 } 1357 } 1358 1359 DimLayer.DimLayerUser getDimLayerUser() { 1360 Task task = getTask(); 1361 if (task != null) { 1362 return task; 1363 } 1364 return getStack(); 1365 } 1366 1367 void maybeRemoveReplacedWindow() { 1368 AppWindowToken token = mAppToken; 1369 if (token != null && token.mWillReplaceWindow && token.mReplacingWindow == this) { 1370 if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replacing window: " + this); 1371 token.mWillReplaceWindow = false; 1372 token.mAnimateReplacingWindow = false; 1373 token.mReplacingRemoveRequested = false; 1374 token.mReplacingWindow = null; 1375 for (int i = token.allAppWindows.size() - 1; i >= 0; i--) { 1376 WindowState win = token.allAppWindows.get(i); 1377 if (win.mExiting) { 1378 mService.removeWindowInnerLocked(win); 1379 } 1380 } 1381 } 1382 } 1383 1384 void setDisplayLayoutNeeded() { 1385 if (mDisplayContent != null) { 1386 mDisplayContent.layoutNeeded = true; 1387 } 1388 } 1389 1390 boolean inDockedWorkspace() { 1391 return mAppToken != null && mAppToken.mTask != null && mAppToken.mTask.inDockedWorkspace(); 1392 } 1393 1394 int getTouchableRegion(Region region, int flags, InputMonitor inputMonitor) { 1395 final boolean modal = (flags & (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 1396 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) == 0; 1397 if (modal && mAppToken != null) { 1398 // Limit the outer touch to the activity stack region. 1399 flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 1400 if (!inFreeformWorkspace()) { 1401 // If this is a modal window we need to dismiss it if it's not full screen and the 1402 // touch happens outside of the frame that displays the content. This means we 1403 // need to intercept touches outside of that window. The dim layer user 1404 // associated with the window (task or stack) will give us the good bounds, as 1405 // they would be used to display the dim layer. 1406 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser(); 1407 if (dimLayerUser != null) { 1408 dimLayerUser.getBounds(mTmpRect); 1409 } else { 1410 getVisibleBounds(mTmpRect, BOUNDS_FOR_TOUCH); 1411 } 1412 } else { 1413 // For freeform windows we the touch region to include the whole surface for the 1414 // shadows. 1415 getVisibleBounds(mTmpRect, BOUNDS_FOR_TOUCH); 1416 } 1417 region.set(mTmpRect); 1418 } else { 1419 // Not modal or full screen modal 1420 getTouchableRegion(region); 1421 } 1422 return flags; 1423 } 1424 1425 void checkPolicyVisibilityChange() { 1426 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) { 1427 if (DEBUG_VISIBILITY) { 1428 Slog.v(TAG, "Policy visibility changing after anim in " + 1429 mWinAnimator + ": " + mPolicyVisibilityAfterAnim); 1430 } 1431 mPolicyVisibility = mPolicyVisibilityAfterAnim; 1432 if (mDisplayContent != null) { 1433 mDisplayContent.layoutNeeded = true; 1434 } 1435 if (!mPolicyVisibility) { 1436 if (mService.mCurrentFocus == this) { 1437 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, 1438 "setAnimationLocked: setting mFocusMayChange true"); 1439 mService.mFocusMayChange = true; 1440 } 1441 // Window is no longer visible -- make sure if we were waiting 1442 // for it to be displayed before enabling the display, that 1443 // we allow the display to be enabled now. 1444 mService.enableScreenIfNeededLocked(); 1445 } 1446 } 1447 } 1448 1449 void setRequestedSize(int requestedWidth, int requestedHeight) { 1450 if ((mRequestedWidth != requestedWidth || mRequestedHeight != requestedHeight)) { 1451 mLayoutNeeded = true; 1452 mRequestedWidth = requestedWidth; 1453 mRequestedHeight = requestedHeight; 1454 } 1455 } 1456 1457 void prepareWindowToDisplayDuringRelayout(Configuration outConfig) { 1458 if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST) 1459 == SOFT_INPUT_ADJUST_RESIZE) { 1460 mLayoutNeeded = true; 1461 } 1462 if (isDrawnLw() && mService.okToDisplay()) { 1463 mWinAnimator.applyEnterAnimationLocked(); 1464 } 1465 if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) { 1466 if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this); 1467 mTurnOnScreen = true; 1468 } 1469 if (isConfigChanged()) { 1470 if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: " 1471 + mService.mCurConfiguration); 1472 outConfig.setTo(mService.mCurConfiguration); 1473 } 1474 } 1475 1476 void adjustStartingWindowFlags() { 1477 if (mAttrs.type == TYPE_BASE_APPLICATION && mAppToken != null 1478 && mAppToken.startingWindow != null) { 1479 // Special handling of starting window over the base 1480 // window of the app: propagate lock screen flags to it, 1481 // to provide the correct semantics while starting. 1482 final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD 1483 | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; 1484 WindowManager.LayoutParams sa = mAppToken.startingWindow.mAttrs; 1485 sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask); 1486 } 1487 } 1488 1489 void setWindowScale(int requestedWidth, int requestedHeight) { 1490 final boolean scaledWindow = (mAttrs.flags & FLAG_SCALED) != 0; 1491 1492 if (scaledWindow) { 1493 // requested{Width|Height} Surface's physical size 1494 // attrs.{width|height} Size on screen 1495 // TODO: We don't check if attrs != null here. Is it implicitly checked? 1496 mHScale = (mAttrs.width != requestedWidth) ? 1497 (mAttrs.width / (float)requestedWidth) : 1.0f; 1498 mVScale = (mAttrs.height != requestedHeight) ? 1499 (mAttrs.height / (float)requestedHeight) : 1.0f; 1500 } else { 1501 mHScale = mVScale = 1; 1502 } 1503 } 1504 1505 private class DeathRecipient implements IBinder.DeathRecipient { 1506 @Override 1507 public void binderDied() { 1508 try { 1509 synchronized(mService.mWindowMap) { 1510 WindowState win = mService.windowForClientLocked(mSession, mClient, false); 1511 Slog.i(TAG, "WIN DEATH: " + win); 1512 if (win != null) { 1513 if (win.mAppToken != null && !win.mAppToken.clientHidden) { 1514 win.mAppToken.appDied = true; 1515 } 1516 mService.removeWindowLocked(win); 1517 } else if (mHasSurface) { 1518 Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid."); 1519 mService.removeWindowLocked(WindowState.this); 1520 } 1521 } 1522 } catch (IllegalArgumentException ex) { 1523 // This will happen if the window has already been 1524 // removed. 1525 } 1526 } 1527 } 1528 1529 /** 1530 * @return true if this window desires key events. 1531 */ 1532 public final boolean canReceiveKeys() { 1533 return isVisibleOrAdding() 1534 && (mViewVisibility == View.VISIBLE) 1535 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0); 1536 } 1537 1538 @Override 1539 public boolean hasDrawnLw() { 1540 return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN; 1541 } 1542 1543 @Override 1544 public boolean showLw(boolean doAnimation) { 1545 return showLw(doAnimation, true); 1546 } 1547 1548 boolean showLw(boolean doAnimation, boolean requestAnim) { 1549 if (isHiddenFromUserLocked()) { 1550 return false; 1551 } 1552 if (!mAppOpVisibility) { 1553 // Being hidden due to app op request. 1554 return false; 1555 } 1556 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) { 1557 // Already showing. 1558 return false; 1559 } 1560 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this); 1561 if (doAnimation) { 1562 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility=" 1563 + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation); 1564 if (!mService.okToDisplay()) { 1565 doAnimation = false; 1566 } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) { 1567 // Check for the case where we are currently visible and 1568 // not animating; we do not want to do animation at such a 1569 // point to become visible when we already are. 1570 doAnimation = false; 1571 } 1572 } 1573 mPolicyVisibility = true; 1574 mPolicyVisibilityAfterAnim = true; 1575 if (doAnimation) { 1576 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true); 1577 } 1578 if (requestAnim) { 1579 mService.scheduleAnimationLocked(); 1580 } 1581 return true; 1582 } 1583 1584 @Override 1585 public boolean hideLw(boolean doAnimation) { 1586 return hideLw(doAnimation, true); 1587 } 1588 1589 boolean hideLw(boolean doAnimation, boolean requestAnim) { 1590 if (doAnimation) { 1591 if (!mService.okToDisplay()) { 1592 doAnimation = false; 1593 } 1594 } 1595 boolean current = doAnimation ? mPolicyVisibilityAfterAnim 1596 : mPolicyVisibility; 1597 if (!current) { 1598 // Already hiding. 1599 return false; 1600 } 1601 if (doAnimation) { 1602 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false); 1603 if (mWinAnimator.mAnimation == null) { 1604 doAnimation = false; 1605 } 1606 } 1607 if (doAnimation) { 1608 mPolicyVisibilityAfterAnim = false; 1609 } else { 1610 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this); 1611 mPolicyVisibilityAfterAnim = false; 1612 mPolicyVisibility = false; 1613 // Window is no longer visible -- make sure if we were waiting 1614 // for it to be displayed before enabling the display, that 1615 // we allow the display to be enabled now. 1616 mService.enableScreenIfNeededLocked(); 1617 if (mService.mCurrentFocus == this) { 1618 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, 1619 "WindowState.hideLw: setting mFocusMayChange true"); 1620 mService.mFocusMayChange = true; 1621 } 1622 } 1623 if (requestAnim) { 1624 mService.scheduleAnimationLocked(); 1625 } 1626 return true; 1627 } 1628 1629 public void setAppOpVisibilityLw(boolean state) { 1630 if (mAppOpVisibility != state) { 1631 mAppOpVisibility = state; 1632 if (state) { 1633 // If the policy visibility had last been to hide, then this 1634 // will incorrectly show at this point since we lost that 1635 // information. Not a big deal -- for the windows that have app 1636 // ops modifies they should only be hidden by policy due to the 1637 // lock screen, and the user won't be changing this if locked. 1638 // Plus it will quickly be fixed the next time we do a layout. 1639 showLw(true, true); 1640 } else { 1641 hideLw(true, true); 1642 } 1643 } 1644 } 1645 1646 public void pokeDrawLockLw(long timeout) { 1647 if (isVisibleOrAdding()) { 1648 if (mDrawLock == null) { 1649 // We want the tag name to be somewhat stable so that it is easier to correlate 1650 // in wake lock statistics. So in particular, we don't want to include the 1651 // window's hash code as in toString(). 1652 final CharSequence tag = getWindowTag(); 1653 mDrawLock = mService.mPowerManager.newWakeLock( 1654 PowerManager.DRAW_WAKE_LOCK, "Window:" + tag); 1655 mDrawLock.setReferenceCounted(false); 1656 mDrawLock.setWorkSource(new WorkSource(mOwnerUid, mAttrs.packageName)); 1657 } 1658 // Each call to acquire resets the timeout. 1659 if (DEBUG_POWER) { 1660 Slog.d(TAG, "pokeDrawLock: poking draw lock on behalf of visible window owned by " 1661 + mAttrs.packageName); 1662 } 1663 mDrawLock.acquire(timeout); 1664 } else if (DEBUG_POWER) { 1665 Slog.d(TAG, "pokeDrawLock: suppressed draw lock request for invisible window " 1666 + "owned by " + mAttrs.packageName); 1667 } 1668 } 1669 1670 @Override 1671 public boolean isAlive() { 1672 return mClient.asBinder().isBinderAlive(); 1673 } 1674 1675 boolean isClosing() { 1676 return mExiting || (mService.mClosingApps.contains(mAppToken)); 1677 } 1678 1679 boolean isAnimatingWithSavedSurface() { 1680 return mAppToken != null && mAppToken.mAnimatingWithSavedSurface; 1681 } 1682 1683 boolean shouldSaveSurface() { 1684 if (ActivityManager.isLowRamDeviceStatic()) { 1685 // Don't save surfaces on Svelte devices. 1686 return false; 1687 } 1688 1689 Task task = getTask(); 1690 if (task == null || task.inHomeStack() 1691 || task.getTopAppWindowToken() != mAppToken) { 1692 // Don't save surfaces for home stack apps. These usually resume and draw 1693 // first frame very fast. Saving surfaces are mostly a waste of memory. 1694 // Don't save if the window is not the topmost window. 1695 return false; 1696 } 1697 1698 return mAppToken.shouldSaveSurface(); 1699 } 1700 1701 @Override 1702 public boolean isDefaultDisplay() { 1703 final DisplayContent displayContent = getDisplayContent(); 1704 if (displayContent == null) { 1705 // Only a window that was on a non-default display can be detached from it. 1706 return false; 1707 } 1708 return displayContent.isDefaultDisplay; 1709 } 1710 1711 @Override 1712 public boolean isDimming() { 1713 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser(); 1714 return dimLayerUser != null && mDisplayContent != null && 1715 mDisplayContent.mDimLayerController.isDimming(dimLayerUser, mWinAnimator); 1716 } 1717 1718 public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) { 1719 mShowToOwnerOnly = showToOwnerOnly; 1720 } 1721 1722 boolean isHiddenFromUserLocked() { 1723 // Attached windows are evaluated based on the window that they are attached to. 1724 WindowState win = this; 1725 while (win.mAttachedWindow != null) { 1726 win = win.mAttachedWindow; 1727 } 1728 if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW 1729 && win.mAppToken != null && win.mAppToken.showForAllUsers) { 1730 // Save some cycles by not calling getDisplayInfo unless it is an application 1731 // window intended for all users. 1732 final DisplayContent displayContent = win.getDisplayContent(); 1733 if (displayContent == null) { 1734 return true; 1735 } 1736 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 1737 if (win.mFrame.left <= 0 && win.mFrame.top <= 0 1738 && win.mFrame.right >= displayInfo.appWidth 1739 && win.mFrame.bottom >= displayInfo.appHeight) { 1740 // Is a fullscreen window, like the clock alarm. Show to everyone. 1741 return false; 1742 } 1743 } 1744 1745 return win.mShowToOwnerOnly 1746 && !mService.isCurrentProfileLocked(UserHandle.getUserId(win.mOwnerUid)); 1747 } 1748 1749 private static void applyInsets(Region outRegion, Rect frame, Rect inset) { 1750 outRegion.set( 1751 frame.left + inset.left, frame.top + inset.top, 1752 frame.right - inset.right, frame.bottom - inset.bottom); 1753 } 1754 1755 public void getTouchableRegion(Region outRegion) { 1756 final Rect frame = mFrame; 1757 switch (mTouchableInsets) { 1758 default: 1759 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME: 1760 outRegion.set(frame); 1761 break; 1762 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: 1763 applyInsets(outRegion, frame, mGivenContentInsets); 1764 break; 1765 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: 1766 applyInsets(outRegion, frame, mGivenVisibleInsets); 1767 break; 1768 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: { 1769 final Region givenTouchableRegion = mGivenTouchableRegion; 1770 outRegion.set(givenTouchableRegion); 1771 outRegion.translate(frame.left, frame.top); 1772 break; 1773 } 1774 } 1775 } 1776 1777 WindowList getWindowList() { 1778 final DisplayContent displayContent = getDisplayContent(); 1779 return displayContent == null ? null : displayContent.getWindowList(); 1780 } 1781 1782 /** 1783 * Report a focus change. Must be called with no locks held, and consistently 1784 * from the same serialized thread (such as dispatched from a handler). 1785 */ 1786 public void reportFocusChangedSerialized(boolean focused, boolean inTouchMode) { 1787 try { 1788 mClient.windowFocusChanged(focused, inTouchMode); 1789 } catch (RemoteException e) { 1790 } 1791 if (mFocusCallbacks != null) { 1792 final int N = mFocusCallbacks.beginBroadcast(); 1793 for (int i=0; i<N; i++) { 1794 IWindowFocusObserver obs = mFocusCallbacks.getBroadcastItem(i); 1795 try { 1796 if (focused) { 1797 obs.focusGained(mWindowId.asBinder()); 1798 } else { 1799 obs.focusLost(mWindowId.asBinder()); 1800 } 1801 } catch (RemoteException e) { 1802 } 1803 } 1804 mFocusCallbacks.finishBroadcast(); 1805 } 1806 } 1807 1808 void reportResized() { 1809 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag()); 1810 try { 1811 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this 1812 + ": " + mCompatFrame); 1813 final boolean configChanged = isConfigChanged(); 1814 final Task task = getTask(); 1815 final Configuration overrideConfig = 1816 (task != null) ? task.mOverrideConfig : Configuration.EMPTY; 1817 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) { 1818 Slog.i(TAG, "Sending new config to window " + this + ": " 1819 + mWinAnimator.mSurfaceW + "x" + mWinAnimator.mSurfaceH + " / config=" 1820 + mService.mCurConfiguration + " overrideConfig=" + overrideConfig); 1821 } 1822 setConfiguration(mService.mCurConfiguration, overrideConfig); 1823 if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) 1824 Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING"); 1825 1826 final Rect frame = mFrame; 1827 final Rect overscanInsets = mLastOverscanInsets; 1828 final Rect contentInsets = mLastContentInsets; 1829 final Rect visibleInsets = mLastVisibleInsets; 1830 final Rect stableInsets = mLastStableInsets; 1831 final Rect outsets = mLastOutsets; 1832 final boolean reportDraw = mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING; 1833 final Configuration newConfig = configChanged ? mConfiguration : null; 1834 if (mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_STARTING 1835 && mClient instanceof IWindow.Stub) { 1836 // To prevent deadlock simulate one-way call if win.mClient is a local object. 1837 mService.mH.post(new Runnable() { 1838 @Override 1839 public void run() { 1840 try { 1841 mClient.resized(frame, overscanInsets, contentInsets, 1842 visibleInsets, stableInsets, outsets, reportDraw, newConfig); 1843 } catch (RemoteException e) { 1844 // Not a remote call, RemoteException won't be raised. 1845 } 1846 } 1847 }); 1848 } else { 1849 mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, 1850 outsets, reportDraw, newConfig); 1851 } 1852 1853 //TODO (multidisplay): Accessibility supported only for the default display. 1854 if (mService.mAccessibilityController != null 1855 && getDisplayId() == Display.DEFAULT_DISPLAY) { 1856 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(); 1857 } 1858 1859 mOverscanInsetsChanged = false; 1860 mContentInsetsChanged = false; 1861 mVisibleInsetsChanged = false; 1862 mStableInsetsChanged = false; 1863 mOutsetsChanged = false; 1864 mWinAnimator.mSurfaceResized = false; 1865 } catch (RemoteException e) { 1866 mOrientationChanging = false; 1867 mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() 1868 - mService.mDisplayFreezeTime); 1869 // We are assuming the hosting process is dead or in a zombie state. 1870 Slog.w(TAG, "Failed to report 'resized' to the client of " + this 1871 + ", removing this window."); 1872 mService.mPendingRemove.add(this); 1873 mService.mWindowPlacerLocked.requestTraversal(); 1874 } 1875 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 1876 } 1877 1878 public void registerFocusObserver(IWindowFocusObserver observer) { 1879 synchronized(mService.mWindowMap) { 1880 if (mFocusCallbacks == null) { 1881 mFocusCallbacks = new RemoteCallbackList<IWindowFocusObserver>(); 1882 } 1883 mFocusCallbacks.register(observer); 1884 } 1885 } 1886 1887 public void unregisterFocusObserver(IWindowFocusObserver observer) { 1888 synchronized(mService.mWindowMap) { 1889 if (mFocusCallbacks != null) { 1890 mFocusCallbacks.unregister(observer); 1891 } 1892 } 1893 } 1894 1895 public boolean isFocused() { 1896 synchronized(mService.mWindowMap) { 1897 return mService.mCurrentFocus == this; 1898 } 1899 } 1900 1901 boolean inFreeformWorkspace() { 1902 final Task task = getTask(); 1903 return task != null && task.inFreeformWorkspace(); 1904 } 1905 1906 boolean isDragResizeChanged() { 1907 return mDragResizing != computeDragResizing(); 1908 } 1909 1910 private boolean computeDragResizing() { 1911 final Task task = getTask(); 1912 if (task == null) { 1913 return false; 1914 } 1915 if (task.isDragResizing()) { 1916 return true; 1917 } 1918 return mDisplayContent.mDividerControllerLocked.isResizing() && 1919 !task.inFreeformWorkspace() && !task.isFullscreen(); 1920 } 1921 1922 void setDragResizing() { 1923 mDragResizing = computeDragResizing(); 1924 } 1925 1926 boolean isDragResizing() { 1927 return mDragResizing; 1928 } 1929 1930 void dump(PrintWriter pw, String prefix, boolean dumpAll) { 1931 final TaskStack stack = getStack(); 1932 pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId()); 1933 if (stack != null) { 1934 pw.print(" stackId="); pw.print(stack.mStackId); 1935 } 1936 pw.print(" mSession="); pw.print(mSession); 1937 pw.print(" mClient="); pw.println(mClient.asBinder()); 1938 pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid); 1939 pw.print(" mShowToOwnerOnly="); pw.print(mShowToOwnerOnly); 1940 pw.print(" package="); pw.print(mAttrs.packageName); 1941 pw.print(" appop="); pw.println(AppOpsManager.opToName(mAppOp)); 1942 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs); 1943 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth); 1944 pw.print(" h="); pw.print(mRequestedHeight); 1945 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq); 1946 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { 1947 pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth); 1948 pw.print(" h="); pw.println(mLastRequestedHeight); 1949 } 1950 if (mAttachedWindow != null || mLayoutAttached) { 1951 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow); 1952 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached); 1953 } 1954 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) { 1955 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow); 1956 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper); 1957 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer); 1958 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible); 1959 } 1960 if (dumpAll) { 1961 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer); 1962 pw.print(" mSubLayer="); pw.print(mSubLayer); 1963 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+"); 1964 pw.print((mTargetAppToken != null ? 1965 mTargetAppToken.mAppAnimator.animLayerAdjustment 1966 : (mAppToken != null ? mAppToken.mAppAnimator.animLayerAdjustment : 0))); 1967 pw.print("="); pw.print(mWinAnimator.mAnimLayer); 1968 pw.print(" mLastLayer="); pw.println(mWinAnimator.mLastLayer); 1969 } 1970 if (dumpAll) { 1971 pw.print(prefix); pw.print("mToken="); pw.println(mToken); 1972 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken); 1973 if (mAppToken != null) { 1974 pw.print(prefix); pw.print("mAppToken="); pw.print(mAppToken); 1975 pw.print(" mAppDied=");pw.println(mAppDied); 1976 } 1977 if (mTargetAppToken != null) { 1978 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken); 1979 } 1980 pw.print(prefix); pw.print("mViewVisibility=0x"); 1981 pw.print(Integer.toHexString(mViewVisibility)); 1982 pw.print(" mHaveFrame="); pw.print(mHaveFrame); 1983 pw.print(" mObscured="); pw.println(mObscured); 1984 pw.print(prefix); pw.print("mSeq="); pw.print(mSeq); 1985 pw.print(" mSystemUiVisibility=0x"); 1986 pw.println(Integer.toHexString(mSystemUiVisibility)); 1987 } 1988 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || !mAppOpVisibility 1989 || mAttachedHidden) { 1990 pw.print(prefix); pw.print("mPolicyVisibility="); 1991 pw.print(mPolicyVisibility); 1992 pw.print(" mPolicyVisibilityAfterAnim="); 1993 pw.print(mPolicyVisibilityAfterAnim); 1994 pw.print(" mAppOpVisibility="); 1995 pw.print(mAppOpVisibility); 1996 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden); 1997 } 1998 if (!mRelayoutCalled || mLayoutNeeded) { 1999 pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled); 2000 pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded); 2001 } 2002 if (mXOffset != 0 || mYOffset != 0) { 2003 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset); 2004 pw.print(" y="); pw.println(mYOffset); 2005 } 2006 if (dumpAll) { 2007 pw.print(prefix); pw.print("mGivenContentInsets="); 2008 mGivenContentInsets.printShortString(pw); 2009 pw.print(" mGivenVisibleInsets="); 2010 mGivenVisibleInsets.printShortString(pw); 2011 pw.println(); 2012 if (mTouchableInsets != 0 || mGivenInsetsPending) { 2013 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets); 2014 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending); 2015 Region region = new Region(); 2016 getTouchableRegion(region); 2017 pw.print(prefix); pw.print("touchable region="); pw.println(region); 2018 } 2019 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration); 2020 if (mOverrideConfig != Configuration.EMPTY) { 2021 pw.print(prefix); pw.print("mOverrideConfig="); pw.println(mOverrideConfig); 2022 } 2023 } 2024 pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface); 2025 pw.print(" mShownPosition="); mShownPosition.printShortString(pw); 2026 pw.print(" isReadyForDisplay()="); pw.println(isReadyForDisplay()); 2027 if (dumpAll) { 2028 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw); 2029 pw.print(" last="); mLastFrame.printShortString(pw); 2030 pw.println(); 2031 pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw); 2032 pw.print(" last="); mLastSystemDecorRect.printShortString(pw); 2033 if (mWinAnimator.mHasClipRect) { 2034 pw.print(" mLastClipRect="); 2035 mWinAnimator.mLastClipRect.printShortString(pw); 2036 } 2037 pw.println(); 2038 } 2039 if (mEnforceSizeCompat) { 2040 pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw); 2041 pw.println(); 2042 } 2043 if (dumpAll) { 2044 pw.print(prefix); pw.print("Frames: containing="); 2045 mContainingFrame.printShortString(pw); 2046 pw.print(" parent="); mParentFrame.printShortString(pw); 2047 pw.println(); 2048 pw.print(prefix); pw.print(" display="); mDisplayFrame.printShortString(pw); 2049 pw.print(" overscan="); mOverscanFrame.printShortString(pw); 2050 pw.println(); 2051 pw.print(prefix); pw.print(" content="); mContentFrame.printShortString(pw); 2052 pw.print(" visible="); mVisibleFrame.printShortString(pw); 2053 pw.println(); 2054 pw.print(prefix); pw.print(" decor="); mDecorFrame.printShortString(pw); 2055 pw.println(); 2056 pw.print(prefix); pw.print(" outset="); mOutsetFrame.printShortString(pw); 2057 pw.println(); 2058 pw.print(prefix); pw.print("Cur insets: overscan="); 2059 mOverscanInsets.printShortString(pw); 2060 pw.print(" content="); mContentInsets.printShortString(pw); 2061 pw.print(" visible="); mVisibleInsets.printShortString(pw); 2062 pw.print(" stable="); mStableInsets.printShortString(pw); 2063 pw.print(" outsets="); mOutsets.printShortString(pw); 2064 pw.println(); 2065 pw.print(prefix); pw.print("Lst insets: overscan="); 2066 mLastOverscanInsets.printShortString(pw); 2067 pw.print(" content="); mLastContentInsets.printShortString(pw); 2068 pw.print(" visible="); mLastVisibleInsets.printShortString(pw); 2069 pw.print(" stable="); mLastStableInsets.printShortString(pw); 2070 pw.print(" physical="); mLastOutsets.printShortString(pw); 2071 pw.print(" outset="); mLastOutsets.printShortString(pw); 2072 pw.println(); 2073 } 2074 pw.print(prefix); pw.print(mWinAnimator); pw.println(":"); 2075 mWinAnimator.dump(pw, prefix + " ", dumpAll); 2076 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) { 2077 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting); 2078 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit); 2079 pw.print(" mDestroying="); pw.print(mDestroying); 2080 pw.print(" mRemoved="); pw.println(mRemoved); 2081 } 2082 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) { 2083 pw.print(prefix); pw.print("mOrientationChanging="); 2084 pw.print(mOrientationChanging); 2085 pw.print(" mAppFreezing="); pw.print(mAppFreezing); 2086 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen); 2087 } 2088 if (mLastFreezeDuration != 0) { 2089 pw.print(prefix); pw.print("mLastFreezeDuration="); 2090 TimeUtils.formatDuration(mLastFreezeDuration, pw); pw.println(); 2091 } 2092 if (mHScale != 1 || mVScale != 1) { 2093 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale); 2094 pw.print(" mVScale="); pw.println(mVScale); 2095 } 2096 if (mWallpaperX != -1 || mWallpaperY != -1) { 2097 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX); 2098 pw.print(" mWallpaperY="); pw.println(mWallpaperY); 2099 } 2100 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) { 2101 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep); 2102 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep); 2103 } 2104 if (mWallpaperDisplayOffsetX != Integer.MIN_VALUE 2105 || mWallpaperDisplayOffsetY != Integer.MIN_VALUE) { 2106 pw.print(prefix); pw.print("mWallpaperDisplayOffsetX="); 2107 pw.print(mWallpaperDisplayOffsetX); 2108 pw.print(" mWallpaperDisplayOffsetY="); 2109 pw.println(mWallpaperDisplayOffsetY); 2110 } 2111 if (mDrawLock != null) { 2112 pw.print(prefix); pw.println("mDrawLock=" + mDrawLock); 2113 } 2114 } 2115 2116 String makeInputChannelName() { 2117 return Integer.toHexString(System.identityHashCode(this)) 2118 + " " + getWindowTag(); 2119 } 2120 2121 private CharSequence getWindowTag() { 2122 CharSequence tag = mAttrs.getTitle(); 2123 if (tag == null || tag.length() <= 0) { 2124 tag = mAttrs.packageName; 2125 } 2126 return tag; 2127 } 2128 2129 @Override 2130 public String toString() { 2131 final CharSequence title = getWindowTag(); 2132 if (mStringNameCache == null || mLastTitle != title || mWasExiting != mExiting) { 2133 mLastTitle = title; 2134 mWasExiting = mExiting; 2135 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) 2136 + " u" + UserHandle.getUserId(mSession.mUid) 2137 + " " + mLastTitle + (mExiting ? " EXITING}" : "}"); 2138 } 2139 return mStringNameCache; 2140 } 2141 2142 void transformFromScreenToSurfaceSpace(Rect rect) { 2143 if (mHScale >= 0) { 2144 rect.right = rect.left + (int)((rect.right - rect.left) / mHScale); 2145 } 2146 if (mVScale >= 0) { 2147 rect.bottom = rect.top + (int)((rect.bottom - rect.top) / mVScale); 2148 } 2149 } 2150} 2151