Home | History | Annotate | Download | only in wm
      1 /*
      2  * Copyright (C) 2014 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.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
     20 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
     21 import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
     22 import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
     23 import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
     24 import static com.android.server.wm.WindowManagerService.DEBUG_STARTING_WINDOW;
     25 import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
     26 import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
     27 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
     28 import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
     29 import static com.android.server.wm.WindowManagerService.SHOW_SURFACE_ALLOC;
     30 import static com.android.server.wm.WindowManagerService.localLOGV;
     31 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
     32 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN;
     33 
     34 import android.content.Context;
     35 import android.graphics.Matrix;
     36 import android.graphics.PixelFormat;
     37 import android.graphics.Point;
     38 import android.graphics.PointF;
     39 import android.graphics.Rect;
     40 import android.graphics.RectF;
     41 import android.graphics.Region;
     42 import android.os.Debug;
     43 import android.os.RemoteException;
     44 import android.os.UserHandle;
     45 import android.util.Slog;
     46 import android.view.Display;
     47 import android.view.DisplayInfo;
     48 import android.view.MagnificationSpec;
     49 import android.view.Surface.OutOfResourcesException;
     50 import android.view.SurfaceControl;
     51 import android.view.SurfaceSession;
     52 import android.view.View;
     53 import android.view.WindowManager;
     54 import android.view.WindowManagerPolicy;
     55 import android.view.WindowManager.LayoutParams;
     56 import android.view.animation.AlphaAnimation;
     57 import android.view.animation.Animation;
     58 import android.view.animation.AnimationSet;
     59 import android.view.animation.AnimationUtils;
     60 import android.view.animation.Transformation;
     61 
     62 import com.android.internal.R;
     63 import com.android.server.wm.WindowManagerService.H;
     64 
     65 import java.io.PrintWriter;
     66 import java.util.ArrayList;
     67 
     68 class WinAnimatorList extends ArrayList<WindowStateAnimator> {
     69 }
     70 
     71 /**
     72  * Keep track of animations and surface operations for a single WindowState.
     73  **/
     74 class WindowStateAnimator {
     75     static final String TAG = "WindowStateAnimator";
     76 
     77     // Unchanging local convenience fields.
     78     final WindowManagerService mService;
     79     final WindowState mWin;
     80     final WindowStateAnimator mAttachedWinAnimator;
     81     final WindowAnimator mAnimator;
     82     AppWindowAnimator mAppAnimator;
     83     final Session mSession;
     84     final WindowManagerPolicy mPolicy;
     85     final Context mContext;
     86     final boolean mIsWallpaper;
     87 
     88     // If this is a universe background window, this is the transformation
     89     // it is applying to the rest of the universe.
     90     final Transformation mUniverseTransform = new Transformation();
     91 
     92     // Currently running animation.
     93     boolean mAnimating;
     94     boolean mLocalAnimating;
     95     Animation mAnimation;
     96     boolean mAnimationIsEntrance;
     97     boolean mHasTransformation;
     98     boolean mHasLocalTransformation;
     99     final Transformation mTransformation = new Transformation();
    100     boolean mWasAnimating;      // Were we animating going into the most recent animation step?
    101     int mAnimLayer;
    102     int mLastLayer;
    103     long mAnimationStartTime;
    104     long mLastAnimationTime;
    105 
    106     SurfaceControl mSurfaceControl;
    107     SurfaceControl mPendingDestroySurface;
    108 
    109     /**
    110      * Set when we have changed the size of the surface, to know that
    111      * we must tell them application to resize (and thus redraw itself).
    112      */
    113     boolean mSurfaceResized;
    114 
    115     /**
    116      * Set if the client has asked that the destroy of its surface be delayed
    117      * until it explicitly says it is okay.
    118      */
    119     boolean mSurfaceDestroyDeferred;
    120 
    121     float mShownAlpha = 0;
    122     float mAlpha = 0;
    123     float mLastAlpha = 0;
    124 
    125     boolean mHasClipRect;
    126     Rect mClipRect = new Rect();
    127     Rect mTmpClipRect = new Rect();
    128     Rect mLastClipRect = new Rect();
    129 
    130     // Used to save animation distances between the time they are calculated and when they are
    131     // used.
    132     int mAnimDw;
    133     int mAnimDh;
    134     float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
    135     float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
    136 
    137     boolean mHaveMatrix;
    138 
    139     // For debugging, this is the last information given to the surface flinger.
    140     boolean mSurfaceShown;
    141     float mSurfaceX, mSurfaceY;
    142     float mSurfaceW, mSurfaceH;
    143     int mSurfaceLayer;
    144     float mSurfaceAlpha;
    145 
    146     // Set to true if, when the window gets displayed, it should perform
    147     // an enter animation.
    148     boolean mEnterAnimationPending;
    149 
    150     /** Used to indicate that this window is undergoing an enter animation. Used for system
    151      * windows to make the callback to View.dispatchOnWindowShownCallback(). Set when the
    152      * window is first added or shown, cleared when the callback has been made. */
    153     boolean mEnteringAnimation;
    154 
    155     boolean mKeyguardGoingAwayAnimation;
    156 
    157     /** This is set when there is no Surface */
    158     static final int NO_SURFACE = 0;
    159     /** This is set after the Surface has been created but before the window has been drawn. During
    160      * this time the surface is hidden. */
    161     static final int DRAW_PENDING = 1;
    162     /** This is set after the window has finished drawing for the first time but before its surface
    163      * is shown.  The surface will be displayed when the next layout is run. */
    164     static final int COMMIT_DRAW_PENDING = 2;
    165     /** This is set during the time after the window's drawing has been committed, and before its
    166      * surface is actually shown.  It is used to delay showing the surface until all windows in a
    167      * token are ready to be shown. */
    168     static final int READY_TO_SHOW = 3;
    169     /** Set when the window has been shown in the screen the first time. */
    170     static final int HAS_DRAWN = 4;
    171 
    172     private static final int SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN =
    173             View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
    174 
    175     String drawStateToString() {
    176         switch (mDrawState) {
    177             case NO_SURFACE: return "NO_SURFACE";
    178             case DRAW_PENDING: return "DRAW_PENDING";
    179             case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
    180             case READY_TO_SHOW: return "READY_TO_SHOW";
    181             case HAS_DRAWN: return "HAS_DRAWN";
    182             default: return Integer.toString(mDrawState);
    183         }
    184     }
    185     int mDrawState;
    186 
    187     /** Was this window last hidden? */
    188     boolean mLastHidden;
    189 
    190     int mAttrType;
    191 
    192     public WindowStateAnimator(final WindowState win) {
    193         final WindowManagerService service = win.mService;
    194 
    195         mService = service;
    196         mAnimator = service.mAnimator;
    197         mPolicy = service.mPolicy;
    198         mContext = service.mContext;
    199         final DisplayContent displayContent = win.getDisplayContent();
    200         if (displayContent != null) {
    201             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
    202             mAnimDw = displayInfo.appWidth;
    203             mAnimDh = displayInfo.appHeight;
    204         } else {
    205             Slog.w(TAG, "WindowStateAnimator ctor: Display has been removed");
    206             // This is checked on return and dealt with.
    207         }
    208 
    209         mWin = win;
    210         mAttachedWinAnimator = win.mAttachedWindow == null
    211                 ? null : win.mAttachedWindow.mWinAnimator;
    212         mAppAnimator = win.mAppToken == null ? null : win.mAppToken.mAppAnimator;
    213         mSession = win.mSession;
    214         mAttrType = win.mAttrs.type;
    215         mIsWallpaper = win.mIsWallpaper;
    216     }
    217 
    218     public void setAnimation(Animation anim, long startTime) {
    219         if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim);
    220         mAnimating = false;
    221         mLocalAnimating = false;
    222         mAnimation = anim;
    223         mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
    224         mAnimation.scaleCurrentDuration(mService.getWindowAnimationScaleLocked());
    225         // Start out animation gone if window is gone, or visible if window is visible.
    226         mTransformation.clear();
    227         mTransformation.setAlpha(mLastHidden ? 0 : 1);
    228         mHasLocalTransformation = true;
    229         mAnimationStartTime = startTime;
    230     }
    231 
    232     public void setAnimation(Animation anim) {
    233         setAnimation(anim, -1);
    234     }
    235 
    236     public void clearAnimation() {
    237         if (mAnimation != null) {
    238             mAnimating = true;
    239             mLocalAnimating = false;
    240             mAnimation.cancel();
    241             mAnimation = null;
    242             mKeyguardGoingAwayAnimation = false;
    243         }
    244     }
    245 
    246     /** Is the window or its container currently animating? */
    247     boolean isAnimating() {
    248         return mAnimation != null
    249                 || (mAttachedWinAnimator != null && mAttachedWinAnimator.mAnimation != null)
    250                 || (mAppAnimator != null &&
    251                         (mAppAnimator.animation != null
    252                                 || mAppAnimator.mAppToken.inPendingTransaction));
    253     }
    254 
    255     /** Is the window animating the DummyAnimation? */
    256     boolean isDummyAnimation() {
    257         return mAppAnimator != null
    258                 && mAppAnimator.animation == AppWindowAnimator.sDummyAnimation;
    259     }
    260 
    261     /** Is this window currently animating? */
    262     boolean isWindowAnimating() {
    263         return mAnimation != null;
    264     }
    265 
    266     void cancelExitAnimationForNextAnimationLocked() {
    267         if (mAnimation != null) {
    268             mAnimation.cancel();
    269             mAnimation = null;
    270             mLocalAnimating = false;
    271             destroySurfaceLocked();
    272         }
    273     }
    274 
    275     private boolean stepAnimation(long currentTime) {
    276         if ((mAnimation == null) || !mLocalAnimating) {
    277             return false;
    278         }
    279         mTransformation.clear();
    280         final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
    281         if (false && DEBUG_ANIM) Slog.v(
    282             TAG, "Stepped animation in " + this +
    283             ": more=" + more + ", xform=" + mTransformation);
    284         return more;
    285     }
    286 
    287     // This must be called while inside a transaction.  Returns true if
    288     // there is more animation to run.
    289     boolean stepAnimationLocked(long currentTime) {
    290         // Save the animation state as it was before this step so WindowManagerService can tell if
    291         // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
    292         mWasAnimating = mAnimating;
    293         final DisplayContent displayContent = mWin.getDisplayContent();
    294         if (displayContent != null && mService.okToDisplay()) {
    295             // We will run animations as long as the display isn't frozen.
    296 
    297             if (mWin.isDrawnLw() && mAnimation != null) {
    298                 mHasTransformation = true;
    299                 mHasLocalTransformation = true;
    300                 if (!mLocalAnimating) {
    301                     if (DEBUG_ANIM) Slog.v(
    302                         TAG, "Starting animation in " + this +
    303                         " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
    304                         " wh=" + mWin.mFrame.height() +
    305                         " dw=" + mAnimDw + " dh=" + mAnimDh +
    306                         " scale=" + mService.getWindowAnimationScaleLocked());
    307                     mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
    308                             mAnimDw, mAnimDh);
    309                     final DisplayInfo displayInfo = displayContent.getDisplayInfo();
    310                     mAnimDw = displayInfo.appWidth;
    311                     mAnimDh = displayInfo.appHeight;
    312                     mAnimation.setStartTime(mAnimationStartTime != -1
    313                             ? mAnimationStartTime
    314                             : currentTime);
    315                     mLocalAnimating = true;
    316                     mAnimating = true;
    317                 }
    318                 if ((mAnimation != null) && mLocalAnimating) {
    319                     mLastAnimationTime = currentTime;
    320                     if (stepAnimation(currentTime)) {
    321                         return true;
    322                     }
    323                 }
    324                 if (DEBUG_ANIM) Slog.v(
    325                     TAG, "Finished animation in " + this +
    326                     " @ " + currentTime);
    327                 //WindowManagerService.this.dump();
    328             }
    329             mHasLocalTransformation = false;
    330             if ((!mLocalAnimating || mAnimationIsEntrance) && mAppAnimator != null
    331                     && mAppAnimator.animation != null) {
    332                 // When our app token is animating, we kind-of pretend like
    333                 // we are as well.  Note the mLocalAnimating mAnimationIsEntrance
    334                 // part of this check means that we will only do this if
    335                 // our window is not currently exiting, or it is not
    336                 // locally animating itself.  The idea being that one that
    337                 // is exiting and doing a local animation should be removed
    338                 // once that animation is done.
    339                 mAnimating = true;
    340                 mHasTransformation = true;
    341                 mTransformation.clear();
    342                 return false;
    343             } else if (mHasTransformation) {
    344                 // Little trick to get through the path below to act like
    345                 // we have finished an animation.
    346                 mAnimating = true;
    347             } else if (isAnimating()) {
    348                 mAnimating = true;
    349             }
    350         } else if (mAnimation != null) {
    351             // If the display is frozen, and there is a pending animation,
    352             // clear it and make sure we run the cleanup code.
    353             mAnimating = true;
    354         }
    355 
    356         if (!mAnimating && !mLocalAnimating) {
    357             return false;
    358         }
    359 
    360         // Done animating, clean up.
    361         if (DEBUG_ANIM) Slog.v(
    362             TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
    363             + ", reportedVisible="
    364             + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
    365 
    366         mAnimating = false;
    367         mKeyguardGoingAwayAnimation = false;
    368         mLocalAnimating = false;
    369         if (mAnimation != null) {
    370             mAnimation.cancel();
    371             mAnimation = null;
    372         }
    373         if (mAnimator.mWindowDetachedWallpaper == mWin) {
    374             mAnimator.mWindowDetachedWallpaper = null;
    375         }
    376         mAnimLayer = mWin.mLayer;
    377         if (mWin.mIsImWindow) {
    378             mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
    379         } else if (mIsWallpaper) {
    380             mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
    381         }
    382         if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
    383                 + " anim layer: " + mAnimLayer);
    384         mHasTransformation = false;
    385         mHasLocalTransformation = false;
    386         if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) {
    387             if (DEBUG_VISIBILITY) {
    388                 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
    389                         + mWin.mPolicyVisibilityAfterAnim);
    390             }
    391             mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim;
    392             if (displayContent != null) {
    393                 displayContent.layoutNeeded = true;
    394             }
    395             if (!mWin.mPolicyVisibility) {
    396                 if (mService.mCurrentFocus == mWin) {
    397                     if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.i(TAG,
    398                             "setAnimationLocked: setting mFocusMayChange true");
    399                     mService.mFocusMayChange = true;
    400                 }
    401                 // Window is no longer visible -- make sure if we were waiting
    402                 // for it to be displayed before enabling the display, that
    403                 // we allow the display to be enabled now.
    404                 mService.enableScreenIfNeededLocked();
    405             }
    406         }
    407         mTransformation.clear();
    408         if (mDrawState == HAS_DRAWN
    409                 && mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
    410                 && mWin.mAppToken != null
    411                 && mWin.mAppToken.firstWindowDrawn
    412                 && mWin.mAppToken.startingData != null) {
    413             if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
    414                     + mWin.mToken + ": first real window done animating");
    415             mService.mFinishedStarting.add(mWin.mAppToken);
    416             mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
    417         } else if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.mPolicyVisibility) {
    418             // Upon completion of a not-visible to visible status bar animation a relayout is
    419             // required.
    420             if (displayContent != null) {
    421                 displayContent.layoutNeeded = true;
    422             }
    423         }
    424 
    425         finishExit();
    426         final int displayId = mWin.getDisplayId();
    427         mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
    428         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
    429                 "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
    430 
    431         if (mWin.mAppToken != null) {
    432             mWin.mAppToken.updateReportedVisibilityLocked();
    433         }
    434 
    435         return false;
    436     }
    437 
    438     void finishExit() {
    439         if (WindowManagerService.DEBUG_ANIM) Slog.v(
    440                 TAG, "finishExit in " + this
    441                 + ": exiting=" + mWin.mExiting
    442                 + " remove=" + mWin.mRemoveOnExit
    443                 + " windowAnimating=" + isWindowAnimating());
    444 
    445         final int N = mWin.mChildWindows.size();
    446         for (int i=0; i<N; i++) {
    447             mWin.mChildWindows.get(i).mWinAnimator.finishExit();
    448         }
    449 
    450         if (mEnteringAnimation && mWin.mAppToken == null) {
    451             try {
    452                 mEnteringAnimation = false;
    453                 mWin.mClient.dispatchWindowShown();
    454             } catch (RemoteException e) {
    455             }
    456         }
    457 
    458         if (!isWindowAnimating()) {
    459             //TODO (multidisplay): Accessibility is supported only for the default display.
    460             if (mService.mAccessibilityController != null
    461                     && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
    462                 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
    463             }
    464         }
    465 
    466         if (!mWin.mExiting) {
    467             return;
    468         }
    469 
    470         if (isWindowAnimating()) {
    471             return;
    472         }
    473 
    474         if (WindowManagerService.localLOGV) Slog.v(
    475                 TAG, "Exit animation finished in " + this
    476                 + ": remove=" + mWin.mRemoveOnExit);
    477         if (mSurfaceControl != null) {
    478             mService.mDestroySurface.add(mWin);
    479             mWin.mDestroying = true;
    480             if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(
    481                 mWin, "HIDE (finishExit)", null);
    482             hide();
    483         }
    484         mWin.mExiting = false;
    485         if (mWin.mRemoveOnExit) {
    486             mService.mPendingRemove.add(mWin);
    487             mWin.mRemoveOnExit = false;
    488         }
    489         mAnimator.hideWallpapersLocked(mWin);
    490     }
    491 
    492     void hide() {
    493         if (!mLastHidden) {
    494             //dump();
    495             mLastHidden = true;
    496             if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
    497                     "HIDE (performLayout)", null);
    498             if (mSurfaceControl != null) {
    499                 mSurfaceShown = false;
    500                 try {
    501                     mSurfaceControl.hide();
    502                 } catch (RuntimeException e) {
    503                     Slog.w(TAG, "Exception hiding surface in " + mWin);
    504                 }
    505             }
    506         }
    507     }
    508 
    509     boolean finishDrawingLocked() {
    510         final boolean startingWindow =
    511                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
    512         if (DEBUG_STARTING_WINDOW && startingWindow) {
    513             Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
    514                     + drawStateToString());
    515         }
    516         if (mDrawState == DRAW_PENDING) {
    517             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
    518                 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
    519                         + mSurfaceControl);
    520             if (DEBUG_STARTING_WINDOW && startingWindow) {
    521                 Slog.v(TAG, "Draw state now committed in " + mWin);
    522             }
    523             mDrawState = COMMIT_DRAW_PENDING;
    524             return true;
    525         }
    526         return false;
    527     }
    528 
    529     // This must be called while inside a transaction.
    530     boolean commitFinishDrawingLocked(long currentTime) {
    531         if (DEBUG_STARTING_WINDOW &&
    532                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
    533             Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
    534                     + drawStateToString());
    535         }
    536         if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
    537             return false;
    538         }
    539         if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
    540             Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceControl);
    541         }
    542         mDrawState = READY_TO_SHOW;
    543         final AppWindowToken atoken = mWin.mAppToken;
    544         if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
    545             performShowLocked();
    546         }
    547         return true;
    548     }
    549 
    550     static class SurfaceTrace extends SurfaceControl {
    551         private final static String SURFACE_TAG = "SurfaceTrace";
    552         private final static boolean logSurfaceTrace = DEBUG_SURFACE_TRACE;
    553         final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
    554 
    555         private float mSurfaceTraceAlpha = 0;
    556         private int mLayer;
    557         private final PointF mPosition = new PointF();
    558         private final Point mSize = new Point();
    559         private final Rect mWindowCrop = new Rect();
    560         private boolean mShown = false;
    561         private int mLayerStack;
    562         private boolean mIsOpaque;
    563         private float mDsdx, mDtdx, mDsdy, mDtdy;
    564         private final String mName;
    565 
    566         public SurfaceTrace(SurfaceSession s,
    567                        String name, int w, int h, int format, int flags)
    568                    throws OutOfResourcesException {
    569             super(s, name, w, h, format, flags);
    570             mName = name != null ? name : "Not named";
    571             mSize.set(w, h);
    572             if (logSurfaceTrace) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
    573                     + Debug.getCallers(3));
    574             synchronized (sSurfaces) {
    575                 sSurfaces.add(0, this);
    576             }
    577         }
    578 
    579         @Override
    580         public void setAlpha(float alpha) {
    581             if (mSurfaceTraceAlpha != alpha) {
    582                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this +
    583                         ". Called by " + Debug.getCallers(3));
    584                 mSurfaceTraceAlpha = alpha;
    585             }
    586             super.setAlpha(alpha);
    587         }
    588 
    589         @Override
    590         public void setLayer(int zorder) {
    591             if (zorder != mLayer) {
    592                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this
    593                         + ". Called by " + Debug.getCallers(3));
    594                 mLayer = zorder;
    595             }
    596             super.setLayer(zorder);
    597 
    598             synchronized (sSurfaces) {
    599                 sSurfaces.remove(this);
    600                 int i;
    601                 for (i = sSurfaces.size() - 1; i >= 0; i--) {
    602                     SurfaceTrace s = sSurfaces.get(i);
    603                     if (s.mLayer < zorder) {
    604                         break;
    605                     }
    606                 }
    607                 sSurfaces.add(i + 1, this);
    608             }
    609         }
    610 
    611         @Override
    612         public void setPosition(float x, float y) {
    613             if (x != mPosition.x || y != mPosition.y) {
    614                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:"
    615                         + this + ". Called by " + Debug.getCallers(3));
    616                 mPosition.set(x, y);
    617             }
    618             super.setPosition(x, y);
    619         }
    620 
    621         @Override
    622         public void setSize(int w, int h) {
    623             if (w != mSize.x || h != mSize.y) {
    624                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"
    625                         + this + ". Called by " + Debug.getCallers(3));
    626                 mSize.set(w, h);
    627             }
    628             super.setSize(w, h);
    629         }
    630 
    631         @Override
    632         public void setWindowCrop(Rect crop) {
    633             if (crop != null) {
    634                 if (!crop.equals(mWindowCrop)) {
    635                     if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setWindowCrop("
    636                             + crop.toShortString() + "): OLD:" + this + ". Called by "
    637                             + Debug.getCallers(3));
    638                     mWindowCrop.set(crop);
    639                 }
    640             }
    641             super.setWindowCrop(crop);
    642         }
    643 
    644         @Override
    645         public void setLayerStack(int layerStack) {
    646             if (layerStack != mLayerStack) {
    647                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
    648                         + this + ". Called by " + Debug.getCallers(3));
    649                 mLayerStack = layerStack;
    650             }
    651             super.setLayerStack(layerStack);
    652         }
    653 
    654         @Override
    655         public void setOpaque(boolean isOpaque) {
    656             if (isOpaque != mIsOpaque) {
    657                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:"
    658                         + this + ". Called by " + Debug.getCallers(3));
    659                 mIsOpaque = isOpaque;
    660             }
    661             super.setOpaque(isOpaque);
    662         }
    663 
    664         @Override
    665         public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
    666             if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
    667                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
    668                         + dsdy + "," + dtdy + "): OLD:" + this + ". Called by "
    669                         + Debug.getCallers(3));
    670                 mDsdx = dsdx;
    671                 mDtdx = dtdx;
    672                 mDsdy = dsdy;
    673                 mDtdy = dtdy;
    674             }
    675             super.setMatrix(dsdx, dtdx, dsdy, dtdy);
    676         }
    677 
    678         @Override
    679         public void hide() {
    680             if (mShown) {
    681                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
    682                         + Debug.getCallers(3));
    683                 mShown = false;
    684             }
    685             super.hide();
    686         }
    687 
    688         @Override
    689         public void show() {
    690             if (!mShown) {
    691                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
    692                         + Debug.getCallers(3));
    693                 mShown = true;
    694             }
    695             super.show();
    696         }
    697 
    698         @Override
    699         public void destroy() {
    700             super.destroy();
    701             if (logSurfaceTrace) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
    702                     + Debug.getCallers(3));
    703             synchronized (sSurfaces) {
    704                 sSurfaces.remove(this);
    705             }
    706         }
    707 
    708         @Override
    709         public void release() {
    710             super.release();
    711             if (logSurfaceTrace) Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
    712                     + Debug.getCallers(3));
    713             synchronized (sSurfaces) {
    714                 sSurfaces.remove(this);
    715             }
    716         }
    717 
    718         static void dumpAllSurfaces(PrintWriter pw, String header) {
    719             synchronized (sSurfaces) {
    720                 final int N = sSurfaces.size();
    721                 if (N <= 0) {
    722                     return;
    723                 }
    724                 if (header != null) {
    725                     pw.println(header);
    726                 }
    727                 pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)");
    728                 for (int i = 0; i < N; i++) {
    729                     SurfaceTrace s = sSurfaces.get(i);
    730                     pw.print("  Surface #"); pw.print(i); pw.print(": #");
    731                             pw.print(Integer.toHexString(System.identityHashCode(s)));
    732                             pw.print(" "); pw.println(s.mName);
    733                     pw.print("    mLayerStack="); pw.print(s.mLayerStack);
    734                             pw.print(" mLayer="); pw.println(s.mLayer);
    735                     pw.print("    mShown="); pw.print(s.mShown); pw.print(" mAlpha=");
    736                             pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque=");
    737                             pw.println(s.mIsOpaque);
    738                     pw.print("    mPosition="); pw.print(s.mPosition.x); pw.print(",");
    739                             pw.print(s.mPosition.y);
    740                             pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
    741                             pw.println(s.mSize.y);
    742                     pw.print("    mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
    743                     pw.print("    Transform: ("); pw.print(s.mDsdx); pw.print(", ");
    744                             pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
    745                             pw.print(", "); pw.print(s.mDtdy); pw.println(")");
    746                 }
    747             }
    748         }
    749 
    750         @Override
    751         public String toString() {
    752             return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
    753                     + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
    754                     + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
    755                     + " " + mSize.x + "x" + mSize.y
    756                     + " crop=" + mWindowCrop.toShortString()
    757                     + " opaque=" + mIsOpaque
    758                     + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
    759         }
    760     }
    761 
    762     SurfaceControl createSurfaceLocked() {
    763         final WindowState w = mWin;
    764         if (mSurfaceControl == null) {
    765             if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
    766                     "createSurface " + this + ": mDrawState=DRAW_PENDING");
    767             mDrawState = DRAW_PENDING;
    768             if (w.mAppToken != null) {
    769                 if (w.mAppToken.mAppAnimator.animation == null) {
    770                     w.mAppToken.allDrawn = false;
    771                     w.mAppToken.deferClearAllDrawn = false;
    772                 } else {
    773                     // Currently animating, persist current state of allDrawn until animation
    774                     // is complete.
    775                     w.mAppToken.deferClearAllDrawn = true;
    776                 }
    777             }
    778 
    779             mService.makeWindowFreezingScreenIfNeededLocked(w);
    780 
    781             int flags = SurfaceControl.HIDDEN;
    782             final WindowManager.LayoutParams attrs = w.mAttrs;
    783 
    784             if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
    785                 flags |= SurfaceControl.SECURE;
    786             }
    787 
    788             if (mService.isScreenCaptureDisabledLocked(UserHandle.getUserId(mWin.mOwnerUid))) {
    789                 flags |= SurfaceControl.SECURE;
    790             }
    791 
    792             int width;
    793             int height;
    794             if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
    795                 // for a scaled surface, we always want the requested
    796                 // size.
    797                 width = w.mRequestedWidth;
    798                 height = w.mRequestedHeight;
    799             } else {
    800                 width = w.mCompatFrame.width();
    801                 height = w.mCompatFrame.height();
    802             }
    803 
    804             // Something is wrong and SurfaceFlinger will not like this,
    805             // try to revert to sane values
    806             if (width <= 0) {
    807                 width = 1;
    808             }
    809             if (height <= 0) {
    810                 height = 1;
    811             }
    812 
    813             float left = w.mFrame.left + w.mXOffset;
    814             float top = w.mFrame.top + w.mYOffset;
    815 
    816             // Adjust for surface insets.
    817             width += attrs.surfaceInsets.left + attrs.surfaceInsets.right;
    818             height += attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
    819             left -= attrs.surfaceInsets.left;
    820             top -= attrs.surfaceInsets.top;
    821 
    822             if (DEBUG_VISIBILITY) {
    823                 Slog.v(TAG, "Creating surface in session "
    824                         + mSession.mSurfaceSession + " window " + this
    825                         + " w=" + width + " h=" + height
    826                         + " x=" + left + " y=" + top
    827                         + " format=" + attrs.format + " flags=" + flags);
    828             }
    829 
    830             // We may abort, so initialize to defaults.
    831             mSurfaceShown = false;
    832             mSurfaceLayer = 0;
    833             mSurfaceAlpha = 0;
    834             mSurfaceX = 0;
    835             mSurfaceY = 0;
    836             w.mLastSystemDecorRect.set(0, 0, 0, 0);
    837             mLastClipRect.set(0, 0, 0, 0);
    838 
    839             // Set up surface control with initial size.
    840             try {
    841                 mSurfaceW = width;
    842                 mSurfaceH = height;
    843 
    844                 final boolean isHwAccelerated = (attrs.flags &
    845                         WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
    846                 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
    847                 if (!PixelFormat.formatHasAlpha(attrs.format)
    848                         && attrs.surfaceInsets.left == 0
    849                         && attrs.surfaceInsets.top == 0
    850                         && attrs.surfaceInsets.right == 0
    851                         && attrs.surfaceInsets.bottom  == 0) {
    852                     flags |= SurfaceControl.OPAQUE;
    853                 }
    854 
    855                 if (DEBUG_SURFACE_TRACE) {
    856                     mSurfaceControl = new SurfaceTrace(
    857                             mSession.mSurfaceSession,
    858                             attrs.getTitle().toString(),
    859                             width, height, format, flags);
    860                 } else {
    861                     mSurfaceControl = new SurfaceControl(
    862                         mSession.mSurfaceSession,
    863                         attrs.getTitle().toString(),
    864                         width, height, format, flags);
    865                 }
    866 
    867                 w.mHasSurface = true;
    868 
    869                 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
    870                     Slog.i(TAG, "  CREATE SURFACE "
    871                             + mSurfaceControl + " IN SESSION "
    872                             + mSession.mSurfaceSession
    873                             + ": pid=" + mSession.mPid + " format="
    874                             + attrs.format + " flags=0x"
    875                             + Integer.toHexString(flags)
    876                             + " / " + this);
    877                 }
    878             } catch (OutOfResourcesException e) {
    879                 w.mHasSurface = false;
    880                 Slog.w(TAG, "OutOfResourcesException creating surface");
    881                 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
    882                 mDrawState = NO_SURFACE;
    883                 return null;
    884             } catch (Exception e) {
    885                 w.mHasSurface = false;
    886                 Slog.e(TAG, "Exception creating surface", e);
    887                 mDrawState = NO_SURFACE;
    888                 return null;
    889             }
    890 
    891             if (WindowManagerService.localLOGV) {
    892                 Slog.v(TAG, "Got surface: " + mSurfaceControl
    893                         + ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
    894                         + ", animLayer=" + mAnimLayer);
    895             }
    896 
    897             if (SHOW_LIGHT_TRANSACTIONS) {
    898                 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
    899                 WindowManagerService.logSurface(w, "CREATE pos=("
    900                         + w.mFrame.left + "," + w.mFrame.top + ") ("
    901                         + w.mCompatFrame.width() + "x" + w.mCompatFrame.height()
    902                         + "), layer=" + mAnimLayer + " HIDE", null);
    903             }
    904 
    905             // Start a new transaction and apply position & offset.
    906             SurfaceControl.openTransaction();
    907             try {
    908                 mSurfaceX = left;
    909                 mSurfaceY = top;
    910 
    911                 try {
    912                     mSurfaceControl.setPosition(left, top);
    913                     mSurfaceLayer = mAnimLayer;
    914                     final DisplayContent displayContent = w.getDisplayContent();
    915                     if (displayContent != null) {
    916                         mSurfaceControl.setLayerStack(displayContent.getDisplay().getLayerStack());
    917                     }
    918                     mSurfaceControl.setLayer(mAnimLayer);
    919                     mSurfaceControl.setAlpha(0);
    920                     mSurfaceShown = false;
    921                 } catch (RuntimeException e) {
    922                     Slog.w(TAG, "Error creating surface in " + w, e);
    923                     mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
    924                 }
    925                 mLastHidden = true;
    926             } finally {
    927                 SurfaceControl.closeTransaction();
    928                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
    929                         "<<< CLOSE TRANSACTION createSurfaceLocked");
    930             }
    931             if (WindowManagerService.localLOGV) Slog.v(
    932                     TAG, "Created surface " + this);
    933         }
    934         return mSurfaceControl;
    935     }
    936 
    937     void destroySurfaceLocked() {
    938         if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) {
    939             mWin.mAppToken.startingDisplayed = false;
    940         }
    941 
    942         if (mSurfaceControl != null) {
    943 
    944             int i = mWin.mChildWindows.size();
    945             while (i > 0) {
    946                 i--;
    947                 WindowState c = mWin.mChildWindows.get(i);
    948                 c.mAttachedHidden = true;
    949             }
    950 
    951             try {
    952                 if (DEBUG_VISIBILITY) {
    953                     RuntimeException e = null;
    954                     if (!WindowManagerService.HIDE_STACK_CRAWLS) {
    955                         e = new RuntimeException();
    956                         e.fillInStackTrace();
    957                     }
    958                     Slog.w(TAG, "Window " + this + " destroying surface "
    959                             + mSurfaceControl + ", session " + mSession, e);
    960                 }
    961                 if (mSurfaceDestroyDeferred) {
    962                     if (mSurfaceControl != null && mPendingDestroySurface != mSurfaceControl) {
    963                         if (mPendingDestroySurface != null) {
    964                             if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
    965                                 RuntimeException e = null;
    966                                 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
    967                                     e = new RuntimeException();
    968                                     e.fillInStackTrace();
    969                                 }
    970                                 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
    971                             }
    972                             mPendingDestroySurface.destroy();
    973                         }
    974                         mPendingDestroySurface = mSurfaceControl;
    975                     }
    976                 } else {
    977                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
    978                         RuntimeException e = null;
    979                         if (!WindowManagerService.HIDE_STACK_CRAWLS) {
    980                             e = new RuntimeException();
    981                             e.fillInStackTrace();
    982                         }
    983                         WindowManagerService.logSurface(mWin, "DESTROY", e);
    984                     }
    985                     mSurfaceControl.destroy();
    986                 }
    987                 mAnimator.hideWallpapersLocked(mWin);
    988             } catch (RuntimeException e) {
    989                 Slog.w(TAG, "Exception thrown when destroying Window " + this
    990                     + " surface " + mSurfaceControl + " session " + mSession
    991                     + ": " + e.toString());
    992             }
    993 
    994             mSurfaceShown = false;
    995             mSurfaceControl = null;
    996             mWin.mHasSurface = false;
    997             mDrawState = NO_SURFACE;
    998         }
    999     }
   1000 
   1001     void destroyDeferredSurfaceLocked() {
   1002         try {
   1003             if (mPendingDestroySurface != null) {
   1004                 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
   1005                     RuntimeException e = null;
   1006                     if (!WindowManagerService.HIDE_STACK_CRAWLS) {
   1007                         e = new RuntimeException();
   1008                         e.fillInStackTrace();
   1009                     }
   1010                     WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
   1011                 }
   1012                 mPendingDestroySurface.destroy();
   1013                 mAnimator.hideWallpapersLocked(mWin);
   1014             }
   1015         } catch (RuntimeException e) {
   1016             Slog.w(TAG, "Exception thrown when destroying Window "
   1017                     + this + " surface " + mPendingDestroySurface
   1018                     + " session " + mSession + ": " + e.toString());
   1019         }
   1020         mSurfaceDestroyDeferred = false;
   1021         mPendingDestroySurface = null;
   1022     }
   1023 
   1024     void computeShownFrameLocked() {
   1025         final boolean selfTransformation = mHasLocalTransformation;
   1026         Transformation attachedTransformation =
   1027                 (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation)
   1028                 ? mAttachedWinAnimator.mTransformation : null;
   1029         Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation)
   1030                 ? mAppAnimator.transformation : null;
   1031 
   1032         // Wallpapers are animated based on the "real" window they
   1033         // are currently targeting.
   1034         final WindowState wallpaperTarget = mService.mWallpaperTarget;
   1035         if (mIsWallpaper && wallpaperTarget != null && mService.mAnimateWallpaperWithTarget) {
   1036             final WindowStateAnimator wallpaperAnimator = wallpaperTarget.mWinAnimator;
   1037             if (wallpaperAnimator.mHasLocalTransformation &&
   1038                     wallpaperAnimator.mAnimation != null &&
   1039                     !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
   1040                 attachedTransformation = wallpaperAnimator.mTransformation;
   1041                 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
   1042                     Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
   1043                 }
   1044             }
   1045             final AppWindowAnimator wpAppAnimator = wallpaperTarget.mAppToken == null ?
   1046                     null : wallpaperTarget.mAppToken.mAppAnimator;
   1047                 if (wpAppAnimator != null && wpAppAnimator.hasTransformation
   1048                     && wpAppAnimator.animation != null
   1049                     && !wpAppAnimator.animation.getDetachWallpaper()) {
   1050                 appTransformation = wpAppAnimator.transformation;
   1051                 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
   1052                     Slog.v(TAG, "WP target app xform: " + appTransformation);
   1053                 }
   1054             }
   1055         }
   1056 
   1057         final int displayId = mWin.getDisplayId();
   1058         final ScreenRotationAnimation screenRotationAnimation =
   1059                 mAnimator.getScreenRotationAnimationLocked(displayId);
   1060         final boolean screenAnimation =
   1061                 screenRotationAnimation != null && screenRotationAnimation.isAnimating();
   1062         if (selfTransformation || attachedTransformation != null
   1063                 || appTransformation != null || screenAnimation) {
   1064             // cache often used attributes locally
   1065             final Rect frame = mWin.mFrame;
   1066             final float tmpFloats[] = mService.mTmpFloats;
   1067             final Matrix tmpMatrix = mWin.mTmpMatrix;
   1068 
   1069             // Compute the desired transformation.
   1070             if (screenAnimation && screenRotationAnimation.isRotating()) {
   1071                 // If we are doing a screen animation, the global rotation
   1072                 // applied to windows can result in windows that are carefully
   1073                 // aligned with each other to slightly separate, allowing you
   1074                 // to see what is behind them.  An unsightly mess.  This...
   1075                 // thing...  magically makes it call good: scale each window
   1076                 // slightly (two pixels larger in each dimension, from the
   1077                 // window's center).
   1078                 final float w = frame.width();
   1079                 final float h = frame.height();
   1080                 if (w>=1 && h>=1) {
   1081                     tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
   1082                 } else {
   1083                     tmpMatrix.reset();
   1084                 }
   1085             } else {
   1086                 tmpMatrix.reset();
   1087             }
   1088             tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
   1089             if (selfTransformation) {
   1090                 tmpMatrix.postConcat(mTransformation.getMatrix());
   1091             }
   1092             tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
   1093             if (attachedTransformation != null) {
   1094                 tmpMatrix.postConcat(attachedTransformation.getMatrix());
   1095             }
   1096             if (appTransformation != null) {
   1097                 tmpMatrix.postConcat(appTransformation.getMatrix());
   1098             }
   1099             if (mAnimator.mUniverseBackground != null) {
   1100                 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
   1101             }
   1102             if (screenAnimation) {
   1103                 tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
   1104             }
   1105 
   1106             //TODO (multidisplay): Magnification is supported only for the default display.
   1107             if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
   1108                 MagnificationSpec spec = mService.mAccessibilityController
   1109                         .getMagnificationSpecForWindowLocked(mWin);
   1110                 if (spec != null && !spec.isNop()) {
   1111                     tmpMatrix.postScale(spec.scale, spec.scale);
   1112                     tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
   1113                 }
   1114             }
   1115 
   1116             // "convert" it into SurfaceFlinger's format
   1117             // (a 2x2 matrix + an offset)
   1118             // Here we must not transform the position of the surface
   1119             // since it is already included in the transformation.
   1120             //Slog.i(TAG, "Transform: " + matrix);
   1121 
   1122             mHaveMatrix = true;
   1123             tmpMatrix.getValues(tmpFloats);
   1124             mDsDx = tmpFloats[Matrix.MSCALE_X];
   1125             mDtDx = tmpFloats[Matrix.MSKEW_Y];
   1126             mDsDy = tmpFloats[Matrix.MSKEW_X];
   1127             mDtDy = tmpFloats[Matrix.MSCALE_Y];
   1128             float x = tmpFloats[Matrix.MTRANS_X];
   1129             float y = tmpFloats[Matrix.MTRANS_Y];
   1130             int w = frame.width();
   1131             int h = frame.height();
   1132             mWin.mShownFrame.set(x, y, x+w, y+h);
   1133 
   1134             // Now set the alpha...  but because our current hardware
   1135             // can't do alpha transformation on a non-opaque surface,
   1136             // turn it off if we are running an animation that is also
   1137             // transforming since it is more important to have that
   1138             // animation be smooth.
   1139             mShownAlpha = mAlpha;
   1140             mHasClipRect = false;
   1141             if (!mService.mLimitedAlphaCompositing
   1142                     || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
   1143                     || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
   1144                             && x == frame.left && y == frame.top))) {
   1145                 //Slog.i(TAG, "Applying alpha transform");
   1146                 if (selfTransformation) {
   1147                     mShownAlpha *= mTransformation.getAlpha();
   1148                 }
   1149                 if (attachedTransformation != null) {
   1150                     mShownAlpha *= attachedTransformation.getAlpha();
   1151                 }
   1152                 if (appTransformation != null) {
   1153                     mShownAlpha *= appTransformation.getAlpha();
   1154                     if (appTransformation.hasClipRect()) {
   1155                         mClipRect.set(appTransformation.getClipRect());
   1156                         if (mWin.mHScale > 0) {
   1157                             mClipRect.left /= mWin.mHScale;
   1158                             mClipRect.right /= mWin.mHScale;
   1159                         }
   1160                         if (mWin.mVScale > 0) {
   1161                             mClipRect.top /= mWin.mVScale;
   1162                             mClipRect.bottom /= mWin.mVScale;
   1163                         }
   1164                         mHasClipRect = true;
   1165                     }
   1166                 }
   1167                 if (mAnimator.mUniverseBackground != null) {
   1168                     mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
   1169                 }
   1170                 if (screenAnimation) {
   1171                     mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
   1172                 }
   1173             } else {
   1174                 //Slog.i(TAG, "Not applying alpha transform");
   1175             }
   1176 
   1177             if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV)
   1178                     && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
   1179                     TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
   1180                     + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null")
   1181                     + " attached=" + (attachedTransformation == null ?
   1182                             "null" : attachedTransformation.getAlpha())
   1183                     + " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha())
   1184                     + " screen=" + (screenAnimation ?
   1185                             screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
   1186             return;
   1187         } else if (mIsWallpaper && mService.mInnerFields.mWallpaperActionPending) {
   1188             return;
   1189         }
   1190 
   1191         if (WindowManagerService.localLOGV) Slog.v(
   1192                 TAG, "computeShownFrameLocked: " + this +
   1193                 " not attached, mAlpha=" + mAlpha);
   1194 
   1195         final boolean applyUniverseTransformation = (mAnimator.mUniverseBackground != null
   1196                 && mWin.mAttrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND
   1197                 && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer);
   1198         MagnificationSpec spec = null;
   1199         //TODO (multidisplay): Magnification is supported only for the default display.
   1200         if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
   1201             spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
   1202         }
   1203         if (applyUniverseTransformation || spec != null) {
   1204             final Rect frame = mWin.mFrame;
   1205             final float tmpFloats[] = mService.mTmpFloats;
   1206             final Matrix tmpMatrix = mWin.mTmpMatrix;
   1207 
   1208             tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
   1209             tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
   1210 
   1211             if (applyUniverseTransformation) {
   1212                 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
   1213             }
   1214 
   1215             if (spec != null && !spec.isNop()) {
   1216                 tmpMatrix.postScale(spec.scale, spec.scale);
   1217                 tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
   1218             }
   1219 
   1220             tmpMatrix.getValues(tmpFloats);
   1221 
   1222             mHaveMatrix = true;
   1223             mDsDx = tmpFloats[Matrix.MSCALE_X];
   1224             mDtDx = tmpFloats[Matrix.MSKEW_Y];
   1225             mDsDy = tmpFloats[Matrix.MSKEW_X];
   1226             mDtDy = tmpFloats[Matrix.MSCALE_Y];
   1227             float x = tmpFloats[Matrix.MTRANS_X];
   1228             float y = tmpFloats[Matrix.MTRANS_Y];
   1229             int w = frame.width();
   1230             int h = frame.height();
   1231             mWin.mShownFrame.set(x, y, x + w, y + h);
   1232 
   1233             mShownAlpha = mAlpha;
   1234             if (applyUniverseTransformation) {
   1235                 mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
   1236             }
   1237         } else {
   1238             mWin.mShownFrame.set(mWin.mFrame);
   1239             if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
   1240                 mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset);
   1241             }
   1242             mShownAlpha = mAlpha;
   1243             mHaveMatrix = false;
   1244             mDsDx = mWin.mGlobalScale;
   1245             mDtDx = 0;
   1246             mDsDy = 0;
   1247             mDtDy = mWin.mGlobalScale;
   1248         }
   1249     }
   1250 
   1251     void applyDecorRect(final Rect decorRect) {
   1252         final WindowState w = mWin;
   1253         final int width = w.mFrame.width();
   1254         final int height = w.mFrame.height();
   1255 
   1256         // Compute the offset of the window in relation to the decor rect.
   1257         final int left = w.mXOffset + w.mFrame.left;
   1258         final int top = w.mYOffset + w.mFrame.top;
   1259 
   1260         // Initialize the decor rect to the entire frame.
   1261         w.mSystemDecorRect.set(0, 0, width, height);
   1262 
   1263         // Intersect with the decor rect, offsetted by window position.
   1264         w.mSystemDecorRect.intersect(decorRect.left - left, decorRect.top - top,
   1265                 decorRect.right - left, decorRect.bottom - top);
   1266 
   1267         // If size compatibility is being applied to the window, the
   1268         // surface is scaled relative to the screen.  Also apply this
   1269         // scaling to the crop rect.  We aren't using the standard rect
   1270         // scale function because we want to round things to make the crop
   1271         // always round to a larger rect to ensure we don't crop too
   1272         // much and hide part of the window that should be seen.
   1273         if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
   1274             final float scale = w.mInvGlobalScale;
   1275             w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
   1276             w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
   1277             w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
   1278             w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
   1279         }
   1280     }
   1281 
   1282     void updateSurfaceWindowCrop(final boolean recoveringMemory) {
   1283         final WindowState w = mWin;
   1284         final DisplayContent displayContent = w.getDisplayContent();
   1285         if (displayContent == null) {
   1286             return;
   1287         }
   1288 
   1289         // Need to recompute a new system decor rect each time.
   1290         if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
   1291             // Currently can't do this cropping for scaled windows.  We'll
   1292             // just keep the crop rect the same as the source surface.
   1293             w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
   1294         } else if (!w.isDefaultDisplay()) {
   1295             // On a different display there is no system decor.  Crop the window
   1296             // by the screen boundaries.
   1297             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
   1298             w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
   1299             w.mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top,
   1300                     displayInfo.logicalWidth - w.mCompatFrame.left,
   1301                     displayInfo.logicalHeight - w.mCompatFrame.top);
   1302         } else if (w.mLayer >= mService.mSystemDecorLayer) {
   1303             // Above the decor layer is easy, just use the entire window.
   1304             // Unless we have a universe background...  in which case all the
   1305             // windows need to be cropped by the screen, so they don't cover
   1306             // the universe background.
   1307             if (mAnimator.mUniverseBackground == null) {
   1308                 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
   1309             } else {
   1310                 applyDecorRect(mService.mScreenRect);
   1311             }
   1312         } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND
   1313                 || w.mDecorFrame.isEmpty()) {
   1314             // The universe background isn't cropped, nor windows without policy decor.
   1315             w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
   1316         } else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.mAnimating) {
   1317             // If we're animating, the wallpaper crop should only be updated at the end of the
   1318             // animation.
   1319             mTmpClipRect.set(w.mSystemDecorRect);
   1320             applyDecorRect(w.mDecorFrame);
   1321             w.mSystemDecorRect.union(mTmpClipRect);
   1322         } else {
   1323             // Crop to the system decor specified by policy.
   1324             applyDecorRect(w.mDecorFrame);
   1325         }
   1326 
   1327         // By default, the clip rect is the system decor.
   1328         final Rect clipRect = mTmpClipRect;
   1329         clipRect.set(w.mSystemDecorRect);
   1330 
   1331         // Expand the clip rect for surface insets.
   1332         final WindowManager.LayoutParams attrs = w.mAttrs;
   1333         clipRect.left -= attrs.surfaceInsets.left;
   1334         clipRect.top -= attrs.surfaceInsets.top;
   1335         clipRect.right += attrs.surfaceInsets.right;
   1336         clipRect.bottom += attrs.surfaceInsets.bottom;
   1337 
   1338         // If we have an animated clip rect, intersect it with the clip rect.
   1339         if (mHasClipRect) {
   1340             // NOTE: We are adding a temporary workaround due to the status bar
   1341             // not always reporting the correct system decor rect. In such
   1342             // cases, we take into account the specified content insets as well.
   1343             if ((w.mSystemUiVisibility & SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN)
   1344                     == SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN
   1345                     || (w.mAttrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
   1346                 // Don't apply the workaround to apps explicitly requesting
   1347                 // fullscreen layout or when the bars are transparent.
   1348                 clipRect.intersect(mClipRect);
   1349             } else {
   1350                 final int offsetTop = Math.max(clipRect.top, w.mContentInsets.top);
   1351                 clipRect.offset(0, -offsetTop);
   1352                 clipRect.intersect(mClipRect);
   1353                 clipRect.offset(0, offsetTop);
   1354             }
   1355         }
   1356 
   1357         // The clip rect was generated assuming (0,0) as the window origin,
   1358         // so we need to translate to match the actual surface coordinates.
   1359         clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
   1360 
   1361         if (!clipRect.equals(mLastClipRect)) {
   1362             mLastClipRect.set(clipRect);
   1363             try {
   1364                 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
   1365                         "CROP " + clipRect.toShortString(), null);
   1366                 mSurfaceControl.setWindowCrop(clipRect);
   1367             } catch (RuntimeException e) {
   1368                 Slog.w(TAG, "Error setting crop surface of " + w
   1369                         + " crop=" + clipRect.toShortString(), e);
   1370                 if (!recoveringMemory) {
   1371                     mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
   1372                 }
   1373             }
   1374         }
   1375     }
   1376 
   1377     void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
   1378         final WindowState w = mWin;
   1379 
   1380         int width;
   1381         int height;
   1382         if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
   1383             // for a scaled surface, we always want the requested
   1384             // size.
   1385             width  = w.mRequestedWidth;
   1386             height = w.mRequestedHeight;
   1387         } else {
   1388             width = w.mCompatFrame.width();
   1389             height = w.mCompatFrame.height();
   1390         }
   1391 
   1392         // Something is wrong and SurfaceFlinger will not like this,
   1393         // try to revert to sane values
   1394         if (width < 1) {
   1395             width = 1;
   1396         }
   1397         if (height < 1) {
   1398             height = 1;
   1399         }
   1400 
   1401         float left = w.mShownFrame.left;
   1402         float top = w.mShownFrame.top;
   1403 
   1404         // Adjust for surface insets.
   1405         final LayoutParams attrs = w.getAttrs();
   1406         width += attrs.surfaceInsets.left + attrs.surfaceInsets.right;
   1407         height += attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
   1408         left -= attrs.surfaceInsets.left;
   1409         top -= attrs.surfaceInsets.top;
   1410 
   1411         final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
   1412         if (surfaceMoved) {
   1413             mSurfaceX = left;
   1414             mSurfaceY = top;
   1415 
   1416             try {
   1417                 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
   1418                         "POS " + left + ", " + top, null);
   1419                 mSurfaceControl.setPosition(left, top);
   1420             } catch (RuntimeException e) {
   1421                 Slog.w(TAG, "Error positioning surface of " + w
   1422                         + " pos=(" + left + "," + top + ")", e);
   1423                 if (!recoveringMemory) {
   1424                     mService.reclaimSomeSurfaceMemoryLocked(this, "position", true);
   1425                 }
   1426             }
   1427         }
   1428 
   1429         final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
   1430         if (surfaceResized) {
   1431             mSurfaceW = width;
   1432             mSurfaceH = height;
   1433             mSurfaceResized = true;
   1434 
   1435             try {
   1436                 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
   1437                         "SIZE " + width + "x" + height, null);
   1438                 mSurfaceControl.setSize(width, height);
   1439                 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
   1440                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
   1441                 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
   1442                     final TaskStack stack = w.getStack();
   1443                     if (stack != null) {
   1444                         stack.startDimmingIfNeeded(this);
   1445                     }
   1446                 }
   1447             } catch (RuntimeException e) {
   1448                 // If something goes wrong with the surface (such
   1449                 // as running out of memory), don't take down the
   1450                 // entire system.
   1451                 Slog.e(TAG, "Error resizing surface of " + w
   1452                         + " size=(" + width + "x" + height + ")", e);
   1453                 if (!recoveringMemory) {
   1454                     mService.reclaimSomeSurfaceMemoryLocked(this, "size", true);
   1455                 }
   1456             }
   1457         }
   1458 
   1459         updateSurfaceWindowCrop(recoveringMemory);
   1460     }
   1461 
   1462     public void prepareSurfaceLocked(final boolean recoveringMemory) {
   1463         final WindowState w = mWin;
   1464         if (mSurfaceControl == null) {
   1465             if (w.mOrientationChanging) {
   1466                 if (DEBUG_ORIENTATION) {
   1467                     Slog.v(TAG, "Orientation change skips hidden " + w);
   1468                 }
   1469                 w.mOrientationChanging = false;
   1470             }
   1471             return;
   1472         }
   1473 
   1474         boolean displayed = false;
   1475 
   1476         computeShownFrameLocked();
   1477 
   1478         setSurfaceBoundariesLocked(recoveringMemory);
   1479 
   1480         if (mIsWallpaper && !mWin.mWallpaperVisible) {
   1481             // Wallpaper is no longer visible and there is no wp target => hide it.
   1482             hide();
   1483         } else if (w.mAttachedHidden || !w.isOnScreen()) {
   1484             hide();
   1485             mAnimator.hideWallpapersLocked(w);
   1486 
   1487             // If we are waiting for this window to handle an
   1488             // orientation change, well, it is hidden, so
   1489             // doesn't really matter.  Note that this does
   1490             // introduce a potential glitch if the window
   1491             // becomes unhidden before it has drawn for the
   1492             // new orientation.
   1493             if (w.mOrientationChanging) {
   1494                 w.mOrientationChanging = false;
   1495                 if (DEBUG_ORIENTATION) Slog.v(TAG,
   1496                         "Orientation change skips hidden " + w);
   1497             }
   1498         } else if (mLastLayer != mAnimLayer
   1499                 || mLastAlpha != mShownAlpha
   1500                 || mLastDsDx != mDsDx
   1501                 || mLastDtDx != mDtDx
   1502                 || mLastDsDy != mDsDy
   1503                 || mLastDtDy != mDtDy
   1504                 || w.mLastHScale != w.mHScale
   1505                 || w.mLastVScale != w.mVScale
   1506                 || mLastHidden) {
   1507             displayed = true;
   1508             mLastAlpha = mShownAlpha;
   1509             mLastLayer = mAnimLayer;
   1510             mLastDsDx = mDsDx;
   1511             mLastDtDx = mDtDx;
   1512             mLastDsDy = mDsDy;
   1513             mLastDtDy = mDtDy;
   1514             w.mLastHScale = w.mHScale;
   1515             w.mLastVScale = w.mVScale;
   1516             if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
   1517                     "alpha=" + mShownAlpha + " layer=" + mAnimLayer
   1518                     + " matrix=[" + mDsDx + "*" + w.mHScale
   1519                     + "," + mDtDx + "*" + w.mVScale
   1520                     + "][" + mDsDy + "*" + w.mHScale
   1521                     + "," + mDtDy + "*" + w.mVScale + "]", null);
   1522             if (mSurfaceControl != null) {
   1523                 try {
   1524                     mSurfaceAlpha = mShownAlpha;
   1525                     mSurfaceControl.setAlpha(mShownAlpha);
   1526                     mSurfaceLayer = mAnimLayer;
   1527                     mSurfaceControl.setLayer(mAnimLayer);
   1528                     mSurfaceControl.setMatrix(
   1529                             mDsDx * w.mHScale, mDtDx * w.mVScale,
   1530                             mDsDy * w.mHScale, mDtDy * w.mVScale);
   1531 
   1532                     if (mLastHidden && mDrawState == HAS_DRAWN) {
   1533                         if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
   1534                                 "SHOW (performLayout)", null);
   1535                         if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
   1536                                 + " during relayout");
   1537                         if (showSurfaceRobustlyLocked()) {
   1538                             mLastHidden = false;
   1539                             if (mIsWallpaper) {
   1540                                 mService.dispatchWallpaperVisibility(w, true);
   1541                             }
   1542                             // This draw means the difference between unique content and mirroring.
   1543                             // Run another pass through performLayout to set mHasContent in the
   1544                             // LogicalDisplay.
   1545                             mAnimator.setPendingLayoutChanges(w.getDisplayId(),
   1546                                     WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
   1547                         } else {
   1548                             w.mOrientationChanging = false;
   1549                         }
   1550                     }
   1551                     if (mSurfaceControl != null) {
   1552                         w.mToken.hasVisible = true;
   1553                     }
   1554                 } catch (RuntimeException e) {
   1555                     Slog.w(TAG, "Error updating surface in " + w, e);
   1556                     if (!recoveringMemory) {
   1557                         mService.reclaimSomeSurfaceMemoryLocked(this, "update", true);
   1558                     }
   1559                 }
   1560             }
   1561         } else {
   1562             if (DEBUG_ANIM && isAnimating()) {
   1563                 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
   1564             }
   1565             displayed = true;
   1566         }
   1567 
   1568         if (displayed) {
   1569             if (w.mOrientationChanging) {
   1570                 if (!w.isDrawnLw()) {
   1571                     mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
   1572                     mAnimator.mLastWindowFreezeSource = w;
   1573                     if (DEBUG_ORIENTATION) Slog.v(TAG,
   1574                             "Orientation continue waiting for draw in " + w);
   1575                 } else {
   1576                     w.mOrientationChanging = false;
   1577                     if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
   1578                 }
   1579             }
   1580             w.mToken.hasVisible = true;
   1581         }
   1582     }
   1583 
   1584     void setTransparentRegionHintLocked(final Region region) {
   1585         if (mSurfaceControl == null) {
   1586             Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
   1587             return;
   1588         }
   1589         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion");
   1590         SurfaceControl.openTransaction();
   1591         try {
   1592             if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
   1593                     "transparentRegionHint=" + region, null);
   1594             mSurfaceControl.setTransparentRegionHint(region);
   1595         } finally {
   1596             SurfaceControl.closeTransaction();
   1597             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
   1598                     "<<< CLOSE TRANSACTION setTransparentRegion");
   1599         }
   1600     }
   1601 
   1602     void setWallpaperOffset(RectF shownFrame) {
   1603         final LayoutParams attrs = mWin.getAttrs();
   1604         final int left = ((int) shownFrame.left) - attrs.surfaceInsets.left;
   1605         final int top = ((int) shownFrame.top) - attrs.surfaceInsets.top;
   1606         if (mSurfaceX != left || mSurfaceY != top) {
   1607             mSurfaceX = left;
   1608             mSurfaceY = top;
   1609             if (mAnimating) {
   1610                 // If this window (or its app token) is animating, then the position
   1611                 // of the surface will be re-computed on the next animation frame.
   1612                 // We can't poke it directly here because it depends on whatever
   1613                 // transformation is being applied by the animation.
   1614                 return;
   1615             }
   1616             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
   1617             SurfaceControl.openTransaction();
   1618             try {
   1619                 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
   1620                         "POS " + left + ", " + top, null);
   1621                 mSurfaceControl.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
   1622                 updateSurfaceWindowCrop(false);
   1623             } catch (RuntimeException e) {
   1624                 Slog.w(TAG, "Error positioning surface of " + mWin
   1625                         + " pos=(" + left + "," + top + ")", e);
   1626             } finally {
   1627                 SurfaceControl.closeTransaction();
   1628                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
   1629                         "<<< CLOSE TRANSACTION setWallpaperOffset");
   1630             }
   1631         }
   1632     }
   1633 
   1634     void setOpaqueLocked(boolean isOpaque) {
   1635         if (mSurfaceControl == null) {
   1636             return;
   1637         }
   1638         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
   1639         SurfaceControl.openTransaction();
   1640         try {
   1641             if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "isOpaque=" + isOpaque,
   1642                     null);
   1643             mSurfaceControl.setOpaque(isOpaque);
   1644         } finally {
   1645             SurfaceControl.closeTransaction();
   1646             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
   1647         }
   1648     }
   1649 
   1650     // This must be called while inside a transaction.
   1651     boolean performShowLocked() {
   1652         if (mWin.isHiddenFromUserLocked()) {
   1653             return false;
   1654         }
   1655         if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
   1656                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
   1657             RuntimeException e = null;
   1658             if (!WindowManagerService.HIDE_STACK_CRAWLS) {
   1659                 e = new RuntimeException();
   1660                 e.fillInStackTrace();
   1661             }
   1662             Slog.v(TAG, "performShow on " + this
   1663                     + ": mDrawState=" + mDrawState + " readyForDisplay="
   1664                     + mWin.isReadyForDisplayIgnoringKeyguard()
   1665                     + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING)
   1666                     + " during animation: policyVis=" + mWin.mPolicyVisibility
   1667                     + " attHidden=" + mWin.mAttachedHidden
   1668                     + " tok.hiddenRequested="
   1669                     + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
   1670                     + " tok.hidden="
   1671                     + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
   1672                     + " animating=" + mAnimating
   1673                     + " tok animating="
   1674                     + (mAppAnimator != null ? mAppAnimator.animating : false), e);
   1675         }
   1676         if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
   1677             if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
   1678                 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
   1679             if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
   1680                     mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
   1681                 Slog.v(TAG, "Showing " + this
   1682                         + " during animation: policyVis=" + mWin.mPolicyVisibility
   1683                         + " attHidden=" + mWin.mAttachedHidden
   1684                         + " tok.hiddenRequested="
   1685                         + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
   1686                         + " tok.hidden="
   1687                         + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
   1688                         + " animating=" + mAnimating
   1689                         + " tok animating="
   1690                         + (mAppAnimator != null ? mAppAnimator.animating : false));
   1691             }
   1692 
   1693             mService.enableScreenIfNeededLocked();
   1694 
   1695             applyEnterAnimationLocked();
   1696 
   1697             // Force the show in the next prepareSurfaceLocked() call.
   1698             mLastAlpha = -1;
   1699             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
   1700                 Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this);
   1701             mDrawState = HAS_DRAWN;
   1702             mService.scheduleAnimationLocked();
   1703 
   1704             int i = mWin.mChildWindows.size();
   1705             while (i > 0) {
   1706                 i--;
   1707                 WindowState c = mWin.mChildWindows.get(i);
   1708                 if (c.mAttachedHidden) {
   1709                     c.mAttachedHidden = false;
   1710                     if (c.mWinAnimator.mSurfaceControl != null) {
   1711                         c.mWinAnimator.performShowLocked();
   1712                         // It hadn't been shown, which means layout not
   1713                         // performed on it, so now we want to make sure to
   1714                         // do a layout.  If called from within the transaction
   1715                         // loop, this will cause it to restart with a new
   1716                         // layout.
   1717                         final DisplayContent displayContent = c.getDisplayContent();
   1718                         if (displayContent != null) {
   1719                             displayContent.layoutNeeded = true;
   1720                         }
   1721                     }
   1722                 }
   1723             }
   1724 
   1725             if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING
   1726                     && mWin.mAppToken != null) {
   1727                 mWin.mAppToken.firstWindowDrawn = true;
   1728 
   1729                 if (mWin.mAppToken.startingData != null) {
   1730                     if (WindowManagerService.DEBUG_STARTING_WINDOW ||
   1731                             WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
   1732                             "Finish starting " + mWin.mToken
   1733                             + ": first real window is shown, no animation");
   1734                     // If this initial window is animating, stop it -- we
   1735                     // will do an animation to reveal it from behind the
   1736                     // starting window, so there is no need for it to also
   1737                     // be doing its own stuff.
   1738                     clearAnimation();
   1739                     mService.mFinishedStarting.add(mWin.mAppToken);
   1740                     mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
   1741                 }
   1742                 mWin.mAppToken.updateReportedVisibilityLocked();
   1743             }
   1744 
   1745             return true;
   1746         }
   1747 
   1748         return false;
   1749     }
   1750 
   1751     /**
   1752      * Have the surface flinger show a surface, robustly dealing with
   1753      * error conditions.  In particular, if there is not enough memory
   1754      * to show the surface, then we will try to get rid of other surfaces
   1755      * in order to succeed.
   1756      *
   1757      * @return Returns true if the surface was successfully shown.
   1758      */
   1759     boolean showSurfaceRobustlyLocked() {
   1760         try {
   1761             if (mSurfaceControl != null) {
   1762                 mSurfaceShown = true;
   1763                 mSurfaceControl.show();
   1764                 if (mWin.mTurnOnScreen) {
   1765                     if (DEBUG_VISIBILITY) Slog.v(TAG,
   1766                             "Show surface turning screen on: " + mWin);
   1767                     mWin.mTurnOnScreen = false;
   1768                     mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
   1769                 }
   1770             }
   1771             return true;
   1772         } catch (RuntimeException e) {
   1773             Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + mWin, e);
   1774         }
   1775 
   1776         mService.reclaimSomeSurfaceMemoryLocked(this, "show", true);
   1777 
   1778         return false;
   1779     }
   1780 
   1781     void applyEnterAnimationLocked() {
   1782         final int transit;
   1783         if (mEnterAnimationPending) {
   1784             mEnterAnimationPending = false;
   1785             transit = WindowManagerPolicy.TRANSIT_ENTER;
   1786         } else {
   1787             transit = WindowManagerPolicy.TRANSIT_SHOW;
   1788         }
   1789         applyAnimationLocked(transit, true);
   1790         //TODO (multidisplay): Magnification is supported only for the default display.
   1791         if (mService.mAccessibilityController != null
   1792                 && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
   1793             mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit);
   1794         }
   1795     }
   1796 
   1797     /**
   1798      * Choose the correct animation and set it to the passed WindowState.
   1799      * @param transit If AppTransition.TRANSIT_PREVIEW_DONE and the app window has been drawn
   1800      *      then the animation will be app_starting_exit. Any other value loads the animation from
   1801      *      the switch statement below.
   1802      * @param isEntrance The animation type the last time this was called. Used to keep from
   1803      *      loading the same animation twice.
   1804      * @return true if an animation has been loaded.
   1805      */
   1806     boolean applyAnimationLocked(int transit, boolean isEntrance) {
   1807         if ((mLocalAnimating && mAnimationIsEntrance == isEntrance)
   1808                 || mKeyguardGoingAwayAnimation) {
   1809             // If we are trying to apply an animation, but already running
   1810             // an animation of the same type, then just leave that one alone.
   1811 
   1812             // If we are in a keyguard exit animation, and the window should animate away, modify
   1813             // keyguard exit animation such that it also fades out.
   1814             if (mAnimation != null && mKeyguardGoingAwayAnimation
   1815                     && transit == WindowManagerPolicy.TRANSIT_PREVIEW_DONE) {
   1816                 applyFadeoutDuringKeyguardExitAnimation();
   1817             }
   1818             return true;
   1819         }
   1820 
   1821         // Only apply an animation if the display isn't frozen.  If it is
   1822         // frozen, there is no reason to animate and it can cause strange
   1823         // artifacts when we unfreeze the display if some different animation
   1824         // is running.
   1825         if (mService.okToDisplay()) {
   1826             int anim = mPolicy.selectAnimationLw(mWin, transit);
   1827             int attr = -1;
   1828             Animation a = null;
   1829             if (anim != 0) {
   1830                 a = anim != -1 ? AnimationUtils.loadAnimation(mContext, anim) : null;
   1831             } else {
   1832                 switch (transit) {
   1833                     case WindowManagerPolicy.TRANSIT_ENTER:
   1834                         attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
   1835                         break;
   1836                     case WindowManagerPolicy.TRANSIT_EXIT:
   1837                         attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
   1838                         break;
   1839                     case WindowManagerPolicy.TRANSIT_SHOW:
   1840                         attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
   1841                         break;
   1842                     case WindowManagerPolicy.TRANSIT_HIDE:
   1843                         attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
   1844                         break;
   1845                 }
   1846                 if (attr >= 0) {
   1847                     a = mService.mAppTransition.loadAnimationAttr(mWin.mAttrs, attr);
   1848                 }
   1849             }
   1850             if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
   1851                     "applyAnimation: win=" + this
   1852                     + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
   1853                     + " a=" + a
   1854                     + " transit=" + transit
   1855                     + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
   1856             if (a != null) {
   1857                 if (WindowManagerService.DEBUG_ANIM) {
   1858                     RuntimeException e = null;
   1859                     if (!WindowManagerService.HIDE_STACK_CRAWLS) {
   1860                         e = new RuntimeException();
   1861                         e.fillInStackTrace();
   1862                     }
   1863                     Slog.v(TAG, "Loaded animation " + a + " for " + this, e);
   1864                 }
   1865                 setAnimation(a);
   1866                 mAnimationIsEntrance = isEntrance;
   1867             }
   1868         } else {
   1869             clearAnimation();
   1870         }
   1871 
   1872         return mAnimation != null;
   1873     }
   1874 
   1875     private void applyFadeoutDuringKeyguardExitAnimation() {
   1876         long startTime = mAnimation.getStartTime();
   1877         long duration = mAnimation.getDuration();
   1878         long elapsed = mLastAnimationTime - startTime;
   1879         long fadeDuration = duration - elapsed;
   1880         if (fadeDuration <= 0) {
   1881             // Never mind, this would be no visible animation, so abort the animation change.
   1882             return;
   1883         }
   1884         AnimationSet newAnimation = new AnimationSet(false /* shareInterpolator */);
   1885         newAnimation.setDuration(duration);
   1886         newAnimation.setStartTime(startTime);
   1887         newAnimation.addAnimation(mAnimation);
   1888         Animation fadeOut = AnimationUtils.loadAnimation(
   1889                 mContext, com.android.internal.R.anim.app_starting_exit);
   1890         fadeOut.setDuration(fadeDuration);
   1891         fadeOut.setStartOffset(elapsed);
   1892         newAnimation.addAnimation(fadeOut);
   1893         newAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mAnimDw, mAnimDh);
   1894         mAnimation = newAnimation;
   1895     }
   1896 
   1897     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
   1898         if (mAnimating || mLocalAnimating || mAnimationIsEntrance
   1899                 || mAnimation != null) {
   1900             pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
   1901                     pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
   1902                     pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
   1903                     pw.print(" mAnimation="); pw.println(mAnimation);
   1904         }
   1905         if (mHasTransformation || mHasLocalTransformation) {
   1906             pw.print(prefix); pw.print("XForm: has=");
   1907                     pw.print(mHasTransformation);
   1908                     pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
   1909                     pw.print(" "); mTransformation.printShortString(pw);
   1910                     pw.println();
   1911         }
   1912         if (mSurfaceControl != null) {
   1913             if (dumpAll) {
   1914                 pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
   1915                 pw.print(prefix); pw.print("mDrawState=");
   1916                 pw.print(drawStateToString());
   1917                 pw.print(" mLastHidden="); pw.println(mLastHidden);
   1918             }
   1919             pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
   1920                     pw.print(" layer="); pw.print(mSurfaceLayer);
   1921                     pw.print(" alpha="); pw.print(mSurfaceAlpha);
   1922                     pw.print(" rect=("); pw.print(mSurfaceX);
   1923                     pw.print(","); pw.print(mSurfaceY);
   1924                     pw.print(") "); pw.print(mSurfaceW);
   1925                     pw.print(" x "); pw.println(mSurfaceH);
   1926         }
   1927         if (mPendingDestroySurface != null) {
   1928             pw.print(prefix); pw.print("mPendingDestroySurface=");
   1929                     pw.println(mPendingDestroySurface);
   1930         }
   1931         if (mSurfaceResized || mSurfaceDestroyDeferred) {
   1932             pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
   1933                     pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
   1934         }
   1935         if (mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) {
   1936             pw.print(prefix); pw.print("mUniverseTransform=");
   1937                     mUniverseTransform.printShortString(pw);
   1938                     pw.println();
   1939         }
   1940         if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
   1941             pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
   1942                     pw.print(" mAlpha="); pw.print(mAlpha);
   1943                     pw.print(" mLastAlpha="); pw.println(mLastAlpha);
   1944         }
   1945         if (mHaveMatrix || mWin.mGlobalScale != 1) {
   1946             pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
   1947                     pw.print(" mDsDx="); pw.print(mDsDx);
   1948                     pw.print(" mDtDx="); pw.print(mDtDx);
   1949                     pw.print(" mDsDy="); pw.print(mDsDy);
   1950                     pw.print(" mDtDy="); pw.println(mDtDy);
   1951         }
   1952     }
   1953 
   1954     @Override
   1955     public String toString() {
   1956         StringBuffer sb = new StringBuffer("WindowStateAnimator{");
   1957         sb.append(Integer.toHexString(System.identityHashCode(this)));
   1958         sb.append(' ');
   1959         sb.append(mWin.mAttrs.getTitle());
   1960         sb.append('}');
   1961         return sb.toString();
   1962     }
   1963 }
   1964