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