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 
WindowSurfaceController(SurfaceSession s, String name, int w, int h, int format, int flags, WindowStateAnimator animator, int windowType, int ownerUid)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 
installRemoteTrace(FileDescriptor fd)118     void installRemoteTrace(FileDescriptor fd) {
119         mSurfaceControl = new RemoteSurfaceTrace(fd, mSurfaceControl, mAnimator.mWin);
120     }
121 
removeRemoteTrace()122     void removeRemoteTrace() {
123         mSurfaceControl = new SurfaceControl(mSurfaceControl);
124     }
125 
126 
logSurface(String msg, RuntimeException where)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 
reparentChildrenInTransaction(WindowSurfaceController other)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 
detachChildren()143     void detachChildren() {
144         if (SHOW_TRANSACTIONS) Slog.i(TAG, "SEVER CHILDREN");
145         if (mSurfaceControl != null) {
146             mSurfaceControl.detachChildren();
147         }
148     }
149 
hideInTransaction(String reason)150     void hideInTransaction(String reason) {
151         if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
152         mHiddenForOtherReasons = true;
153 
154         mAnimator.destroyPreservedSurfaceLocked();
155         updateVisibility();
156     }
157 
hideSurface()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 
destroyInTransaction()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 
disconnectInTransaction()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 
setCropInTransaction(Rect clipRect, boolean recoveringMemory)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 
clearCropInTransaction(boolean recoveringMemory)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 
setFinalCropInTransaction(Rect clipRect)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 
setLayer(int layer)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 
setLayerStackInTransaction(int layerStack)265     void setLayerStackInTransaction(int layerStack) {
266         if (mSurfaceControl != null) {
267             mSurfaceControl.setLayerStack(layerStack);
268         }
269     }
270 
setPositionInTransaction(float left, float top, boolean recoveringMemory)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 
setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory)292     void setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory) {
293         mSurfaceControl.setGeometryAppliesWithResize();
294     }
295 
setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy, boolean recoveringMemory)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 
setSizeInTransaction(int width, int height, boolean recoveringMemory)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 
prepareToShowInTransaction(float alpha, float dsdx, float dtdx, float dsdy, float dtdy, boolean recoveringMemory)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 
setTransparentRegionHint(final Region region)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 
setOpaque(boolean isOpaque)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 
setSecure(boolean isSecure)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 
showRobustlyInTransaction()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 
updateVisibility()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 
showSurface()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 
deferTransactionUntil(IBinder handle, long frame)464     void deferTransactionUntil(IBinder handle, long frame) {
465         // TODO: Logging
466         mSurfaceControl.deferTransactionUntil(handle, frame);
467     }
468 
forceScaleableInTransaction(boolean force)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 
clearWindowContentFrameStats()476     boolean clearWindowContentFrameStats() {
477         if (mSurfaceControl == null) {
478             return false;
479         }
480         return mSurfaceControl.clearContentFrameStats();
481     }
482 
getWindowContentFrameStats(WindowContentFrameStats outStats)483     boolean getWindowContentFrameStats(WindowContentFrameStats outStats) {
484         if (mSurfaceControl == null) {
485             return false;
486         }
487         return mSurfaceControl.getContentFrameStats(outStats);
488     }
489 
490 
hasSurface()491     boolean hasSurface() {
492         return mSurfaceControl != null;
493     }
494 
getHandle()495     IBinder getHandle() {
496         if (mSurfaceControl == null) {
497             return null;
498         }
499         return mSurfaceControl.getHandle();
500     }
501 
getSurface(Surface outSurface)502     void getSurface(Surface outSurface) {
503         outSurface.copyFrom(mSurfaceControl);
504     }
505 
getLayer()506     int getLayer() {
507         return mSurfaceLayer;
508     }
509 
getShown()510     boolean getShown() {
511         return mSurfaceShown;
512     }
513 
setShown(boolean surfaceShown)514     void setShown(boolean surfaceShown) {
515         mSurfaceShown = surfaceShown;
516 
517         if (mWindowSession != null) {
518             mWindowSession.onWindowSurfaceVisibilityChanged(this, mSurfaceShown, mWindowType);
519         }
520     }
521 
getX()522     float getX() {
523         return mSurfaceX;
524     }
525 
getY()526     float getY() {
527         return mSurfaceY;
528     }
529 
getWidth()530     float getWidth() {
531         return mSurfaceW;
532     }
533 
getHeight()534     float getHeight() {
535         return mSurfaceH;
536     }
537 
538 
dump(PrintWriter pw, String prefix, boolean dumpAll)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
toString()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 
SurfaceTrace(SurfaceSession s, String name, int w, int h, int format, int flags, int windowType, int ownerUid)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 
SurfaceTrace(SurfaceSession s, String name, int w, int h, int format, int flags)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
setAlpha(float alpha)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
setLayer(int zorder)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
setPosition(float x, float y)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
setGeometryAppliesWithResize()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
setSize(int w, int h)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
setWindowCrop(Rect crop)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
setFinalCrop(Rect crop)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
setLayerStack(int layerStack)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
setOpaque(boolean isOpaque)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
setSecure(boolean isSecure)708         public void setSecure(boolean isSecure) {
709             super.setSecure(isSecure);
710         }
711 
712         @Override
setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)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
hide()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
show()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
destroy()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
release()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
setTransparentRegionHint(Region region)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 
dumpAllSurfaces(PrintWriter pw, String header)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
toString()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