WindowState.java revision cc4f7db698f88b633a286d8ab1105b28a474cd09
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_APPLICATION_STARTING; 23import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 24import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 25import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 26 27import com.android.server.wm.WindowManagerService.H; 28 29import android.content.res.Configuration; 30import android.graphics.Matrix; 31import android.graphics.PixelFormat; 32import android.graphics.Rect; 33import android.graphics.Region; 34import android.os.IBinder; 35import android.os.RemoteException; 36import android.util.Slog; 37import android.view.Gravity; 38import android.view.IApplicationToken; 39import android.view.IWindow; 40import android.view.InputChannel; 41import android.view.Surface; 42import android.view.View; 43import android.view.ViewTreeObserver; 44import android.view.WindowManager; 45import android.view.WindowManagerPolicy; 46import android.view.WindowManager.LayoutParams; 47import android.view.animation.Animation; 48import android.view.animation.Transformation; 49 50import java.io.PrintWriter; 51import java.util.ArrayList; 52 53/** 54 * A window in the window manager. 55 */ 56final class WindowState implements WindowManagerPolicy.WindowState { 57 static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY; 58 static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS; 59 static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC; 60 61 final WindowManagerService mService; 62 final Session mSession; 63 final IWindow mClient; 64 WindowToken mToken; 65 WindowToken mRootToken; 66 AppWindowToken mAppToken; 67 AppWindowToken mTargetAppToken; 68 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams(); 69 final DeathRecipient mDeathRecipient; 70 final WindowState mAttachedWindow; 71 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>(); 72 final int mBaseLayer; 73 final int mSubLayer; 74 final boolean mLayoutAttached; 75 final boolean mIsImWindow; 76 final boolean mIsWallpaper; 77 final boolean mIsFloatingLayer; 78 boolean mEnforceSizeCompat; 79 int mViewVisibility; 80 boolean mPolicyVisibility = true; 81 boolean mPolicyVisibilityAfterAnim = true; 82 boolean mAppFreezing; 83 Surface mSurface; 84 boolean mReportDestroySurface; 85 boolean mSurfacePendingDestroy; 86 boolean mAttachedHidden; // is our parent window hidden? 87 boolean mLastHidden; // was this window last hidden? 88 boolean mWallpaperVisible; // for wallpaper, what was last vis report? 89 90 /** 91 * The window size that was requested by the application. These are in 92 * the application's coordinate space (without compatibility scale applied). 93 */ 94 int mRequestedWidth; 95 int mRequestedHeight; 96 97 int mLayer; 98 int mAnimLayer; 99 int mLastLayer; 100 boolean mHaveFrame; 101 boolean mObscured; 102 boolean mTurnOnScreen; 103 104 int mLayoutSeq = -1; 105 106 Configuration mConfiguration = null; 107 108 /** 109 * Actual frame shown on-screen (may be modified by animation). These 110 * are in the screen's coordinate space (WITH the compatibility scale 111 * applied). 112 */ 113 final Rect mShownFrame = new Rect(); 114 115 /** 116 * Set when we have changed the size of the surface, to know that 117 * we must tell them application to resize (and thus redraw itself). 118 */ 119 boolean mSurfaceResized; 120 121 /** 122 * Insets that determine the actually visible area. These are in the application's 123 * coordinate space (without compatibility scale applied). 124 */ 125 final Rect mVisibleInsets = new Rect(); 126 final Rect mLastVisibleInsets = new Rect(); 127 boolean mVisibleInsetsChanged; 128 129 /** 130 * Insets that are covered by system windows. These are in the application's 131 * coordinate space (without compatibility scale applied). 132 */ 133 final Rect mContentInsets = new Rect(); 134 final Rect mLastContentInsets = new Rect(); 135 boolean mContentInsetsChanged; 136 137 /** 138 * Set to true if we are waiting for this window to receive its 139 * given internal insets before laying out other windows based on it. 140 */ 141 boolean mGivenInsetsPending; 142 143 /** 144 * These are the content insets that were given during layout for 145 * this window, to be applied to windows behind it. 146 */ 147 final Rect mGivenContentInsets = new Rect(); 148 149 /** 150 * These are the visible insets that were given during layout for 151 * this window, to be applied to windows behind it. 152 */ 153 final Rect mGivenVisibleInsets = new Rect(); 154 155 /** 156 * This is the given touchable area relative to the window frame, or null if none. 157 */ 158 final Region mGivenTouchableRegion = new Region(); 159 160 /** 161 * Flag indicating whether the touchable region should be adjusted by 162 * the visible insets; if false the area outside the visible insets is 163 * NOT touchable, so we must use those to adjust the frame during hit 164 * tests. 165 */ 166 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME; 167 168 // Current transformation being applied. 169 boolean mHaveMatrix; 170 float mGlobalScale=1; 171 float mInvGlobalScale=1; 172 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1; 173 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1; 174 float mHScale=1, mVScale=1; 175 float mLastHScale=1, mLastVScale=1; 176 final Matrix mTmpMatrix = new Matrix(); 177 178 // "Real" frame that the application sees, in display coordinate space. 179 final Rect mFrame = new Rect(); 180 final Rect mLastFrame = new Rect(); 181 // Frame that is scaled to the application's coordinate space when in 182 // screen size compatibility mode. 183 final Rect mCompatFrame = new Rect(); 184 185 final Rect mContainingFrame = new Rect(); 186 final Rect mDisplayFrame = new Rect(); 187 final Rect mContentFrame = new Rect(); 188 final Rect mParentFrame = new Rect(); 189 final Rect mVisibleFrame = new Rect(); 190 191 boolean mContentChanged; 192 193 float mShownAlpha = 1; 194 float mAlpha = 1; 195 float mLastAlpha = 1; 196 197 // Set to true if, when the window gets displayed, it should perform 198 // an enter animation. 199 boolean mEnterAnimationPending; 200 201 // Currently running animation. 202 boolean mAnimating; 203 boolean mLocalAnimating; 204 Animation mAnimation; 205 boolean mAnimationIsEntrance; 206 boolean mHasTransformation; 207 boolean mHasLocalTransformation; 208 final Transformation mTransformation = new Transformation(); 209 210 // If a window showing a wallpaper: the requested offset for the 211 // wallpaper; if a wallpaper window: the currently applied offset. 212 float mWallpaperX = -1; 213 float mWallpaperY = -1; 214 215 // If a window showing a wallpaper: what fraction of the offset 216 // range corresponds to a full virtual screen. 217 float mWallpaperXStep = -1; 218 float mWallpaperYStep = -1; 219 220 // Wallpaper windows: pixels offset based on above variables. 221 int mXOffset; 222 int mYOffset; 223 224 // This is set after IWindowSession.relayout() has been called at 225 // least once for the window. It allows us to detect the situation 226 // where we don't yet have a surface, but should have one soon, so 227 // we can give the window focus before waiting for the relayout. 228 boolean mRelayoutCalled; 229 230 // This is set after the Surface has been created but before the 231 // window has been drawn. During this time the surface is hidden. 232 boolean mDrawPending; 233 234 // This is set after the window has finished drawing for the first 235 // time but before its surface is shown. The surface will be 236 // displayed when the next layout is run. 237 boolean mCommitDrawPending; 238 239 // This is set during the time after the window's drawing has been 240 // committed, and before its surface is actually shown. It is used 241 // to delay showing the surface until all windows in a token are ready 242 // to be shown. 243 boolean mReadyToShow; 244 245 // Set when the window has been shown in the screen the first time. 246 boolean mHasDrawn; 247 248 // Currently running an exit animation? 249 boolean mExiting; 250 251 // Currently on the mDestroySurface list? 252 boolean mDestroying; 253 254 // Completely remove from window manager after exit animation? 255 boolean mRemoveOnExit; 256 257 // Set when the orientation is changing and this window has not yet 258 // been updated for the new orientation. 259 boolean mOrientationChanging; 260 261 // Is this window now (or just being) removed? 262 boolean mRemoved; 263 264 // Temp for keeping track of windows that have been removed when 265 // rebuilding window list. 266 boolean mRebuilding; 267 268 // For debugging, this is the last information given to the surface flinger. 269 boolean mSurfaceShown; 270 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH; 271 int mSurfaceLayer; 272 float mSurfaceAlpha; 273 274 // Input channel and input window handle used by the input dispatcher. 275 final InputWindowHandle mInputWindowHandle; 276 InputChannel mInputChannel; 277 278 // Used to improve performance of toString() 279 String mStringNameCache; 280 CharSequence mLastTitle; 281 boolean mWasPaused; 282 283 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, 284 WindowState attachedWindow, WindowManager.LayoutParams a, 285 int viewVisibility) { 286 mService = service; 287 mSession = s; 288 mClient = c; 289 mToken = token; 290 mAttrs.copyFrom(a); 291 mViewVisibility = viewVisibility; 292 DeathRecipient deathRecipient = new DeathRecipient(); 293 mAlpha = a.alpha; 294 mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0; 295 if (WindowManagerService.localLOGV) Slog.v( 296 WindowManagerService.TAG, "Window " + this + " client=" + c.asBinder() 297 + " token=" + token + " (" + mAttrs.token + ")"); 298 try { 299 c.asBinder().linkToDeath(deathRecipient, 0); 300 } catch (RemoteException e) { 301 mDeathRecipient = null; 302 mAttachedWindow = null; 303 mLayoutAttached = false; 304 mIsImWindow = false; 305 mIsWallpaper = false; 306 mIsFloatingLayer = false; 307 mBaseLayer = 0; 308 mSubLayer = 0; 309 mInputWindowHandle = null; 310 return; 311 } 312 mDeathRecipient = deathRecipient; 313 314 if ((mAttrs.type >= FIRST_SUB_WINDOW && 315 mAttrs.type <= LAST_SUB_WINDOW)) { 316 // The multiplier here is to reserve space for multiple 317 // windows in the same type layer. 318 mBaseLayer = mService.mPolicy.windowTypeToLayerLw( 319 attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER 320 + WindowManagerService.TYPE_LAYER_OFFSET; 321 mSubLayer = mService.mPolicy.subWindowTypeToLayerLw(a.type); 322 mAttachedWindow = attachedWindow; 323 if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Adding " + this + " to " + mAttachedWindow); 324 mAttachedWindow.mChildWindows.add(this); 325 mLayoutAttached = mAttrs.type != 326 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 327 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD 328 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 329 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER; 330 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 331 } else { 332 // The multiplier here is to reserve space for multiple 333 // windows in the same type layer. 334 mBaseLayer = mService.mPolicy.windowTypeToLayerLw(a.type) 335 * WindowManagerService.TYPE_LAYER_MULTIPLIER 336 + WindowManagerService.TYPE_LAYER_OFFSET; 337 mSubLayer = 0; 338 mAttachedWindow = null; 339 mLayoutAttached = false; 340 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD 341 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 342 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER; 343 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 344 } 345 346 WindowState appWin = this; 347 while (appWin.mAttachedWindow != null) { 348 appWin = mAttachedWindow; 349 } 350 WindowToken appToken = appWin.mToken; 351 while (appToken.appWindowToken == null) { 352 WindowToken parent = mService.mTokenMap.get(appToken.token); 353 if (parent == null || appToken == parent) { 354 break; 355 } 356 appToken = parent; 357 } 358 mRootToken = appToken; 359 mAppToken = appToken.appWindowToken; 360 361 mSurface = null; 362 mRequestedWidth = 0; 363 mRequestedHeight = 0; 364 mXOffset = 0; 365 mYOffset = 0; 366 mLayer = 0; 367 mAnimLayer = 0; 368 mLastLayer = 0; 369 mInputWindowHandle = new InputWindowHandle( 370 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this); 371 } 372 373 void attach() { 374 if (WindowManagerService.localLOGV) Slog.v( 375 WindowManagerService.TAG, "Attaching " + this + " token=" + mToken 376 + ", list=" + mToken.windows); 377 mSession.windowAddedLocked(); 378 } 379 380 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) { 381 mHaveFrame = true; 382 383 final Rect container = mContainingFrame; 384 container.set(pf); 385 386 final Rect display = mDisplayFrame; 387 display.set(df); 388 389 final int pw = container.right - container.left; 390 final int ph = container.bottom - container.top; 391 392 int w,h; 393 if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) { 394 if (mAttrs.width < 0) { 395 w = pw; 396 } else if (mEnforceSizeCompat) { 397 w = (int)(mAttrs.width * mGlobalScale + .5f); 398 } else { 399 w = mAttrs.width; 400 } 401 if (mAttrs.height < 0) { 402 h = ph; 403 } else if (mEnforceSizeCompat) { 404 h = (int)(mAttrs.height * mGlobalScale + .5f); 405 } else { 406 h = mAttrs.height; 407 } 408 } else { 409 if (mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT) { 410 w = pw; 411 } else if (mEnforceSizeCompat) { 412 w = (int)(mRequestedWidth * mGlobalScale + .5f); 413 } else { 414 w = mRequestedWidth; 415 } 416 if (mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT) { 417 h = ph; 418 } else if (mEnforceSizeCompat) { 419 h = (int)(mRequestedHeight * mGlobalScale + .5f); 420 } else { 421 h = mRequestedHeight; 422 } 423 } 424 425 if (!mParentFrame.equals(pf)) { 426 //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame 427 // + " to " + pf); 428 mParentFrame.set(pf); 429 mContentChanged = true; 430 } 431 432 final Rect content = mContentFrame; 433 content.set(cf); 434 435 final Rect visible = mVisibleFrame; 436 visible.set(vf); 437 438 final Rect frame = mFrame; 439 final int fw = frame.width(); 440 final int fh = frame.height(); 441 442 //System.out.println("In: w=" + w + " h=" + h + " container=" + 443 // container + " x=" + mAttrs.x + " y=" + mAttrs.y); 444 445 float x, y; 446 if (mEnforceSizeCompat) { 447 x = mAttrs.x * mGlobalScale; 448 y = mAttrs.y * mGlobalScale; 449 } else { 450 x = mAttrs.x; 451 y = mAttrs.y; 452 } 453 454 Gravity.apply(mAttrs.gravity, w, h, container, 455 (int) (x + mAttrs.horizontalMargin * pw), 456 (int) (y + mAttrs.verticalMargin * ph), frame); 457 458 //System.out.println("Out: " + mFrame); 459 460 // Now make sure the window fits in the overall display. 461 Gravity.applyDisplay(mAttrs.gravity, df, frame); 462 463 // Make sure the content and visible frames are inside of the 464 // final window frame. 465 if (content.left < frame.left) content.left = frame.left; 466 if (content.top < frame.top) content.top = frame.top; 467 if (content.right > frame.right) content.right = frame.right; 468 if (content.bottom > frame.bottom) content.bottom = frame.bottom; 469 if (visible.left < frame.left) visible.left = frame.left; 470 if (visible.top < frame.top) visible.top = frame.top; 471 if (visible.right > frame.right) visible.right = frame.right; 472 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom; 473 474 final Rect contentInsets = mContentInsets; 475 contentInsets.left = content.left-frame.left; 476 contentInsets.top = content.top-frame.top; 477 contentInsets.right = frame.right-content.right; 478 contentInsets.bottom = frame.bottom-content.bottom; 479 480 final Rect visibleInsets = mVisibleInsets; 481 visibleInsets.left = visible.left-frame.left; 482 visibleInsets.top = visible.top-frame.top; 483 visibleInsets.right = frame.right-visible.right; 484 visibleInsets.bottom = frame.bottom-visible.bottom; 485 486 mCompatFrame.set(frame); 487 if (mEnforceSizeCompat) { 488 // If there is a size compatibility scale being applied to the 489 // window, we need to apply this to its insets so that they are 490 // reported to the app in its coordinate space. 491 contentInsets.scale(mInvGlobalScale); 492 visibleInsets.scale(mInvGlobalScale); 493 494 // Also the scaled frame that we report to the app needs to be 495 // adjusted to be in its coordinate space. 496 mCompatFrame.scale(mInvGlobalScale); 497 } 498 499 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) { 500 mService.updateWallpaperOffsetLocked(this, 501 mService.mAppDisplayWidth, mService.mAppDisplayHeight, false); 502 } 503 504 if (WindowManagerService.localLOGV) { 505 //if ("com.google.android.youtube".equals(mAttrs.packageName) 506 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { 507 Slog.v(WindowManagerService.TAG, "Resolving (mRequestedWidth=" 508 + mRequestedWidth + ", mRequestedheight=" 509 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph 510 + "): frame=" + mFrame.toShortString() 511 + " ci=" + contentInsets.toShortString() 512 + " vi=" + visibleInsets.toShortString()); 513 //} 514 } 515 } 516 517 public Rect getFrameLw() { 518 return mFrame; 519 } 520 521 public Rect getShownFrameLw() { 522 return mShownFrame; 523 } 524 525 public Rect getDisplayFrameLw() { 526 return mDisplayFrame; 527 } 528 529 public Rect getContentFrameLw() { 530 return mContentFrame; 531 } 532 533 public Rect getVisibleFrameLw() { 534 return mVisibleFrame; 535 } 536 537 public boolean getGivenInsetsPendingLw() { 538 return mGivenInsetsPending; 539 } 540 541 public Rect getGivenContentInsetsLw() { 542 return mGivenContentInsets; 543 } 544 545 public Rect getGivenVisibleInsetsLw() { 546 return mGivenVisibleInsets; 547 } 548 549 public WindowManager.LayoutParams getAttrs() { 550 return mAttrs; 551 } 552 553 public int getSurfaceLayer() { 554 return mLayer; 555 } 556 557 public IApplicationToken getAppToken() { 558 return mAppToken != null ? mAppToken.appToken : null; 559 } 560 561 public long getInputDispatchingTimeoutNanos() { 562 return mAppToken != null 563 ? mAppToken.inputDispatchingTimeoutNanos 564 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 565 } 566 567 public boolean hasAppShownWindows() { 568 return mAppToken != null ? mAppToken.firstWindowDrawn : false; 569 } 570 571 public void setAnimation(Animation anim) { 572 if (WindowManagerService.localLOGV) Slog.v( 573 WindowManagerService.TAG, "Setting animation in " + this + ": " + anim); 574 mAnimating = false; 575 mLocalAnimating = false; 576 mAnimation = anim; 577 mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION); 578 mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale); 579 } 580 581 public void clearAnimation() { 582 if (mAnimation != null) { 583 mAnimating = true; 584 mLocalAnimating = false; 585 mAnimation.cancel(); 586 mAnimation = null; 587 } 588 } 589 590 Surface createSurfaceLocked() { 591 if (mSurface == null) { 592 mReportDestroySurface = false; 593 mSurfacePendingDestroy = false; 594 mDrawPending = true; 595 mCommitDrawPending = false; 596 mReadyToShow = false; 597 if (mAppToken != null) { 598 mAppToken.allDrawn = false; 599 } 600 601 int flags = 0; 602 603 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) { 604 flags |= Surface.SECURE; 605 } 606 if (DEBUG_VISIBILITY) Slog.v( 607 WindowManagerService.TAG, "Creating surface in session " 608 + mSession.mSurfaceSession + " window " + this 609 + " w=" + mCompatFrame.width() 610 + " h=" + mCompatFrame.height() + " format=" 611 + mAttrs.format + " flags=" + flags); 612 613 int w = mCompatFrame.width(); 614 int h = mCompatFrame.height(); 615 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) { 616 // for a scaled surface, we always want the requested 617 // size. 618 w = mRequestedWidth; 619 h = mRequestedHeight; 620 } 621 622 // Something is wrong and SurfaceFlinger will not like this, 623 // try to revert to sane values 624 if (w <= 0) w = 1; 625 if (h <= 0) h = 1; 626 627 mSurfaceShown = false; 628 mSurfaceLayer = 0; 629 mSurfaceAlpha = 1; 630 mSurfaceX = 0; 631 mSurfaceY = 0; 632 mSurfaceW = w; 633 mSurfaceH = h; 634 try { 635 final boolean isHwAccelerated = (mAttrs.flags & 636 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0; 637 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format; 638 if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) { 639 flags |= Surface.OPAQUE; 640 } 641 mSurface = new Surface( 642 mSession.mSurfaceSession, mSession.mPid, 643 mAttrs.getTitle().toString(), 644 0, w, h, format, flags); 645 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG, 646 " CREATE SURFACE " 647 + mSurface + " IN SESSION " 648 + mSession.mSurfaceSession 649 + ": pid=" + mSession.mPid + " format=" 650 + mAttrs.format + " flags=0x" 651 + Integer.toHexString(flags) 652 + " / " + this); 653 } catch (Surface.OutOfResourcesException e) { 654 Slog.w(WindowManagerService.TAG, "OutOfResourcesException creating surface"); 655 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true); 656 return null; 657 } catch (Exception e) { 658 Slog.e(WindowManagerService.TAG, "Exception creating surface", e); 659 return null; 660 } 661 662 if (WindowManagerService.localLOGV) Slog.v( 663 WindowManagerService.TAG, "Got surface: " + mSurface 664 + ", set left=" + mFrame.left + " top=" + mFrame.top 665 + ", animLayer=" + mAnimLayer); 666 if (SHOW_TRANSACTIONS) { 667 Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION createSurfaceLocked"); 668 WindowManagerService.logSurface(this, "CREATE pos=(" + mFrame.left 669 + "," + mFrame.top + ") (" + 670 mCompatFrame.width() + "x" + mCompatFrame.height() + "), layer=" + 671 mAnimLayer + " HIDE", null); 672 } 673 Surface.openTransaction(); 674 try { 675 try { 676 mSurfaceX = mFrame.left + mXOffset; 677 mSurfaceY = mFrame.top + mYOffset; 678 mSurface.setPosition(mSurfaceX, mSurfaceY); 679 mSurfaceLayer = mAnimLayer; 680 mSurface.setLayer(mAnimLayer); 681 mSurfaceShown = false; 682 mSurface.hide(); 683 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) { 684 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "DITHER", null); 685 mSurface.setFlags(Surface.SURFACE_DITHER, 686 Surface.SURFACE_DITHER); 687 } 688 } catch (RuntimeException e) { 689 Slog.w(WindowManagerService.TAG, "Error creating surface in " + w, e); 690 mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true); 691 } 692 mLastHidden = true; 693 } finally { 694 Surface.closeTransaction(); 695 if (SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION createSurfaceLocked"); 696 } 697 if (WindowManagerService.localLOGV) Slog.v( 698 WindowManagerService.TAG, "Created surface " + this); 699 } 700 return mSurface; 701 } 702 703 void destroySurfaceLocked() { 704 if (mAppToken != null && this == mAppToken.startingWindow) { 705 mAppToken.startingDisplayed = false; 706 } 707 708 if (mSurface != null) { 709 mDrawPending = false; 710 mCommitDrawPending = false; 711 mReadyToShow = false; 712 713 int i = mChildWindows.size(); 714 while (i > 0) { 715 i--; 716 WindowState c = mChildWindows.get(i); 717 c.mAttachedHidden = true; 718 } 719 720 if (mReportDestroySurface) { 721 mReportDestroySurface = false; 722 mSurfacePendingDestroy = true; 723 try { 724 mClient.dispatchGetNewSurface(); 725 // We'll really destroy on the next time around. 726 return; 727 } catch (RemoteException e) { 728 } 729 } 730 731 try { 732 if (DEBUG_VISIBILITY) { 733 RuntimeException e = null; 734 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 735 e = new RuntimeException(); 736 e.fillInStackTrace(); 737 } 738 Slog.w(WindowManagerService.TAG, "Window " + this + " destroying surface " 739 + mSurface + ", session " + mSession, e); 740 } 741 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { 742 RuntimeException e = null; 743 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 744 e = new RuntimeException(); 745 e.fillInStackTrace(); 746 } 747 WindowManagerService.logSurface(this, "DESTROY", e); 748 } 749 mSurface.destroy(); 750 } catch (RuntimeException e) { 751 Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window " + this 752 + " surface " + mSurface + " session " + mSession 753 + ": " + e.toString()); 754 } 755 756 mSurfaceShown = false; 757 mSurface = null; 758 } 759 } 760 761 boolean finishDrawingLocked() { 762 if (mDrawPending) { 763 if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) Slog.v( 764 WindowManagerService.TAG, "finishDrawingLocked: " + mSurface); 765 mCommitDrawPending = true; 766 mDrawPending = false; 767 return true; 768 } 769 return false; 770 } 771 772 // This must be called while inside a transaction. 773 boolean commitFinishDrawingLocked(long currentTime) { 774 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface); 775 if (!mCommitDrawPending) { 776 return false; 777 } 778 mCommitDrawPending = false; 779 mReadyToShow = true; 780 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING; 781 final AppWindowToken atoken = mAppToken; 782 if (atoken == null || atoken.allDrawn || starting) { 783 performShowLocked(); 784 } 785 return true; 786 } 787 788 // This must be called while inside a transaction. 789 boolean performShowLocked() { 790 if (DEBUG_VISIBILITY) { 791 RuntimeException e = null; 792 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 793 e = new RuntimeException(); 794 e.fillInStackTrace(); 795 } 796 Slog.v(WindowManagerService.TAG, "performShow on " + this 797 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay() 798 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e); 799 } 800 if (mReadyToShow && isReadyForDisplay()) { 801 if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) WindowManagerService.logSurface(this, 802 "SHOW (performShowLocked)", null); 803 if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Showing " + this 804 + " during animation: policyVis=" + mPolicyVisibility 805 + " attHidden=" + mAttachedHidden 806 + " tok.hiddenRequested=" 807 + (mAppToken != null ? mAppToken.hiddenRequested : false) 808 + " tok.hidden=" 809 + (mAppToken != null ? mAppToken.hidden : false) 810 + " animating=" + mAnimating 811 + " tok animating=" 812 + (mAppToken != null ? mAppToken.animating : false)); 813 if (!mService.showSurfaceRobustlyLocked(this)) { 814 return false; 815 } 816 mLastAlpha = -1; 817 mHasDrawn = true; 818 mLastHidden = false; 819 mReadyToShow = false; 820 mService.enableScreenIfNeededLocked(); 821 822 mService.applyEnterAnimationLocked(this); 823 824 int i = mChildWindows.size(); 825 while (i > 0) { 826 i--; 827 WindowState c = mChildWindows.get(i); 828 if (c.mAttachedHidden) { 829 c.mAttachedHidden = false; 830 if (c.mSurface != null) { 831 c.performShowLocked(); 832 // It hadn't been shown, which means layout not 833 // performed on it, so now we want to make sure to 834 // do a layout. If called from within the transaction 835 // loop, this will cause it to restart with a new 836 // layout. 837 mService.mLayoutNeeded = true; 838 } 839 } 840 } 841 842 if (mAttrs.type != TYPE_APPLICATION_STARTING 843 && mAppToken != null) { 844 mAppToken.firstWindowDrawn = true; 845 846 if (mAppToken.startingData != null) { 847 if (WindowManagerService.DEBUG_STARTING_WINDOW || WindowManagerService.DEBUG_ANIM) Slog.v(WindowManagerService.TAG, 848 "Finish starting " + mToken 849 + ": first real window is shown, no animation"); 850 // If this initial window is animating, stop it -- we 851 // will do an animation to reveal it from behind the 852 // starting window, so there is no need for it to also 853 // be doing its own stuff. 854 if (mAnimation != null) { 855 mAnimation.cancel(); 856 mAnimation = null; 857 // Make sure we clean up the animation. 858 mAnimating = true; 859 } 860 mService.mFinishedStarting.add(mAppToken); 861 mService.mH.sendEmptyMessage(H.FINISHED_STARTING); 862 } 863 mAppToken.updateReportedVisibilityLocked(); 864 } 865 } 866 return true; 867 } 868 869 // This must be called while inside a transaction. Returns true if 870 // there is more animation to run. 871 boolean stepAnimationLocked(long currentTime, int dw, int dh) { 872 if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOn()) { 873 // We will run animations as long as the display isn't frozen. 874 875 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) { 876 mHasTransformation = true; 877 mHasLocalTransformation = true; 878 if (!mLocalAnimating) { 879 if (WindowManagerService.DEBUG_ANIM) Slog.v( 880 WindowManagerService.TAG, "Starting animation in " + this + 881 " @ " + currentTime + ": ww=" + mFrame.width() + 882 " wh=" + mFrame.height() + 883 " dw=" + dw + " dh=" + dh + " scale=" + mService.mWindowAnimationScale); 884 mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh); 885 mAnimation.setStartTime(currentTime); 886 mLocalAnimating = true; 887 mAnimating = true; 888 } 889 mTransformation.clear(); 890 final boolean more = mAnimation.getTransformation( 891 currentTime, mTransformation); 892 if (WindowManagerService.DEBUG_ANIM) Slog.v( 893 WindowManagerService.TAG, "Stepped animation in " + this + 894 ": more=" + more + ", xform=" + mTransformation); 895 if (more) { 896 // we're not done! 897 return true; 898 } 899 if (WindowManagerService.DEBUG_ANIM) Slog.v( 900 WindowManagerService.TAG, "Finished animation in " + this + 901 " @ " + currentTime); 902 903 if (mAnimation != null) { 904 mAnimation.cancel(); 905 mAnimation = null; 906 } 907 //WindowManagerService.this.dump(); 908 } 909 mHasLocalTransformation = false; 910 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null 911 && mAppToken.animation != null) { 912 // When our app token is animating, we kind-of pretend like 913 // we are as well. Note the mLocalAnimating mAnimationIsEntrance 914 // part of this check means that we will only do this if 915 // our window is not currently exiting, or it is not 916 // locally animating itself. The idea being that one that 917 // is exiting and doing a local animation should be removed 918 // once that animation is done. 919 mAnimating = true; 920 mHasTransformation = true; 921 mTransformation.clear(); 922 return false; 923 } else if (mHasTransformation) { 924 // Little trick to get through the path below to act like 925 // we have finished an animation. 926 mAnimating = true; 927 } else if (isAnimating()) { 928 mAnimating = true; 929 } 930 } else if (mAnimation != null) { 931 // If the display is frozen, and there is a pending animation, 932 // clear it and make sure we run the cleanup code. 933 mAnimating = true; 934 mLocalAnimating = true; 935 mAnimation.cancel(); 936 mAnimation = null; 937 } 938 939 if (!mAnimating && !mLocalAnimating) { 940 return false; 941 } 942 943 if (WindowManagerService.DEBUG_ANIM) Slog.v( 944 WindowManagerService.TAG, "Animation done in " + this + ": exiting=" + mExiting 945 + ", reportedVisible=" 946 + (mAppToken != null ? mAppToken.reportedVisible : false)); 947 948 mAnimating = false; 949 mLocalAnimating = false; 950 if (mAnimation != null) { 951 mAnimation.cancel(); 952 mAnimation = null; 953 } 954 mAnimLayer = mLayer; 955 if (mIsImWindow) { 956 mAnimLayer += mService.mInputMethodAnimLayerAdjustment; 957 } else if (mIsWallpaper) { 958 mAnimLayer += mService.mWallpaperAnimLayerAdjustment; 959 } 960 if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Stepping win " + this 961 + " anim layer: " + mAnimLayer); 962 mHasTransformation = false; 963 mHasLocalTransformation = false; 964 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) { 965 if (DEBUG_VISIBILITY) { 966 Slog.v(WindowManagerService.TAG, "Policy visibility changing after anim in " + this + ": " 967 + mPolicyVisibilityAfterAnim); 968 } 969 mPolicyVisibility = mPolicyVisibilityAfterAnim; 970 if (!mPolicyVisibility) { 971 if (mService.mCurrentFocus == this) { 972 mService.mFocusMayChange = true; 973 } 974 // Window is no longer visible -- make sure if we were waiting 975 // for it to be displayed before enabling the display, that 976 // we allow the display to be enabled now. 977 mService.enableScreenIfNeededLocked(); 978 } 979 } 980 mTransformation.clear(); 981 if (mHasDrawn 982 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING 983 && mAppToken != null 984 && mAppToken.firstWindowDrawn 985 && mAppToken.startingData != null) { 986 if (WindowManagerService.DEBUG_STARTING_WINDOW) Slog.v(WindowManagerService.TAG, "Finish starting " 987 + mToken + ": first real window done animating"); 988 mService.mFinishedStarting.add(mAppToken); 989 mService.mH.sendEmptyMessage(H.FINISHED_STARTING); 990 } 991 992 finishExit(); 993 994 if (mAppToken != null) { 995 mAppToken.updateReportedVisibilityLocked(); 996 } 997 998 return false; 999 } 1000 1001 void finishExit() { 1002 if (WindowManagerService.DEBUG_ANIM) Slog.v( 1003 WindowManagerService.TAG, "finishExit in " + this 1004 + ": exiting=" + mExiting 1005 + " remove=" + mRemoveOnExit 1006 + " windowAnimating=" + isWindowAnimating()); 1007 1008 final int N = mChildWindows.size(); 1009 for (int i=0; i<N; i++) { 1010 mChildWindows.get(i).finishExit(); 1011 } 1012 1013 if (!mExiting) { 1014 return; 1015 } 1016 1017 if (isWindowAnimating()) { 1018 return; 1019 } 1020 1021 if (WindowManagerService.localLOGV) Slog.v( 1022 WindowManagerService.TAG, "Exit animation finished in " + this 1023 + ": remove=" + mRemoveOnExit); 1024 if (mSurface != null) { 1025 mService.mDestroySurface.add(this); 1026 mDestroying = true; 1027 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "HIDE (finishExit)", null); 1028 mSurfaceShown = false; 1029 try { 1030 mSurface.hide(); 1031 } catch (RuntimeException e) { 1032 Slog.w(WindowManagerService.TAG, "Error hiding surface in " + this, e); 1033 } 1034 mLastHidden = true; 1035 } 1036 mExiting = false; 1037 if (mRemoveOnExit) { 1038 mService.mPendingRemove.add(this); 1039 mRemoveOnExit = false; 1040 } 1041 } 1042 1043 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 1044 if (dsdx < .99999f || dsdx > 1.00001f) return false; 1045 if (dtdy < .99999f || dtdy > 1.00001f) return false; 1046 if (dtdx < -.000001f || dtdx > .000001f) return false; 1047 if (dsdy < -.000001f || dsdy > .000001f) return false; 1048 return true; 1049 } 1050 1051 void prelayout() { 1052 if (mEnforceSizeCompat) { 1053 mGlobalScale = mService.mCompatibleScreenScale; 1054 mInvGlobalScale = 1/mGlobalScale; 1055 } else { 1056 mGlobalScale = mInvGlobalScale = 1; 1057 } 1058 } 1059 1060 void computeShownFrameLocked() { 1061 final boolean selfTransformation = mHasLocalTransformation; 1062 Transformation attachedTransformation = 1063 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation) 1064 ? mAttachedWindow.mTransformation : null; 1065 Transformation appTransformation = 1066 (mAppToken != null && mAppToken.hasTransformation) 1067 ? mAppToken.transformation : null; 1068 1069 // Wallpapers are animated based on the "real" window they 1070 // are currently targeting. 1071 if (mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null 1072 && mService.mWallpaperTarget != null) { 1073 if (mService.mWallpaperTarget.mHasLocalTransformation && 1074 mService.mWallpaperTarget.mAnimation != null && 1075 !mService.mWallpaperTarget.mAnimation.getDetachWallpaper()) { 1076 attachedTransformation = mService.mWallpaperTarget.mTransformation; 1077 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) { 1078 Slog.v(WindowManagerService.TAG, "WP target attached xform: " + attachedTransformation); 1079 } 1080 } 1081 if (mService.mWallpaperTarget.mAppToken != null && 1082 mService.mWallpaperTarget.mAppToken.hasTransformation && 1083 mService.mWallpaperTarget.mAppToken.animation != null && 1084 !mService.mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) { 1085 appTransformation = mService.mWallpaperTarget.mAppToken.transformation; 1086 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) { 1087 Slog.v(WindowManagerService.TAG, "WP target app xform: " + appTransformation); 1088 } 1089 } 1090 } 1091 1092 final boolean screenAnimation = mService.mScreenRotationAnimation != null 1093 && mService.mScreenRotationAnimation.isAnimating(); 1094 if (selfTransformation || attachedTransformation != null 1095 || appTransformation != null || screenAnimation) { 1096 // cache often used attributes locally 1097 final Rect frame = mFrame; 1098 final float tmpFloats[] = mService.mTmpFloats; 1099 final Matrix tmpMatrix = mTmpMatrix; 1100 1101 // Compute the desired transformation. 1102 tmpMatrix.setTranslate(0, 0); 1103 tmpMatrix.postScale(mGlobalScale, mGlobalScale); 1104 if (selfTransformation) { 1105 tmpMatrix.postConcat(mTransformation.getMatrix()); 1106 } 1107 tmpMatrix.postTranslate(frame.left + mXOffset, frame.top + mYOffset); 1108 if (attachedTransformation != null) { 1109 tmpMatrix.postConcat(attachedTransformation.getMatrix()); 1110 } 1111 if (appTransformation != null) { 1112 tmpMatrix.postConcat(appTransformation.getMatrix()); 1113 } 1114 if (screenAnimation) { 1115 tmpMatrix.postConcat( 1116 mService.mScreenRotationAnimation.getEnterTransformation().getMatrix()); 1117 } 1118 1119 // "convert" it into SurfaceFlinger's format 1120 // (a 2x2 matrix + an offset) 1121 // Here we must not transform the position of the surface 1122 // since it is already included in the transformation. 1123 //Slog.i(TAG, "Transform: " + matrix); 1124 1125 mHaveMatrix = true; 1126 tmpMatrix.getValues(tmpFloats); 1127 mDsDx = tmpFloats[Matrix.MSCALE_X]; 1128 mDtDx = tmpFloats[Matrix.MSKEW_Y]; 1129 mDsDy = tmpFloats[Matrix.MSKEW_X]; 1130 mDtDy = tmpFloats[Matrix.MSCALE_Y]; 1131 int x = (int)tmpFloats[Matrix.MTRANS_X]; 1132 int y = (int)tmpFloats[Matrix.MTRANS_Y]; 1133 int w = frame.width(); 1134 int h = frame.height(); 1135 mShownFrame.set(x, y, x+w, y+h); 1136 1137 // Now set the alpha... but because our current hardware 1138 // can't do alpha transformation on a non-opaque surface, 1139 // turn it off if we are running an animation that is also 1140 // transforming since it is more important to have that 1141 // animation be smooth. 1142 mShownAlpha = mAlpha; 1143 if (!mService.mLimitedAlphaCompositing 1144 || (!PixelFormat.formatHasAlpha(mAttrs.format) 1145 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy) 1146 && x == frame.left && y == frame.top))) { 1147 //Slog.i(TAG, "Applying alpha transform"); 1148 if (selfTransformation) { 1149 mShownAlpha *= mTransformation.getAlpha(); 1150 } 1151 if (attachedTransformation != null) { 1152 mShownAlpha *= attachedTransformation.getAlpha(); 1153 } 1154 if (appTransformation != null) { 1155 mShownAlpha *= appTransformation.getAlpha(); 1156 } 1157 if (screenAnimation) { 1158 mShownAlpha *= 1159 mService.mScreenRotationAnimation.getEnterTransformation().getAlpha(); 1160 } 1161 } else { 1162 //Slog.i(TAG, "Not applying alpha transform"); 1163 } 1164 1165 if (WindowManagerService.localLOGV) Slog.v( 1166 WindowManagerService.TAG, "Continuing animation in " + this + 1167 ": " + mShownFrame + 1168 ", alpha=" + mTransformation.getAlpha()); 1169 return; 1170 } 1171 1172 mShownFrame.set(mFrame); 1173 if (mXOffset != 0 || mYOffset != 0) { 1174 mShownFrame.offset(mXOffset, mYOffset); 1175 } 1176 mShownAlpha = mAlpha; 1177 mHaveMatrix = false; 1178 mDsDx = mGlobalScale; 1179 mDtDx = 0; 1180 mDsDy = 0; 1181 mDtDy = mGlobalScale; 1182 } 1183 1184 /** 1185 * Is this window visible? It is not visible if there is no 1186 * surface, or we are in the process of running an exit animation 1187 * that will remove the surface, or its app token has been hidden. 1188 */ 1189 public boolean isVisibleLw() { 1190 final AppWindowToken atoken = mAppToken; 1191 return mSurface != null && mPolicyVisibility && !mAttachedHidden 1192 && (atoken == null || !atoken.hiddenRequested) 1193 && !mExiting && !mDestroying; 1194 } 1195 1196 /** 1197 * Like {@link #isVisibleLw}, but also counts a window that is currently 1198 * "hidden" behind the keyguard as visible. This allows us to apply 1199 * things like window flags that impact the keyguard. 1200 * XXX I am starting to think we need to have ANOTHER visibility flag 1201 * for this "hidden behind keyguard" state rather than overloading 1202 * mPolicyVisibility. Ungh. 1203 */ 1204 public boolean isVisibleOrBehindKeyguardLw() { 1205 final AppWindowToken atoken = mAppToken; 1206 return mSurface != null && !mAttachedHidden 1207 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested) 1208 && !mDrawPending && !mCommitDrawPending 1209 && !mExiting && !mDestroying; 1210 } 1211 1212 /** 1213 * Is this window visible, ignoring its app token? It is not visible 1214 * if there is no surface, or we are in the process of running an exit animation 1215 * that will remove the surface. 1216 */ 1217 public boolean isWinVisibleLw() { 1218 final AppWindowToken atoken = mAppToken; 1219 return mSurface != null && mPolicyVisibility && !mAttachedHidden 1220 && (atoken == null || !atoken.hiddenRequested || atoken.animating) 1221 && !mExiting && !mDestroying; 1222 } 1223 1224 /** 1225 * The same as isVisible(), but follows the current hidden state of 1226 * the associated app token, not the pending requested hidden state. 1227 */ 1228 boolean isVisibleNow() { 1229 return mSurface != null && mPolicyVisibility && !mAttachedHidden 1230 && !mRootToken.hidden && !mExiting && !mDestroying; 1231 } 1232 1233 /** 1234 * Can this window possibly be a drag/drop target? The test here is 1235 * a combination of the above "visible now" with the check that the 1236 * Input Manager uses when discarding windows from input consideration. 1237 */ 1238 boolean isPotentialDragTarget() { 1239 return isVisibleNow() && !mRemoved 1240 && mInputChannel != null && mInputWindowHandle != null; 1241 } 1242 1243 /** 1244 * Same as isVisible(), but we also count it as visible between the 1245 * call to IWindowSession.add() and the first relayout(). 1246 */ 1247 boolean isVisibleOrAdding() { 1248 final AppWindowToken atoken = mAppToken; 1249 return ((mSurface != null && !mReportDestroySurface) 1250 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE)) 1251 && mPolicyVisibility && !mAttachedHidden 1252 && (atoken == null || !atoken.hiddenRequested) 1253 && !mExiting && !mDestroying; 1254 } 1255 1256 /** 1257 * Is this window currently on-screen? It is on-screen either if it 1258 * is visible or it is currently running an animation before no longer 1259 * being visible. 1260 */ 1261 boolean isOnScreen() { 1262 final AppWindowToken atoken = mAppToken; 1263 if (atoken != null) { 1264 return mSurface != null && mPolicyVisibility && !mDestroying 1265 && ((!mAttachedHidden && !atoken.hiddenRequested) 1266 || mAnimation != null || atoken.animation != null); 1267 } else { 1268 return mSurface != null && mPolicyVisibility && !mDestroying 1269 && (!mAttachedHidden || mAnimation != null); 1270 } 1271 } 1272 1273 /** 1274 * Like isOnScreen(), but we don't return true if the window is part 1275 * of a transition that has not yet been started. 1276 */ 1277 boolean isReadyForDisplay() { 1278 if (mRootToken.waitingToShow && 1279 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) { 1280 return false; 1281 } 1282 final AppWindowToken atoken = mAppToken; 1283 final boolean animating = atoken != null 1284 ? (atoken.animation != null) : false; 1285 return mSurface != null && mPolicyVisibility && !mDestroying 1286 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE 1287 && !mRootToken.hidden) 1288 || mAnimation != null || animating); 1289 } 1290 1291 /** Is the window or its container currently animating? */ 1292 boolean isAnimating() { 1293 final WindowState attached = mAttachedWindow; 1294 final AppWindowToken atoken = mAppToken; 1295 return mAnimation != null 1296 || (attached != null && attached.mAnimation != null) 1297 || (atoken != null && 1298 (atoken.animation != null 1299 || atoken.inPendingTransaction)); 1300 } 1301 1302 /** Is this window currently animating? */ 1303 boolean isWindowAnimating() { 1304 return mAnimation != null; 1305 } 1306 1307 /** 1308 * Like isOnScreen, but returns false if the surface hasn't yet 1309 * been drawn. 1310 */ 1311 public boolean isDisplayedLw() { 1312 final AppWindowToken atoken = mAppToken; 1313 return mSurface != null && mPolicyVisibility && !mDestroying 1314 && !mDrawPending && !mCommitDrawPending 1315 && ((!mAttachedHidden && 1316 (atoken == null || !atoken.hiddenRequested)) 1317 || mAnimating); 1318 } 1319 1320 /** 1321 * Returns true if the window has a surface that it has drawn a 1322 * complete UI in to. 1323 */ 1324 public boolean isDrawnLw() { 1325 final AppWindowToken atoken = mAppToken; 1326 return mSurface != null && !mDestroying 1327 && !mDrawPending && !mCommitDrawPending; 1328 } 1329 1330 /** 1331 * Return true if the window is opaque and fully drawn. This indicates 1332 * it may obscure windows behind it. 1333 */ 1334 boolean isOpaqueDrawn() { 1335 return (mAttrs.format == PixelFormat.OPAQUE 1336 || mAttrs.type == TYPE_WALLPAPER) 1337 && mSurface != null && mAnimation == null 1338 && (mAppToken == null || mAppToken.animation == null) 1339 && !mDrawPending && !mCommitDrawPending; 1340 } 1341 1342 /** 1343 * Return whether this window is wanting to have a translation 1344 * animation applied to it for an in-progress move. (Only makes 1345 * sense to call from performLayoutAndPlaceSurfacesLockedInner().) 1346 */ 1347 boolean shouldAnimateMove() { 1348 return mContentChanged && !mExiting && !mLastHidden && !mService.mDisplayFrozen 1349 && (mFrame.top != mLastFrame.top 1350 || mFrame.left != mLastFrame.left) 1351 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove()) 1352 && mService.mPolicy.isScreenOn(); 1353 } 1354 1355 boolean isFullscreen(int screenWidth, int screenHeight) { 1356 return mFrame.left <= 0 && mFrame.top <= 0 && 1357 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight; 1358 } 1359 1360 void removeLocked() { 1361 disposeInputChannel(); 1362 1363 if (mAttachedWindow != null) { 1364 if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Removing " + this + " from " + mAttachedWindow); 1365 mAttachedWindow.mChildWindows.remove(this); 1366 } 1367 destroySurfaceLocked(); 1368 mSession.windowRemovedLocked(); 1369 try { 1370 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0); 1371 } catch (RuntimeException e) { 1372 // Ignore if it has already been removed (usually because 1373 // we are doing this as part of processing a death note.) 1374 } 1375 } 1376 1377 void setInputChannel(InputChannel inputChannel) { 1378 if (mInputChannel != null) { 1379 throw new IllegalStateException("Window already has an input channel."); 1380 } 1381 1382 mInputChannel = inputChannel; 1383 mInputWindowHandle.inputChannel = inputChannel; 1384 } 1385 1386 void disposeInputChannel() { 1387 if (mInputChannel != null) { 1388 mService.mInputManager.unregisterInputChannel(mInputChannel); 1389 1390 mInputChannel.dispose(); 1391 mInputChannel = null; 1392 } 1393 1394 mInputWindowHandle.inputChannel = null; 1395 } 1396 1397 private class DeathRecipient implements IBinder.DeathRecipient { 1398 public void binderDied() { 1399 try { 1400 synchronized(mService.mWindowMap) { 1401 WindowState win = mService.windowForClientLocked(mSession, mClient, false); 1402 Slog.i(WindowManagerService.TAG, "WIN DEATH: " + win); 1403 if (win != null) { 1404 mService.removeWindowLocked(mSession, win); 1405 } 1406 } 1407 } catch (IllegalArgumentException ex) { 1408 // This will happen if the window has already been 1409 // removed. 1410 } 1411 } 1412 } 1413 1414 /** Returns true if this window desires key events. */ 1415 public final boolean canReceiveKeys() { 1416 return isVisibleOrAdding() 1417 && (mViewVisibility == View.VISIBLE) 1418 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0); 1419 } 1420 1421 public boolean hasDrawnLw() { 1422 return mHasDrawn; 1423 } 1424 1425 public boolean showLw(boolean doAnimation) { 1426 return showLw(doAnimation, true); 1427 } 1428 1429 boolean showLw(boolean doAnimation, boolean requestAnim) { 1430 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) { 1431 return false; 1432 } 1433 if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility true: " + this); 1434 if (doAnimation) { 1435 if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "doAnimation: mPolicyVisibility=" 1436 + mPolicyVisibility + " mAnimation=" + mAnimation); 1437 if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) { 1438 doAnimation = false; 1439 } else if (mPolicyVisibility && mAnimation == null) { 1440 // Check for the case where we are currently visible and 1441 // not animating; we do not want to do animation at such a 1442 // point to become visible when we already are. 1443 doAnimation = false; 1444 } 1445 } 1446 mPolicyVisibility = true; 1447 mPolicyVisibilityAfterAnim = true; 1448 if (doAnimation) { 1449 mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true); 1450 } 1451 if (requestAnim) { 1452 mService.requestAnimationLocked(0); 1453 } 1454 return true; 1455 } 1456 1457 public boolean hideLw(boolean doAnimation) { 1458 return hideLw(doAnimation, true); 1459 } 1460 1461 boolean hideLw(boolean doAnimation, boolean requestAnim) { 1462 if (doAnimation) { 1463 if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) { 1464 doAnimation = false; 1465 } 1466 } 1467 boolean current = doAnimation ? mPolicyVisibilityAfterAnim 1468 : mPolicyVisibility; 1469 if (!current) { 1470 return false; 1471 } 1472 if (doAnimation) { 1473 mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false); 1474 if (mAnimation == null) { 1475 doAnimation = false; 1476 } 1477 } 1478 if (doAnimation) { 1479 mPolicyVisibilityAfterAnim = false; 1480 } else { 1481 if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility false: " + this); 1482 mPolicyVisibilityAfterAnim = false; 1483 mPolicyVisibility = false; 1484 // Window is no longer visible -- make sure if we were waiting 1485 // for it to be displayed before enabling the display, that 1486 // we allow the display to be enabled now. 1487 mService.enableScreenIfNeededLocked(); 1488 if (mService.mCurrentFocus == this) { 1489 mService.mFocusMayChange = true; 1490 } 1491 } 1492 if (requestAnim) { 1493 mService.requestAnimationLocked(0); 1494 } 1495 return true; 1496 } 1497 1498 private static void applyInsets(Region outRegion, Rect frame, Rect inset) { 1499 outRegion.set( 1500 frame.left + inset.left, frame.top + inset.top, 1501 frame.right - inset.right, frame.bottom - inset.bottom); 1502 } 1503 1504 public void getTouchableRegion(Region outRegion) { 1505 final Rect frame = mFrame; 1506 switch (mTouchableInsets) { 1507 default: 1508 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME: 1509 outRegion.set(frame); 1510 break; 1511 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: 1512 applyInsets(outRegion, frame, mGivenContentInsets); 1513 break; 1514 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: 1515 applyInsets(outRegion, frame, mGivenVisibleInsets); 1516 break; 1517 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: { 1518 final Region givenTouchableRegion = mGivenTouchableRegion; 1519 outRegion.set(givenTouchableRegion); 1520 outRegion.translate(frame.left, frame.top); 1521 break; 1522 } 1523 } 1524 } 1525 1526 void dump(PrintWriter pw, String prefix, boolean dumpAll) { 1527 pw.print(prefix); pw.print("mSession="); pw.print(mSession); 1528 pw.print(" mClient="); pw.println(mClient.asBinder()); 1529 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs); 1530 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth); 1531 pw.print(" h="); pw.print(mRequestedHeight); 1532 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq); 1533 if (mAttachedWindow != null || mLayoutAttached) { 1534 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow); 1535 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached); 1536 } 1537 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) { 1538 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow); 1539 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper); 1540 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer); 1541 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible); 1542 } 1543 if (dumpAll) { 1544 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer); 1545 pw.print(" mSubLayer="); pw.print(mSubLayer); 1546 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+"); 1547 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment 1548 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0))); 1549 pw.print("="); pw.print(mAnimLayer); 1550 pw.print(" mLastLayer="); pw.println(mLastLayer); 1551 } 1552 if (mSurface != null) { 1553 if (dumpAll) { 1554 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface); 1555 } 1556 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown); 1557 pw.print(" layer="); pw.print(mSurfaceLayer); 1558 pw.print(" alpha="); pw.print(mSurfaceAlpha); 1559 pw.print(" rect=("); pw.print(mSurfaceX); 1560 pw.print(","); pw.print(mSurfaceY); 1561 pw.print(") "); pw.print(mSurfaceW); 1562 pw.print(" x "); pw.println(mSurfaceH); 1563 } 1564 if (dumpAll) { 1565 pw.print(prefix); pw.print("mToken="); pw.println(mToken); 1566 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken); 1567 if (mAppToken != null) { 1568 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken); 1569 } 1570 if (mTargetAppToken != null) { 1571 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken); 1572 } 1573 pw.print(prefix); pw.print("mViewVisibility=0x"); 1574 pw.print(Integer.toHexString(mViewVisibility)); 1575 pw.print(" mLastHidden="); pw.print(mLastHidden); 1576 pw.print(" mHaveFrame="); pw.print(mHaveFrame); 1577 pw.print(" mObscured="); pw.println(mObscured); 1578 } 1579 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) { 1580 pw.print(prefix); pw.print("mPolicyVisibility="); 1581 pw.print(mPolicyVisibility); 1582 pw.print(" mPolicyVisibilityAfterAnim="); 1583 pw.print(mPolicyVisibilityAfterAnim); 1584 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden); 1585 } 1586 if (!mRelayoutCalled) { 1587 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled); 1588 } 1589 if (mXOffset != 0 || mYOffset != 0) { 1590 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset); 1591 pw.print(" y="); pw.println(mYOffset); 1592 } 1593 if (dumpAll) { 1594 pw.print(prefix); pw.print("mGivenContentInsets="); 1595 mGivenContentInsets.printShortString(pw); 1596 pw.print(" mGivenVisibleInsets="); 1597 mGivenVisibleInsets.printShortString(pw); 1598 pw.println(); 1599 if (mTouchableInsets != 0 || mGivenInsetsPending) { 1600 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets); 1601 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending); 1602 } 1603 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration); 1604 } 1605 pw.print(prefix); pw.print("mShownFrame="); 1606 mShownFrame.printShortString(pw); pw.println(); 1607 if (dumpAll) { 1608 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw); 1609 pw.print(" last="); mLastFrame.printShortString(pw); 1610 pw.println(); 1611 } 1612 if (mEnforceSizeCompat) { 1613 pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw); 1614 pw.println(); 1615 } 1616 if (dumpAll) { 1617 pw.print(prefix); pw.print("mContainingFrame="); 1618 mContainingFrame.printShortString(pw); 1619 pw.print(" mParentFrame="); 1620 mParentFrame.printShortString(pw); 1621 pw.print(" mDisplayFrame="); 1622 mDisplayFrame.printShortString(pw); 1623 pw.println(); 1624 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw); 1625 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw); 1626 pw.println(); 1627 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw); 1628 pw.print(" last="); mLastContentInsets.printShortString(pw); 1629 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw); 1630 pw.print(" last="); mLastVisibleInsets.printShortString(pw); 1631 pw.println(); 1632 } 1633 if (mAnimating || mLocalAnimating || mAnimationIsEntrance 1634 || mAnimation != null) { 1635 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating); 1636 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating); 1637 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance); 1638 pw.print(" mAnimation="); pw.println(mAnimation); 1639 } 1640 if (mHasTransformation || mHasLocalTransformation) { 1641 pw.print(prefix); pw.print("XForm: has="); 1642 pw.print(mHasTransformation); 1643 pw.print(" hasLocal="); pw.print(mHasLocalTransformation); 1644 pw.print(" "); mTransformation.printShortString(pw); 1645 pw.println(); 1646 } 1647 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) { 1648 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha); 1649 pw.print(" mAlpha="); pw.print(mAlpha); 1650 pw.print(" mLastAlpha="); pw.println(mLastAlpha); 1651 } 1652 if (mHaveMatrix || mGlobalScale != 1) { 1653 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mGlobalScale); 1654 pw.print(" mDsDx="); pw.print(mDsDx); 1655 pw.print(" mDtDx="); pw.print(mDtDx); 1656 pw.print(" mDsDy="); pw.print(mDsDy); 1657 pw.print(" mDtDy="); pw.println(mDtDy); 1658 } 1659 if (dumpAll) { 1660 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending); 1661 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending); 1662 pw.print(" mReadyToShow="); pw.print(mReadyToShow); 1663 pw.print(" mHasDrawn="); pw.println(mHasDrawn); 1664 } 1665 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) { 1666 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting); 1667 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit); 1668 pw.print(" mDestroying="); pw.print(mDestroying); 1669 pw.print(" mRemoved="); pw.println(mRemoved); 1670 } 1671 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) { 1672 pw.print(prefix); pw.print("mOrientationChanging="); 1673 pw.print(mOrientationChanging); 1674 pw.print(" mAppFreezing="); pw.print(mAppFreezing); 1675 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen); 1676 } 1677 if (mHScale != 1 || mVScale != 1) { 1678 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale); 1679 pw.print(" mVScale="); pw.println(mVScale); 1680 } 1681 if (mWallpaperX != -1 || mWallpaperY != -1) { 1682 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX); 1683 pw.print(" mWallpaperY="); pw.println(mWallpaperY); 1684 } 1685 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) { 1686 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep); 1687 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep); 1688 } 1689 } 1690 1691 String makeInputChannelName() { 1692 return Integer.toHexString(System.identityHashCode(this)) 1693 + " " + mAttrs.getTitle(); 1694 } 1695 1696 @Override 1697 public String toString() { 1698 if (mStringNameCache == null || mLastTitle != mAttrs.getTitle() 1699 || mWasPaused != mToken.paused) { 1700 mLastTitle = mAttrs.getTitle(); 1701 mWasPaused = mToken.paused; 1702 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) 1703 + " " + mLastTitle + " paused=" + mWasPaused + "}"; 1704 } 1705 return mStringNameCache; 1706 } 1707}