• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory)263     void setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory) {
264         mSurfaceControl.setGeometryAppliesWithResize();
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 
getTransformToDisplayInverse()461     boolean getTransformToDisplayInverse() {
462         return mSurfaceControl.getTransformToDisplayInverse();
463     }
464 
getSurface(Surface outSurface)465     void getSurface(Surface outSurface) {
466         outSurface.copyFrom(mSurfaceControl);
467     }
468 
getLayer()469     int getLayer() {
470         return mSurfaceLayer;
471     }
472 
getShown()473     boolean getShown() {
474         return mSurfaceShown;
475     }
476 
setShown(boolean surfaceShown)477     void setShown(boolean surfaceShown) {
478         mSurfaceShown = surfaceShown;
479     }
480 
getX()481     float getX() {
482         return mSurfaceX;
483     }
484 
getY()485     float getY() {
486         return mSurfaceY;
487     }
488 
getWidth()489     float getWidth() {
490         return mSurfaceW;
491     }
492 
getHeight()493     float getHeight() {
494         return mSurfaceH;
495     }
496 
497 
dump(PrintWriter pw, String prefix, boolean dumpAll)498     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
499         if (dumpAll) {
500             pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
501         }
502         pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
503         pw.print(" layer="); pw.print(mSurfaceLayer);
504         pw.print(" alpha="); pw.print(mSurfaceAlpha);
505         pw.print(" rect=("); pw.print(mSurfaceX);
506         pw.print(","); pw.print(mSurfaceY);
507         pw.print(") "); pw.print(mSurfaceW);
508         pw.print(" x "); pw.println(mSurfaceH);
509     }
510 
511     @Override
toString()512     public String toString() {
513         return mSurfaceControl.toString();
514     }
515 
516     static class SurfaceTrace extends SurfaceControl {
517         private final static String SURFACE_TAG = TAG_WITH_CLASS_NAME ? "SurfaceTrace" : TAG_WM;
518         private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE;
519         final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
520 
521         private float mSurfaceTraceAlpha = 0;
522         private int mLayer;
523         private final PointF mPosition = new PointF();
524         private final Point mSize = new Point();
525         private final Rect mWindowCrop = new Rect();
526         private final Rect mFinalCrop = new Rect();
527         private boolean mShown = false;
528         private int mLayerStack;
529         private boolean mIsOpaque;
530         private float mDsdx, mDtdx, mDsdy, mDtdy;
531         private final String mName;
532 
SurfaceTrace(SurfaceSession s, String name, int w, int h, int format, int flags)533         public SurfaceTrace(SurfaceSession s,
534                        String name, int w, int h, int format, int flags)
535                    throws OutOfResourcesException {
536             super(s, name, w, h, format, flags);
537             mName = name != null ? name : "Not named";
538             mSize.set(w, h);
539             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
540                     + Debug.getCallers(3));
541             synchronized (sSurfaces) {
542                 sSurfaces.add(0, this);
543             }
544         }
545 
546         @Override
setAlpha(float alpha)547         public void setAlpha(float alpha) {
548             if (mSurfaceTraceAlpha != alpha) {
549                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this +
550                         ". Called by " + Debug.getCallers(3));
551                 mSurfaceTraceAlpha = alpha;
552             }
553             super.setAlpha(alpha);
554         }
555 
556         @Override
setLayer(int zorder)557         public void setLayer(int zorder) {
558             if (zorder != mLayer) {
559                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this
560                         + ". Called by " + Debug.getCallers(3));
561                 mLayer = zorder;
562             }
563             super.setLayer(zorder);
564 
565             synchronized (sSurfaces) {
566                 sSurfaces.remove(this);
567                 int i;
568                 for (i = sSurfaces.size() - 1; i >= 0; i--) {
569                     SurfaceTrace s = sSurfaces.get(i);
570                     if (s.mLayer < zorder) {
571                         break;
572                     }
573                 }
574                 sSurfaces.add(i + 1, this);
575             }
576         }
577 
578         @Override
setPosition(float x, float y)579         public void setPosition(float x, float y) {
580             if (x != mPosition.x || y != mPosition.y) {
581                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:"
582                         + this + ". Called by " + Debug.getCallers(3));
583                 mPosition.set(x, y);
584             }
585             super.setPosition(x, y);
586         }
587 
588         @Override
setGeometryAppliesWithResize()589         public void setGeometryAppliesWithResize() {
590             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setGeometryAppliesWithResize(): OLD: "
591                     + this + ". Called by" + Debug.getCallers(3));
592             super.setGeometryAppliesWithResize();
593         }
594 
595         @Override
setSize(int w, int h)596         public void setSize(int w, int h) {
597             if (w != mSize.x || h != mSize.y) {
598                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"
599                         + this + ". Called by " + Debug.getCallers(3));
600                 mSize.set(w, h);
601             }
602             super.setSize(w, h);
603         }
604 
605         @Override
setWindowCrop(Rect crop)606         public void setWindowCrop(Rect crop) {
607             if (crop != null) {
608                 if (!crop.equals(mWindowCrop)) {
609                     if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setWindowCrop("
610                             + crop.toShortString() + "): OLD:" + this + ". Called by "
611                             + Debug.getCallers(3));
612                     mWindowCrop.set(crop);
613                 }
614             }
615             super.setWindowCrop(crop);
616         }
617 
618         @Override
setFinalCrop(Rect crop)619         public void setFinalCrop(Rect crop) {
620             if (crop != null) {
621                 if (!crop.equals(mFinalCrop)) {
622                     if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setFinalCrop("
623                             + crop.toShortString() + "): OLD:" + this + ". Called by "
624                             + Debug.getCallers(3));
625                     mFinalCrop.set(crop);
626                 }
627             }
628             super.setFinalCrop(crop);
629         }
630 
631         @Override
setLayerStack(int layerStack)632         public void setLayerStack(int layerStack) {
633             if (layerStack != mLayerStack) {
634                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
635                         + this + ". Called by " + Debug.getCallers(3));
636                 mLayerStack = layerStack;
637             }
638             super.setLayerStack(layerStack);
639         }
640 
641         @Override
setOpaque(boolean isOpaque)642         public void setOpaque(boolean isOpaque) {
643             if (isOpaque != mIsOpaque) {
644                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:"
645                         + this + ". Called by " + Debug.getCallers(3));
646                 mIsOpaque = isOpaque;
647             }
648             super.setOpaque(isOpaque);
649         }
650 
651         @Override
setSecure(boolean isSecure)652         public void setSecure(boolean isSecure) {
653             super.setSecure(isSecure);
654         }
655 
656         @Override
setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)657         public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
658             if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
659                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
660                         + dsdy + "," + dtdy + "): OLD:" + this + ". Called by "
661                         + Debug.getCallers(3));
662                 mDsdx = dsdx;
663                 mDtdx = dtdx;
664                 mDsdy = dsdy;
665                 mDtdy = dtdy;
666             }
667             super.setMatrix(dsdx, dtdx, dsdy, dtdy);
668         }
669 
670         @Override
hide()671         public void hide() {
672             if (mShown) {
673                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
674                         + Debug.getCallers(3));
675                 mShown = false;
676             }
677             super.hide();
678         }
679 
680         @Override
show()681         public void show() {
682             if (!mShown) {
683                 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
684                         + Debug.getCallers(3));
685                 mShown = true;
686             }
687             super.show();
688         }
689 
690         @Override
destroy()691         public void destroy() {
692             super.destroy();
693             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
694                     + Debug.getCallers(3));
695             synchronized (sSurfaces) {
696                 sSurfaces.remove(this);
697             }
698         }
699 
700         @Override
release()701         public void release() {
702             super.release();
703             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
704                     + Debug.getCallers(3));
705             synchronized (sSurfaces) {
706                 sSurfaces.remove(this);
707             }
708         }
709 
710         @Override
setTransparentRegionHint(Region region)711         public void setTransparentRegionHint(Region region) {
712             if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "setTransparentRegionHint(" + region
713                     + "): OLD: " + this + " . Called by " + Debug.getCallers(3));
714             super.setTransparentRegionHint(region);
715         }
716 
dumpAllSurfaces(PrintWriter pw, String header)717         static void dumpAllSurfaces(PrintWriter pw, String header) {
718             synchronized (sSurfaces) {
719                 final int N = sSurfaces.size();
720                 if (N <= 0) {
721                     return;
722                 }
723                 if (header != null) {
724                     pw.println(header);
725                 }
726                 pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)");
727                 for (int i = 0; i < N; i++) {
728                     SurfaceTrace s = sSurfaces.get(i);
729                     pw.print("  Surface #"); pw.print(i); pw.print(": #");
730                             pw.print(Integer.toHexString(System.identityHashCode(s)));
731                             pw.print(" "); pw.println(s.mName);
732                     pw.print("    mLayerStack="); pw.print(s.mLayerStack);
733                             pw.print(" mLayer="); pw.println(s.mLayer);
734                     pw.print("    mShown="); pw.print(s.mShown); pw.print(" mAlpha=");
735                             pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque=");
736                             pw.println(s.mIsOpaque);
737                     pw.print("    mPosition="); pw.print(s.mPosition.x); pw.print(",");
738                             pw.print(s.mPosition.y);
739                             pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
740                             pw.println(s.mSize.y);
741                     pw.print("    mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
742                     pw.print("    mFinalCrop="); s.mFinalCrop.printShortString(pw); pw.println();
743                     pw.print("    Transform: ("); pw.print(s.mDsdx); pw.print(", ");
744                             pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
745                             pw.print(", "); pw.print(s.mDtdy); pw.println(")");
746                 }
747             }
748         }
749 
750         @Override
toString()751         public String toString() {
752             return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
753                     + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
754                     + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
755                     + " " + mSize.x + "x" + mSize.y
756                     + " crop=" + mWindowCrop.toShortString()
757                     + " opaque=" + mIsOpaque
758                     + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
759         }
760     }
761 
762     class SurfaceControlWithBackground extends SurfaceControl {
763         private SurfaceControl mBackgroundControl;
764         private boolean mOpaque = true;
765         private boolean mAppForcedInvisible = false;
766         private AppWindowToken mAppToken;
767         public boolean mVisible = false;
768         public int mLayer = -1;
769 
SurfaceControlWithBackground(SurfaceSession s, String name, int w, int h, int format, int flags, AppWindowToken token)770         public SurfaceControlWithBackground(SurfaceSession s,
771                         String name, int w, int h, int format, int flags,
772                         AppWindowToken token)
773                    throws OutOfResourcesException {
774             super(s, name, w, h, format, flags);
775             mBackgroundControl = new SurfaceControl(s, name, w, h,
776                     PixelFormat.OPAQUE, flags | SurfaceControl.FX_SURFACE_DIM);
777             mOpaque = (flags & SurfaceControl.OPAQUE) != 0;
778             mAppToken = token;
779 
780             mAppToken.addSurfaceViewBackground(this);
781         }
782 
783         @Override
setAlpha(float alpha)784         public void setAlpha(float alpha) {
785             super.setAlpha(alpha);
786             mBackgroundControl.setAlpha(alpha);
787         }
788 
789         @Override
setLayer(int zorder)790         public void setLayer(int zorder) {
791             super.setLayer(zorder);
792             mBackgroundControl.setLayer(zorder - 1);
793             if (mLayer != zorder) {
794                 mLayer = zorder;
795                 mAppToken.updateSurfaceViewBackgroundVisibilities();
796             }
797         }
798 
799         @Override
setPosition(float x, float y)800         public void setPosition(float x, float y) {
801             super.setPosition(x, y);
802             mBackgroundControl.setPosition(x, y);
803         }
804 
805         @Override
setSize(int w, int h)806         public void setSize(int w, int h) {
807             super.setSize(w, h);
808             mBackgroundControl.setSize(w, h);
809         }
810 
811         @Override
setWindowCrop(Rect crop)812         public void setWindowCrop(Rect crop) {
813             super.setWindowCrop(crop);
814             mBackgroundControl.setWindowCrop(crop);
815         }
816 
817         @Override
setFinalCrop(Rect crop)818         public void setFinalCrop(Rect crop) {
819             super.setFinalCrop(crop);
820             mBackgroundControl.setFinalCrop(crop);
821         }
822 
823         @Override
setLayerStack(int layerStack)824         public void setLayerStack(int layerStack) {
825             super.setLayerStack(layerStack);
826             mBackgroundControl.setLayerStack(layerStack);
827         }
828 
829         @Override
setOpaque(boolean isOpaque)830         public void setOpaque(boolean isOpaque) {
831             super.setOpaque(isOpaque);
832             mOpaque = isOpaque;
833             updateBackgroundVisibility(mAppForcedInvisible);
834         }
835 
836         @Override
setSecure(boolean isSecure)837         public void setSecure(boolean isSecure) {
838             super.setSecure(isSecure);
839         }
840 
841         @Override
setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)842         public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
843             super.setMatrix(dsdx, dtdx, dsdy, dtdy);
844             mBackgroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy);
845         }
846 
847         @Override
hide()848         public void hide() {
849             super.hide();
850             if (mVisible) {
851                 mVisible = false;
852                 mAppToken.updateSurfaceViewBackgroundVisibilities();
853             }
854         }
855 
856         @Override
show()857         public void show() {
858             super.show();
859             if (!mVisible) {
860                 mVisible = true;
861                 mAppToken.updateSurfaceViewBackgroundVisibilities();
862             }
863         }
864 
865         @Override
destroy()866         public void destroy() {
867             super.destroy();
868             mBackgroundControl.destroy();
869             mAppToken.removeSurfaceViewBackground(this);
870          }
871 
872         @Override
release()873         public void release() {
874             super.release();
875             mBackgroundControl.release();
876         }
877 
878         @Override
setTransparentRegionHint(Region region)879         public void setTransparentRegionHint(Region region) {
880             super.setTransparentRegionHint(region);
881             mBackgroundControl.setTransparentRegionHint(region);
882         }
883 
884         @Override
deferTransactionUntil(IBinder handle, long frame)885         public void deferTransactionUntil(IBinder handle, long frame) {
886             super.deferTransactionUntil(handle, frame);
887             mBackgroundControl.deferTransactionUntil(handle, frame);
888         }
889 
updateBackgroundVisibility(boolean forcedInvisible)890         void updateBackgroundVisibility(boolean forcedInvisible) {
891             mAppForcedInvisible = forcedInvisible;
892             if (mOpaque && mVisible && !mAppForcedInvisible) {
893                 mBackgroundControl.show();
894             } else {
895                 mBackgroundControl.hide();
896             }
897         }
898     }
899 }
900