WindowState.java revision 9dc52bc44c94854fcd3384a045b4b862e30e25de
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.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 20import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW; 21import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; 22import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 23import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 24import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 25import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 26import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; 27import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 28 29import com.android.server.input.InputWindowHandle; 30 31import android.content.Context; 32import android.content.res.Configuration; 33import android.graphics.Matrix; 34import android.graphics.PixelFormat; 35import android.graphics.Rect; 36import android.graphics.RectF; 37import android.graphics.Region; 38import android.os.IBinder; 39import android.os.RemoteException; 40import android.os.UserHandle; 41import android.util.Slog; 42import android.view.DisplayInfo; 43import android.view.Gravity; 44import android.view.IApplicationToken; 45import android.view.IWindow; 46import android.view.InputChannel; 47import android.view.View; 48import android.view.ViewTreeObserver; 49import android.view.WindowManager; 50import android.view.WindowManagerPolicy; 51 52import java.io.PrintWriter; 53import java.util.ArrayList; 54 55class WindowList extends ArrayList<WindowState> { 56} 57 58/** 59 * A window in the window manager. 60 */ 61final class WindowState implements WindowManagerPolicy.WindowState { 62 static final String TAG = "WindowState"; 63 64 static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY; 65 static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS; 66 static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS; 67 static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC; 68 69 final WindowManagerService mService; 70 final WindowManagerPolicy mPolicy; 71 final Context mContext; 72 final Session mSession; 73 final IWindow mClient; 74 WindowToken mToken; 75 WindowToken mRootToken; 76 AppWindowToken mAppToken; 77 AppWindowToken mTargetAppToken; 78 79 // mAttrs.flags is tested in animation without being locked. If the bits tested are ever 80 // modified they will need to be locked. 81 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams(); 82 final DeathRecipient mDeathRecipient; 83 final WindowState mAttachedWindow; 84 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>(); 85 final int mBaseLayer; 86 final int mSubLayer; 87 final boolean mLayoutAttached; 88 final boolean mIsImWindow; 89 final boolean mIsWallpaper; 90 final boolean mIsFloatingLayer; 91 int mSeq; 92 boolean mEnforceSizeCompat; 93 int mViewVisibility; 94 int mSystemUiVisibility; 95 boolean mPolicyVisibility = true; 96 boolean mPolicyVisibilityAfterAnim = true; 97 boolean mAppFreezing; 98 boolean mAttachedHidden; // is our parent window hidden? 99 boolean mWallpaperVisible; // for wallpaper, what was last vis report? 100 101 /** 102 * The window size that was requested by the application. These are in 103 * the application's coordinate space (without compatibility scale applied). 104 */ 105 int mRequestedWidth; 106 int mRequestedHeight; 107 int mLastRequestedWidth; 108 int mLastRequestedHeight; 109 110 int mLayer; 111 boolean mHaveFrame; 112 boolean mObscured; 113 boolean mTurnOnScreen; 114 115 int mLayoutSeq = -1; 116 117 Configuration mConfiguration = null; 118 119 /** 120 * Actual frame shown on-screen (may be modified by animation). These 121 * are in the screen's coordinate space (WITH the compatibility scale 122 * applied). 123 */ 124 final RectF mShownFrame = new RectF(); 125 126 /** 127 * Insets that determine the actually visible area. These are in the application's 128 * coordinate space (without compatibility scale applied). 129 */ 130 final Rect mVisibleInsets = new Rect(); 131 final Rect mLastVisibleInsets = new Rect(); 132 boolean mVisibleInsetsChanged; 133 134 /** 135 * Insets that are covered by system windows (such as the status bar) and 136 * transient docking windows (such as the IME). These are in the application's 137 * coordinate space (without compatibility scale applied). 138 */ 139 final Rect mContentInsets = new Rect(); 140 final Rect mLastContentInsets = new Rect(); 141 boolean mContentInsetsChanged; 142 143 /** 144 * Set to true if we are waiting for this window to receive its 145 * given internal insets before laying out other windows based on it. 146 */ 147 boolean mGivenInsetsPending; 148 149 /** 150 * These are the content insets that were given during layout for 151 * this window, to be applied to windows behind it. 152 */ 153 final Rect mGivenContentInsets = new Rect(); 154 155 /** 156 * These are the visible insets that were given during layout for 157 * this window, to be applied to windows behind it. 158 */ 159 final Rect mGivenVisibleInsets = new Rect(); 160 161 /** 162 * This is the given touchable area relative to the window frame, or null if none. 163 */ 164 final Region mGivenTouchableRegion = new Region(); 165 166 /** 167 * Flag indicating whether the touchable region should be adjusted by 168 * the visible insets; if false the area outside the visible insets is 169 * NOT touchable, so we must use those to adjust the frame during hit 170 * tests. 171 */ 172 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME; 173 174 /** 175 * This is rectangle of the window's surface that is not covered by 176 * system decorations. 177 */ 178 final Rect mSystemDecorRect = new Rect(); 179 final Rect mLastSystemDecorRect = new Rect(); 180 181 // Current transformation being applied. 182 float mGlobalScale=1; 183 float mInvGlobalScale=1; 184 float mHScale=1, mVScale=1; 185 float mLastHScale=1, mLastVScale=1; 186 final Matrix mTmpMatrix = new Matrix(); 187 188 // "Real" frame that the application sees, in display coordinate space. 189 final Rect mFrame = new Rect(); 190 final Rect mLastFrame = new Rect(); 191 // Frame that is scaled to the application's coordinate space when in 192 // screen size compatibility mode. 193 final Rect mCompatFrame = new Rect(); 194 195 final Rect mContainingFrame = new Rect(); 196 final Rect mDisplayFrame = new Rect(); 197 final Rect mContentFrame = new Rect(); 198 final Rect mParentFrame = new Rect(); 199 final Rect mVisibleFrame = new Rect(); 200 201 boolean mContentChanged; 202 203 // If a window showing a wallpaper: the requested offset for the 204 // wallpaper; if a wallpaper window: the currently applied offset. 205 float mWallpaperX = -1; 206 float mWallpaperY = -1; 207 208 // If a window showing a wallpaper: what fraction of the offset 209 // range corresponds to a full virtual screen. 210 float mWallpaperXStep = -1; 211 float mWallpaperYStep = -1; 212 213 // Wallpaper windows: pixels offset based on above variables. 214 int mXOffset; 215 int mYOffset; 216 217 // This is set after IWindowSession.relayout() has been called at 218 // least once for the window. It allows us to detect the situation 219 // where we don't yet have a surface, but should have one soon, so 220 // we can give the window focus before waiting for the relayout. 221 boolean mRelayoutCalled; 222 223 // If the application has called relayout() with changes that can 224 // impact its window's size, we need to perform a layout pass on it 225 // even if it is not currently visible for layout. This is set 226 // when in that case until the layout is done. 227 boolean mLayoutNeeded; 228 229 // Currently running an exit animation? 230 boolean mExiting; 231 232 // Currently on the mDestroySurface list? 233 boolean mDestroying; 234 235 // Completely remove from window manager after exit animation? 236 boolean mRemoveOnExit; 237 238 // Set when the orientation is changing and this window has not yet 239 // been updated for the new orientation. 240 boolean mOrientationChanging; 241 242 // Is this window now (or just being) removed? 243 boolean mRemoved; 244 245 // Temp for keeping track of windows that have been removed when 246 // rebuilding window list. 247 boolean mRebuilding; 248 249 // Input channel and input window handle used by the input dispatcher. 250 final InputWindowHandle mInputWindowHandle; 251 InputChannel mInputChannel; 252 253 // Used to improve performance of toString() 254 String mStringNameCache; 255 CharSequence mLastTitle; 256 boolean mWasPaused; 257 258 final WindowStateAnimator mWinAnimator; 259 260 boolean mHasSurface = false; 261 262 DisplayContent mDisplayContent; 263 264 // UserId of the owner. Don't display windows of non-current user. 265 final int mOwnerUserId; 266 267 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, 268 WindowState attachedWindow, int seq, WindowManager.LayoutParams a, 269 int viewVisibility, final DisplayContent displayContent) { 270 mService = service; 271 mSession = s; 272 mClient = c; 273 mToken = token; 274 mOwnerUserId = UserHandle.getUserId(s.mUid); 275 mAttrs.copyFrom(a); 276 mViewVisibility = viewVisibility; 277 mDisplayContent = displayContent; 278 mPolicy = mService.mPolicy; 279 mContext = mService.mContext; 280 DeathRecipient deathRecipient = new DeathRecipient(); 281 mSeq = seq; 282 mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0; 283 if (WindowManagerService.localLOGV) Slog.v( 284 TAG, "Window " + this + " client=" + c.asBinder() 285 + " token=" + token + " (" + mAttrs.token + ")"); 286 try { 287 c.asBinder().linkToDeath(deathRecipient, 0); 288 } catch (RemoteException e) { 289 mDeathRecipient = null; 290 mAttachedWindow = null; 291 mLayoutAttached = false; 292 mIsImWindow = false; 293 mIsWallpaper = false; 294 mIsFloatingLayer = false; 295 mBaseLayer = 0; 296 mSubLayer = 0; 297 mInputWindowHandle = null; 298 mWinAnimator = null; 299 return; 300 } 301 mDeathRecipient = deathRecipient; 302 303 if ((mAttrs.type >= FIRST_SUB_WINDOW && 304 mAttrs.type <= LAST_SUB_WINDOW)) { 305 // The multiplier here is to reserve space for multiple 306 // windows in the same type layer. 307 mBaseLayer = mPolicy.windowTypeToLayerLw( 308 attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER 309 + WindowManagerService.TYPE_LAYER_OFFSET; 310 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type); 311 mAttachedWindow = attachedWindow; 312 if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow); 313 mAttachedWindow.mChildWindows.add(this); 314 mLayoutAttached = mAttrs.type != 315 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 316 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD 317 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 318 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER; 319 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 320 } else { 321 // The multiplier here is to reserve space for multiple 322 // windows in the same type layer. 323 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type) 324 * WindowManagerService.TYPE_LAYER_MULTIPLIER 325 + WindowManagerService.TYPE_LAYER_OFFSET; 326 mSubLayer = 0; 327 mAttachedWindow = null; 328 mLayoutAttached = false; 329 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD 330 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 331 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER; 332 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 333 } 334 335 WindowState appWin = this; 336 while (appWin.mAttachedWindow != null) { 337 appWin = appWin.mAttachedWindow; 338 } 339 WindowToken appToken = appWin.mToken; 340 while (appToken.appWindowToken == null) { 341 WindowToken parent = mService.mTokenMap.get(appToken.token); 342 if (parent == null || appToken == parent) { 343 break; 344 } 345 appToken = parent; 346 } 347 mRootToken = appToken; 348 mAppToken = appToken.appWindowToken; 349 350 mWinAnimator = new WindowStateAnimator(this); 351 mWinAnimator.mAlpha = a.alpha; 352 353 mRequestedWidth = 0; 354 mRequestedHeight = 0; 355 mLastRequestedWidth = 0; 356 mLastRequestedHeight = 0; 357 mXOffset = 0; 358 mYOffset = 0; 359 mLayer = 0; 360 mInputWindowHandle = new InputWindowHandle( 361 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this, 362 displayContent.getDisplayId()); 363 } 364 365 void attach() { 366 if (WindowManagerService.localLOGV) Slog.v( 367 TAG, "Attaching " + this + " token=" + mToken 368 + ", list=" + mToken.windows); 369 mSession.windowAddedLocked(); 370 } 371 372 @Override 373 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) { 374 mHaveFrame = true; 375 376 final Rect container = mContainingFrame; 377 container.set(pf); 378 379 final Rect display = mDisplayFrame; 380 display.set(df); 381 382 final int pw = container.right - container.left; 383 final int ph = container.bottom - container.top; 384 385 int w,h; 386 if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) { 387 if (mAttrs.width < 0) { 388 w = pw; 389 } else if (mEnforceSizeCompat) { 390 w = (int)(mAttrs.width * mGlobalScale + .5f); 391 } else { 392 w = mAttrs.width; 393 } 394 if (mAttrs.height < 0) { 395 h = ph; 396 } else if (mEnforceSizeCompat) { 397 h = (int)(mAttrs.height * mGlobalScale + .5f); 398 } else { 399 h = mAttrs.height; 400 } 401 } else { 402 if (mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT) { 403 w = pw; 404 } else if (mEnforceSizeCompat) { 405 w = (int)(mRequestedWidth * mGlobalScale + .5f); 406 } else { 407 w = mRequestedWidth; 408 } 409 if (mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT) { 410 h = ph; 411 } else if (mEnforceSizeCompat) { 412 h = (int)(mRequestedHeight * mGlobalScale + .5f); 413 } else { 414 h = mRequestedHeight; 415 } 416 } 417 418 if (!mParentFrame.equals(pf)) { 419 //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame 420 // + " to " + pf); 421 mParentFrame.set(pf); 422 mContentChanged = true; 423 } 424 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { 425 mLastRequestedWidth = mRequestedWidth; 426 mLastRequestedHeight = mRequestedHeight; 427 mContentChanged = true; 428 } 429 430 final Rect content = mContentFrame; 431 content.set(cf); 432 433 final Rect visible = mVisibleFrame; 434 visible.set(vf); 435 436 final Rect frame = mFrame; 437 final int fw = frame.width(); 438 final int fh = frame.height(); 439 440 //System.out.println("In: w=" + w + " h=" + h + " container=" + 441 // container + " x=" + mAttrs.x + " y=" + mAttrs.y); 442 443 float x, y; 444 if (mEnforceSizeCompat) { 445 x = mAttrs.x * mGlobalScale; 446 y = mAttrs.y * mGlobalScale; 447 } else { 448 x = mAttrs.x; 449 y = mAttrs.y; 450 } 451 452 Gravity.apply(mAttrs.gravity, w, h, container, 453 (int) (x + mAttrs.horizontalMargin * pw), 454 (int) (y + mAttrs.verticalMargin * ph), frame); 455 456 //System.out.println("Out: " + mFrame); 457 458 // Now make sure the window fits in the overall display. 459 Gravity.applyDisplay(mAttrs.gravity, df, frame); 460 461 // Make sure the system, content and visible frames are inside of the 462 // final window frame. 463 if (content.left < frame.left) content.left = frame.left; 464 if (content.top < frame.top) content.top = frame.top; 465 if (content.right > frame.right) content.right = frame.right; 466 if (content.bottom > frame.bottom) content.bottom = frame.bottom; 467 if (visible.left < frame.left) visible.left = frame.left; 468 if (visible.top < frame.top) visible.top = frame.top; 469 if (visible.right > frame.right) visible.right = frame.right; 470 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom; 471 472 final Rect contentInsets = mContentInsets; 473 contentInsets.left = content.left-frame.left; 474 contentInsets.top = content.top-frame.top; 475 contentInsets.right = frame.right-content.right; 476 contentInsets.bottom = frame.bottom-content.bottom; 477 478 final Rect visibleInsets = mVisibleInsets; 479 visibleInsets.left = visible.left-frame.left; 480 visibleInsets.top = visible.top-frame.top; 481 visibleInsets.right = frame.right-visible.right; 482 visibleInsets.bottom = frame.bottom-visible.bottom; 483 484 mCompatFrame.set(frame); 485 if (mEnforceSizeCompat) { 486 // If there is a size compatibility scale being applied to the 487 // window, we need to apply this to its insets so that they are 488 // reported to the app in its coordinate space. 489 contentInsets.scale(mInvGlobalScale); 490 visibleInsets.scale(mInvGlobalScale); 491 492 // Also the scaled frame that we report to the app needs to be 493 // adjusted to be in its coordinate space. 494 mCompatFrame.scale(mInvGlobalScale); 495 } 496 497 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) { 498 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo(); 499 mService.updateWallpaperOffsetLocked(this, displayInfo.appWidth, displayInfo.appHeight, 500 false); 501 } 502 503 if (WindowManagerService.localLOGV) { 504 //if ("com.google.android.youtube".equals(mAttrs.packageName) 505 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { 506 Slog.v(TAG, "Resolving (mRequestedWidth=" 507 + mRequestedWidth + ", mRequestedheight=" 508 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph 509 + "): frame=" + mFrame.toShortString() 510 + " ci=" + contentInsets.toShortString() 511 + " vi=" + visibleInsets.toShortString()); 512 //} 513 } 514 } 515 516 @Override 517 public Rect getFrameLw() { 518 return mFrame; 519 } 520 521 @Override 522 public RectF getShownFrameLw() { 523 return mShownFrame; 524 } 525 526 @Override 527 public Rect getDisplayFrameLw() { 528 return mDisplayFrame; 529 } 530 531 @Override 532 public Rect getContentFrameLw() { 533 return mContentFrame; 534 } 535 536 @Override 537 public Rect getVisibleFrameLw() { 538 return mVisibleFrame; 539 } 540 541 @Override 542 public boolean getGivenInsetsPendingLw() { 543 return mGivenInsetsPending; 544 } 545 546 @Override 547 public Rect getGivenContentInsetsLw() { 548 return mGivenContentInsets; 549 } 550 551 @Override 552 public Rect getGivenVisibleInsetsLw() { 553 return mGivenVisibleInsets; 554 } 555 556 @Override 557 public WindowManager.LayoutParams getAttrs() { 558 return mAttrs; 559 } 560 561 public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) { 562 int index = -1; 563 WindowState ws = this; 564 WindowList windows = getWindowList(); 565 while (true) { 566 if ((ws.mAttrs.privateFlags 567 & WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY) != 0) { 568 return (ws.mAttrs.flags & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0; 569 } 570 // If we reached the bottom of the range of windows we are considering, 571 // assume no menu is needed. 572 if (ws == bottom) { 573 return false; 574 } 575 // The current window hasn't specified whether menu key is needed; 576 // look behind it. 577 // First, we may need to determine the starting position. 578 if (index < 0) { 579 index = windows.indexOf(ws); 580 } 581 index--; 582 if (index < 0) { 583 return false; 584 } 585 ws = windows.get(index); 586 } 587 } 588 589 public int getSystemUiVisibility() { 590 return mSystemUiVisibility; 591 } 592 593 public int getSurfaceLayer() { 594 return mLayer; 595 } 596 597 public IApplicationToken getAppToken() { 598 return mAppToken != null ? mAppToken.appToken : null; 599 } 600 601 public long getInputDispatchingTimeoutNanos() { 602 return mAppToken != null 603 ? mAppToken.inputDispatchingTimeoutNanos 604 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 605 } 606 607 public boolean hasAppShownWindows() { 608 return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed); 609 } 610 611 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 612 if (dsdx < .99999f || dsdx > 1.00001f) return false; 613 if (dtdy < .99999f || dtdy > 1.00001f) return false; 614 if (dtdx < -.000001f || dtdx > .000001f) return false; 615 if (dsdy < -.000001f || dsdy > .000001f) return false; 616 return true; 617 } 618 619 void prelayout() { 620 if (mEnforceSizeCompat) { 621 mGlobalScale = mService.mCompatibleScreenScale; 622 mInvGlobalScale = 1/mGlobalScale; 623 } else { 624 mGlobalScale = mInvGlobalScale = 1; 625 } 626 } 627 628 /** 629 * Is this window visible? It is not visible if there is no 630 * surface, or we are in the process of running an exit animation 631 * that will remove the surface, or its app token has been hidden. 632 */ 633 public boolean isVisibleLw() { 634 final AppWindowToken atoken = mAppToken; 635 return mHasSurface && mPolicyVisibility && !mAttachedHidden 636 && (atoken == null || !atoken.hiddenRequested) 637 && !mExiting && !mDestroying; 638 } 639 640 /** 641 * Like {@link #isVisibleLw}, but also counts a window that is currently 642 * "hidden" behind the keyguard as visible. This allows us to apply 643 * things like window flags that impact the keyguard. 644 * XXX I am starting to think we need to have ANOTHER visibility flag 645 * for this "hidden behind keyguard" state rather than overloading 646 * mPolicyVisibility. Ungh. 647 */ 648 public boolean isVisibleOrBehindKeyguardLw() { 649 if (mRootToken.waitingToShow && 650 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) { 651 return false; 652 } 653 final AppWindowToken atoken = mAppToken; 654 final boolean animating = atoken != null 655 ? (atoken.mAppAnimator.animation != null) : false; 656 return mHasSurface && !mDestroying && !mExiting 657 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested) 658 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE 659 && !mRootToken.hidden) 660 || mWinAnimator.mAnimation != null || animating); 661 } 662 663 /** 664 * Is this window visible, ignoring its app token? It is not visible 665 * if there is no surface, or we are in the process of running an exit animation 666 * that will remove the surface. 667 */ 668 public boolean isWinVisibleLw() { 669 final AppWindowToken atoken = mAppToken; 670 return mHasSurface && mPolicyVisibility && !mAttachedHidden 671 && (atoken == null || !atoken.hiddenRequested || atoken.mAppAnimator.animating) 672 && !mExiting && !mDestroying; 673 } 674 675 /** 676 * The same as isVisible(), but follows the current hidden state of 677 * the associated app token, not the pending requested hidden state. 678 */ 679 boolean isVisibleNow() { 680 return mHasSurface && mPolicyVisibility && !mAttachedHidden 681 && !mRootToken.hidden && !mExiting && !mDestroying; 682 } 683 684 /** 685 * Can this window possibly be a drag/drop target? The test here is 686 * a combination of the above "visible now" with the check that the 687 * Input Manager uses when discarding windows from input consideration. 688 */ 689 boolean isPotentialDragTarget() { 690 return isVisibleNow() && !mRemoved 691 && mInputChannel != null && mInputWindowHandle != null; 692 } 693 694 /** 695 * Same as isVisible(), but we also count it as visible between the 696 * call to IWindowSession.add() and the first relayout(). 697 */ 698 boolean isVisibleOrAdding() { 699 final AppWindowToken atoken = mAppToken; 700 return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE)) 701 && mPolicyVisibility && !mAttachedHidden 702 && (atoken == null || !atoken.hiddenRequested) 703 && !mExiting && !mDestroying; 704 } 705 706 /** 707 * Is this window currently on-screen? It is on-screen either if it 708 * is visible or it is currently running an animation before no longer 709 * being visible. 710 */ 711 boolean isOnScreen() { 712 if (!mHasSurface || !mPolicyVisibility || mDestroying) { 713 return false; 714 } 715 final AppWindowToken atoken = mAppToken; 716 if (atoken != null) { 717 return ((!mAttachedHidden && !atoken.hiddenRequested) 718 || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null); 719 } 720 return !mAttachedHidden || mWinAnimator.mAnimation != null; 721 } 722 723 /** 724 * Like isOnScreen(), but we don't return true if the window is part 725 * of a transition that has not yet been started. 726 */ 727 boolean isReadyForDisplay() { 728 if (mRootToken.waitingToShow && 729 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) { 730 return false; 731 } 732 return mHasSurface && mPolicyVisibility && !mDestroying 733 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE 734 && !mRootToken.hidden) 735 || mWinAnimator.mAnimation != null 736 || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null))); 737 } 738 739 /** 740 * Like isReadyForDisplay(), but ignores any force hiding of the window due 741 * to the keyguard. 742 */ 743 boolean isReadyForDisplayIgnoringKeyguard() { 744 if (mRootToken.waitingToShow && 745 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) { 746 return false; 747 } 748 final AppWindowToken atoken = mAppToken; 749 if (atoken == null && !mPolicyVisibility) { 750 // If this is not an app window, and the policy has asked to force 751 // hide, then we really do want to hide. 752 return false; 753 } 754 return mHasSurface && !mDestroying 755 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE 756 && !mRootToken.hidden) 757 || mWinAnimator.mAnimation != null 758 || ((atoken != null) && (atoken.mAppAnimator.animation != null) 759 && !mWinAnimator.isDummyAnimation())); 760 } 761 762 /** 763 * Like isOnScreen, but returns false if the surface hasn't yet 764 * been drawn. 765 */ 766 public boolean isDisplayedLw() { 767 final AppWindowToken atoken = mAppToken; 768 return isDrawnLw() && mPolicyVisibility 769 && ((!mAttachedHidden && 770 (atoken == null || !atoken.hiddenRequested)) 771 || mWinAnimator.mAnimating); 772 } 773 774 /** 775 * Return true if this window (or a window it is attached to, but not 776 * considering its app token) is currently animating. 777 */ 778 public boolean isAnimatingLw() { 779 return mWinAnimator.mAnimation != null; 780 } 781 782 public boolean isGoneForLayoutLw() { 783 final AppWindowToken atoken = mAppToken; 784 return mViewVisibility == View.GONE 785 || !mRelayoutCalled 786 || (atoken == null && mRootToken.hidden) 787 || (atoken != null && (atoken.hiddenRequested || atoken.hidden)) 788 || mAttachedHidden 789 || mExiting || mDestroying; 790 } 791 792 /** 793 * Returns true if the window has a surface that it has drawn a 794 * complete UI in to. 795 */ 796 public boolean isDrawnLw() { 797 return mHasSurface && !mDestroying && 798 (mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW 799 || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN); 800 } 801 802 /** 803 * Return true if the window is opaque and fully drawn. This indicates 804 * it may obscure windows behind it. 805 */ 806 boolean isOpaqueDrawn() { 807 return (mAttrs.format == PixelFormat.OPAQUE 808 || mAttrs.type == TYPE_WALLPAPER) 809 && isDrawnLw() && mWinAnimator.mAnimation == null 810 && (mAppToken == null || mAppToken.mAppAnimator.animation == null); 811 } 812 813 /** 814 * Return whether this window is wanting to have a translation 815 * animation applied to it for an in-progress move. (Only makes 816 * sense to call from performLayoutAndPlaceSurfacesLockedInner().) 817 */ 818 boolean shouldAnimateMove() { 819 return mContentChanged && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay() 820 && (mFrame.top != mLastFrame.top 821 || mFrame.left != mLastFrame.left) 822 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove()); 823 } 824 825 boolean isFullscreen(int screenWidth, int screenHeight) { 826 return mFrame.left <= 0 && mFrame.top <= 0 && 827 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight; 828 } 829 830 void removeLocked() { 831 disposeInputChannel(); 832 833 if (mAttachedWindow != null) { 834 if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow); 835 mAttachedWindow.mChildWindows.remove(this); 836 } 837 mWinAnimator.destroyDeferredSurfaceLocked(); 838 mWinAnimator.destroySurfaceLocked(); 839 mSession.windowRemovedLocked(); 840 try { 841 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0); 842 } catch (RuntimeException e) { 843 // Ignore if it has already been removed (usually because 844 // we are doing this as part of processing a death note.) 845 } 846 } 847 848 void setInputChannel(InputChannel inputChannel) { 849 if (mInputChannel != null) { 850 throw new IllegalStateException("Window already has an input channel."); 851 } 852 853 mInputChannel = inputChannel; 854 mInputWindowHandle.inputChannel = inputChannel; 855 } 856 857 void disposeInputChannel() { 858 if (mInputChannel != null) { 859 mService.mInputManager.unregisterInputChannel(mInputChannel); 860 861 mInputChannel.dispose(); 862 mInputChannel = null; 863 } 864 865 mInputWindowHandle.inputChannel = null; 866 } 867 868 private class DeathRecipient implements IBinder.DeathRecipient { 869 public void binderDied() { 870 try { 871 synchronized(mService.mWindowMap) { 872 WindowState win = mService.windowForClientLocked(mSession, mClient, false); 873 Slog.i(TAG, "WIN DEATH: " + win); 874 if (win != null) { 875 mService.removeWindowLocked(mSession, win); 876 } 877 } 878 } catch (IllegalArgumentException ex) { 879 // This will happen if the window has already been 880 // removed. 881 } 882 } 883 } 884 885 /** Returns true if this window desires key events. 886 * TODO(cmautner): Is this the same as {@link WindowManagerService#canBeImeTarget} 887 */ 888 public final boolean canReceiveKeys() { 889 return isVisibleOrAdding() 890 && (mViewVisibility == View.VISIBLE) 891 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0); 892 } 893 894 @Override 895 public boolean hasDrawnLw() { 896 return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN; 897 } 898 899 @Override 900 public boolean showLw(boolean doAnimation) { 901 return showLw(doAnimation, true); 902 } 903 904 boolean showLw(boolean doAnimation, boolean requestAnim) { 905 if (isOtherUsersAppWindow()) { 906 Slog.w(TAG, "Current user " + mService.mCurrentUserId + " trying to display " 907 + this + ", type " + mAttrs.type + ", belonging to " + mOwnerUserId); 908 return false; 909 } 910 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) { 911 // Already showing. 912 return false; 913 } 914 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this); 915 if (doAnimation) { 916 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility=" 917 + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation); 918 if (!mService.okToDisplay()) { 919 doAnimation = false; 920 } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) { 921 // Check for the case where we are currently visible and 922 // not animating; we do not want to do animation at such a 923 // point to become visible when we already are. 924 doAnimation = false; 925 } 926 } 927 mPolicyVisibility = true; 928 mPolicyVisibilityAfterAnim = true; 929 if (doAnimation) { 930 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true); 931 } 932 if (requestAnim) { 933 mService.updateLayoutToAnimationLocked(); 934 } 935 return true; 936 } 937 938 @Override 939 public boolean hideLw(boolean doAnimation) { 940 return hideLw(doAnimation, true); 941 } 942 943 boolean hideLw(boolean doAnimation, boolean requestAnim) { 944 if (doAnimation) { 945 if (!mService.okToDisplay()) { 946 doAnimation = false; 947 } 948 } 949 boolean current = doAnimation ? mPolicyVisibilityAfterAnim 950 : mPolicyVisibility; 951 if (!current) { 952 // Already hiding. 953 return false; 954 } 955 if (doAnimation) { 956 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false); 957 if (mWinAnimator.mAnimation == null) { 958 doAnimation = false; 959 } 960 } 961 if (doAnimation) { 962 mPolicyVisibilityAfterAnim = false; 963 } else { 964 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this); 965 mPolicyVisibilityAfterAnim = false; 966 mPolicyVisibility = false; 967 // Window is no longer visible -- make sure if we were waiting 968 // for it to be displayed before enabling the display, that 969 // we allow the display to be enabled now. 970 mService.enableScreenIfNeededLocked(); 971 if (mService.mCurrentFocus == this) { 972 mService.mFocusMayChange = true; 973 } 974 } 975 if (requestAnim) { 976 mService.updateLayoutToAnimationLocked(); 977 } 978 return true; 979 } 980 981 @Override 982 public boolean isAlive() { 983 return mClient.asBinder().isBinderAlive(); 984 } 985 986 boolean isOtherUsersAppWindow() { 987 final int type = mAttrs.type; 988 if ((mOwnerUserId != mService.mCurrentUserId) 989 && (type >= TYPE_BASE_APPLICATION) && (type <= LAST_APPLICATION_WINDOW) 990 && (type != TYPE_APPLICATION_STARTING)) { 991 return true; 992 } 993 return false; 994 } 995 996 private static void applyInsets(Region outRegion, Rect frame, Rect inset) { 997 outRegion.set( 998 frame.left + inset.left, frame.top + inset.top, 999 frame.right - inset.right, frame.bottom - inset.bottom); 1000 } 1001 1002 public void getTouchableRegion(Region outRegion) { 1003 final Rect frame = mFrame; 1004 switch (mTouchableInsets) { 1005 default: 1006 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME: 1007 outRegion.set(frame); 1008 break; 1009 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: 1010 applyInsets(outRegion, frame, mGivenContentInsets); 1011 break; 1012 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: 1013 applyInsets(outRegion, frame, mGivenVisibleInsets); 1014 break; 1015 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: { 1016 final Region givenTouchableRegion = mGivenTouchableRegion; 1017 outRegion.set(givenTouchableRegion); 1018 outRegion.translate(frame.left, frame.top); 1019 break; 1020 } 1021 } 1022 } 1023 1024 WindowList getWindowList() { 1025 return mDisplayContent.getWindowList(); 1026 } 1027 1028 void dump(PrintWriter pw, String prefix, boolean dumpAll) { 1029 pw.print(prefix); pw.print("mDisplayId="); pw.print(mDisplayContent.getDisplayId()); 1030 pw.print(" mSession="); pw.print(mSession); 1031 pw.print(" mClient="); pw.println(mClient.asBinder()); 1032 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs); 1033 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth); 1034 pw.print(" h="); pw.print(mRequestedHeight); 1035 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq); 1036 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { 1037 pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth); 1038 pw.print(" h="); pw.println(mLastRequestedHeight); 1039 } 1040 if (mAttachedWindow != null || mLayoutAttached) { 1041 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow); 1042 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached); 1043 } 1044 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) { 1045 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow); 1046 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper); 1047 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer); 1048 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible); 1049 } 1050 if (dumpAll) { 1051 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer); 1052 pw.print(" mSubLayer="); pw.print(mSubLayer); 1053 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+"); 1054 pw.print((mTargetAppToken != null ? 1055 mTargetAppToken.mAppAnimator.animLayerAdjustment 1056 : (mAppToken != null ? mAppToken.mAppAnimator.animLayerAdjustment : 0))); 1057 pw.print("="); pw.print(mWinAnimator.mAnimLayer); 1058 pw.print(" mLastLayer="); pw.println(mWinAnimator.mLastLayer); 1059 } 1060 if (dumpAll) { 1061 pw.print(prefix); pw.print("mToken="); pw.println(mToken); 1062 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken); 1063 if (mAppToken != null) { 1064 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken); 1065 } 1066 if (mTargetAppToken != null) { 1067 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken); 1068 } 1069 pw.print(prefix); pw.print("mViewVisibility=0x"); 1070 pw.print(Integer.toHexString(mViewVisibility)); 1071 pw.print(" mHaveFrame="); pw.print(mHaveFrame); 1072 pw.print(" mObscured="); pw.println(mObscured); 1073 pw.print(prefix); pw.print("mSeq="); pw.print(mSeq); 1074 pw.print(" mSystemUiVisibility=0x"); 1075 pw.println(Integer.toHexString(mSystemUiVisibility)); 1076 } 1077 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) { 1078 pw.print(prefix); pw.print("mPolicyVisibility="); 1079 pw.print(mPolicyVisibility); 1080 pw.print(" mPolicyVisibilityAfterAnim="); 1081 pw.print(mPolicyVisibilityAfterAnim); 1082 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden); 1083 } 1084 if (!mRelayoutCalled || mLayoutNeeded) { 1085 pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled); 1086 pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded); 1087 } 1088 if (mXOffset != 0 || mYOffset != 0) { 1089 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset); 1090 pw.print(" y="); pw.println(mYOffset); 1091 } 1092 if (dumpAll) { 1093 pw.print(prefix); pw.print("mGivenContentInsets="); 1094 mGivenContentInsets.printShortString(pw); 1095 pw.print(" mGivenVisibleInsets="); 1096 mGivenVisibleInsets.printShortString(pw); 1097 pw.println(); 1098 if (mTouchableInsets != 0 || mGivenInsetsPending) { 1099 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets); 1100 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending); 1101 Region region = new Region(); 1102 getTouchableRegion(region); 1103 pw.print(prefix); pw.print("touchable region="); pw.println(region); 1104 } 1105 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration); 1106 } 1107 pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface); 1108 pw.print(" mShownFrame="); mShownFrame.printShortString(pw); pw.println(); 1109 if (dumpAll) { 1110 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw); 1111 pw.print(" last="); mLastFrame.printShortString(pw); 1112 pw.println(); 1113 pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw); 1114 pw.print(" last="); mLastSystemDecorRect.printShortString(pw); 1115 pw.println(); 1116 } 1117 if (mEnforceSizeCompat) { 1118 pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw); 1119 pw.println(); 1120 } 1121 if (dumpAll) { 1122 pw.print(prefix); pw.print("Frames: containing="); 1123 mContainingFrame.printShortString(pw); 1124 pw.print(" parent="); mParentFrame.printShortString(pw); 1125 pw.print(" display="); mDisplayFrame.printShortString(pw); 1126 pw.println(); 1127 pw.print(prefix); pw.print(" content="); mContentFrame.printShortString(pw); 1128 pw.print(" visible="); mVisibleFrame.printShortString(pw); 1129 pw.println(); 1130 pw.print(prefix); pw.print("Cur insets: content="); 1131 mContentInsets.printShortString(pw); 1132 pw.print(" visible="); mVisibleInsets.printShortString(pw); 1133 pw.println(); 1134 pw.print(prefix); pw.print("Lst insets: content="); 1135 mLastContentInsets.printShortString(pw); 1136 pw.print(" visible="); mLastVisibleInsets.printShortString(pw); 1137 pw.println(); 1138 } 1139 mWinAnimator.dump(pw, prefix, dumpAll); 1140 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) { 1141 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting); 1142 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit); 1143 pw.print(" mDestroying="); pw.print(mDestroying); 1144 pw.print(" mRemoved="); pw.println(mRemoved); 1145 } 1146 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) { 1147 pw.print(prefix); pw.print("mOrientationChanging="); 1148 pw.print(mOrientationChanging); 1149 pw.print(" mAppFreezing="); pw.print(mAppFreezing); 1150 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen); 1151 } 1152 if (mHScale != 1 || mVScale != 1) { 1153 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale); 1154 pw.print(" mVScale="); pw.println(mVScale); 1155 } 1156 if (mWallpaperX != -1 || mWallpaperY != -1) { 1157 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX); 1158 pw.print(" mWallpaperY="); pw.println(mWallpaperY); 1159 } 1160 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) { 1161 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep); 1162 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep); 1163 } 1164 } 1165 1166 String makeInputChannelName() { 1167 return Integer.toHexString(System.identityHashCode(this)) 1168 + " " + mAttrs.getTitle(); 1169 } 1170 1171 @Override 1172 public String toString() { 1173 if (mStringNameCache == null || mLastTitle != mAttrs.getTitle() 1174 || mWasPaused != mToken.paused) { 1175 mLastTitle = mAttrs.getTitle(); 1176 mWasPaused = mToken.paused; 1177 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) 1178 + " " + mLastTitle + " paused=" + mWasPaused + "}"; 1179 } 1180 return mStringNameCache; 1181 } 1182} 1183