OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / services / core / java / com / android / server / wm / WindowSurfaceController.java
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
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
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
110     void hideInTransaction(String reason) {
111         if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
112         mHiddenForOtherReasons = true;
113
114         mAnimator.destroyPreservedSurfaceLocked();
115         updateVisibility();
116     }
117
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
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
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
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
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
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
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
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
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
263     void setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory) {
264         mSurfaceControl.setGeometryAppliesWithResize();
265     }
266
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
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
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
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
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
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
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
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
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
423     void deferTransactionUntil(IBinder handle, long frame) {
424         // TODO: Logging
425         mSurfaceControl.deferTransactionUntil(handle, frame);
426     }
427
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
435     boolean clearWindowContentFrameStats() {
436         if (mSurfaceControl == null) {
437             return false;
438         }
439         return mSurfaceControl.clearContentFrameStats();
440     }
441
442     boolean getWindowContentFrameStats(WindowContentFrameStats outStats) {
443         if (mSurfaceControl == null) {
444             return false;
445         }
446         return mSurfaceControl.getContentFrameStats(outStats);
447     }
448
449
450     boolean hasSurface() {
451         return mSurfaceControl != null;
452     }
453
454     IBinder getHandle() {
455         if (mSurfaceControl == null) {
456             return null;
457         }
458         return mSurfaceControl.getHandle();
459     }
460
461     boolean getTransformToDisplayInverse() {
462         return mSurfaceControl.getTransformToDisplayInverse();
463     }
464
465     void getSurface(Surface outSurface) {
466         outSurface.copyFrom(mSurfaceControl);
467     }
468
469     int getLayer() {
470         return mSurfaceLayer;
471     }
472
473     boolean getShown() {
474         return mSurfaceShown;
475     }
476
477     void setShown(boolean surfaceShown) {
478         mSurfaceShown = surfaceShown;
479     }
480
481     float getX() {
482         return mSurfaceX;
483     }
484
485     float getY() {
486         return mSurfaceY;
487     }
488
489     float getWidth() {
490         return mSurfaceW;
491     }
492
493     float getHeight() {
494         return mSurfaceH;
495     }
496
497
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
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
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
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
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
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
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
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
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
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
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
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
652         public void setSecure(boolean isSecure) {
653             super.setSecure(isSecure);
654         }
655
656         @Override
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
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
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
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
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
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
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
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
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
784         public void setAlpha(float alpha) {
785             super.setAlpha(alpha);
786             mBackgroundControl.setAlpha(alpha);
787         }
788
789         @Override
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
800         public void setPosition(float x, float y) {
801             super.setPosition(x, y);
802             mBackgroundControl.setPosition(x, y);
803         }
804
805         @Override
806         public void setSize(int w, int h) {
807             super.setSize(w, h);
808             mBackgroundControl.setSize(w, h);
809         }
810
811         @Override
812         public void setWindowCrop(Rect crop) {
813             super.setWindowCrop(crop);
814             mBackgroundControl.setWindowCrop(crop);
815         }
816
817         @Override
818         public void setFinalCrop(Rect crop) {
819             super.setFinalCrop(crop);
820             mBackgroundControl.setFinalCrop(crop);
821         }
822
823         @Override
824         public void setLayerStack(int layerStack) {
825             super.setLayerStack(layerStack);
826             mBackgroundControl.setLayerStack(layerStack);
827         }
828
829         @Override
830         public void setOpaque(boolean isOpaque) {
831             super.setOpaque(isOpaque);
832             mOpaque = isOpaque;
833             updateBackgroundVisibility(mAppForcedInvisible);
834         }
835
836         @Override
837         public void setSecure(boolean isSecure) {
838             super.setSecure(isSecure);
839         }
840
841         @Override
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
848         public void hide() {
849             super.hide();
850             if (mVisible) {
851                 mVisible = false;
852                 mAppToken.updateSurfaceViewBackgroundVisibilities();
853             }
854         }
855
856         @Override
857         public void show() {
858             super.show();
859             if (!mVisible) {
860                 mVisible = true;
861                 mAppToken.updateSurfaceViewBackgroundVisibilities();
862             }
863         }
864
865         @Override
866         public void destroy() {
867             super.destroy();
868             mBackgroundControl.destroy();
869             mAppToken.removeSurfaceViewBackground(this);
870          }
871
872         @Override
873         public void release() {
874             super.release();
875             mBackgroundControl.release();
876         }
877
878         @Override
879         public void setTransparentRegionHint(Region region) {
880             super.setTransparentRegionHint(region);
881             mBackgroundControl.setTransparentRegionHint(region);
882         }
883
884         @Override
885         public void deferTransactionUntil(IBinder handle, long frame) {
886             super.deferTransactionUntil(handle, frame);
887             mBackgroundControl.deferTransactionUntil(handle, frame);
888         }
889
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 }