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