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