1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wm; 18 19 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 20 import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW; 21 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; 22 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 23 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 24 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 25 26 import com.android.server.input.InputWindowHandle; 27 28 import android.content.Context; 29 import android.content.res.Configuration; 30 import android.graphics.Matrix; 31 import android.graphics.PixelFormat; 32 import android.graphics.Rect; 33 import android.graphics.RectF; 34 import android.graphics.Region; 35 import android.os.IBinder; 36 import android.os.RemoteException; 37 import android.util.Slog; 38 import android.view.Gravity; 39 import android.view.IApplicationToken; 40 import android.view.IWindow; 41 import android.view.InputChannel; 42 import android.view.View; 43 import android.view.ViewTreeObserver; 44 import android.view.WindowManager; 45 import android.view.WindowManagerPolicy; 46 47 import java.io.PrintWriter; 48 import java.util.ArrayList; 49 50 /** 51 * A window in the window manager. 52 */ 53 final 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 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState attachedWindow, int seq, WindowManager.LayoutParams a, int viewVisibility)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 attach()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 computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf)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 getFrameLw()500 public Rect getFrameLw() { 501 return mFrame; 502 } 503 504 @Override getShownFrameLw()505 public RectF getShownFrameLw() { 506 return mShownFrame; 507 } 508 509 @Override getDisplayFrameLw()510 public Rect getDisplayFrameLw() { 511 return mDisplayFrame; 512 } 513 514 @Override getContentFrameLw()515 public Rect getContentFrameLw() { 516 return mContentFrame; 517 } 518 519 @Override getVisibleFrameLw()520 public Rect getVisibleFrameLw() { 521 return mVisibleFrame; 522 } 523 524 @Override getGivenInsetsPendingLw()525 public boolean getGivenInsetsPendingLw() { 526 return mGivenInsetsPending; 527 } 528 529 @Override getGivenContentInsetsLw()530 public Rect getGivenContentInsetsLw() { 531 return mGivenContentInsets; 532 } 533 534 @Override getGivenVisibleInsetsLw()535 public Rect getGivenVisibleInsetsLw() { 536 return mGivenVisibleInsets; 537 } 538 539 @Override getAttrs()540 public WindowManager.LayoutParams getAttrs() { 541 return mAttrs; 542 } 543 getNeedsMenuLw(WindowManagerPolicy.WindowState bottom)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 getSystemUiVisibility()571 public int getSystemUiVisibility() { 572 return mSystemUiVisibility; 573 } 574 getSurfaceLayer()575 public int getSurfaceLayer() { 576 return mLayer; 577 } 578 getAppToken()579 public IApplicationToken getAppToken() { 580 return mAppToken != null ? mAppToken.appToken : null; 581 } 582 getInputDispatchingTimeoutNanos()583 public long getInputDispatchingTimeoutNanos() { 584 return mAppToken != null 585 ? mAppToken.inputDispatchingTimeoutNanos 586 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 587 } 588 hasAppShownWindows()589 public boolean hasAppShownWindows() { 590 return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed); 591 } 592 isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy)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 prelayout()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 */ isVisibleLw()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 */ isVisibleOrBehindKeyguardLw()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 */ isWinVisibleLw()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 */ isVisibleNow()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 */ isPotentialDragTarget()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 */ isVisibleOrAdding()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 */ isOnScreen()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 */ isReadyForDisplay()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 */ isReadyForDisplayIgnoringKeyguard()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 */ isDisplayedLw()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 */ isAnimatingLw()760 public boolean isAnimatingLw() { 761 return mWinAnimator.mAnimation != null; 762 } 763 isGoneForLayoutLw()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 */ isDrawnLw()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 */ isOpaqueDrawn()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 */ shouldAnimateMove()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 isFullscreen(int screenWidth, int screenHeight)807 boolean isFullscreen(int screenWidth, int screenHeight) { 808 return mFrame.left <= 0 && mFrame.top <= 0 && 809 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight; 810 } 811 removeLocked()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 setInputChannel(InputChannel inputChannel)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 disposeInputChannel()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 { binderDied()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 */ canReceiveKeys()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 hasDrawnLw()877 public boolean hasDrawnLw() { 878 return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN; 879 } 880 881 @Override showLw(boolean doAnimation)882 public boolean showLw(boolean doAnimation) { 883 return showLw(doAnimation, true); 884 } 885 showLw(boolean doAnimation, boolean requestAnim)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 hideLw(boolean doAnimation)916 public boolean hideLw(boolean doAnimation) { 917 return hideLw(doAnimation, true); 918 } 919 hideLw(boolean doAnimation, boolean requestAnim)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 isAlive()959 public boolean isAlive() { 960 return mClient.asBinder().isBinderAlive(); 961 } 962 applyInsets(Region outRegion, Rect frame, Rect inset)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 getTouchableRegion(Region outRegion)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 dump(PrintWriter pw, String prefix, boolean dumpAll)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 makeInputChannelName()1125 String makeInputChannelName() { 1126 return Integer.toHexString(System.identityHashCode(this)) 1127 + " " + mAttrs.getTitle(); 1128 } 1129 1130 @Override toString()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