Home | History | Annotate | Download | only in wm
      1 /*
      2  * Copyright (C) 2015 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.os.Trace.TRACE_TAG_WINDOW_MANAGER;
     20 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
     21 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
     22 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
     23 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
     24 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
     25 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
     26 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
     27 import static android.view.Surface.SCALING_MODE_SCALE_TO_WINDOW;
     28 
     29 import android.graphics.Point;
     30 import android.graphics.PointF;
     31 import android.graphics.Rect;
     32 import android.graphics.Region;
     33 import android.os.IBinder;
     34 import android.os.Debug;
     35 import android.os.Trace;
     36 import android.view.Surface;
     37 import android.view.SurfaceControl;
     38 import android.view.SurfaceSession;
     39 import android.view.WindowContentFrameStats;
     40 import android.view.Surface.OutOfResourcesException;
     41 
     42 import android.util.Slog;
     43 
     44 import java.io.FileDescriptor;
     45 import java.io.PrintWriter;
     46 import java.util.ArrayList;
     47 
     48 class WindowSurfaceController {
     49     static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfaceController" : TAG_WM;
     50 
     51     final WindowStateAnimator mAnimator;
     52 
     53     private SurfaceControlWithBackground mSurfaceControl;
     54 
     55     // Should only be set from within setShown().
     56     private boolean mSurfaceShown = false;
     57     private float mSurfaceX = 0;
     58     private float mSurfaceY = 0;
     59     private float mSurfaceW = 0;
     60     private float mSurfaceH = 0;
     61 
     62     // Initialize to the identity matrix.
     63     private float mLastDsdx = 1;
     64     private float mLastDtdx = 0;
     65     private float mLastDsdy = 0;
     66     private float mLastDtdy = 1;
     67 
     68     private float mSurfaceAlpha = 0;
     69 
     70     private int mSurfaceLayer = 0;
     71 
     72     // Surface flinger doesn't support crop rectangles where width or height is non-positive.
     73     // However, we need to somehow handle the situation where the cropping would completely hide
     74     // the window. We achieve this by explicitly hiding the surface and not letting it be shown.
     75     private boolean mHiddenForCrop = false;
     76 
     77     // Initially a surface is hidden after just being created.
     78     private boolean mHiddenForOtherReasons = true;
     79     private final String title;
     80 
     81     private final WindowManagerService mService;
     82 
     83     private final int mWindowType;
     84     private final Session mWindowSession;
     85 
     86     public WindowSurfaceController(SurfaceSession s, String name, int w, int h, int format,
     87             int flags, WindowStateAnimator animator, int windowType, int ownerUid) {
     88         mAnimator = animator;
     89 
     90         mSurfaceW = w;
     91         mSurfaceH = h;
     92 
     93         title = name;
     94 
     95         mService = animator.mService;
     96         final WindowState win = animator.mWin;
     97         mWindowType = windowType;
     98         mWindowSession = win.mSession;
     99 
    100         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
    101         mSurfaceControl = new SurfaceControlWithBackground(
    102                 s, name, w, h, format, flags, windowType, ownerUid, this);
    103         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    104 
    105         if (mService.mRoot.mSurfaceTraceEnabled) {
    106             mSurfaceControl = new RemoteSurfaceTrace(
    107                     mService.mRoot.mSurfaceTraceFd.getFileDescriptor(), mSurfaceControl, win);
    108         }
    109     }
    110 
    111     void installRemoteTrace(FileDescriptor fd) {
    112         mSurfaceControl = new RemoteSurfaceTrace(fd, mSurfaceControl, mAnimator.mWin);
    113     }
    114 
    115     void removeRemoteTrace() {
    116         mSurfaceControl = new SurfaceControlWithBackground(mSurfaceControl);
    117     }
    118 
    119 
    120     private void logSurface(String msg, RuntimeException where) {
    121         String str = "  SURFACE " + msg + ": " + title;
    122         if (where != null) {
    123             Slog.i(TAG, str, where);
    124         } else {
    125             Slog.i(TAG, str);
    126         }
    127     }
    128 
    129     void reparentChildrenInTransaction(WindowSurfaceController other) {
    130         if (SHOW_TRANSACTIONS) Slog.i(TAG, "REPARENT from: " + this + " to: " + other);
    131         if ((mSurfaceControl != null) && (other.mSurfaceControl != null)) {
    132             mSurfaceControl.reparentChildren(other.getHandle());
    133         }
    134     }
    135 
    136     void detachChildren() {
    137         if (SHOW_TRANSACTIONS) Slog.i(TAG, "SEVER CHILDREN");
    138         if (mSurfaceControl != null) {
    139             mSurfaceControl.detachChildren();
    140         }
    141     }
    142 
    143     void hideInTransaction(String reason) {
    144         if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
    145         mHiddenForOtherReasons = true;
    146 
    147         mAnimator.destroyPreservedSurfaceLocked();
    148         updateVisibility();
    149     }
    150 
    151     private void hideSurface() {
    152         if (mSurfaceControl == null) {
    153             return;
    154         }
    155         setShown(false);
    156         try {
    157             mSurfaceControl.hide();
    158         } catch (RuntimeException e) {
    159             Slog.w(TAG, "Exception hiding surface in " + this);
    160         }
    161     }
    162 
    163     void destroyInTransaction() {
    164         if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
    165             Slog.i(TAG, "Destroying surface " + this + " called by " + Debug.getCallers(8));
    166         }
    167         try {
    168             if (mSurfaceControl != null) {
    169                 mSurfaceControl.destroy();
    170             }
    171         } catch (RuntimeException e) {
    172             Slog.w(TAG, "Error destroying surface in: " + this, e);
    173         } finally {
    174             setShown(false);
    175             mSurfaceControl = null;
    176         }
    177     }
    178 
    179     void disconnectInTransaction() {
    180         if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
    181             Slog.i(TAG, "Disconnecting client: " + this);
    182         }
    183 
    184         try {
    185             if (mSurfaceControl != null) {
    186                 mSurfaceControl.disconnect();
    187             }
    188         } catch (RuntimeException e) {
    189             Slog.w(TAG, "Error disconnecting surface in: " + this, e);
    190         }
    191     }
    192 
    193     void setCropInTransaction(Rect clipRect, boolean recoveringMemory) {
    194         if (SHOW_TRANSACTIONS) logSurface(
    195                 "CROP " + clipRect.toShortString(), null);
    196         try {
    197             if (clipRect.width() > 0 && clipRect.height() > 0) {
    198                 mSurfaceControl.setWindowCrop(clipRect);
    199                 mHiddenForCrop = false;
    200                 updateVisibility();
    201             } else {
    202                 mHiddenForCrop = true;
    203                 mAnimator.destroyPreservedSurfaceLocked();
    204                 updateVisibility();
    205             }
    206         } catch (RuntimeException e) {
    207             Slog.w(TAG, "Error setting crop surface of " + this
    208                     + " crop=" + clipRect.toShortString(), e);
    209             if (!recoveringMemory) {
    210                 mAnimator.reclaimSomeSurfaceMemory("crop", true);
    211             }
    212         }
    213     }
    214 
    215     void clearCropInTransaction(boolean recoveringMemory) {
    216         if (SHOW_TRANSACTIONS) logSurface(
    217                 "CLEAR CROP", null);
    218         try {
    219             Rect clipRect = new Rect(0, 0, -1, -1);
    220             mSurfaceControl.setWindowCrop(clipRect);
    221         } catch (RuntimeException e) {
    222             Slog.w(TAG, "Error setting clearing crop of " + this, e);
    223             if (!recoveringMemory) {
    224                 mAnimator.reclaimSomeSurfaceMemory("crop", true);
    225             }
    226         }
    227     }
    228 
    229     void setFinalCropInTransaction(Rect clipRect) {
    230         if (SHOW_TRANSACTIONS) logSurface(
    231                 "FINAL CROP " + clipRect.toShortString(), null);
    232         try {
    233             mSurfaceControl.setFinalCrop(clipRect);
    234         } catch (RuntimeException e) {
    235             Slog.w(TAG, "Error disconnecting surface in: " + this, e);
    236         }
    237     }
    238 
    239     void setLayer(int layer) {
    240         if (mSurfaceControl != null) {
    241             mService.openSurfaceTransaction();
    242             try {
    243                 if (mAnimator.mWin.usesRelativeZOrdering()) {
    244                     mSurfaceControl.setRelativeLayer(
    245                             mAnimator.mWin.getParentWindow()
    246                             .mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
    247                             -1);
    248                 } else {
    249                     mSurfaceLayer = layer;
    250                     mSurfaceControl.setLayer(layer);
    251                 }
    252             } finally {
    253                 mService.closeSurfaceTransaction();
    254             }
    255         }
    256     }
    257 
    258     void setLayerStackInTransaction(int layerStack) {
    259         if (mSurfaceControl != null) {
    260             mSurfaceControl.setLayerStack(layerStack);
    261         }
    262     }
    263 
    264     void setPositionInTransaction(float left, float top, boolean recoveringMemory) {
    265         final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
    266         if (surfaceMoved) {
    267             mSurfaceX = left;
    268             mSurfaceY = top;
    269 
    270             try {
    271                 if (SHOW_TRANSACTIONS) logSurface(
    272                         "POS (setPositionInTransaction) @ (" + left + "," + top + ")", null);
    273 
    274                 mSurfaceControl.setPosition(left, top);
    275             } catch (RuntimeException e) {
    276                 Slog.w(TAG, "Error positioning surface of " + this
    277                         + " pos=(" + left + "," + top + ")", e);
    278                 if (!recoveringMemory) {
    279                     mAnimator.reclaimSomeSurfaceMemory("position", true);
    280                 }
    281             }
    282         }
    283     }
    284 
    285     void setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory) {
    286         mSurfaceControl.setGeometryAppliesWithResize();
    287     }
    288 
    289     void setMatrixInTransaction(float dsdx, float dtdx, float dtdy, float dsdy,
    290             boolean recoveringMemory) {
    291         final boolean matrixChanged = mLastDsdx != dsdx || mLastDtdx != dtdx ||
    292                                       mLastDtdy != dtdy || mLastDsdy != dsdy;
    293         if (!matrixChanged) {
    294             return;
    295         }
    296 
    297         mLastDsdx = dsdx;
    298         mLastDtdx = dtdx;
    299         mLastDtdy = dtdy;
    300         mLastDsdy = dsdy;
    301 
    302         try {
    303             if (SHOW_TRANSACTIONS) logSurface(
    304                     "MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
    305             mSurfaceControl.setMatrix(
    306                     dsdx, dtdx, dtdy, dsdy);
    307         } catch (RuntimeException e) {
    308             // If something goes wrong with the surface (such
    309             // as running out of memory), don't take down the
    310             // entire system.
    311             Slog.e(TAG, "Error setting matrix on surface surface" + title
    312                     + " MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
    313             if (!recoveringMemory) {
    314                 mAnimator.reclaimSomeSurfaceMemory("matrix", true);
    315             }
    316         }
    317     }
    318 
    319     boolean setSizeInTransaction(int width, int height, boolean recoveringMemory) {
    320         final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
    321         if (surfaceResized) {
    322             mSurfaceW = width;
    323             mSurfaceH = height;
    324 
    325             try {
    326                 if (SHOW_TRANSACTIONS) logSurface(
    327                         "SIZE " + width + "x" + height, null);
    328                 mSurfaceControl.setSize(width, height);
    329             } catch (RuntimeException e) {
    330                 // If something goes wrong with the surface (such
    331                 // as running out of memory), don't take down the
    332                 // entire system.
    333                 Slog.e(TAG, "Error resizing surface of " + title
    334                         + " size=(" + width + "x" + height + ")", e);
    335                 if (!recoveringMemory) {
    336                     mAnimator.reclaimSomeSurfaceMemory("size", true);
    337                 }
    338                 return false;
    339             }
    340             return true;
    341         }
    342         return false;
    343     }
    344 
    345     boolean prepareToShowInTransaction(float alpha,
    346             float dsdx, float dtdx, float dsdy,
    347             float dtdy, boolean recoveringMemory) {
    348         if (mSurfaceControl != null) {
    349             try {
    350                 mSurfaceAlpha = alpha;
    351                 mSurfaceControl.setAlpha(alpha);
    352                 mLastDsdx = dsdx;
    353                 mLastDtdx = dtdx;
    354                 mLastDsdy = dsdy;
    355                 mLastDtdy = dtdy;
    356                 mSurfaceControl.setMatrix(
    357                         dsdx, dtdx, dsdy, dtdy);
    358             } catch (RuntimeException e) {
    359                 Slog.w(TAG, "Error updating surface in " + title, e);
    360                 if (!recoveringMemory) {
    361                     mAnimator.reclaimSomeSurfaceMemory("update", true);
    362                 }
    363                 return false;
    364             }
    365         }
    366         return true;
    367     }
    368 
    369     void setTransparentRegionHint(final Region region) {
    370         if (mSurfaceControl == null) {
    371             Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
    372             return;
    373         }
    374         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion");
    375         mService.openSurfaceTransaction();
    376         try {
    377             mSurfaceControl.setTransparentRegionHint(region);
    378         } finally {
    379             mService.closeSurfaceTransaction();
    380             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
    381                     "<<< CLOSE TRANSACTION setTransparentRegion");
    382         }
    383     }
    384 
    385     void setOpaque(boolean isOpaque) {
    386         if (SHOW_TRANSACTIONS) logSurface("isOpaque=" + isOpaque,
    387                 null);
    388 
    389         if (mSurfaceControl == null) {
    390             return;
    391         }
    392         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
    393         mService.openSurfaceTransaction();
    394         try {
    395             mSurfaceControl.setOpaque(isOpaque);
    396         } finally {
    397             mService.closeSurfaceTransaction();
    398             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
    399         }
    400     }
    401 
    402     void setSecure(boolean isSecure) {
    403         if (SHOW_TRANSACTIONS) logSurface("isSecure=" + isSecure,
    404                 null);
    405 
    406         if (mSurfaceControl == null) {
    407             return;
    408         }
    409         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked");
    410         mService.openSurfaceTransaction();
    411         try {
    412             mSurfaceControl.setSecure(isSecure);
    413         } finally {
    414             mService.closeSurfaceTransaction();
    415             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked");
    416         }
    417     }
    418 
    419     void getContainerRect(Rect rect) {
    420         mAnimator.getContainerRect(rect);
    421     }
    422 
    423     boolean showRobustlyInTransaction() {
    424         if (SHOW_TRANSACTIONS) logSurface(
    425                 "SHOW (performLayout)", null);
    426         if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
    427                 + " during relayout");
    428         mHiddenForOtherReasons = false;
    429         return updateVisibility();
    430     }
    431 
    432     private boolean updateVisibility() {
    433         if (mHiddenForCrop || mHiddenForOtherReasons) {
    434             if (mSurfaceShown) {
    435                 hideSurface();
    436             }
    437             return false;
    438         } else {
    439             if (!mSurfaceShown) {
    440                 return showSurface();
    441             } else {
    442                 return true;
    443             }
    444         }
    445     }
    446 
    447     private boolean showSurface() {
    448         try {
    449             setShown(true);
    450             mSurfaceControl.show();
    451             return true;
    452         } catch (RuntimeException e) {
    453             Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + this, e);
    454         }
    455 
    456         mAnimator.reclaimSomeSurfaceMemory("show", true);
    457 
    458         return false;
    459     }
    460 
    461     void deferTransactionUntil(IBinder handle, long frame) {
    462         // TODO: Logging
    463         mSurfaceControl.deferTransactionUntil(handle, frame);
    464     }
    465 
    466     void forceScaleableInTransaction(boolean force) {
    467         // -1 means we don't override the default or client specified
    468         // scaling mode.
    469         int scalingMode = force ? SCALING_MODE_SCALE_TO_WINDOW : -1;
    470         mSurfaceControl.setOverrideScalingMode(scalingMode);
    471     }
    472 
    473     boolean clearWindowContentFrameStats() {
    474         if (mSurfaceControl == null) {
    475             return false;
    476         }
    477         return mSurfaceControl.clearContentFrameStats();
    478     }
    479 
    480     boolean getWindowContentFrameStats(WindowContentFrameStats outStats) {
    481         if (mSurfaceControl == null) {
    482             return false;
    483         }
    484         return mSurfaceControl.getContentFrameStats(outStats);
    485     }
    486 
    487 
    488     boolean hasSurface() {
    489         return mSurfaceControl != null;
    490     }
    491 
    492     IBinder getHandle() {
    493         if (mSurfaceControl == null) {
    494             return null;
    495         }
    496         return mSurfaceControl.getHandle();
    497     }
    498 
    499     void getSurface(Surface outSurface) {
    500         outSurface.copyFrom(mSurfaceControl);
    501     }
    502 
    503     int getLayer() {
    504         return mSurfaceLayer;
    505     }
    506 
    507     boolean getShown() {
    508         return mSurfaceShown;
    509     }
    510 
    511     void setShown(boolean surfaceShown) {
    512         mSurfaceShown = surfaceShown;
    513 
    514         mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mAnimator.mWin, surfaceShown);
    515 
    516         if (mWindowSession != null) {
    517             mWindowSession.onWindowSurfaceVisibilityChanged(this, mSurfaceShown, mWindowType);
    518         }
    519     }
    520 
    521     float getX() {
    522         return mSurfaceX;
    523     }
    524 
    525     float getY() {
    526         return mSurfaceY;
    527     }
    528 
    529     float getWidth() {
    530         return mSurfaceW;
    531     }
    532 
    533     float getHeight() {
    534         return mSurfaceH;
    535     }
    536 
    537 
    538     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
    539         if (dumpAll) {
    540             pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
    541         }
    542         pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
    543         pw.print(" layer="); pw.print(mSurfaceLayer);
    544         pw.print(" alpha="); pw.print(mSurfaceAlpha);
    545         pw.print(" rect=("); pw.print(mSurfaceX);
    546         pw.print(","); pw.print(mSurfaceY);
    547         pw.print(") "); pw.print(mSurfaceW);
    548         pw.print(" x "); pw.print(mSurfaceH);
    549         pw.print(" transform=("); pw.print(mLastDsdx); pw.print(", ");
    550         pw.print(mLastDtdx); pw.print(", "); pw.print(mLastDsdy);
    551         pw.print(", "); pw.print(mLastDtdy); pw.println(")");
    552     }
    553 
    554     @Override
    555     public String toString() {
    556         return mSurfaceControl.toString();
    557     }
    558 
    559     static class SurfaceTrace extends SurfaceControl {
    560         private final static String SURFACE_TAG = TAG_WITH_CLASS_NAME ? "SurfaceTrace" : TAG_WM;
    561         private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE;
    562         final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
    563 
    564         private float mSurfaceTraceAlpha = 0;
    565         private int mLayer;
    566         private final PointF mPosition = new PointF();
    567         private final Point mSize = new Point();
    568         private final Rect mWindowCrop = new Rect();
    569         private final Rect mFinalCrop = new Rect();
    570         private boolean mShown = false;
    571         private int mLayerStack;
    572         private boolean mIsOpaque;
    573         private float mDsdx, mDtdx, mDsdy, mDtdy;
    574         private final String mName;
    575 
    576         public SurfaceTrace(SurfaceSession s, String name, int w, int h, int format, int flags,
    577                         int windowType, int ownerUid)
    578                     throws OutOfResourcesException {
    579             super(s, name, w, h, format, flags, windowType, ownerUid);
    580             mName = name != null ? name : "Not named";
    581             mSize.set(w, h);
    582             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
    583                     + Debug.getCallers(3));
    584             synchronized (sSurfaces) {
    585                 sSurfaces.add(0, this);
    586             }
    587         }
    588 
    589         public SurfaceTrace(SurfaceSession s,
    590                         String name, int w, int h, int format, int flags) {
    591             super(s, name, w, h, format, flags);
    592             mName = name != null ? name : "Not named";
    593             mSize.set(w, h);
    594             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
    595                     + Debug.getCallers(3));
    596             synchronized (sSurfaces) {
    597                 sSurfaces.add(0, this);
    598             }
    599         }
    600 
    601         @Override
    602         public void setAlpha(float alpha) {
    603             if (mSurfaceTraceAlpha != alpha) {
    604                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this +
    605                         ". Called by " + Debug.getCallers(3));
    606                 mSurfaceTraceAlpha = alpha;
    607             }
    608             super.setAlpha(alpha);
    609         }
    610 
    611         @Override
    612         public void setLayer(int zorder) {
    613             if (zorder != mLayer) {
    614                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this
    615                         + ". Called by " + Debug.getCallers(3));
    616                 mLayer = zorder;
    617             }
    618             super.setLayer(zorder);
    619 
    620             synchronized (sSurfaces) {
    621                 sSurfaces.remove(this);
    622                 int i;
    623                 for (i = sSurfaces.size() - 1; i >= 0; i--) {
    624                     SurfaceTrace s = sSurfaces.get(i);
    625                     if (s.mLayer < zorder) {
    626                         break;
    627                     }
    628                 }
    629                 sSurfaces.add(i + 1, this);
    630             }
    631         }
    632 
    633         @Override
    634         public void setPosition(float x, float y) {
    635             if (x != mPosition.x || y != mPosition.y) {
    636                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:"
    637                         + this + ". Called by " + Debug.getCallers(3));
    638                 mPosition.set(x, y);
    639             }
    640             super.setPosition(x, y);
    641         }
    642 
    643         @Override
    644         public void setGeometryAppliesWithResize() {
    645             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setGeometryAppliesWithResize(): OLD: "
    646                     + this + ". Called by" + Debug.getCallers(3));
    647             super.setGeometryAppliesWithResize();
    648         }
    649 
    650         @Override
    651         public void setSize(int w, int h) {
    652             if (w != mSize.x || h != mSize.y) {
    653                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"
    654                         + this + ". Called by " + Debug.getCallers(3));
    655                 mSize.set(w, h);
    656             }
    657             super.setSize(w, h);
    658         }
    659 
    660         @Override
    661         public void setWindowCrop(Rect crop) {
    662             if (crop != null) {
    663                 if (!crop.equals(mWindowCrop)) {
    664                     if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setWindowCrop("
    665                             + crop.toShortString() + "): OLD:" + this + ". Called by "
    666                             + Debug.getCallers(3));
    667                     mWindowCrop.set(crop);
    668                 }
    669             }
    670             super.setWindowCrop(crop);
    671         }
    672 
    673         @Override
    674         public void setFinalCrop(Rect crop) {
    675             if (crop != null) {
    676                 if (!crop.equals(mFinalCrop)) {
    677                     if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setFinalCrop("
    678                             + crop.toShortString() + "): OLD:" + this + ". Called by "
    679                             + Debug.getCallers(3));
    680                     mFinalCrop.set(crop);
    681                 }
    682             }
    683             super.setFinalCrop(crop);
    684         }
    685 
    686         @Override
    687         public void setLayerStack(int layerStack) {
    688             if (layerStack != mLayerStack) {
    689                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
    690                         + this + ". Called by " + Debug.getCallers(3));
    691                 mLayerStack = layerStack;
    692             }
    693             super.setLayerStack(layerStack);
    694         }
    695 
    696         @Override
    697         public void setOpaque(boolean isOpaque) {
    698             if (isOpaque != mIsOpaque) {
    699                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:"
    700                         + this + ". Called by " + Debug.getCallers(3));
    701                 mIsOpaque = isOpaque;
    702             }
    703             super.setOpaque(isOpaque);
    704         }
    705 
    706         @Override
    707         public void setSecure(boolean isSecure) {
    708             super.setSecure(isSecure);
    709         }
    710 
    711         @Override
    712         public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
    713             if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
    714                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
    715                         + dsdy + "," + dtdy + "): OLD:" + this + ". Called by "
    716                         + Debug.getCallers(3));
    717                 mDsdx = dsdx;
    718                 mDtdx = dtdx;
    719                 mDsdy = dsdy;
    720                 mDtdy = dtdy;
    721             }
    722             super.setMatrix(dsdx, dtdx, dsdy, dtdy);
    723         }
    724 
    725         @Override
    726         public void hide() {
    727             if (mShown) {
    728                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
    729                         + Debug.getCallers(3));
    730                 mShown = false;
    731             }
    732             super.hide();
    733         }
    734 
    735         @Override
    736         public void show() {
    737             if (!mShown) {
    738                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
    739                         + Debug.getCallers(3));
    740                 mShown = true;
    741             }
    742             super.show();
    743         }
    744 
    745         @Override
    746         public void destroy() {
    747             super.destroy();
    748             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
    749                     + Debug.getCallers(3));
    750             synchronized (sSurfaces) {
    751                 sSurfaces.remove(this);
    752             }
    753         }
    754 
    755         @Override
    756         public void release() {
    757             super.release();
    758             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
    759                     + Debug.getCallers(3));
    760             synchronized (sSurfaces) {
    761                 sSurfaces.remove(this);
    762             }
    763         }
    764 
    765         @Override
    766         public void setTransparentRegionHint(Region region) {
    767             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setTransparentRegionHint(" + region
    768                     + "): OLD: " + this + " . Called by " + Debug.getCallers(3));
    769             super.setTransparentRegionHint(region);
    770         }
    771 
    772         static void dumpAllSurfaces(PrintWriter pw, String header) {
    773             synchronized (sSurfaces) {
    774                 final int N = sSurfaces.size();
    775                 if (N <= 0) {
    776                     return;
    777                 }
    778                 if (header != null) {
    779                     pw.println(header);
    780                 }
    781                 pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)");
    782                 for (int i = 0; i < N; i++) {
    783                     SurfaceTrace s = sSurfaces.get(i);
    784                     pw.print("  Surface #"); pw.print(i); pw.print(": #");
    785                             pw.print(Integer.toHexString(System.identityHashCode(s)));
    786                             pw.print(" "); pw.println(s.mName);
    787                     pw.print("    mLayerStack="); pw.print(s.mLayerStack);
    788                             pw.print(" mLayer="); pw.println(s.mLayer);
    789                     pw.print("    mShown="); pw.print(s.mShown); pw.print(" mAlpha=");
    790                             pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque=");
    791                             pw.println(s.mIsOpaque);
    792                     pw.print("    mPosition="); pw.print(s.mPosition.x); pw.print(",");
    793                             pw.print(s.mPosition.y);
    794                             pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
    795                             pw.println(s.mSize.y);
    796                     pw.print("    mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
    797                     pw.print("    mFinalCrop="); s.mFinalCrop.printShortString(pw); pw.println();
    798                     pw.print("    Transform: ("); pw.print(s.mDsdx); pw.print(", ");
    799                             pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
    800                             pw.print(", "); pw.print(s.mDtdy); pw.println(")");
    801                 }
    802             }
    803         }
    804 
    805         @Override
    806         public String toString() {
    807             return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
    808                     + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
    809                     + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
    810                     + " " + mSize.x + "x" + mSize.y
    811                     + " crop=" + mWindowCrop.toShortString()
    812                     + " opaque=" + mIsOpaque
    813                     + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
    814         }
    815     }
    816 }
    817