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