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