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