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 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, 255 WindowState attachedWindow, int seq, WindowManager.LayoutParams a, 256 int viewVisibility) { 257 mService = service; 258 mSession = s; 259 mClient = c; 260 mToken = token; 261 mAttrs.copyFrom(a); 262 mViewVisibility = viewVisibility; 263 mPolicy = mService.mPolicy; 264 mContext = mService.mContext; 265 DeathRecipient deathRecipient = new DeathRecipient(); 266 mSeq = seq; 267 mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0; 268 if (WindowManagerService.localLOGV) Slog.v( 269 TAG, "Window " + this + " client=" + c.asBinder() 270 + " token=" + token + " (" + mAttrs.token + ")"); 271 try { 272 c.asBinder().linkToDeath(deathRecipient, 0); 273 } catch (RemoteException e) { 274 mDeathRecipient = null; 275 mAttachedWindow = null; 276 mLayoutAttached = false; 277 mIsImWindow = false; 278 mIsWallpaper = false; 279 mIsFloatingLayer = false; 280 mBaseLayer = 0; 281 mSubLayer = 0; 282 mInputWindowHandle = null; 283 mWinAnimator = null; 284 return; 285 } 286 mDeathRecipient = deathRecipient; 287 288 if ((mAttrs.type >= FIRST_SUB_WINDOW && 289 mAttrs.type <= LAST_SUB_WINDOW)) { 290 // The multiplier here is to reserve space for multiple 291 // windows in the same type layer. 292 mBaseLayer = mPolicy.windowTypeToLayerLw( 293 attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER 294 + WindowManagerService.TYPE_LAYER_OFFSET; 295 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type); 296 mAttachedWindow = attachedWindow; 297 if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow); 298 mAttachedWindow.mChildWindows.add(this); 299 mLayoutAttached = mAttrs.type != 300 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 301 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD 302 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 303 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER; 304 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 305 } else { 306 // The multiplier here is to reserve space for multiple 307 // windows in the same type layer. 308 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type) 309 * WindowManagerService.TYPE_LAYER_MULTIPLIER 310 + WindowManagerService.TYPE_LAYER_OFFSET; 311 mSubLayer = 0; 312 mAttachedWindow = null; 313 mLayoutAttached = false; 314 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD 315 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 316 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER; 317 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 318 } 319 320 mWinAnimator = new WindowStateAnimator(service, this, mAttachedWindow); 321 mWinAnimator.mAlpha = a.alpha; 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 mRequestedWidth = 0; 339 mRequestedHeight = 0; 340 mLastRequestedWidth = 0; 341 mLastRequestedHeight = 0; 342 mXOffset = 0; 343 mYOffset = 0; 344 mLayer = 0; 345 mInputWindowHandle = new InputWindowHandle( 346 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this); 347 } 348 349 void attach() { 350 if (WindowManagerService.localLOGV) Slog.v( 351 TAG, "Attaching " + this + " token=" + mToken 352 + ", list=" + mToken.windows); 353 mSession.windowAddedLocked(); 354 } 355 356 @Override 357 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) { 358 mHaveFrame = true; 359 360 final Rect container = mContainingFrame; 361 container.set(pf); 362 363 final Rect display = mDisplayFrame; 364 display.set(df); 365 366 final int pw = container.right - container.left; 367 final int ph = container.bottom - container.top; 368 369 int w,h; 370 if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) { 371 if (mAttrs.width < 0) { 372 w = pw; 373 } else if (mEnforceSizeCompat) { 374 w = (int)(mAttrs.width * mGlobalScale + .5f); 375 } else { 376 w = mAttrs.width; 377 } 378 if (mAttrs.height < 0) { 379 h = ph; 380 } else if (mEnforceSizeCompat) { 381 h = (int)(mAttrs.height * mGlobalScale + .5f); 382 } else { 383 h = mAttrs.height; 384 } 385 } else { 386 if (mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT) { 387 w = pw; 388 } else if (mEnforceSizeCompat) { 389 w = (int)(mRequestedWidth * mGlobalScale + .5f); 390 } else { 391 w = mRequestedWidth; 392 } 393 if (mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT) { 394 h = ph; 395 } else if (mEnforceSizeCompat) { 396 h = (int)(mRequestedHeight * mGlobalScale + .5f); 397 } else { 398 h = mRequestedHeight; 399 } 400 } 401 402 if (!mParentFrame.equals(pf)) { 403 //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame 404 // + " to " + pf); 405 mParentFrame.set(pf); 406 mContentChanged = true; 407 } 408 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { 409 mLastRequestedWidth = mRequestedWidth; 410 mLastRequestedHeight = mRequestedHeight; 411 mContentChanged = true; 412 } 413 414 final Rect content = mContentFrame; 415 content.set(cf); 416 417 final Rect visible = mVisibleFrame; 418 visible.set(vf); 419 420 final Rect frame = mFrame; 421 final int fw = frame.width(); 422 final int fh = frame.height(); 423 424 //System.out.println("In: w=" + w + " h=" + h + " container=" + 425 // container + " x=" + mAttrs.x + " y=" + mAttrs.y); 426 427 float x, y; 428 if (mEnforceSizeCompat) { 429 x = mAttrs.x * mGlobalScale; 430 y = mAttrs.y * mGlobalScale; 431 } else { 432 x = mAttrs.x; 433 y = mAttrs.y; 434 } 435 436 Gravity.apply(mAttrs.gravity, w, h, container, 437 (int) (x + mAttrs.horizontalMargin * pw), 438 (int) (y + mAttrs.verticalMargin * ph), frame); 439 440 //System.out.println("Out: " + mFrame); 441 442 // Now make sure the window fits in the overall display. 443 Gravity.applyDisplay(mAttrs.gravity, df, frame); 444 445 // Make sure the system, content and visible frames are inside of the 446 // final window frame. 447 if (content.left < frame.left) content.left = frame.left; 448 if (content.top < frame.top) content.top = frame.top; 449 if (content.right > frame.right) content.right = frame.right; 450 if (content.bottom > frame.bottom) content.bottom = frame.bottom; 451 if (visible.left < frame.left) visible.left = frame.left; 452 if (visible.top < frame.top) visible.top = frame.top; 453 if (visible.right > frame.right) visible.right = frame.right; 454 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom; 455 456 final Rect contentInsets = mContentInsets; 457 contentInsets.left = content.left-frame.left; 458 contentInsets.top = content.top-frame.top; 459 contentInsets.right = frame.right-content.right; 460 contentInsets.bottom = frame.bottom-content.bottom; 461 462 final Rect visibleInsets = mVisibleInsets; 463 visibleInsets.left = visible.left-frame.left; 464 visibleInsets.top = visible.top-frame.top; 465 visibleInsets.right = frame.right-visible.right; 466 visibleInsets.bottom = frame.bottom-visible.bottom; 467 468 mCompatFrame.set(frame); 469 if (mEnforceSizeCompat) { 470 // If there is a size compatibility scale being applied to the 471 // window, we need to apply this to its insets so that they are 472 // reported to the app in its coordinate space. 473 contentInsets.scale(mInvGlobalScale); 474 visibleInsets.scale(mInvGlobalScale); 475 476 // Also the scaled frame that we report to the app needs to be 477 // adjusted to be in its coordinate space. 478 mCompatFrame.scale(mInvGlobalScale); 479 } 480 481 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) { 482 mService.updateWallpaperOffsetLocked(this, 483 mService.mAppDisplayWidth, mService.mAppDisplayHeight, false); 484 } 485 486 if (WindowManagerService.localLOGV) { 487 //if ("com.google.android.youtube".equals(mAttrs.packageName) 488 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { 489 Slog.v(TAG, "Resolving (mRequestedWidth=" 490 + mRequestedWidth + ", mRequestedheight=" 491 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph 492 + "): frame=" + mFrame.toShortString() 493 + " ci=" + contentInsets.toShortString() 494 + " vi=" + visibleInsets.toShortString()); 495 //} 496 } 497 } 498 499 @Override 500 public Rect getFrameLw() { 501 return mFrame; 502 } 503 504 @Override 505 public RectF getShownFrameLw() { 506 return mShownFrame; 507 } 508 509 @Override 510 public Rect getDisplayFrameLw() { 511 return mDisplayFrame; 512 } 513 514 @Override 515 public Rect getContentFrameLw() { 516 return mContentFrame; 517 } 518 519 @Override 520 public Rect getVisibleFrameLw() { 521 return mVisibleFrame; 522 } 523 524 @Override 525 public boolean getGivenInsetsPendingLw() { 526 return mGivenInsetsPending; 527 } 528 529 @Override 530 public Rect getGivenContentInsetsLw() { 531 return mGivenContentInsets; 532 } 533 534 @Override 535 public Rect getGivenVisibleInsetsLw() { 536 return mGivenVisibleInsets; 537 } 538 539 @Override 540 public WindowManager.LayoutParams getAttrs() { 541 return mAttrs; 542 } 543 544 public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) { 545 int index = -1; 546 WindowState ws = this; 547 while (true) { 548 if ((ws.mAttrs.privateFlags 549 & WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY) != 0) { 550 return (ws.mAttrs.flags & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0; 551 } 552 // If we reached the bottom of the range of windows we are considering, 553 // assume no menu is needed. 554 if (ws == bottom) { 555 return false; 556 } 557 // The current window hasn't specified whether menu key is needed; 558 // look behind it. 559 // First, we may need to determine the starting position. 560 if (index < 0) { 561 index = mService.mWindows.indexOf(ws); 562 } 563 index--; 564 if (index < 0) { 565 return false; 566 } 567 ws = mService.mWindows.get(index); 568 } 569 } 570 571 public int getSystemUiVisibility() { 572 return mSystemUiVisibility; 573 } 574 575 public int getSurfaceLayer() { 576 return mLayer; 577 } 578 579 public IApplicationToken getAppToken() { 580 return mAppToken != null ? mAppToken.appToken : null; 581 } 582 583 public long getInputDispatchingTimeoutNanos() { 584 return mAppToken != null 585 ? mAppToken.inputDispatchingTimeoutNanos 586 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 587 } 588 589 public boolean hasAppShownWindows() { 590 return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed); 591 } 592 593 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 594 if (dsdx < .99999f || dsdx > 1.00001f) return false; 595 if (dtdy < .99999f || dtdy > 1.00001f) return false; 596 if (dtdx < -.000001f || dtdx > .000001f) return false; 597 if (dsdy < -.000001f || dsdy > .000001f) return false; 598 return true; 599 } 600 601 void prelayout() { 602 if (mEnforceSizeCompat) { 603 mGlobalScale = mService.mCompatibleScreenScale; 604 mInvGlobalScale = 1/mGlobalScale; 605 } else { 606 mGlobalScale = mInvGlobalScale = 1; 607 } 608 } 609 610 /** 611 * Is this window visible? It is not visible if there is no 612 * surface, or we are in the process of running an exit animation 613 * that will remove the surface, or its app token has been hidden. 614 */ 615 public boolean isVisibleLw() { 616 final AppWindowToken atoken = mAppToken; 617 return mHasSurface && mPolicyVisibility && !mAttachedHidden 618 && (atoken == null || !atoken.hiddenRequested) 619 && !mExiting && !mDestroying; 620 } 621 622 /** 623 * Like {@link #isVisibleLw}, but also counts a window that is currently 624 * "hidden" behind the keyguard as visible. This allows us to apply 625 * things like window flags that impact the keyguard. 626 * XXX I am starting to think we need to have ANOTHER visibility flag 627 * for this "hidden behind keyguard" state rather than overloading 628 * mPolicyVisibility. Ungh. 629 */ 630 public boolean isVisibleOrBehindKeyguardLw() { 631 if (mRootToken.waitingToShow && 632 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) { 633 return false; 634 } 635 final AppWindowToken atoken = mAppToken; 636 final boolean animating = atoken != null 637 ? (atoken.mAppAnimator.animation != null) : false; 638 return mHasSurface && !mDestroying && !mExiting 639 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested) 640 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE 641 && !mRootToken.hidden) 642 || mWinAnimator.mAnimation != null || animating); 643 } 644 645 /** 646 * Is this window visible, ignoring its app token? It is not visible 647 * if there is no surface, or we are in the process of running an exit animation 648 * that will remove the surface. 649 */ 650 public boolean isWinVisibleLw() { 651 final AppWindowToken atoken = mAppToken; 652 return mHasSurface && mPolicyVisibility && !mAttachedHidden 653 && (atoken == null || !atoken.hiddenRequested || atoken.mAppAnimator.animating) 654 && !mExiting && !mDestroying; 655 } 656 657 /** 658 * The same as isVisible(), but follows the current hidden state of 659 * the associated app token, not the pending requested hidden state. 660 */ 661 boolean isVisibleNow() { 662 return mHasSurface && mPolicyVisibility && !mAttachedHidden 663 && !mRootToken.hidden && !mExiting && !mDestroying; 664 } 665 666 /** 667 * Can this window possibly be a drag/drop target? The test here is 668 * a combination of the above "visible now" with the check that the 669 * Input Manager uses when discarding windows from input consideration. 670 */ 671 boolean isPotentialDragTarget() { 672 return isVisibleNow() && !mRemoved 673 && mInputChannel != null && mInputWindowHandle != null; 674 } 675 676 /** 677 * Same as isVisible(), but we also count it as visible between the 678 * call to IWindowSession.add() and the first relayout(). 679 */ 680 boolean isVisibleOrAdding() { 681 final AppWindowToken atoken = mAppToken; 682 return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE)) 683 && mPolicyVisibility && !mAttachedHidden 684 && (atoken == null || !atoken.hiddenRequested) 685 && !mExiting && !mDestroying; 686 } 687 688 /** 689 * Is this window currently on-screen? It is on-screen either if it 690 * is visible or it is currently running an animation before no longer 691 * being visible. 692 */ 693 boolean isOnScreen() { 694 if (!mHasSurface || !mPolicyVisibility || mDestroying) { 695 return false; 696 } 697 final AppWindowToken atoken = mAppToken; 698 if (atoken != null) { 699 return ((!mAttachedHidden && !atoken.hiddenRequested) 700 || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null); 701 } 702 return !mAttachedHidden || mWinAnimator.mAnimation != null; 703 } 704 705 /** 706 * Like isOnScreen(), but we don't return true if the window is part 707 * of a transition that has not yet been started. 708 */ 709 boolean isReadyForDisplay() { 710 if (mRootToken.waitingToShow && 711 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) { 712 return false; 713 } 714 return mHasSurface && mPolicyVisibility && !mDestroying 715 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE 716 && !mRootToken.hidden) 717 || mWinAnimator.mAnimation != null 718 || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null))); 719 } 720 721 /** 722 * Like isReadyForDisplay(), but ignores any force hiding of the window due 723 * to the keyguard. 724 */ 725 boolean isReadyForDisplayIgnoringKeyguard() { 726 if (mRootToken.waitingToShow && 727 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) { 728 return false; 729 } 730 final AppWindowToken atoken = mAppToken; 731 if (atoken == null && !mPolicyVisibility) { 732 // If this is not an app window, and the policy has asked to force 733 // hide, then we really do want to hide. 734 return false; 735 } 736 return mHasSurface && !mDestroying 737 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE 738 && !mRootToken.hidden) 739 || mWinAnimator.mAnimation != null 740 || ((atoken != null) && (atoken.mAppAnimator.animation != null) 741 && !mWinAnimator.isDummyAnimation())); 742 } 743 744 /** 745 * Like isOnScreen, but returns false if the surface hasn't yet 746 * been drawn. 747 */ 748 public boolean isDisplayedLw() { 749 final AppWindowToken atoken = mAppToken; 750 return isDrawnLw() && mPolicyVisibility 751 && ((!mAttachedHidden && 752 (atoken == null || !atoken.hiddenRequested)) 753 || mWinAnimator.mAnimating); 754 } 755 756 /** 757 * Return true if this window (or a window it is attached to, but not 758 * considering its app token) is currently animating. 759 */ 760 public boolean isAnimatingLw() { 761 return mWinAnimator.mAnimation != null; 762 } 763 764 public boolean isGoneForLayoutLw() { 765 final AppWindowToken atoken = mAppToken; 766 return mViewVisibility == View.GONE 767 || !mRelayoutCalled 768 || (atoken == null && mRootToken.hidden) 769 || (atoken != null && (atoken.hiddenRequested || atoken.hidden)) 770 || mAttachedHidden 771 || mExiting || mDestroying; 772 } 773 774 /** 775 * Returns true if the window has a surface that it has drawn a 776 * complete UI in to. 777 */ 778 public boolean isDrawnLw() { 779 return mHasSurface && !mDestroying && 780 (mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW 781 || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN); 782 } 783 784 /** 785 * Return true if the window is opaque and fully drawn. This indicates 786 * it may obscure windows behind it. 787 */ 788 boolean isOpaqueDrawn() { 789 return (mAttrs.format == PixelFormat.OPAQUE 790 || mAttrs.type == TYPE_WALLPAPER) 791 && isDrawnLw() && mWinAnimator.mAnimation == null 792 && (mAppToken == null || mAppToken.mAppAnimator.animation == null); 793 } 794 795 /** 796 * Return whether this window is wanting to have a translation 797 * animation applied to it for an in-progress move. (Only makes 798 * sense to call from performLayoutAndPlaceSurfacesLockedInner().) 799 */ 800 boolean shouldAnimateMove() { 801 return mContentChanged && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay() 802 && (mFrame.top != mLastFrame.top 803 || mFrame.left != mLastFrame.left) 804 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove()); 805 } 806 807 boolean isFullscreen(int screenWidth, int screenHeight) { 808 return mFrame.left <= 0 && mFrame.top <= 0 && 809 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight; 810 } 811 812 void removeLocked() { 813 disposeInputChannel(); 814 815 if (mAttachedWindow != null) { 816 if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow); 817 mAttachedWindow.mChildWindows.remove(this); 818 } 819 mWinAnimator.destroyDeferredSurfaceLocked(); 820 mWinAnimator.destroySurfaceLocked(); 821 mSession.windowRemovedLocked(); 822 try { 823 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0); 824 } catch (RuntimeException e) { 825 // Ignore if it has already been removed (usually because 826 // we are doing this as part of processing a death note.) 827 } 828 } 829 830 void setInputChannel(InputChannel inputChannel) { 831 if (mInputChannel != null) { 832 throw new IllegalStateException("Window already has an input channel."); 833 } 834 835 mInputChannel = inputChannel; 836 mInputWindowHandle.inputChannel = inputChannel; 837 } 838 839 void disposeInputChannel() { 840 if (mInputChannel != null) { 841 mService.mInputManager.unregisterInputChannel(mInputChannel); 842 843 mInputChannel.dispose(); 844 mInputChannel = null; 845 } 846 847 mInputWindowHandle.inputChannel = null; 848 } 849 850 private class DeathRecipient implements IBinder.DeathRecipient { 851 public void binderDied() { 852 try { 853 synchronized(mService.mWindowMap) { 854 WindowState win = mService.windowForClientLocked(mSession, mClient, false); 855 Slog.i(TAG, "WIN DEATH: " + win); 856 if (win != null) { 857 mService.removeWindowLocked(mSession, win); 858 } 859 } 860 } catch (IllegalArgumentException ex) { 861 // This will happen if the window has already been 862 // removed. 863 } 864 } 865 } 866 867 /** Returns true if this window desires key events. 868 * TODO(cmautner): Is this the same as {@link WindowManagerService#canBeImeTarget} 869 */ 870 public final boolean canReceiveKeys() { 871 return isVisibleOrAdding() 872 && (mViewVisibility == View.VISIBLE) 873 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0); 874 } 875 876 @Override 877 public boolean hasDrawnLw() { 878 return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN; 879 } 880 881 @Override 882 public boolean showLw(boolean doAnimation) { 883 return showLw(doAnimation, true); 884 } 885 886 boolean showLw(boolean doAnimation, boolean requestAnim) { 887 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) { 888 // Already showing. 889 return false; 890 } 891 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this); 892 if (doAnimation) { 893 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility=" 894 + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation); 895 if (!mService.okToDisplay()) { 896 doAnimation = false; 897 } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) { 898 // Check for the case where we are currently visible and 899 // not animating; we do not want to do animation at such a 900 // point to become visible when we already are. 901 doAnimation = false; 902 } 903 } 904 mPolicyVisibility = true; 905 mPolicyVisibilityAfterAnim = true; 906 if (doAnimation) { 907 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true); 908 } 909 if (requestAnim) { 910 mService.scheduleAnimationLocked(); 911 } 912 return true; 913 } 914 915 @Override 916 public boolean hideLw(boolean doAnimation) { 917 return hideLw(doAnimation, true); 918 } 919 920 boolean hideLw(boolean doAnimation, boolean requestAnim) { 921 if (doAnimation) { 922 if (!mService.okToDisplay()) { 923 doAnimation = false; 924 } 925 } 926 boolean current = doAnimation ? mPolicyVisibilityAfterAnim 927 : mPolicyVisibility; 928 if (!current) { 929 // Already hiding. 930 return false; 931 } 932 if (doAnimation) { 933 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false); 934 if (mWinAnimator.mAnimation == null) { 935 doAnimation = false; 936 } 937 } 938 if (doAnimation) { 939 mPolicyVisibilityAfterAnim = false; 940 } else { 941 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this); 942 mPolicyVisibilityAfterAnim = false; 943 mPolicyVisibility = false; 944 // Window is no longer visible -- make sure if we were waiting 945 // for it to be displayed before enabling the display, that 946 // we allow the display to be enabled now. 947 mService.enableScreenIfNeededLocked(); 948 if (mService.mCurrentFocus == this) { 949 mService.mFocusMayChange = true; 950 } 951 } 952 if (requestAnim) { 953 mService.scheduleAnimationLocked(); 954 } 955 return true; 956 } 957 958 @Override 959 public boolean isAlive() { 960 return mClient.asBinder().isBinderAlive(); 961 } 962 963 private static void applyInsets(Region outRegion, Rect frame, Rect inset) { 964 outRegion.set( 965 frame.left + inset.left, frame.top + inset.top, 966 frame.right - inset.right, frame.bottom - inset.bottom); 967 } 968 969 public void getTouchableRegion(Region outRegion) { 970 final Rect frame = mFrame; 971 switch (mTouchableInsets) { 972 default: 973 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME: 974 outRegion.set(frame); 975 break; 976 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: 977 applyInsets(outRegion, frame, mGivenContentInsets); 978 break; 979 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: 980 applyInsets(outRegion, frame, mGivenVisibleInsets); 981 break; 982 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: { 983 final Region givenTouchableRegion = mGivenTouchableRegion; 984 outRegion.set(givenTouchableRegion); 985 outRegion.translate(frame.left, frame.top); 986 break; 987 } 988 } 989 } 990 991 void dump(PrintWriter pw, String prefix, boolean dumpAll) { 992 pw.print(prefix); pw.print("mSession="); pw.print(mSession); 993 pw.print(" mClient="); pw.println(mClient.asBinder()); 994 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs); 995 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth); 996 pw.print(" h="); pw.print(mRequestedHeight); 997 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq); 998 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { 999 pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth); 1000 pw.print(" h="); pw.println(mLastRequestedHeight); 1001 } 1002 if (mAttachedWindow != null || mLayoutAttached) { 1003 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow); 1004 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached); 1005 } 1006 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) { 1007 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow); 1008 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper); 1009 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer); 1010 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible); 1011 } 1012 if (dumpAll) { 1013 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer); 1014 pw.print(" mSubLayer="); pw.print(mSubLayer); 1015 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+"); 1016 pw.print((mTargetAppToken != null ? 1017 mTargetAppToken.mAppAnimator.animLayerAdjustment 1018 : (mAppToken != null ? mAppToken.mAppAnimator.animLayerAdjustment : 0))); 1019 pw.print("="); pw.print(mWinAnimator.mAnimLayer); 1020 pw.print(" mLastLayer="); pw.println(mWinAnimator.mLastLayer); 1021 } 1022 if (dumpAll) { 1023 pw.print(prefix); pw.print("mToken="); pw.println(mToken); 1024 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken); 1025 if (mAppToken != null) { 1026 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken); 1027 } 1028 if (mTargetAppToken != null) { 1029 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken); 1030 } 1031 pw.print(prefix); pw.print("mViewVisibility=0x"); 1032 pw.print(Integer.toHexString(mViewVisibility)); 1033 pw.print(" mHaveFrame="); pw.print(mHaveFrame); 1034 pw.print(" mObscured="); pw.println(mObscured); 1035 pw.print(prefix); pw.print("mSeq="); pw.print(mSeq); 1036 pw.print(" mSystemUiVisibility=0x"); 1037 pw.println(Integer.toHexString(mSystemUiVisibility)); 1038 } 1039 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) { 1040 pw.print(prefix); pw.print("mPolicyVisibility="); 1041 pw.print(mPolicyVisibility); 1042 pw.print(" mPolicyVisibilityAfterAnim="); 1043 pw.print(mPolicyVisibilityAfterAnim); 1044 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden); 1045 } 1046 if (!mRelayoutCalled || mLayoutNeeded) { 1047 pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled); 1048 pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded); 1049 } 1050 if (mXOffset != 0 || mYOffset != 0) { 1051 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset); 1052 pw.print(" y="); pw.println(mYOffset); 1053 } 1054 if (dumpAll) { 1055 pw.print(prefix); pw.print("mGivenContentInsets="); 1056 mGivenContentInsets.printShortString(pw); 1057 pw.print(" mGivenVisibleInsets="); 1058 mGivenVisibleInsets.printShortString(pw); 1059 pw.println(); 1060 if (mTouchableInsets != 0 || mGivenInsetsPending) { 1061 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets); 1062 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending); 1063 } 1064 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration); 1065 } 1066 pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface); 1067 pw.print(" mShownFrame="); mShownFrame.printShortString(pw); pw.println(); 1068 if (dumpAll) { 1069 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw); 1070 pw.print(" last="); mLastFrame.printShortString(pw); 1071 pw.println(); 1072 pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw); 1073 pw.print(" last="); mLastSystemDecorRect.printShortString(pw); 1074 pw.println(); 1075 } 1076 if (mEnforceSizeCompat) { 1077 pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw); 1078 pw.println(); 1079 } 1080 if (dumpAll) { 1081 pw.print(prefix); pw.print("Frames: containing="); 1082 mContainingFrame.printShortString(pw); 1083 pw.print(" parent="); mParentFrame.printShortString(pw); 1084 pw.print(" display="); mDisplayFrame.printShortString(pw); 1085 pw.println(); 1086 pw.print(prefix); pw.print(" content="); mContentFrame.printShortString(pw); 1087 pw.print(" visible="); mVisibleFrame.printShortString(pw); 1088 pw.println(); 1089 pw.print(prefix); pw.print("Cur insets: content="); 1090 mContentInsets.printShortString(pw); 1091 pw.print(" visible="); mVisibleInsets.printShortString(pw); 1092 pw.println(); 1093 pw.print(prefix); pw.print("Lst insets: content="); 1094 mLastContentInsets.printShortString(pw); 1095 pw.print(" visible="); mLastVisibleInsets.printShortString(pw); 1096 pw.println(); 1097 } 1098 mWinAnimator.dump(pw, prefix, dumpAll); 1099 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) { 1100 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting); 1101 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit); 1102 pw.print(" mDestroying="); pw.print(mDestroying); 1103 pw.print(" mRemoved="); pw.println(mRemoved); 1104 } 1105 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) { 1106 pw.print(prefix); pw.print("mOrientationChanging="); 1107 pw.print(mOrientationChanging); 1108 pw.print(" mAppFreezing="); pw.print(mAppFreezing); 1109 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen); 1110 } 1111 if (mHScale != 1 || mVScale != 1) { 1112 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale); 1113 pw.print(" mVScale="); pw.println(mVScale); 1114 } 1115 if (mWallpaperX != -1 || mWallpaperY != -1) { 1116 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX); 1117 pw.print(" mWallpaperY="); pw.println(mWallpaperY); 1118 } 1119 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) { 1120 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep); 1121 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep); 1122 } 1123 } 1124 1125 String makeInputChannelName() { 1126 return Integer.toHexString(System.identityHashCode(this)) 1127 + " " + mAttrs.getTitle(); 1128 } 1129 1130 @Override 1131 public String toString() { 1132 if (mStringNameCache == null || mLastTitle != mAttrs.getTitle() 1133 || mWasPaused != mToken.paused) { 1134 mLastTitle = mAttrs.getTitle(); 1135 mWasPaused = mToken.paused; 1136 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) 1137 + " " + mLastTitle + " paused=" + mWasPaused + "}"; 1138 } 1139 return mStringNameCache; 1140 } 1141} 1142