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