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