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