WindowState.java revision acd7a22cd7fe1c2d1a1ba6ed8e97e4e21dd31a1d
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 android.app.ActivityManager; 20import android.app.AppOpsManager; 21import android.content.Context; 22import android.content.res.Configuration; 23import android.graphics.Matrix; 24import android.graphics.PixelFormat; 25import android.graphics.Point; 26import android.graphics.Rect; 27import android.graphics.Region; 28import android.os.IBinder; 29import android.os.PowerManager; 30import android.os.RemoteCallbackList; 31import android.os.RemoteException; 32import android.os.SystemClock; 33import android.os.Trace; 34import android.os.UserHandle; 35import android.os.WorkSource; 36import android.util.DisplayMetrics; 37import android.util.Slog; 38import android.util.TimeUtils; 39import android.view.Display; 40import android.view.DisplayInfo; 41import android.view.Gravity; 42import android.view.IApplicationToken; 43import android.view.IWindow; 44import android.view.IWindowFocusObserver; 45import android.view.IWindowId; 46import android.view.InputChannel; 47import android.view.InputEvent; 48import android.view.InputEventReceiver; 49import android.view.View; 50import android.view.ViewTreeObserver; 51import android.view.WindowManager; 52import android.view.WindowManagerPolicy; 53 54import com.android.server.input.InputWindowHandle; 55 56import java.io.PrintWriter; 57import java.util.ArrayList; 58 59import static android.app.ActivityManager.StackId; 60import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 61import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 62import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; 63import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT; 64import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME; 65import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; 66import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE; 67import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; 68import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; 69import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; 70import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; 71import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 72import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 73import static android.view.WindowManager.LayoutParams.FLAG_SCALED; 74import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; 75import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; 76import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; 77import static android.view.WindowManager.LayoutParams.MATCH_PARENT; 78import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; 79import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; 80import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; 81import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH; 82import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 83import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; 84import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 85import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 86import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; 87import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 88import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; 89import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; 90import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; 91import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; 92import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; 93import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION; 94import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; 95import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT; 96import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; 97import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER; 98import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE; 99import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; 100import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 101import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 102 103class WindowList extends ArrayList<WindowState> { 104} 105 106/** 107 * A window in the window manager. 108 */ 109final class WindowState implements WindowManagerPolicy.WindowState { 110 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowState" : TAG_WM; 111 112 // The minimal size of a window within the usable area of the freeform stack. 113 // TODO(multi-window): fix the min sizes when we have mininum width/height support, 114 // use hard-coded min sizes for now. 115 static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48; 116 static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32; 117 118 // The thickness of a window resize handle outside the window bounds on the free form workspace 119 // to capture touch events in that area. 120 static final int RESIZE_HANDLE_WIDTH_IN_DP = 30; 121 122 static final int DRAG_RESIZE_MODE_FREEFORM = 0; 123 static final int DRAG_RESIZE_MODE_DOCKED_DIVIDER = 1; 124 125 static final boolean DEBUG_DISABLE_SAVING_SURFACES = false; 126 127 final WindowManagerService mService; 128 final WindowManagerPolicy mPolicy; 129 final Context mContext; 130 final Session mSession; 131 final IWindow mClient; 132 final int mAppOp; 133 // UserId and appId of the owner. Don't display windows of non-current user. 134 final int mOwnerUid; 135 final IWindowId mWindowId; 136 WindowToken mToken; 137 WindowToken mRootToken; 138 AppWindowToken mAppToken; 139 AppWindowToken mTargetAppToken; 140 141 // mAttrs.flags is tested in animation without being locked. If the bits tested are ever 142 // modified they will need to be locked. 143 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams(); 144 final DeathRecipient mDeathRecipient; 145 final WindowState mAttachedWindow; 146 final WindowList mChildWindows = new WindowList(); 147 final int mBaseLayer; 148 final int mSubLayer; 149 final boolean mLayoutAttached; 150 final boolean mIsImWindow; 151 final boolean mIsWallpaper; 152 final boolean mIsFloatingLayer; 153 int mSeq; 154 boolean mEnforceSizeCompat; 155 int mViewVisibility; 156 int mSystemUiVisibility; 157 boolean mPolicyVisibility = true; 158 boolean mPolicyVisibilityAfterAnim = true; 159 boolean mAppOpVisibility = true; 160 boolean mAppFreezing; 161 boolean mAttachedHidden; // is our parent window hidden? 162 boolean mWallpaperVisible; // for wallpaper, what was last vis report? 163 boolean mDragResizing; 164 boolean mDragResizingChangeReported; 165 int mResizeMode; 166 167 RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks; 168 169 /** 170 * The window size that was requested by the application. These are in 171 * the application's coordinate space (without compatibility scale applied). 172 */ 173 int mRequestedWidth; 174 int mRequestedHeight; 175 int mLastRequestedWidth; 176 int mLastRequestedHeight; 177 178 int mLayer; 179 boolean mHaveFrame; 180 boolean mObscured; 181 boolean mTurnOnScreen; 182 183 int mLayoutSeq = -1; 184 185 private Configuration mConfiguration = Configuration.EMPTY; 186 private Configuration mOverrideConfig = Configuration.EMPTY; 187 // Sticky answer to isConfigChanged(), remains true until new Configuration is assigned. 188 // Used only on {@link #TYPE_KEYGUARD}. 189 private boolean mConfigHasChanged; 190 191 /** 192 * Actual position of the surface shown on-screen (may be modified by animation). These are 193 * in the screen's coordinate space (WITH the compatibility scale applied). 194 */ 195 final Point mShownPosition = new Point(); 196 197 /** 198 * Insets that determine the actually visible area. These are in the application's 199 * coordinate space (without compatibility scale applied). 200 */ 201 final Rect mVisibleInsets = new Rect(); 202 final Rect mLastVisibleInsets = new Rect(); 203 boolean mVisibleInsetsChanged; 204 205 /** 206 * Insets that are covered by system windows (such as the status bar) and 207 * transient docking windows (such as the IME). These are in the application's 208 * coordinate space (without compatibility scale applied). 209 */ 210 final Rect mContentInsets = new Rect(); 211 final Rect mLastContentInsets = new Rect(); 212 boolean mContentInsetsChanged; 213 214 /** 215 * Insets that determine the area covered by the display overscan region. These are in the 216 * application's coordinate space (without compatibility scale applied). 217 */ 218 final Rect mOverscanInsets = new Rect(); 219 final Rect mLastOverscanInsets = new Rect(); 220 boolean mOverscanInsetsChanged; 221 222 /** 223 * Insets that determine the area covered by the stable system windows. These are in the 224 * application's coordinate space (without compatibility scale applied). 225 */ 226 final Rect mStableInsets = new Rect(); 227 final Rect mLastStableInsets = new Rect(); 228 boolean mStableInsetsChanged; 229 230 /** 231 * Outsets determine the area outside of the surface where we want to pretend that it's possible 232 * to draw anyway. 233 */ 234 final Rect mOutsets = new Rect(); 235 final Rect mLastOutsets = new Rect(); 236 boolean mOutsetsChanged = false; 237 238 /** 239 * Set to true if we are waiting for this window to receive its 240 * given internal insets before laying out other windows based on it. 241 */ 242 boolean mGivenInsetsPending; 243 244 /** 245 * These are the content insets that were given during layout for 246 * this window, to be applied to windows behind it. 247 */ 248 final Rect mGivenContentInsets = new Rect(); 249 250 /** 251 * These are the visible insets that were given during layout for 252 * this window, to be applied to windows behind it. 253 */ 254 final Rect mGivenVisibleInsets = new Rect(); 255 256 /** 257 * This is the given touchable area relative to the window frame, or null if none. 258 */ 259 final Region mGivenTouchableRegion = new Region(); 260 261 /** 262 * Flag indicating whether the touchable region should be adjusted by 263 * the visible insets; if false the area outside the visible insets is 264 * NOT touchable, so we must use those to adjust the frame during hit 265 * tests. 266 */ 267 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME; 268 269 // Current transformation being applied. 270 float mGlobalScale=1; 271 float mInvGlobalScale=1; 272 float mHScale=1, mVScale=1; 273 float mLastHScale=1, mLastVScale=1; 274 final Matrix mTmpMatrix = new Matrix(); 275 276 // "Real" frame that the application sees, in display coordinate space. 277 final Rect mFrame = new Rect(); 278 final Rect mLastFrame = new Rect(); 279 // Frame that is scaled to the application's coordinate space when in 280 // screen size compatibility mode. 281 final Rect mCompatFrame = new Rect(); 282 283 final Rect mContainingFrame = new Rect(); 284 285 final Rect mParentFrame = new Rect(); 286 287 // The entire screen area of the {@link TaskStack} this window is in. Usually equal to the 288 // screen area of the device. 289 final Rect mDisplayFrame = new Rect(); 290 291 // The region of the display frame that the display type supports displaying content on. This 292 // is mostly a special case for TV where some displays don’t have the entire display usable. 293 // {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_OVERSCAN} flag can be used to allow 294 // window display contents to extend into the overscan region. 295 final Rect mOverscanFrame = new Rect(); 296 297 // The display frame minus the stable insets. This value is always constant regardless of if 298 // the status bar or navigation bar is visible. 299 final Rect mStableFrame = new Rect(); 300 301 // The area not occupied by the status and navigation bars. So, if both status and navigation 302 // bars are visible, the decor frame is equal to the stable frame. 303 final Rect mDecorFrame = new Rect(); 304 305 // Equal to the decor frame if the IME (e.g. keyboard) is not present. Equal to the decor frame 306 // minus the area occupied by the IME if the IME is present. 307 final Rect mContentFrame = new Rect(); 308 309 // Legacy stuff. Generally equal to the content frame expect when the IME for older apps 310 // displays hint text. 311 final Rect mVisibleFrame = new Rect(); 312 313 // Frame that includes dead area outside of the surface but where we want to pretend that it's 314 // possible to draw. 315 final Rect mOutsetFrame = new Rect(); 316 317 /** 318 * Usually empty. Set to the task's tempInsetFrame. See 319 *{@link android.app.IActivityManager#resizeDockedStack}. 320 */ 321 final Rect mInsetFrame = new Rect(); 322 323 boolean mContentChanged; 324 325 // If a window showing a wallpaper: the requested offset for the 326 // wallpaper; if a wallpaper window: the currently applied offset. 327 float mWallpaperX = -1; 328 float mWallpaperY = -1; 329 330 // If a window showing a wallpaper: what fraction of the offset 331 // range corresponds to a full virtual screen. 332 float mWallpaperXStep = -1; 333 float mWallpaperYStep = -1; 334 335 // If a window showing a wallpaper: a raw pixel offset to forcibly apply 336 // to its window; if a wallpaper window: not used. 337 int mWallpaperDisplayOffsetX = Integer.MIN_VALUE; 338 int mWallpaperDisplayOffsetY = Integer.MIN_VALUE; 339 340 // Wallpaper windows: pixels offset based on above variables. 341 int mXOffset; 342 int mYOffset; 343 344 /** 345 * This is set after IWindowSession.relayout() has been called at 346 * least once for the window. It allows us to detect the situation 347 * where we don't yet have a surface, but should have one soon, so 348 * we can give the window focus before waiting for the relayout. 349 */ 350 boolean mRelayoutCalled; 351 352 /** 353 * If the application has called relayout() with changes that can 354 * impact its window's size, we need to perform a layout pass on it 355 * even if it is not currently visible for layout. This is set 356 * when in that case until the layout is done. 357 */ 358 boolean mLayoutNeeded; 359 360 /** Currently running an exit animation? */ 361 boolean mAnimatingExit; 362 363 /** Currently on the mDestroySurface list? */ 364 boolean mDestroying; 365 366 /** Completely remove from window manager after exit animation? */ 367 boolean mRemoveOnExit; 368 369 /** 370 * Whether the app died while it was visible, if true we might need 371 * to continue to show it until it's restarted. 372 */ 373 boolean mAppDied; 374 375 /** 376 * Set when the orientation is changing and this window has not yet 377 * been updated for the new orientation. 378 */ 379 boolean mOrientationChanging; 380 381 /** 382 * How long we last kept the screen frozen. 383 */ 384 int mLastFreezeDuration; 385 386 /** Is this window now (or just being) removed? */ 387 boolean mRemoved; 388 389 /** 390 * It is save to remove the window and destroy the surface because the client requested removal 391 * or some other higher level component said so (e.g. activity manager). 392 * TODO: We should either have different booleans for the removal reason or use a bit-field. 393 */ 394 boolean mWindowRemovalAllowed; 395 396 /** 397 * Temp for keeping track of windows that have been removed when 398 * rebuilding window list. 399 */ 400 boolean mRebuilding; 401 402 // Input channel and input window handle used by the input dispatcher. 403 final InputWindowHandle mInputWindowHandle; 404 InputChannel mInputChannel; 405 InputChannel mClientChannel; 406 407 // Used to improve performance of toString() 408 String mStringNameCache; 409 CharSequence mLastTitle; 410 boolean mWasExiting; 411 412 final WindowStateAnimator mWinAnimator; 413 414 boolean mHasSurface = false; 415 416 boolean mNotOnAppsDisplay = false; 417 DisplayContent mDisplayContent; 418 419 /** When true this window can be displayed on screens owther than mOwnerUid's */ 420 private boolean mShowToOwnerOnly; 421 422 // Whether the window has a saved surface from last pause, which can be 423 // used to start an entering animation earlier. 424 public boolean mSurfaceSaved = false; 425 426 // This window will be replaced due to relaunch. This allows window manager 427 // to differentiate between simple removal of a window and replacement. In the latter case it 428 // will preserve the old window until the new one is drawn. 429 boolean mWillReplaceWindow = false; 430 // If true, the replaced window was already requested to be removed. 431 boolean mReplacingRemoveRequested = false; 432 // Whether the replacement of the window should trigger app transition animation. 433 boolean mAnimateReplacingWindow = false; 434 // If not null, the window that will be used to replace the old one. This is being set when 435 // the window is added and unset when this window reports its first draw. 436 WindowState mReplacingWindow = null; 437 438 // Whether this window is being moved via the resize API 439 boolean mMovedByResize; 440 /** 441 * Wake lock for drawing. 442 * Even though it's slightly more expensive to do so, we will use a separate wake lock 443 * for each app that is requesting to draw while dozing so that we can accurately track 444 * who is preventing the system from suspending. 445 * This lock is only acquired on first use. 446 */ 447 PowerManager.WakeLock mDrawLock; 448 449 final private Rect mTmpRect = new Rect(); 450 451 /** 452 * See {@link #notifyMovedInStack}. 453 */ 454 private boolean mJustMovedInStack; 455 456 /** 457 * Whether the window was resized by us while it was gone for layout. 458 */ 459 boolean mResizedWhileGone = false; 460 461 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, 462 WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a, 463 int viewVisibility, final DisplayContent displayContent) { 464 mService = service; 465 mSession = s; 466 mClient = c; 467 mAppOp = appOp; 468 mToken = token; 469 mOwnerUid = s.mUid; 470 mWindowId = new IWindowId.Stub() { 471 @Override 472 public void registerFocusObserver(IWindowFocusObserver observer) { 473 WindowState.this.registerFocusObserver(observer); 474 } 475 @Override 476 public void unregisterFocusObserver(IWindowFocusObserver observer) { 477 WindowState.this.unregisterFocusObserver(observer); 478 } 479 @Override 480 public boolean isFocused() { 481 return WindowState.this.isFocused(); 482 } 483 }; 484 mAttrs.copyFrom(a); 485 mViewVisibility = viewVisibility; 486 mDisplayContent = displayContent; 487 mPolicy = mService.mPolicy; 488 mContext = mService.mContext; 489 DeathRecipient deathRecipient = new DeathRecipient(); 490 mSeq = seq; 491 mEnforceSizeCompat = (mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0; 492 if (WindowManagerService.localLOGV) Slog.v( 493 TAG, "Window " + this + " client=" + c.asBinder() 494 + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a); 495 try { 496 c.asBinder().linkToDeath(deathRecipient, 0); 497 } catch (RemoteException e) { 498 mDeathRecipient = null; 499 mAttachedWindow = null; 500 mLayoutAttached = false; 501 mIsImWindow = false; 502 mIsWallpaper = false; 503 mIsFloatingLayer = false; 504 mBaseLayer = 0; 505 mSubLayer = 0; 506 mInputWindowHandle = null; 507 mWinAnimator = null; 508 return; 509 } 510 mDeathRecipient = deathRecipient; 511 512 if ((mAttrs.type >= FIRST_SUB_WINDOW && 513 mAttrs.type <= LAST_SUB_WINDOW)) { 514 // The multiplier here is to reserve space for multiple 515 // windows in the same type layer. 516 mBaseLayer = mPolicy.windowTypeToLayerLw( 517 attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER 518 + WindowManagerService.TYPE_LAYER_OFFSET; 519 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type); 520 mAttachedWindow = attachedWindow; 521 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow); 522 523 final WindowList childWindows = mAttachedWindow.mChildWindows; 524 final int numChildWindows = childWindows.size(); 525 if (numChildWindows == 0) { 526 childWindows.add(this); 527 } else { 528 boolean added = false; 529 for (int i = 0; i < numChildWindows; i++) { 530 final int childSubLayer = childWindows.get(i).mSubLayer; 531 if (mSubLayer < childSubLayer 532 || (mSubLayer == childSubLayer && childSubLayer < 0)) { 533 // We insert the child window into the list ordered by the sub-layer. For 534 // same sub-layers, the negative one should go below others; the positive 535 // one should go above others. 536 childWindows.add(i, this); 537 added = true; 538 break; 539 } 540 } 541 if (!added) { 542 childWindows.add(this); 543 } 544 } 545 546 mLayoutAttached = mAttrs.type != 547 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 548 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD 549 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 550 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER; 551 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 552 } else { 553 // The multiplier here is to reserve space for multiple 554 // windows in the same type layer. 555 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type) 556 * WindowManagerService.TYPE_LAYER_MULTIPLIER 557 + WindowManagerService.TYPE_LAYER_OFFSET; 558 mSubLayer = 0; 559 mAttachedWindow = null; 560 mLayoutAttached = false; 561 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD 562 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG; 563 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER; 564 mIsFloatingLayer = mIsImWindow || mIsWallpaper; 565 } 566 567 WindowState appWin = this; 568 while (appWin.isChildWindow()) { 569 appWin = appWin.mAttachedWindow; 570 } 571 WindowToken appToken = appWin.mToken; 572 while (appToken.appWindowToken == null) { 573 WindowToken parent = mService.mTokenMap.get(appToken.token); 574 if (parent == null || appToken == parent) { 575 break; 576 } 577 appToken = parent; 578 } 579 mRootToken = appToken; 580 mAppToken = appToken.appWindowToken; 581 if (mAppToken != null) { 582 final DisplayContent appDisplay = getDisplayContent(); 583 mNotOnAppsDisplay = displayContent != appDisplay; 584 585 if (mAppToken.showForAllUsers) { 586 // Windows for apps that can show for all users should also show when the 587 // device is locked. 588 mAttrs.flags |= FLAG_SHOW_WHEN_LOCKED; 589 } 590 } 591 592 mWinAnimator = new WindowStateAnimator(this); 593 mWinAnimator.mAlpha = a.alpha; 594 595 mRequestedWidth = 0; 596 mRequestedHeight = 0; 597 mLastRequestedWidth = 0; 598 mLastRequestedHeight = 0; 599 mXOffset = 0; 600 mYOffset = 0; 601 mLayer = 0; 602 mInputWindowHandle = new InputWindowHandle( 603 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this, 604 displayContent.getDisplayId()); 605 } 606 607 void attach() { 608 if (WindowManagerService.localLOGV) Slog.v( 609 TAG, "Attaching " + this + " token=" + mToken 610 + ", list=" + mToken.windows); 611 mSession.windowAddedLocked(); 612 } 613 614 @Override 615 public int getOwningUid() { 616 return mOwnerUid; 617 } 618 619 @Override 620 public String getOwningPackage() { 621 return mAttrs.packageName; 622 } 623 624 @Override 625 public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf, 626 Rect osf) { 627 if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) { 628 // This window is being replaced and either already got information that it's being 629 // removed or we are still waiting for some information. Because of this we don't 630 // want to apply any more changes to it, so it remains in this state until new window 631 // appears. 632 return; 633 } 634 mHaveFrame = true; 635 636 final Task task = getTask(); 637 final boolean fullscreenTask = task == null || task.isFullscreen(); 638 final boolean windowsAreFloating = task != null && task.isFloating(); 639 640 if (fullscreenTask || (isChildWindow() 641 && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0)) { 642 // We use the parent frame as the containing frame for fullscreen and child windows 643 mContainingFrame.set(pf); 644 mDisplayFrame.set(df); 645 mInsetFrame.setEmpty(); 646 } else { 647 task.getBounds(mContainingFrame); 648 task.getTempInsetBounds(mInsetFrame); 649 if (mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) { 650 651 // If the bounds are frozen, we still want to translate the window freely and only 652 // freeze the size. 653 Rect frozen = mAppToken.mFrozenBounds.peek(); 654 mContainingFrame.right = mContainingFrame.left + frozen.width(); 655 mContainingFrame.bottom = mContainingFrame.top + frozen.height(); 656 } 657 final WindowState imeWin = mService.mInputMethodWindow; 658 if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this 659 && mContainingFrame.bottom > cf.bottom) { 660 // IME is up and obscuring this window. Adjust the window position so it is visible. 661 mContainingFrame.top -= mContainingFrame.bottom - cf.bottom; 662 } 663 664 if (windowsAreFloating) { 665 // In floating modes (e.g. freeform, pinned) we have only to set the rectangle 666 // if it wasn't set already. No need to intersect it with the (visible) 667 // "content frame" since it is allowed to be outside the visible desktop. 668 if (mContainingFrame.isEmpty()) { 669 mContainingFrame.set(cf); 670 } 671 } 672 mDisplayFrame.set(mContainingFrame); 673 } 674 675 final int pw = mContainingFrame.width(); 676 final int ph = mContainingFrame.height(); 677 678 if (!mParentFrame.equals(pf)) { 679 //Slog.i(TAG_WM, "Window " + this + " content frame from " + mParentFrame 680 // + " to " + pf); 681 mParentFrame.set(pf); 682 mContentChanged = true; 683 } 684 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { 685 mLastRequestedWidth = mRequestedWidth; 686 mLastRequestedHeight = mRequestedHeight; 687 mContentChanged = true; 688 } 689 690 mOverscanFrame.set(of); 691 mContentFrame.set(cf); 692 mVisibleFrame.set(vf); 693 mDecorFrame.set(dcf); 694 mStableFrame.set(sf); 695 final boolean hasOutsets = osf != null; 696 if (hasOutsets) { 697 mOutsetFrame.set(osf); 698 } 699 700 final int fw = mFrame.width(); 701 final int fh = mFrame.height(); 702 703 applyGravityAndUpdateFrame(); 704 705 // Calculate the outsets before the content frame gets shrinked to the window frame. 706 if (hasOutsets) { 707 mOutsets.set(Math.max(mContentFrame.left - mOutsetFrame.left, 0), 708 Math.max(mContentFrame.top - mOutsetFrame.top, 0), 709 Math.max(mOutsetFrame.right - mContentFrame.right, 0), 710 Math.max(mOutsetFrame.bottom - mContentFrame.bottom, 0)); 711 } else { 712 mOutsets.set(0, 0, 0, 0); 713 } 714 715 // Denotes the actual frame used to calculate the insets. When resizing in docked mode, 716 // we'd like to freeze the layout, so we also need to freeze the insets temporarily. By the 717 // notion of a task having a different inset frame, we can achieve that while still moving 718 // the task around. 719 final Rect frame = !mInsetFrame.isEmpty() ? mInsetFrame : mFrame; 720 721 // Make sure the content and visible frames are inside of the 722 // final window frame. 723 if (windowsAreFloating && !mFrame.isEmpty()) { 724 // Keep the frame out of the blocked system area, limit it in size to the content area 725 // and make sure that there is always a minimum visible so that the user can drag it 726 // into a usable area.. 727 final int height = Math.min(mFrame.height(), mContentFrame.height()); 728 final int width = Math.min(mContentFrame.width(), mFrame.width()); 729 final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); 730 final int minVisibleHeight = WindowManagerService.dipToPixel( 731 MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics); 732 final int minVisibleWidth = WindowManagerService.dipToPixel( 733 MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics); 734 final int top = Math.max(mContentFrame.top, 735 Math.min(mFrame.top, mContentFrame.bottom - minVisibleHeight)); 736 final int left = Math.max(mContentFrame.left + minVisibleWidth - width, 737 Math.min(mFrame.left, mContentFrame.right - minVisibleWidth)); 738 mFrame.set(left, top, left + width, top + height); 739 mContentFrame.set(mFrame); 740 mVisibleFrame.set(mContentFrame); 741 mStableFrame.set(mContentFrame); 742 } else if (mAttrs.type == TYPE_DOCK_DIVIDER) { 743 if (isVisibleLw() || mWinAnimator.isAnimating()) { 744 // We don't adjust the dock divider frame for reasons other than performance. The 745 // real reason is that if it gets adjusted before it is shown for the first time, 746 // it would get size (0, 0). This causes a problem when we finally show the dock 747 // divider and try to draw to it. We do set the surface size at that moment to 748 // the correct size, but it's too late for the Surface Flinger to make it 749 // available for view rendering and as a result the renderer receives size 1, 1. 750 // This way we just keep the divider at the original size and Surface Flinger 751 // will return the correct value to the renderer. 752 mDisplayContent.getDockedDividerController().positionDockedStackedDivider(mFrame); 753 mContentFrame.set(mFrame); 754 if (!mFrame.equals(mLastFrame)) { 755 mMovedByResize = true; 756 } 757 } 758 } else { 759 mContentFrame.set(Math.max(mContentFrame.left, frame.left), 760 Math.max(mContentFrame.top, frame.top), 761 Math.min(mContentFrame.right, frame.right), 762 Math.min(mContentFrame.bottom, frame.bottom)); 763 764 mVisibleFrame.set(Math.max(mVisibleFrame.left, frame.left), 765 Math.max(mVisibleFrame.top, frame.top), 766 Math.min(mVisibleFrame.right, frame.right), 767 Math.min(mVisibleFrame.bottom, frame.bottom)); 768 769 mStableFrame.set(Math.max(mStableFrame.left, frame.left), 770 Math.max(mStableFrame.top, frame.top), 771 Math.min(mStableFrame.right, frame.right), 772 Math.min(mStableFrame.bottom, frame.bottom)); 773 } 774 775 if (!windowsAreFloating) { 776 // Windows from floating tasks (e.g. freeform, pinned) may be positioned outside 777 // of the display frame, but that is not a reason to provide them with overscan insets. 778 mOverscanInsets.set(Math.max(mOverscanFrame.left - frame.left, 0), 779 Math.max(mOverscanFrame.top - frame.top, 0), 780 Math.max(frame.right - mOverscanFrame.right, 0), 781 Math.max(frame.bottom - mOverscanFrame.bottom, 0)); 782 } 783 784 if (mAttrs.type == TYPE_DOCK_DIVIDER) { 785 // For the docked divider, we calculate the stable insets like a full-screen window 786 // so it can use it to calculate the snap positions. 787 mStableInsets.set(Math.max(mStableFrame.left - mDisplayFrame.left, 0), 788 Math.max(mStableFrame.top - mDisplayFrame.top, 0), 789 Math.max(mDisplayFrame.right - mStableFrame.right, 0), 790 Math.max(mDisplayFrame.bottom - mStableFrame.bottom, 0)); 791 792 // The divider doesn't care about insets in any case, so set it to empty so we don't 793 // trigger a relayout when moving it. 794 mContentInsets.setEmpty(); 795 mVisibleInsets.setEmpty(); 796 } else { 797 mContentInsets.set(mContentFrame.left - frame.left, 798 mContentFrame.top - frame.top, 799 frame.right - mContentFrame.right, 800 frame.bottom - mContentFrame.bottom); 801 802 mVisibleInsets.set(mVisibleFrame.left - frame.left, 803 mVisibleFrame.top - frame.top, 804 frame.right - mVisibleFrame.right, 805 frame.bottom - mVisibleFrame.bottom); 806 807 mStableInsets.set(Math.max(mStableFrame.left - frame.left, 0), 808 Math.max(mStableFrame.top - frame.top, 0), 809 Math.max(frame.right - mStableFrame.right, 0), 810 Math.max(frame.bottom - mStableFrame.bottom, 0)); 811 } 812 813 if (!mInsetFrame.isEmpty()) { 814 mContentFrame.set(mFrame); 815 mContentFrame.top += mContentInsets.top; 816 mContentFrame.bottom += mContentInsets.bottom; 817 mContentFrame.left += mContentInsets.left; 818 mContentFrame.right += mContentInsets.right; 819 mVisibleFrame.set(mFrame); 820 mVisibleFrame.top += mVisibleInsets.top; 821 mVisibleFrame.bottom += mVisibleInsets.bottom; 822 mVisibleFrame.left += mVisibleInsets.left; 823 mVisibleFrame.right += mVisibleInsets.right; 824 mStableFrame.set(mFrame); 825 mStableFrame.top += mStableInsets.top; 826 mStableFrame.bottom += mStableInsets.bottom; 827 mStableFrame.left += mStableInsets.left; 828 mStableFrame.right += mStableInsets.right; 829 } 830 mCompatFrame.set(mFrame); 831 if (mEnforceSizeCompat) { 832 // If there is a size compatibility scale being applied to the 833 // window, we need to apply this to its insets so that they are 834 // reported to the app in its coordinate space. 835 mOverscanInsets.scale(mInvGlobalScale); 836 mContentInsets.scale(mInvGlobalScale); 837 mVisibleInsets.scale(mInvGlobalScale); 838 mStableInsets.scale(mInvGlobalScale); 839 mOutsets.scale(mInvGlobalScale); 840 841 // Also the scaled frame that we report to the app needs to be 842 // adjusted to be in its coordinate space. 843 mCompatFrame.scale(mInvGlobalScale); 844 } 845 846 if (mIsWallpaper && (fw != mFrame.width() || fh != mFrame.height())) { 847 final DisplayContent displayContent = getDisplayContent(); 848 if (displayContent != null) { 849 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 850 mService.mWallpaperControllerLocked.updateWallpaperOffset( 851 this, displayInfo.logicalWidth, displayInfo.logicalHeight, false); 852 } 853 } 854 855 if (DEBUG_LAYOUT || WindowManagerService.localLOGV) Slog.v(TAG, 856 "Resolving (mRequestedWidth=" 857 + mRequestedWidth + ", mRequestedheight=" 858 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph 859 + "): frame=" + mFrame.toShortString() 860 + " ci=" + mContentInsets.toShortString() 861 + " vi=" + mVisibleInsets.toShortString() 862 + " vi=" + mStableInsets.toShortString() 863 + " of=" + mOutsets.toShortString()); 864 } 865 866 @Override 867 public Rect getFrameLw() { 868 return mFrame; 869 } 870 871 @Override 872 public Point getShownPositionLw() { 873 return mShownPosition; 874 } 875 876 @Override 877 public Rect getDisplayFrameLw() { 878 return mDisplayFrame; 879 } 880 881 @Override 882 public Rect getOverscanFrameLw() { 883 return mOverscanFrame; 884 } 885 886 @Override 887 public Rect getContentFrameLw() { 888 return mContentFrame; 889 } 890 891 @Override 892 public Rect getVisibleFrameLw() { 893 return mVisibleFrame; 894 } 895 896 @Override 897 public boolean getGivenInsetsPendingLw() { 898 return mGivenInsetsPending; 899 } 900 901 @Override 902 public Rect getGivenContentInsetsLw() { 903 return mGivenContentInsets; 904 } 905 906 @Override 907 public Rect getGivenVisibleInsetsLw() { 908 return mGivenVisibleInsets; 909 } 910 911 @Override 912 public WindowManager.LayoutParams getAttrs() { 913 return mAttrs; 914 } 915 916 @Override 917 public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) { 918 int index = -1; 919 WindowState ws = this; 920 WindowList windows = getWindowList(); 921 while (true) { 922 if (ws.mAttrs.needsMenuKey != WindowManager.LayoutParams.NEEDS_MENU_UNSET) { 923 return ws.mAttrs.needsMenuKey == WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE; 924 } 925 // If we reached the bottom of the range of windows we are considering, 926 // assume no menu is needed. 927 if (ws == bottom) { 928 return false; 929 } 930 // The current window hasn't specified whether menu key is needed; 931 // look behind it. 932 // First, we may need to determine the starting position. 933 if (index < 0) { 934 index = windows.indexOf(ws); 935 } 936 index--; 937 if (index < 0) { 938 return false; 939 } 940 ws = windows.get(index); 941 } 942 } 943 944 @Override 945 public int getSystemUiVisibility() { 946 return mSystemUiVisibility; 947 } 948 949 @Override 950 public int getSurfaceLayer() { 951 return mLayer; 952 } 953 954 @Override 955 public int getBaseType() { 956 WindowState win = this; 957 while (win.isChildWindow()) { 958 win = win.mAttachedWindow; 959 } 960 return win.mAttrs.type; 961 } 962 963 @Override 964 public IApplicationToken getAppToken() { 965 return mAppToken != null ? mAppToken.appToken : null; 966 } 967 968 @Override 969 public boolean isVoiceInteraction() { 970 return mAppToken != null && mAppToken.voiceInteraction; 971 } 972 973 boolean setInsetsChanged() { 974 mOverscanInsetsChanged |= !mLastOverscanInsets.equals(mOverscanInsets); 975 mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets); 976 mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets); 977 mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets); 978 mOutsetsChanged |= !mLastOutsets.equals(mOutsets); 979 return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged 980 || mOutsetsChanged; 981 } 982 983 public DisplayContent getDisplayContent() { 984 if (mAppToken == null || mNotOnAppsDisplay) { 985 return mDisplayContent; 986 } 987 final TaskStack stack = getStack(); 988 return stack == null ? mDisplayContent : stack.getDisplayContent(); 989 } 990 991 public DisplayInfo getDisplayInfo() { 992 final DisplayContent displayContent = getDisplayContent(); 993 return displayContent != null ? displayContent.getDisplayInfo() : null; 994 } 995 996 public int getDisplayId() { 997 final DisplayContent displayContent = getDisplayContent(); 998 if (displayContent == null) { 999 return -1; 1000 } 1001 return displayContent.getDisplayId(); 1002 } 1003 1004 Task getTask() { 1005 return mAppToken != null ? mAppToken.mTask : null; 1006 } 1007 1008 TaskStack getStack() { 1009 Task task = getTask(); 1010 if (task != null) { 1011 if (task.mStack != null) { 1012 return task.mStack; 1013 } 1014 } 1015 // Some system windows (e.g. "Power off" dialog) don't have a task, but we would still 1016 // associate them with some stack to enable dimming. 1017 return mAttrs.type >= WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW 1018 && mDisplayContent != null ? mDisplayContent.getHomeStack() : null; 1019 } 1020 1021 /** 1022 * Retrieves the visible bounds of the window. 1023 * @param bounds The rect which gets the bounds. 1024 */ 1025 void getVisibleBounds(Rect bounds) { 1026 final Task task = getTask(); 1027 boolean intersectWithStackBounds = task != null && task.cropWindowsToStackBounds(); 1028 bounds.setEmpty(); 1029 mTmpRect.setEmpty(); 1030 if (intersectWithStackBounds) { 1031 final TaskStack stack = task.mStack; 1032 if (stack != null) { 1033 stack.getDimBounds(mTmpRect); 1034 } else { 1035 intersectWithStackBounds = false; 1036 } 1037 } 1038 1039 bounds.set(mVisibleFrame); 1040 if (intersectWithStackBounds) { 1041 bounds.intersect(mTmpRect); 1042 } 1043 1044 if (bounds.isEmpty()) { 1045 bounds.set(mFrame); 1046 if (intersectWithStackBounds) { 1047 bounds.intersect(mTmpRect); 1048 } 1049 return; 1050 } 1051 } 1052 1053 public long getInputDispatchingTimeoutNanos() { 1054 return mAppToken != null 1055 ? mAppToken.inputDispatchingTimeoutNanos 1056 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 1057 } 1058 1059 @Override 1060 public boolean hasAppShownWindows() { 1061 return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed); 1062 } 1063 1064 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 1065 if (dsdx < .99999f || dsdx > 1.00001f) return false; 1066 if (dtdy < .99999f || dtdy > 1.00001f) return false; 1067 if (dtdx < -.000001f || dtdx > .000001f) return false; 1068 if (dsdy < -.000001f || dsdy > .000001f) return false; 1069 return true; 1070 } 1071 1072 void prelayout() { 1073 if (mEnforceSizeCompat) { 1074 mGlobalScale = mService.mCompatibleScreenScale; 1075 mInvGlobalScale = 1/mGlobalScale; 1076 } else { 1077 mGlobalScale = mInvGlobalScale = 1; 1078 } 1079 } 1080 1081 /** 1082 * Does the minimal check for visibility. Callers generally want to use one of the public 1083 * methods as they perform additional checks on the app token. 1084 * TODO: See if there are other places we can use this check below instead of duplicating... 1085 */ 1086 private boolean isVisibleUnchecked() { 1087 return mHasSurface && mPolicyVisibility && !mAttachedHidden 1088 && !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible); 1089 } 1090 1091 /** 1092 * Is this window visible? It is not visible if there is no surface, or we are in the process 1093 * of running an exit animation that will remove the surface, or its app token has been hidden. 1094 */ 1095 @Override 1096 public boolean isVisibleLw() { 1097 return (mAppToken == null || !mAppToken.hiddenRequested) && isVisibleUnchecked(); 1098 } 1099 1100 /** 1101 * Like {@link #isVisibleLw}, but also counts a window that is currently "hidden" behind the 1102 * keyguard as visible. This allows us to apply things like window flags that impact the 1103 * keyguard. XXX I am starting to think we need to have ANOTHER visibility flag for this 1104 * "hidden behind keyguard" state rather than overloading mPolicyVisibility. Ungh. 1105 */ 1106 @Override 1107 public boolean isVisibleOrBehindKeyguardLw() { 1108 if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { 1109 return false; 1110 } 1111 final AppWindowToken atoken = mAppToken; 1112 final boolean animating = atoken != null && atoken.mAppAnimator.animation != null; 1113 return mHasSurface && !mDestroying && !mAnimatingExit 1114 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested) 1115 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden) 1116 || mWinAnimator.mAnimation != null || animating); 1117 } 1118 1119 /** 1120 * Is this window visible, ignoring its app token? It is not visible if there is no surface, 1121 * or we are in the process of running an exit animation that will remove the surface. 1122 */ 1123 public boolean isWinVisibleLw() { 1124 return (mAppToken == null || !mAppToken.hiddenRequested || mAppToken.mAppAnimator.animating) 1125 && isVisibleUnchecked(); 1126 } 1127 1128 /** 1129 * The same as isVisible(), but follows the current hidden state of the associated app token, 1130 * not the pending requested hidden state. 1131 */ 1132 boolean isVisibleNow() { 1133 return (!mRootToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING) 1134 && isVisibleUnchecked(); 1135 } 1136 1137 /** 1138 * Can this window possibly be a drag/drop target? The test here is 1139 * a combination of the above "visible now" with the check that the 1140 * Input Manager uses when discarding windows from input consideration. 1141 */ 1142 boolean isPotentialDragTarget() { 1143 return isVisibleNow() && !mRemoved 1144 && mInputChannel != null && mInputWindowHandle != null; 1145 } 1146 1147 /** 1148 * Same as isVisible(), but we also count it as visible between the 1149 * call to IWindowSession.add() and the first relayout(). 1150 */ 1151 boolean isVisibleOrAdding() { 1152 final AppWindowToken atoken = mAppToken; 1153 return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE)) 1154 && mPolicyVisibility && !mAttachedHidden 1155 && (atoken == null || !atoken.hiddenRequested) 1156 && !mAnimatingExit && !mDestroying; 1157 } 1158 1159 /** 1160 * Is this window currently on-screen? It is on-screen either if it 1161 * is visible or it is currently running an animation before no longer 1162 * being visible. 1163 */ 1164 boolean isOnScreen() { 1165 return mPolicyVisibility && isOnScreenIgnoringKeyguard(); 1166 } 1167 1168 /** 1169 * Like isOnScreen(), but ignores any force hiding of the window due 1170 * to the keyguard. 1171 */ 1172 boolean isOnScreenIgnoringKeyguard() { 1173 if (!mHasSurface || mDestroying) { 1174 return false; 1175 } 1176 final AppWindowToken atoken = mAppToken; 1177 if (atoken != null) { 1178 return ((!mAttachedHidden && !atoken.hiddenRequested) 1179 || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null); 1180 } 1181 return !mAttachedHidden || mWinAnimator.mAnimation != null; 1182 } 1183 1184 /** 1185 * Like isOnScreen(), but we don't return true if the window is part 1186 * of a transition that has not yet been started. 1187 */ 1188 boolean isReadyForDisplay() { 1189 if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { 1190 return false; 1191 } 1192 return mHasSurface && mPolicyVisibility && !mDestroying 1193 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden) 1194 || mWinAnimator.mAnimation != null 1195 || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null))); 1196 } 1197 1198 /** 1199 * Like isReadyForDisplay(), but ignores any force hiding of the window due 1200 * to the keyguard. 1201 */ 1202 boolean isReadyForDisplayIgnoringKeyguard() { 1203 if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) { 1204 return false; 1205 } 1206 final AppWindowToken atoken = mAppToken; 1207 if (atoken == null && !mPolicyVisibility) { 1208 // If this is not an app window, and the policy has asked to force 1209 // hide, then we really do want to hide. 1210 return false; 1211 } 1212 return mHasSurface && !mDestroying 1213 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden) 1214 || mWinAnimator.mAnimation != null 1215 || ((atoken != null) && (atoken.mAppAnimator.animation != null) 1216 && !mWinAnimator.isDummyAnimation())); 1217 } 1218 1219 /** 1220 * Like isOnScreen, but returns false if the surface hasn't yet 1221 * been drawn. 1222 */ 1223 @Override 1224 public boolean isDisplayedLw() { 1225 final AppWindowToken atoken = mAppToken; 1226 return isDrawnLw() && mPolicyVisibility 1227 && ((!mAttachedHidden && 1228 (atoken == null || !atoken.hiddenRequested)) 1229 || mWinAnimator.mAnimating 1230 || (atoken != null && atoken.mAppAnimator.animation != null)); 1231 } 1232 1233 /** 1234 * Return true if this window or its app token is currently animating. 1235 */ 1236 @Override 1237 public boolean isAnimatingLw() { 1238 return mWinAnimator.mAnimation != null 1239 || (mAppToken != null && mAppToken.mAppAnimator.animation != null); 1240 } 1241 1242 @Override 1243 public boolean isGoneForLayoutLw() { 1244 final AppWindowToken atoken = mAppToken; 1245 return mViewVisibility == View.GONE 1246 || !mRelayoutCalled 1247 || (atoken == null && mRootToken.hidden) 1248 || (atoken != null && atoken.hiddenRequested) 1249 || mAttachedHidden 1250 || (mAnimatingExit && !isAnimatingLw()) 1251 || mDestroying; 1252 } 1253 1254 /** 1255 * Returns true if the window has a surface that it has drawn a 1256 * complete UI in to. 1257 */ 1258 public boolean isDrawFinishedLw() { 1259 return mHasSurface && !mDestroying && 1260 (mWinAnimator.mDrawState == WindowStateAnimator.COMMIT_DRAW_PENDING 1261 || mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW 1262 || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN); 1263 } 1264 1265 /** 1266 * Returns true if the window has a surface that it has drawn a 1267 * complete UI in to. 1268 */ 1269 @Override 1270 public boolean isDrawnLw() { 1271 return mHasSurface && !mDestroying && 1272 (mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW 1273 || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN); 1274 } 1275 1276 /** 1277 * Return true if the window is opaque and fully drawn. This indicates 1278 * it may obscure windows behind it. 1279 */ 1280 boolean isOpaqueDrawn() { 1281 // When there is keyguard, wallpaper could be placed over the secure app 1282 // window but invisible. We need to check wallpaper visibility explicitly 1283 // to determine if it's occluding apps. 1284 return ((!mIsWallpaper && mAttrs.format == PixelFormat.OPAQUE) 1285 || (mIsWallpaper && mWallpaperVisible)) 1286 && isDrawnLw() && mWinAnimator.mAnimation == null 1287 && (mAppToken == null || mAppToken.mAppAnimator.animation == null); 1288 } 1289 1290 /** 1291 * Return whether this window has moved. (Only makes 1292 * sense to call from performLayoutAndPlaceSurfacesLockedInner().) 1293 */ 1294 boolean hasMoved() { 1295 return mHasSurface && (mContentChanged || mMovedByResize) 1296 && !mAnimatingExit && !mWinAnimator.mLastHidden && mService.okToDisplay() 1297 && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left) 1298 && (mAttachedWindow == null || !mAttachedWindow.hasMoved()); 1299 } 1300 1301 boolean isObscuringFullscreen(final DisplayInfo displayInfo) { 1302 Task task = getTask(); 1303 if (task != null && task.mStack != null && !task.mStack.isFullscreen()) { 1304 return false; 1305 } 1306 if (!isOpaqueDrawn() || !isFrameFullscreen(displayInfo)) { 1307 return false; 1308 } 1309 return true; 1310 } 1311 1312 boolean isFrameFullscreen(final DisplayInfo displayInfo) { 1313 return mFrame.left <= 0 && mFrame.top <= 0 1314 && mFrame.right >= displayInfo.appWidth && mFrame.bottom >= displayInfo.appHeight; 1315 } 1316 1317 boolean isConfigChanged() { 1318 final Task task = getTask(); 1319 final Configuration overrideConfig = 1320 (task != null) ? task.mOverrideConfig : Configuration.EMPTY; 1321 final Configuration serviceConfig = mService.mCurConfiguration; 1322 boolean configChanged = 1323 (mConfiguration != serviceConfig && mConfiguration.diff(serviceConfig) != 0) 1324 || (mOverrideConfig != overrideConfig && !mOverrideConfig.equals(overrideConfig)); 1325 1326 if ((mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 1327 // Retain configuration changed status until resetConfiguration called. 1328 mConfigHasChanged |= configChanged; 1329 configChanged = mConfigHasChanged; 1330 } 1331 1332 return configChanged; 1333 } 1334 1335 void removeLocked() { 1336 disposeInputChannel(); 1337 1338 if (isChildWindow()) { 1339 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow); 1340 mAttachedWindow.mChildWindows.remove(this); 1341 } 1342 mWinAnimator.destroyDeferredSurfaceLocked(); 1343 mWinAnimator.destroySurfaceLocked(); 1344 mSession.windowRemovedLocked(); 1345 try { 1346 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0); 1347 } catch (RuntimeException e) { 1348 // Ignore if it has already been removed (usually because 1349 // we are doing this as part of processing a death note.) 1350 } 1351 } 1352 1353 private void setConfiguration( 1354 final Configuration newConfig, final Configuration newOverrideConfig) { 1355 mConfiguration = newConfig; 1356 mOverrideConfig = newOverrideConfig; 1357 mConfigHasChanged = false; 1358 } 1359 1360 void setHasSurface(boolean hasSurface) { 1361 mHasSurface = hasSurface; 1362 } 1363 1364 int getAnimLayerAdjustment() { 1365 if (mTargetAppToken != null) { 1366 return mTargetAppToken.mAppAnimator.animLayerAdjustment; 1367 } else if (mAppToken != null) { 1368 return mAppToken.mAppAnimator.animLayerAdjustment; 1369 } else { 1370 // Nothing is animating, so there is no animation adjustment. 1371 return 0; 1372 } 1373 } 1374 1375 void scheduleAnimationIfDimming() { 1376 if (mDisplayContent == null) { 1377 return; 1378 } 1379 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser(); 1380 if (dimLayerUser != null && mDisplayContent.mDimLayerController.isDimming( 1381 dimLayerUser, mWinAnimator)) { 1382 // Force an animation pass just to update the mDimLayer layer. 1383 mService.scheduleAnimationLocked(); 1384 } 1385 } 1386 1387 /** 1388 * Notifies this window that the corresponding task has just moved in the stack. 1389 * <p> 1390 * This is used to fix the following: If we moved in the stack, and if the last clip rect was 1391 * empty, meaning that our task was completely offscreen, we need to keep it invisible because 1392 * the actual app transition that updates the visibility is delayed by a few transactions. 1393 * Instead of messing around with the ordering and timing how transitions and transactions are 1394 * executed, we introduce this little hack which prevents this window of getting visible again 1395 * with the wrong bounds until the app transitions has started. 1396 * <p> 1397 * This method notifies the window about that we just moved in the stack so we can apply this 1398 * logic in {@link WindowStateAnimator#updateSurfaceWindowCrop} 1399 */ 1400 void notifyMovedInStack() { 1401 mJustMovedInStack = true; 1402 } 1403 1404 /** 1405 * See {@link #notifyMovedInStack}. 1406 * 1407 * @return Whether we just got moved in the corresponding stack. 1408 */ 1409 boolean hasJustMovedInStack() { 1410 return mJustMovedInStack; 1411 } 1412 1413 /** 1414 * Resets that we just moved in the corresponding stack. See {@link #notifyMovedInStack}. 1415 */ 1416 void resetJustMovedInStack() { 1417 mJustMovedInStack = false; 1418 } 1419 1420 private final class DeadWindowEventReceiver extends InputEventReceiver { 1421 DeadWindowEventReceiver(InputChannel inputChannel) { 1422 super(inputChannel, mService.mH.getLooper()); 1423 } 1424 @Override 1425 public void onInputEvent(InputEvent event) { 1426 finishInputEvent(event, true); 1427 } 1428 } 1429 /** 1430 * Dummy event receiver for windows that died visible. 1431 */ 1432 private DeadWindowEventReceiver mDeadWindowEventReceiver; 1433 1434 void openInputChannel(InputChannel outInputChannel) { 1435 if (mInputChannel != null) { 1436 throw new IllegalStateException("Window already has an input channel."); 1437 } 1438 String name = makeInputChannelName(); 1439 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); 1440 mInputChannel = inputChannels[0]; 1441 mClientChannel = inputChannels[1]; 1442 mInputWindowHandle.inputChannel = inputChannels[0]; 1443 if (outInputChannel != null) { 1444 mClientChannel.transferTo(outInputChannel); 1445 mClientChannel.dispose(); 1446 mClientChannel = null; 1447 } else { 1448 // If the window died visible, we setup a dummy input channel, so that taps 1449 // can still detected by input monitor channel, and we can relaunch the app. 1450 // Create dummy event receiver that simply reports all events as handled. 1451 mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel); 1452 } 1453 mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle); 1454 } 1455 1456 void disposeInputChannel() { 1457 if (mDeadWindowEventReceiver != null) { 1458 mDeadWindowEventReceiver.dispose(); 1459 mDeadWindowEventReceiver = null; 1460 } 1461 1462 // unregister server channel first otherwise it complains about broken channel 1463 if (mInputChannel != null) { 1464 mService.mInputManager.unregisterInputChannel(mInputChannel); 1465 mInputChannel.dispose(); 1466 mInputChannel = null; 1467 } 1468 if (mClientChannel != null) { 1469 mClientChannel.dispose(); 1470 mClientChannel = null; 1471 } 1472 mInputWindowHandle.inputChannel = null; 1473 } 1474 1475 void applyDimLayerIfNeeded() { 1476 // When the app is terminated (eg. from Recents), the task might have already been 1477 // removed with the window pending removal. Don't apply dim in such cases, as there 1478 // will be no more updateDimLayer() calls, which leaves the dimlayer invalid. 1479 final AppWindowToken token = mAppToken; 1480 if (token != null && token.removed) { 1481 return; 1482 } 1483 1484 if (!mAnimatingExit && mAppDied) { 1485 // If app died visible, apply a dim over the window to indicate that it's inactive 1486 mDisplayContent.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator); 1487 } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0 1488 && mDisplayContent != null && !mAnimatingExit && isDisplayedLw()) { 1489 mDisplayContent.mDimLayerController.applyDimBehind(getDimLayerUser(), mWinAnimator); 1490 } 1491 } 1492 1493 DimLayer.DimLayerUser getDimLayerUser() { 1494 Task task = getTask(); 1495 if (task != null) { 1496 return task; 1497 } 1498 return getStack(); 1499 } 1500 1501 void maybeRemoveReplacedWindow() { 1502 if (mAppToken == null) { 1503 return; 1504 } 1505 for (int i = mAppToken.allAppWindows.size() - 1; i >= 0; i--) { 1506 final WindowState win = mAppToken.allAppWindows.get(i); 1507 if (win.mWillReplaceWindow && win.mReplacingWindow == this) { 1508 if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replaced window: " + win); 1509 win.mWillReplaceWindow = false; 1510 win.mAnimateReplacingWindow = false; 1511 win.mReplacingRemoveRequested = false; 1512 win.mReplacingWindow = null; 1513 if (win.mAnimatingExit) { 1514 mService.removeWindowInnerLocked(win); 1515 } 1516 } 1517 } 1518 } 1519 1520 void setDisplayLayoutNeeded() { 1521 if (mDisplayContent != null) { 1522 mDisplayContent.layoutNeeded = true; 1523 } 1524 } 1525 1526 boolean inDockedWorkspace() { 1527 final Task task = getTask(); 1528 return task != null && task.inDockedWorkspace(); 1529 } 1530 1531 boolean isDockedInEffect() { 1532 final Task task = getTask(); 1533 return task != null && task.isDockedInEffect(); 1534 } 1535 1536 void applyScrollIfNeeded() { 1537 final Task task = getTask(); 1538 if (task != null) { 1539 task.applyScrollToWindowIfNeeded(this); 1540 } 1541 } 1542 1543 int getTouchableRegion(Region region, int flags) { 1544 final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0; 1545 if (modal && mAppToken != null) { 1546 // Limit the outer touch to the activity stack region. 1547 flags |= FLAG_NOT_TOUCH_MODAL; 1548 // If this is a modal window we need to dismiss it if it's not full screen and the 1549 // touch happens outside of the frame that displays the content. This means we 1550 // need to intercept touches outside of that window. The dim layer user 1551 // associated with the window (task or stack) will give us the good bounds, as 1552 // they would be used to display the dim layer. 1553 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser(); 1554 if (dimLayerUser != null) { 1555 dimLayerUser.getDimBounds(mTmpRect); 1556 } else { 1557 getVisibleBounds(mTmpRect); 1558 } 1559 if (inFreeformWorkspace()) { 1560 // For freeform windows we the touch region to include the whole surface for the 1561 // shadows. 1562 final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics(); 1563 final int delta = WindowManagerService.dipToPixel( 1564 RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics); 1565 mTmpRect.inset(-delta, -delta); 1566 } 1567 region.set(mTmpRect); 1568 cropRegionToStackBoundsIfNeeded(region); 1569 } else { 1570 // Not modal or full screen modal 1571 getTouchableRegion(region); 1572 } 1573 return flags; 1574 } 1575 1576 void checkPolicyVisibilityChange() { 1577 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) { 1578 if (DEBUG_VISIBILITY) { 1579 Slog.v(TAG, "Policy visibility changing after anim in " + 1580 mWinAnimator + ": " + mPolicyVisibilityAfterAnim); 1581 } 1582 mPolicyVisibility = mPolicyVisibilityAfterAnim; 1583 setDisplayLayoutNeeded(); 1584 if (!mPolicyVisibility) { 1585 if (mService.mCurrentFocus == this) { 1586 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, 1587 "setAnimationLocked: setting mFocusMayChange true"); 1588 mService.mFocusMayChange = true; 1589 } 1590 // Window is no longer visible -- make sure if we were waiting 1591 // for it to be displayed before enabling the display, that 1592 // we allow the display to be enabled now. 1593 mService.enableScreenIfNeededLocked(); 1594 } 1595 } 1596 } 1597 1598 void setRequestedSize(int requestedWidth, int requestedHeight) { 1599 if ((mRequestedWidth != requestedWidth || mRequestedHeight != requestedHeight)) { 1600 mLayoutNeeded = true; 1601 mRequestedWidth = requestedWidth; 1602 mRequestedHeight = requestedHeight; 1603 } 1604 } 1605 1606 void prepareWindowToDisplayDuringRelayout(Configuration outConfig) { 1607 if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST) 1608 == SOFT_INPUT_ADJUST_RESIZE) { 1609 mLayoutNeeded = true; 1610 } 1611 if (isDrawnLw() && mService.okToDisplay()) { 1612 mWinAnimator.applyEnterAnimationLocked(); 1613 } 1614 if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) { 1615 if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this); 1616 mTurnOnScreen = true; 1617 } 1618 if (isConfigChanged()) { 1619 if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: " 1620 + mService.mCurConfiguration); 1621 outConfig.setTo(mService.mCurConfiguration); 1622 } 1623 } 1624 1625 void adjustStartingWindowFlags() { 1626 if (mAttrs.type == TYPE_BASE_APPLICATION && mAppToken != null 1627 && mAppToken.startingWindow != null) { 1628 // Special handling of starting window over the base 1629 // window of the app: propagate lock screen flags to it, 1630 // to provide the correct semantics while starting. 1631 final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD 1632 | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; 1633 WindowManager.LayoutParams sa = mAppToken.startingWindow.mAttrs; 1634 sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask); 1635 } 1636 } 1637 1638 void setWindowScale(int requestedWidth, int requestedHeight) { 1639 final boolean scaledWindow = (mAttrs.flags & FLAG_SCALED) != 0; 1640 1641 if (scaledWindow) { 1642 // requested{Width|Height} Surface's physical size 1643 // attrs.{width|height} Size on screen 1644 // TODO: We don't check if attrs != null here. Is it implicitly checked? 1645 mHScale = (mAttrs.width != requestedWidth) ? 1646 (mAttrs.width / (float)requestedWidth) : 1.0f; 1647 mVScale = (mAttrs.height != requestedHeight) ? 1648 (mAttrs.height / (float)requestedHeight) : 1.0f; 1649 } else { 1650 mHScale = mVScale = 1; 1651 } 1652 } 1653 1654 private class DeathRecipient implements IBinder.DeathRecipient { 1655 @Override 1656 public void binderDied() { 1657 try { 1658 synchronized(mService.mWindowMap) { 1659 WindowState win = mService.windowForClientLocked(mSession, mClient, false); 1660 Slog.i(TAG, "WIN DEATH: " + win); 1661 if (win != null) { 1662 if (win.mAppToken != null && !win.mAppToken.clientHidden) { 1663 win.mAppToken.appDied = true; 1664 } 1665 mService.removeWindowLocked(win); 1666 if (win.mAttrs.type == TYPE_DOCK_DIVIDER) { 1667 // The owner of the docked divider died :( We reset the docked stack, 1668 // just in case they have the divider at an unstable position. Better 1669 // also reset drag resizing state, because the owner can't do it 1670 // anymore. 1671 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID); 1672 if (stack != null) { 1673 stack.resetDockedStackToMiddle(); 1674 } 1675 mService.setDockedStackResizing(false); 1676 } 1677 } else if (mHasSurface) { 1678 Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid."); 1679 mService.removeWindowLocked(WindowState.this); 1680 } 1681 } 1682 } catch (IllegalArgumentException ex) { 1683 // This will happen if the window has already been 1684 // removed. 1685 } 1686 } 1687 } 1688 1689 /** 1690 * Returns true if this window is visible and belongs to a dead app and shouldn't be removed, 1691 * because we want to preserve its location on screen to be re-activated later when the user 1692 * interacts with it. 1693 */ 1694 boolean shouldKeepVisibleDeadAppWindow() { 1695 if (!isWinVisibleLw() || mAppToken == null || !mAppToken.appDied) { 1696 // Not a visible app window or the app isn't dead. 1697 return false; 1698 } 1699 1700 if (mAttrs.type == TYPE_APPLICATION_STARTING) { 1701 // We don't keep starting windows since they were added by the window manager before 1702 // the app even launched. 1703 return false; 1704 } 1705 1706 final TaskStack stack = getStack(); 1707 return stack != null && StackId.keepVisibleDeadAppWindowOnScreen(stack.mStackId); 1708 } 1709 1710 /** @return true if this window desires key events. */ 1711 boolean canReceiveKeys() { 1712 return isVisibleOrAdding() 1713 && (mViewVisibility == View.VISIBLE) 1714 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0) 1715 && (mAppToken == null || mAppToken.windowsAreFocusable()); 1716 } 1717 1718 @Override 1719 public boolean hasDrawnLw() { 1720 return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN; 1721 } 1722 1723 @Override 1724 public boolean showLw(boolean doAnimation) { 1725 return showLw(doAnimation, true); 1726 } 1727 1728 boolean showLw(boolean doAnimation, boolean requestAnim) { 1729 if (isHiddenFromUserLocked()) { 1730 return false; 1731 } 1732 if (!mAppOpVisibility) { 1733 // Being hidden due to app op request. 1734 return false; 1735 } 1736 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) { 1737 // Already showing. 1738 return false; 1739 } 1740 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this); 1741 if (doAnimation) { 1742 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility=" 1743 + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation); 1744 if (!mService.okToDisplay()) { 1745 doAnimation = false; 1746 } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) { 1747 // Check for the case where we are currently visible and 1748 // not animating; we do not want to do animation at such a 1749 // point to become visible when we already are. 1750 doAnimation = false; 1751 } 1752 } 1753 mPolicyVisibility = true; 1754 mPolicyVisibilityAfterAnim = true; 1755 if (doAnimation) { 1756 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true); 1757 } 1758 if (requestAnim) { 1759 mService.scheduleAnimationLocked(); 1760 } 1761 return true; 1762 } 1763 1764 @Override 1765 public boolean hideLw(boolean doAnimation) { 1766 return hideLw(doAnimation, true); 1767 } 1768 1769 boolean hideLw(boolean doAnimation, boolean requestAnim) { 1770 if (doAnimation) { 1771 if (!mService.okToDisplay()) { 1772 doAnimation = false; 1773 } 1774 } 1775 boolean current = doAnimation ? mPolicyVisibilityAfterAnim 1776 : mPolicyVisibility; 1777 if (!current) { 1778 // Already hiding. 1779 return false; 1780 } 1781 if (doAnimation) { 1782 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false); 1783 if (mWinAnimator.mAnimation == null) { 1784 doAnimation = false; 1785 } 1786 } 1787 if (doAnimation) { 1788 mPolicyVisibilityAfterAnim = false; 1789 } else { 1790 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this); 1791 mPolicyVisibilityAfterAnim = false; 1792 mPolicyVisibility = false; 1793 // Window is no longer visible -- make sure if we were waiting 1794 // for it to be displayed before enabling the display, that 1795 // we allow the display to be enabled now. 1796 mService.enableScreenIfNeededLocked(); 1797 if (mService.mCurrentFocus == this) { 1798 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, 1799 "WindowState.hideLw: setting mFocusMayChange true"); 1800 mService.mFocusMayChange = true; 1801 } 1802 } 1803 if (requestAnim) { 1804 mService.scheduleAnimationLocked(); 1805 } 1806 return true; 1807 } 1808 1809 public void setAppOpVisibilityLw(boolean state) { 1810 if (mAppOpVisibility != state) { 1811 mAppOpVisibility = state; 1812 if (state) { 1813 // If the policy visibility had last been to hide, then this 1814 // will incorrectly show at this point since we lost that 1815 // information. Not a big deal -- for the windows that have app 1816 // ops modifies they should only be hidden by policy due to the 1817 // lock screen, and the user won't be changing this if locked. 1818 // Plus it will quickly be fixed the next time we do a layout. 1819 showLw(true, true); 1820 } else { 1821 hideLw(true, true); 1822 } 1823 } 1824 } 1825 1826 public void pokeDrawLockLw(long timeout) { 1827 if (isVisibleOrAdding()) { 1828 if (mDrawLock == null) { 1829 // We want the tag name to be somewhat stable so that it is easier to correlate 1830 // in wake lock statistics. So in particular, we don't want to include the 1831 // window's hash code as in toString(). 1832 final CharSequence tag = getWindowTag(); 1833 mDrawLock = mService.mPowerManager.newWakeLock( 1834 PowerManager.DRAW_WAKE_LOCK, "Window:" + tag); 1835 mDrawLock.setReferenceCounted(false); 1836 mDrawLock.setWorkSource(new WorkSource(mOwnerUid, mAttrs.packageName)); 1837 } 1838 // Each call to acquire resets the timeout. 1839 if (DEBUG_POWER) { 1840 Slog.d(TAG, "pokeDrawLock: poking draw lock on behalf of visible window owned by " 1841 + mAttrs.packageName); 1842 } 1843 mDrawLock.acquire(timeout); 1844 } else if (DEBUG_POWER) { 1845 Slog.d(TAG, "pokeDrawLock: suppressed draw lock request for invisible window " 1846 + "owned by " + mAttrs.packageName); 1847 } 1848 } 1849 1850 @Override 1851 public boolean isAlive() { 1852 return mClient.asBinder().isBinderAlive(); 1853 } 1854 1855 boolean isClosing() { 1856 return mAnimatingExit || (mService.mClosingApps.contains(mAppToken)); 1857 } 1858 1859 boolean isAnimatingWithSavedSurface() { 1860 return mAppToken != null && mAppToken.mAnimatingWithSavedSurface; 1861 } 1862 1863 private boolean shouldSaveSurface() { 1864 if (ActivityManager.isLowRamDeviceStatic()) { 1865 // Don't save surfaces on Svelte devices. 1866 return false; 1867 } 1868 1869 Task task = getTask(); 1870 if (task == null || task.inHomeStack()) { 1871 // Don't save surfaces for home stack apps. These usually resume and draw 1872 // first frame very fast. Saving surfaces are mostly a waste of memory. 1873 return false; 1874 } 1875 1876 final AppWindowToken taskTop = task.getTopVisibleAppToken(); 1877 if (taskTop != null && taskTop != mAppToken) { 1878 // Don't save if the window is not the topmost window. 1879 return false; 1880 } 1881 1882 if (mResizedWhileGone) { 1883 // Somebody resized our window while we were gone for layout, which means that the 1884 // client got an old size, so we have an outdated surface here. 1885 return false; 1886 } 1887 1888 if (DEBUG_DISABLE_SAVING_SURFACES) { 1889 return false; 1890 } 1891 1892 return mAppToken.shouldSaveSurface(); 1893 } 1894 1895 void destroyOrSaveSurface() { 1896 mSurfaceSaved = shouldSaveSurface(); 1897 if (mSurfaceSaved) { 1898 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { 1899 Slog.v(TAG, "Saving surface: " + this); 1900 } 1901 1902 mWinAnimator.hide("saved surface"); 1903 mWinAnimator.mDrawState = WindowStateAnimator.NO_SURFACE; 1904 setHasSurface(false); 1905 // The client should have disconnected at this point, but if it doesn't, 1906 // we need to make sure it's disconnected. Otherwise when we reuse the surface 1907 // the client can't reconnect to the buffer queue, and rendering will fail. 1908 if (mWinAnimator.mSurfaceController != null) { 1909 mWinAnimator.mSurfaceController.disconnectInTransaction(); 1910 } 1911 } else { 1912 mWinAnimator.destroySurfaceLocked(); 1913 } 1914 } 1915 1916 public void destroySavedSurface() { 1917 if (mSurfaceSaved) { 1918 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { 1919 Slog.v(TAG, "Destroying saved surface: " + this); 1920 } 1921 mWinAnimator.destroySurfaceLocked(); 1922 } 1923 } 1924 1925 public void restoreSavedSurface() { 1926 if (!mSurfaceSaved) { 1927 return; 1928 } 1929 mSurfaceSaved = false; 1930 setHasSurface(true); 1931 mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW; 1932 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { 1933 Slog.v(TAG, "Restoring saved surface: " + this); 1934 } 1935 } 1936 1937 public boolean hasSavedSurface() { 1938 return mSurfaceSaved; 1939 } 1940 1941 @Override 1942 public boolean isDefaultDisplay() { 1943 final DisplayContent displayContent = getDisplayContent(); 1944 if (displayContent == null) { 1945 // Only a window that was on a non-default display can be detached from it. 1946 return false; 1947 } 1948 return displayContent.isDefaultDisplay; 1949 } 1950 1951 @Override 1952 public boolean isDimming() { 1953 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser(); 1954 return dimLayerUser != null && mDisplayContent != null && 1955 mDisplayContent.mDimLayerController.isDimming(dimLayerUser, mWinAnimator); 1956 } 1957 1958 public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) { 1959 mShowToOwnerOnly = showToOwnerOnly; 1960 } 1961 1962 boolean isHiddenFromUserLocked() { 1963 // Attached windows are evaluated based on the window that they are attached to. 1964 WindowState win = this; 1965 while (win.isChildWindow()) { 1966 win = win.mAttachedWindow; 1967 } 1968 if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW 1969 && win.mAppToken != null && win.mAppToken.showForAllUsers) { 1970 // Save some cycles by not calling getDisplayInfo unless it is an application 1971 // window intended for all users. 1972 final DisplayContent displayContent = win.getDisplayContent(); 1973 if (displayContent == null) { 1974 return true; 1975 } 1976 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 1977 if (win.mFrame.left <= 0 && win.mFrame.top <= 0 1978 && win.mFrame.right >= displayInfo.appWidth 1979 && win.mFrame.bottom >= displayInfo.appHeight) { 1980 // Is a fullscreen window, like the clock alarm. Show to everyone. 1981 return false; 1982 } 1983 } 1984 1985 return win.mShowToOwnerOnly 1986 && !mService.isCurrentProfileLocked(UserHandle.getUserId(win.mOwnerUid)); 1987 } 1988 1989 private static void applyInsets(Region outRegion, Rect frame, Rect inset) { 1990 outRegion.set( 1991 frame.left + inset.left, frame.top + inset.top, 1992 frame.right - inset.right, frame.bottom - inset.bottom); 1993 } 1994 1995 void getTouchableRegion(Region outRegion) { 1996 final Rect frame = mFrame; 1997 switch (mTouchableInsets) { 1998 default: 1999 case TOUCHABLE_INSETS_FRAME: 2000 outRegion.set(frame); 2001 break; 2002 case TOUCHABLE_INSETS_CONTENT: 2003 applyInsets(outRegion, frame, mGivenContentInsets); 2004 break; 2005 case TOUCHABLE_INSETS_VISIBLE: 2006 applyInsets(outRegion, frame, mGivenVisibleInsets); 2007 break; 2008 case TOUCHABLE_INSETS_REGION: { 2009 final Region givenTouchableRegion = mGivenTouchableRegion; 2010 outRegion.set(givenTouchableRegion); 2011 outRegion.translate(frame.left, frame.top); 2012 break; 2013 } 2014 } 2015 cropRegionToStackBoundsIfNeeded(outRegion); 2016 } 2017 2018 void cropRegionToStackBoundsIfNeeded(Region region) { 2019 final Task task = getTask(); 2020 if (task == null || !task.cropWindowsToStackBounds()) { 2021 return; 2022 } 2023 2024 final TaskStack stack = task.mStack; 2025 if (stack == null) { 2026 return; 2027 } 2028 2029 stack.getDimBounds(mTmpRect); 2030 region.op(mTmpRect, Region.Op.INTERSECT); 2031 } 2032 2033 WindowList getWindowList() { 2034 final DisplayContent displayContent = getDisplayContent(); 2035 return displayContent == null ? null : displayContent.getWindowList(); 2036 } 2037 2038 /** 2039 * Report a focus change. Must be called with no locks held, and consistently 2040 * from the same serialized thread (such as dispatched from a handler). 2041 */ 2042 public void reportFocusChangedSerialized(boolean focused, boolean inTouchMode) { 2043 try { 2044 mClient.windowFocusChanged(focused, inTouchMode); 2045 } catch (RemoteException e) { 2046 } 2047 if (mFocusCallbacks != null) { 2048 final int N = mFocusCallbacks.beginBroadcast(); 2049 for (int i=0; i<N; i++) { 2050 IWindowFocusObserver obs = mFocusCallbacks.getBroadcastItem(i); 2051 try { 2052 if (focused) { 2053 obs.focusGained(mWindowId.asBinder()); 2054 } else { 2055 obs.focusLost(mWindowId.asBinder()); 2056 } 2057 } catch (RemoteException e) { 2058 } 2059 } 2060 mFocusCallbacks.finishBroadcast(); 2061 } 2062 } 2063 2064 void reportResized() { 2065 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag()); 2066 try { 2067 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this 2068 + ": " + mCompatFrame); 2069 final boolean configChanged = isConfigChanged(); 2070 final Task task = getTask(); 2071 final Configuration overrideConfig = 2072 (task != null) ? task.mOverrideConfig : Configuration.EMPTY; 2073 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) { 2074 Slog.i(TAG, "Sending new config to window " + this + ": " 2075 + " / config=" 2076 + mService.mCurConfiguration + " overrideConfig=" + overrideConfig); 2077 } 2078 setConfiguration(mService.mCurConfiguration, overrideConfig); 2079 if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) 2080 Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING"); 2081 2082 final Rect frame = mFrame; 2083 final Rect overscanInsets = mLastOverscanInsets; 2084 final Rect contentInsets = mLastContentInsets; 2085 final Rect visibleInsets = mLastVisibleInsets; 2086 final Rect stableInsets = mLastStableInsets; 2087 final Rect outsets = mLastOutsets; 2088 final boolean reportDraw = mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING; 2089 final Configuration newConfig = configChanged ? mConfiguration : null; 2090 if (mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_STARTING 2091 && mClient instanceof IWindow.Stub) { 2092 // To prevent deadlock simulate one-way call if win.mClient is a local object. 2093 mService.mH.post(new Runnable() { 2094 @Override 2095 public void run() { 2096 try { 2097 dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, 2098 stableInsets, outsets, reportDraw, newConfig); 2099 } catch (RemoteException e) { 2100 // Not a remote call, RemoteException won't be raised. 2101 } 2102 } 2103 }); 2104 } else { 2105 dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, 2106 outsets, reportDraw, newConfig); 2107 } 2108 2109 //TODO (multidisplay): Accessibility supported only for the default display. 2110 if (mService.mAccessibilityController != null 2111 && getDisplayId() == Display.DEFAULT_DISPLAY) { 2112 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(); 2113 } 2114 2115 mOverscanInsetsChanged = false; 2116 mContentInsetsChanged = false; 2117 mVisibleInsetsChanged = false; 2118 mStableInsetsChanged = false; 2119 mOutsetsChanged = false; 2120 mWinAnimator.mSurfaceResized = false; 2121 } catch (RemoteException e) { 2122 mOrientationChanging = false; 2123 mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() 2124 - mService.mDisplayFreezeTime); 2125 // We are assuming the hosting process is dead or in a zombie state. 2126 Slog.w(TAG, "Failed to report 'resized' to the client of " + this 2127 + ", removing this window."); 2128 mService.mPendingRemove.add(this); 2129 mService.mWindowPlacerLocked.requestTraversal(); 2130 } 2131 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 2132 } 2133 2134 Rect getBackdropFrame(Rect frame) { 2135 // When the task is docked, we send fullscreen sized backDropFrame as soon as resizing 2136 // start even if we haven't received the relayout window, so that the client requests 2137 // the relayout sooner. When dragging stops, backDropFrame needs to stay fullscreen 2138 // until the window to small size, otherwise the multithread renderer will shift last 2139 // one or more frame to wrong offset. So here we send fullscreen backdrop if either 2140 // isDragResizing() or isDragResizeChanged() is true. 2141 boolean resizing = isDragResizing() || isDragResizeChanged(); 2142 if (StackId.useWindowFrameForBackdrop(getStackId()) || !resizing) { 2143 return frame; 2144 } 2145 DisplayInfo displayInfo = getDisplayInfo(); 2146 mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); 2147 return mTmpRect; 2148 } 2149 2150 @Override 2151 public int getStackId() { 2152 final TaskStack stack = getStack(); 2153 if (stack == null) { 2154 return INVALID_STACK_ID; 2155 } 2156 return stack.mStackId; 2157 } 2158 2159 private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, 2160 Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, 2161 Configuration newConfig) throws RemoteException { 2162 mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets, 2163 reportDraw, newConfig, getBackdropFrame(frame), 2164 isDragResizeChanged() /* forceRelayout */, mPolicy.isNavBarForcedShownLw(this)); 2165 mDragResizingChangeReported = true; 2166 } 2167 2168 public void registerFocusObserver(IWindowFocusObserver observer) { 2169 synchronized(mService.mWindowMap) { 2170 if (mFocusCallbacks == null) { 2171 mFocusCallbacks = new RemoteCallbackList<IWindowFocusObserver>(); 2172 } 2173 mFocusCallbacks.register(observer); 2174 } 2175 } 2176 2177 public void unregisterFocusObserver(IWindowFocusObserver observer) { 2178 synchronized(mService.mWindowMap) { 2179 if (mFocusCallbacks != null) { 2180 mFocusCallbacks.unregister(observer); 2181 } 2182 } 2183 } 2184 2185 public boolean isFocused() { 2186 synchronized(mService.mWindowMap) { 2187 return mService.mCurrentFocus == this; 2188 } 2189 } 2190 2191 boolean inFreeformWorkspace() { 2192 final Task task = getTask(); 2193 return task != null && task.inFreeformWorkspace(); 2194 } 2195 2196 boolean isDragResizeChanged() { 2197 return mDragResizing != computeDragResizing(); 2198 } 2199 2200 /** 2201 * @return Whether we reported a drag resize change to the application or not already. 2202 */ 2203 boolean isDragResizingChangeReported() { 2204 return mDragResizingChangeReported; 2205 } 2206 2207 /** 2208 * Resets the state whether we reported a drag resize change to the app. 2209 */ 2210 void resetDragResizingChangeReported() { 2211 mDragResizingChangeReported = false; 2212 } 2213 2214 int getResizeMode() { 2215 return mResizeMode; 2216 } 2217 2218 private boolean computeDragResizing() { 2219 final Task task = getTask(); 2220 if (task == null) { 2221 return false; 2222 } 2223 if (mAttrs.width != MATCH_PARENT || mAttrs.height != MATCH_PARENT) { 2224 2225 // Floating windows never enter drag resize mode. 2226 return false; 2227 } 2228 if (task.isDragResizing()) { 2229 return true; 2230 } 2231 2232 // If the bounds are currently frozen, it means that the layout size that the app sees 2233 // and the bounds we clip this window to might be different. In order to avoid holes, we 2234 // simulate that we are still resizing so the app fills the hole with the resizing 2235 // background. 2236 return (mDisplayContent.mDividerControllerLocked.isResizing() 2237 || mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) && 2238 !task.inFreeformWorkspace() && isVisibleLw(); 2239 2240 } 2241 2242 void setDragResizing() { 2243 final boolean resizing = computeDragResizing(); 2244 if (resizing == mDragResizing) { 2245 return; 2246 } 2247 mDragResizing = resizing; 2248 mResizeMode = mDragResizing && mDisplayContent.mDividerControllerLocked.isResizing() 2249 ? DRAG_RESIZE_MODE_DOCKED_DIVIDER 2250 : DRAG_RESIZE_MODE_FREEFORM; 2251 } 2252 2253 boolean isDragResizing() { 2254 return mDragResizing; 2255 } 2256 2257 void dump(PrintWriter pw, String prefix, boolean dumpAll) { 2258 final TaskStack stack = getStack(); 2259 pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId()); 2260 if (stack != null) { 2261 pw.print(" stackId="); pw.print(stack.mStackId); 2262 } 2263 pw.print(" mSession="); pw.print(mSession); 2264 pw.print(" mClient="); pw.println(mClient.asBinder()); 2265 pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid); 2266 pw.print(" mShowToOwnerOnly="); pw.print(mShowToOwnerOnly); 2267 pw.print(" package="); pw.print(mAttrs.packageName); 2268 pw.print(" appop="); pw.println(AppOpsManager.opToName(mAppOp)); 2269 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs); 2270 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth); 2271 pw.print(" h="); pw.print(mRequestedHeight); 2272 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq); 2273 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) { 2274 pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth); 2275 pw.print(" h="); pw.println(mLastRequestedHeight); 2276 } 2277 if (isChildWindow() || mLayoutAttached) { 2278 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow); 2279 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached); 2280 } 2281 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) { 2282 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow); 2283 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper); 2284 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer); 2285 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible); 2286 } 2287 if (dumpAll) { 2288 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer); 2289 pw.print(" mSubLayer="); pw.print(mSubLayer); 2290 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+"); 2291 pw.print((mTargetAppToken != null ? 2292 mTargetAppToken.mAppAnimator.animLayerAdjustment 2293 : (mAppToken != null ? mAppToken.mAppAnimator.animLayerAdjustment : 0))); 2294 pw.print("="); pw.print(mWinAnimator.mAnimLayer); 2295 pw.print(" mLastLayer="); pw.println(mWinAnimator.mLastLayer); 2296 } 2297 if (dumpAll) { 2298 pw.print(prefix); pw.print("mToken="); pw.println(mToken); 2299 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken); 2300 if (mAppToken != null) { 2301 pw.print(prefix); pw.print("mAppToken="); pw.print(mAppToken); 2302 pw.print(" isAnimatingWithSavedSurface()="); 2303 pw.print(isAnimatingWithSavedSurface()); 2304 pw.print(" mAppDied=");pw.println(mAppDied); 2305 } 2306 if (mTargetAppToken != null) { 2307 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken); 2308 } 2309 pw.print(prefix); pw.print("mViewVisibility=0x"); 2310 pw.print(Integer.toHexString(mViewVisibility)); 2311 pw.print(" mHaveFrame="); pw.print(mHaveFrame); 2312 pw.print(" mObscured="); pw.println(mObscured); 2313 pw.print(prefix); pw.print("mSeq="); pw.print(mSeq); 2314 pw.print(" mSystemUiVisibility=0x"); 2315 pw.println(Integer.toHexString(mSystemUiVisibility)); 2316 } 2317 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || !mAppOpVisibility 2318 || mAttachedHidden) { 2319 pw.print(prefix); pw.print("mPolicyVisibility="); 2320 pw.print(mPolicyVisibility); 2321 pw.print(" mPolicyVisibilityAfterAnim="); 2322 pw.print(mPolicyVisibilityAfterAnim); 2323 pw.print(" mAppOpVisibility="); 2324 pw.print(mAppOpVisibility); 2325 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden); 2326 } 2327 if (!mRelayoutCalled || mLayoutNeeded) { 2328 pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled); 2329 pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded); 2330 } 2331 if (mXOffset != 0 || mYOffset != 0) { 2332 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset); 2333 pw.print(" y="); pw.println(mYOffset); 2334 } 2335 if (dumpAll) { 2336 pw.print(prefix); pw.print("mGivenContentInsets="); 2337 mGivenContentInsets.printShortString(pw); 2338 pw.print(" mGivenVisibleInsets="); 2339 mGivenVisibleInsets.printShortString(pw); 2340 pw.println(); 2341 if (mTouchableInsets != 0 || mGivenInsetsPending) { 2342 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets); 2343 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending); 2344 Region region = new Region(); 2345 getTouchableRegion(region); 2346 pw.print(prefix); pw.print("touchable region="); pw.println(region); 2347 } 2348 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration); 2349 if (mOverrideConfig != Configuration.EMPTY) { 2350 pw.print(prefix); pw.print("mOverrideConfig="); pw.println(mOverrideConfig); 2351 } 2352 } 2353 pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface); 2354 pw.print(" mShownPosition="); mShownPosition.printShortString(pw); 2355 pw.print(" isReadyForDisplay()="); pw.print(isReadyForDisplay()); 2356 pw.print(" hasSavedSurface()="); pw.print(hasSavedSurface()); 2357 pw.print(" mWindowRemovalAllowed="); pw.println(mWindowRemovalAllowed); 2358 if (dumpAll) { 2359 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw); 2360 pw.print(" last="); mLastFrame.printShortString(pw); 2361 pw.println(); 2362 } 2363 if (mEnforceSizeCompat) { 2364 pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw); 2365 pw.println(); 2366 } 2367 if (dumpAll) { 2368 pw.print(prefix); pw.print("Frames: containing="); 2369 mContainingFrame.printShortString(pw); 2370 pw.print(" parent="); mParentFrame.printShortString(pw); 2371 pw.println(); 2372 pw.print(prefix); pw.print(" display="); mDisplayFrame.printShortString(pw); 2373 pw.print(" overscan="); mOverscanFrame.printShortString(pw); 2374 pw.println(); 2375 pw.print(prefix); pw.print(" content="); mContentFrame.printShortString(pw); 2376 pw.print(" visible="); mVisibleFrame.printShortString(pw); 2377 pw.println(); 2378 pw.print(prefix); pw.print(" decor="); mDecorFrame.printShortString(pw); 2379 pw.println(); 2380 pw.print(prefix); pw.print(" outset="); mOutsetFrame.printShortString(pw); 2381 pw.println(); 2382 pw.print(prefix); pw.print("Cur insets: overscan="); 2383 mOverscanInsets.printShortString(pw); 2384 pw.print(" content="); mContentInsets.printShortString(pw); 2385 pw.print(" visible="); mVisibleInsets.printShortString(pw); 2386 pw.print(" stable="); mStableInsets.printShortString(pw); 2387 pw.print(" outsets="); mOutsets.printShortString(pw); 2388 pw.println(); 2389 pw.print(prefix); pw.print("Lst insets: overscan="); 2390 mLastOverscanInsets.printShortString(pw); 2391 pw.print(" content="); mLastContentInsets.printShortString(pw); 2392 pw.print(" visible="); mLastVisibleInsets.printShortString(pw); 2393 pw.print(" stable="); mLastStableInsets.printShortString(pw); 2394 pw.print(" physical="); mLastOutsets.printShortString(pw); 2395 pw.print(" outset="); mLastOutsets.printShortString(pw); 2396 pw.println(); 2397 } 2398 pw.print(prefix); pw.print(mWinAnimator); pw.println(":"); 2399 mWinAnimator.dump(pw, prefix + " ", dumpAll); 2400 if (mAnimatingExit || mRemoveOnExit || mDestroying || mRemoved) { 2401 pw.print(prefix); pw.print("mAnimatingExit="); pw.print(mAnimatingExit); 2402 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit); 2403 pw.print(" mDestroying="); pw.print(mDestroying); 2404 pw.print(" mRemoved="); pw.println(mRemoved); 2405 } 2406 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) { 2407 pw.print(prefix); pw.print("mOrientationChanging="); 2408 pw.print(mOrientationChanging); 2409 pw.print(" mAppFreezing="); pw.print(mAppFreezing); 2410 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen); 2411 } 2412 if (mLastFreezeDuration != 0) { 2413 pw.print(prefix); pw.print("mLastFreezeDuration="); 2414 TimeUtils.formatDuration(mLastFreezeDuration, pw); pw.println(); 2415 } 2416 if (mHScale != 1 || mVScale != 1) { 2417 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale); 2418 pw.print(" mVScale="); pw.println(mVScale); 2419 } 2420 if (mWallpaperX != -1 || mWallpaperY != -1) { 2421 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX); 2422 pw.print(" mWallpaperY="); pw.println(mWallpaperY); 2423 } 2424 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) { 2425 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep); 2426 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep); 2427 } 2428 if (mWallpaperDisplayOffsetX != Integer.MIN_VALUE 2429 || mWallpaperDisplayOffsetY != Integer.MIN_VALUE) { 2430 pw.print(prefix); pw.print("mWallpaperDisplayOffsetX="); 2431 pw.print(mWallpaperDisplayOffsetX); 2432 pw.print(" mWallpaperDisplayOffsetY="); 2433 pw.println(mWallpaperDisplayOffsetY); 2434 } 2435 if (mDrawLock != null) { 2436 pw.print(prefix); pw.println("mDrawLock=" + mDrawLock); 2437 } 2438 if (isDragResizing()) { 2439 pw.print(prefix); pw.println("isDragResizing=" + isDragResizing()); 2440 } 2441 if (computeDragResizing()) { 2442 pw.print(prefix); pw.println("computeDragResizing=" + computeDragResizing()); 2443 } 2444 } 2445 2446 String makeInputChannelName() { 2447 return Integer.toHexString(System.identityHashCode(this)) 2448 + " " + getWindowTag(); 2449 } 2450 2451 CharSequence getWindowTag() { 2452 CharSequence tag = mAttrs.getTitle(); 2453 if (tag == null || tag.length() <= 0) { 2454 tag = mAttrs.packageName; 2455 } 2456 return tag; 2457 } 2458 2459 @Override 2460 public String toString() { 2461 final CharSequence title = getWindowTag(); 2462 if (mStringNameCache == null || mLastTitle != title || mWasExiting != mAnimatingExit) { 2463 mLastTitle = title; 2464 mWasExiting = mAnimatingExit; 2465 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) 2466 + " u" + UserHandle.getUserId(mSession.mUid) 2467 + " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}"); 2468 } 2469 return mStringNameCache; 2470 } 2471 2472 void transformFromScreenToSurfaceSpace(Rect rect) { 2473 if (mHScale >= 0) { 2474 rect.left = (int) (rect.left / mHScale); 2475 rect.right = (int) (rect.right / mHScale); 2476 } 2477 if (mVScale >= 0) { 2478 rect.top = (int) (rect.top / mVScale); 2479 rect.bottom = (int) (rect.bottom / mVScale); 2480 } 2481 } 2482 2483 void applyGravityAndUpdateFrame() { 2484 final int pw = mContainingFrame.width(); 2485 final int ph = mContainingFrame.height(); 2486 final Task task = getTask(); 2487 final boolean nonFullscreenTask = task != null && !task.isFullscreen(); 2488 final boolean fitToDisplay = task != null && 2489 !task.isFloating(); 2490 float x, y; 2491 int w,h; 2492 2493 if ((mAttrs.flags & FLAG_SCALED) != 0) { 2494 if (mAttrs.width < 0) { 2495 w = pw; 2496 } else if (mEnforceSizeCompat) { 2497 w = (int)(mAttrs.width * mGlobalScale + .5f); 2498 } else { 2499 w = mAttrs.width; 2500 } 2501 if (mAttrs.height < 0) { 2502 h = ph; 2503 } else if (mEnforceSizeCompat) { 2504 h = (int)(mAttrs.height * mGlobalScale + .5f); 2505 } else { 2506 h = mAttrs.height; 2507 } 2508 } else { 2509 if (mAttrs.width == MATCH_PARENT) { 2510 w = pw; 2511 } else if (mEnforceSizeCompat) { 2512 w = (int)(mRequestedWidth * mGlobalScale + .5f); 2513 } else { 2514 w = mRequestedWidth; 2515 } 2516 if (mAttrs.height == MATCH_PARENT) { 2517 h = ph; 2518 } else if (mEnforceSizeCompat) { 2519 h = (int)(mRequestedHeight * mGlobalScale + .5f); 2520 } else { 2521 h = mRequestedHeight; 2522 } 2523 } 2524 2525 if (mEnforceSizeCompat) { 2526 x = mAttrs.x * mGlobalScale; 2527 y = mAttrs.y * mGlobalScale; 2528 } else { 2529 x = mAttrs.x; 2530 y = mAttrs.y; 2531 } 2532 2533 if (nonFullscreenTask) { 2534 // Make sure window fits in containing frame since it is in a non-fullscreen task as 2535 // required by {@link Gravity#apply} call. 2536 w = Math.min(w, pw); 2537 h = Math.min(h, ph); 2538 } 2539 2540 // Set mFrame 2541 Gravity.apply(mAttrs.gravity, w, h, mContainingFrame, 2542 (int) (x + mAttrs.horizontalMargin * pw), 2543 (int) (y + mAttrs.verticalMargin * ph), mFrame); 2544 2545 // Now make sure the window fits in the overall display frame. 2546 if (fitToDisplay) { 2547 Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame); 2548 } 2549 } 2550 2551 boolean isChildWindow() { 2552 return mAttachedWindow != null; 2553 } 2554 2555 void setReplacing(boolean animate) { 2556 if ((mAttrs.privateFlags & PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH) != 0 2557 || mAttrs.type == TYPE_APPLICATION_STARTING) { 2558 // We don't set replacing on starting windows since they are added by window manager and 2559 // not the client so won't be replaced by the client. 2560 return; 2561 } 2562 2563 mWillReplaceWindow = true; 2564 mReplacingWindow = null; 2565 mAnimateReplacingWindow = animate; 2566 } 2567 2568 void resetReplacing() { 2569 mWillReplaceWindow = false; 2570 mReplacingWindow = null; 2571 mAnimateReplacingWindow = false; 2572 } 2573 2574 float translateToWindowX(float x) { 2575 float winX = x - mFrame.left; 2576 if (mEnforceSizeCompat) { 2577 winX *= mGlobalScale; 2578 } 2579 return winX; 2580 } 2581 2582 float translateToWindowY(float y) { 2583 float winY = y - mFrame.top; 2584 if (mEnforceSizeCompat) { 2585 winY *= mGlobalScale; 2586 } 2587 return winY; 2588 } 2589} 2590