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