2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.server.wm;
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;
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;
42 import android.util.Slog;
44 import java.io.PrintWriter;
45 import java.util.ArrayList;
47 class WindowSurfaceController {
48 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfaceController" : TAG_WM;
50 final WindowStateAnimator mAnimator;
52 private SurfaceControl mSurfaceControl;
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;
60 private float mSurfaceAlpha = 0;
62 private int mSurfaceLayer = 0;
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;
69 // Initially a surface is hidden after just being created.
70 private boolean mHiddenForOtherReasons = true;
71 private final String title;
73 public WindowSurfaceController(SurfaceSession s,
74 String name, int w, int h, int format, int flags, WindowStateAnimator animator) {
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);
95 mSurfaceControl = new SurfaceControl(
96 s, name, w, h, format, flags);
101 void logSurface(String msg, RuntimeException where) {
102 String str = " SURFACE " + msg + ": " + title;
104 Slog.i(TAG, str, where);
110 void hideInTransaction(String reason) {
111 if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
112 mHiddenForOtherReasons = true;
114 mAnimator.destroyPreservedSurfaceLocked();
118 private void hideSurface() {
119 if (mSurfaceControl != null) {
120 mSurfaceShown = false;
122 mSurfaceControl.hide();
123 } catch (RuntimeException e) {
124 Slog.w(TAG, "Exception hiding surface in " + this);
129 void setPositionAndLayer(float left, float top, int layerStack, int layer) {
130 SurfaceControl.openTransaction();
136 if (SHOW_TRANSACTIONS) logSurface(
137 "POS (setPositionAndLayer) @ (" + left + "," + top + ")", null);
138 mSurfaceControl.setPosition(left, top);
139 mSurfaceControl.setLayerStack(layerStack);
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);
149 SurfaceControl.closeTransaction();
150 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
151 "<<< CLOSE TRANSACTION setPositionAndLayer");
155 void destroyInTransaction() {
156 // if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
157 Slog.i(TAG, "Destroying surface " + this + " called by " + Debug.getCallers(8));
160 if (mSurfaceControl != null) {
161 mSurfaceControl.destroy();
163 } catch (RuntimeException e) {
164 Slog.w(TAG, "Error destroying surface in: " + this, e);
166 mSurfaceShown = false;
167 mSurfaceControl = null;
171 void disconnectInTransaction() {
172 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
173 Slog.i(TAG, "Disconnecting client: " + this);
177 if (mSurfaceControl != null) {
178 mSurfaceControl.disconnect();
180 } catch (RuntimeException e) {
181 Slog.w(TAG, "Error disconnecting surface in: " + this, e);
185 void setCropInTransaction(Rect clipRect, boolean recoveringMemory) {
186 if (SHOW_TRANSACTIONS) logSurface(
187 "CROP " + clipRect.toShortString(), null);
189 if (clipRect.width() > 0 && clipRect.height() > 0) {
190 mSurfaceControl.setWindowCrop(clipRect);
191 mHiddenForCrop = false;
194 mHiddenForCrop = true;
195 mAnimator.destroyPreservedSurfaceLocked();
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);
207 void clearCropInTransaction(boolean recoveringMemory) {
208 if (SHOW_TRANSACTIONS) logSurface(
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);
221 void setFinalCropInTransaction(Rect clipRect) {
222 if (SHOW_TRANSACTIONS) logSurface(
223 "FINAL CROP " + clipRect.toShortString(), null);
225 mSurfaceControl.setFinalCrop(clipRect);
226 } catch (RuntimeException e) {
227 Slog.w(TAG, "Error disconnecting surface in: " + this, e);
231 void setLayer(int layer) {
232 if (mSurfaceControl != null) {
233 SurfaceControl.openTransaction();
235 mSurfaceControl.setLayer(layer);
237 SurfaceControl.closeTransaction();
242 void setPositionInTransaction(float left, float top, boolean recoveringMemory) {
243 final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
249 if (SHOW_TRANSACTIONS) logSurface(
250 "POS (setPositionInTransaction) @ (" + left + "," + top + ")", null);
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);
263 void setGeometryAppliesWithResizeInTransaction(boolean recoveringMemory) {
264 mSurfaceControl.setGeometryAppliesWithResize();
267 void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy,
268 boolean recoveringMemory) {
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
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);
287 boolean setSizeInTransaction(int width, int height, boolean recoveringMemory) {
288 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
289 if (surfaceResized) {
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
301 Slog.e(TAG, "Error resizing surface of " + title
302 + " size=(" + width + "x" + height + ")", e);
303 if (!recoveringMemory) {
304 mAnimator.reclaimSomeSurfaceMemory("size", true);
313 boolean prepareToShowInTransaction(float alpha, int layer, float dsdx, float dtdx, float dsdy,
314 float dtdy, boolean recoveringMemory) {
315 if (mSurfaceControl != null) {
317 mSurfaceAlpha = alpha;
318 mSurfaceControl.setAlpha(alpha);
319 mSurfaceLayer = layer;
320 mSurfaceControl.setLayer(layer);
321 mSurfaceControl.setMatrix(
322 dsdx, dtdx, dsdy, dtdy);
324 } catch (RuntimeException e) {
325 Slog.w(TAG, "Error updating surface in " + title, e);
326 if (!recoveringMemory) {
327 mAnimator.reclaimSomeSurfaceMemory("update", true);
335 void setTransparentRegionHint(final Region region) {
336 if (mSurfaceControl == null) {
337 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
340 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion");
341 SurfaceControl.openTransaction();
343 mSurfaceControl.setTransparentRegionHint(region);
345 SurfaceControl.closeTransaction();
346 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
347 "<<< CLOSE TRANSACTION setTransparentRegion");
351 void setOpaque(boolean isOpaque) {
352 if (SHOW_TRANSACTIONS) logSurface("isOpaque=" + isOpaque,
355 if (mSurfaceControl == null) {
358 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
359 SurfaceControl.openTransaction();
361 mSurfaceControl.setOpaque(isOpaque);
363 SurfaceControl.closeTransaction();
364 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
368 void setSecure(boolean isSecure) {
369 if (SHOW_TRANSACTIONS) logSurface("isSecure=" + isSecure,
372 if (mSurfaceControl == null) {
375 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked");
376 SurfaceControl.openTransaction();
378 mSurfaceControl.setSecure(isSecure);
380 SurfaceControl.closeTransaction();
381 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked");
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();
394 private boolean updateVisibility() {
395 if (mHiddenForCrop || mHiddenForOtherReasons) {
401 if (!mSurfaceShown) {
402 return showSurface();
409 private boolean showSurface() {
411 mSurfaceShown = true;
412 mSurfaceControl.show();
414 } catch (RuntimeException e) {
415 Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + this, e);
418 mAnimator.reclaimSomeSurfaceMemory("show", true);
423 void deferTransactionUntil(IBinder handle, long frame) {
425 mSurfaceControl.deferTransactionUntil(handle, frame);
428 void forceScaleableInTransaction(boolean force) {
429 // -1 means we don't override the default or client specified
431 int scalingMode = force ? SCALING_MODE_SCALE_TO_WINDOW : -1;
432 mSurfaceControl.setOverrideScalingMode(scalingMode);
435 boolean clearWindowContentFrameStats() {
436 if (mSurfaceControl == null) {
439 return mSurfaceControl.clearContentFrameStats();
442 boolean getWindowContentFrameStats(WindowContentFrameStats outStats) {
443 if (mSurfaceControl == null) {
446 return mSurfaceControl.getContentFrameStats(outStats);
450 boolean hasSurface() {
451 return mSurfaceControl != null;
454 IBinder getHandle() {
455 if (mSurfaceControl == null) {
458 return mSurfaceControl.getHandle();
461 boolean getTransformToDisplayInverse() {
462 return mSurfaceControl.getTransformToDisplayInverse();
465 void getSurface(Surface outSurface) {
466 outSurface.copyFrom(mSurfaceControl);
470 return mSurfaceLayer;
474 return mSurfaceShown;
477 void setShown(boolean surfaceShown) {
478 mSurfaceShown = surfaceShown;
498 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
500 pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
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);
512 public String toString() {
513 return mSurfaceControl.toString();
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>();
521 private float mSurfaceTraceAlpha = 0;
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;
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";
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);
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;
553 super.setAlpha(alpha);
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));
563 super.setLayer(zorder);
565 synchronized (sSurfaces) {
566 sSurfaces.remove(this);
568 for (i = sSurfaces.size() - 1; i >= 0; i--) {
569 SurfaceTrace s = sSurfaces.get(i);
570 if (s.mLayer < zorder) {
574 sSurfaces.add(i + 1, this);
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));
585 super.setPosition(x, y);
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();
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));
606 public void setWindowCrop(Rect crop) {
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);
615 super.setWindowCrop(crop);
619 public void setFinalCrop(Rect crop) {
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);
628 super.setFinalCrop(crop);
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;
638 super.setLayerStack(layerStack);
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;
648 super.setOpaque(isOpaque);
652 public void setSecure(boolean isSecure) {
653 super.setSecure(isSecure);
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));
667 super.setMatrix(dsdx, dtdx, dsdy, dtdy);
673 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
674 + Debug.getCallers(3));
683 if (LOG_SURFACE_TRACE) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
684 + Debug.getCallers(3));
691 public void 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);
701 public void 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);
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);
717 static void dumpAllSurfaces(PrintWriter pw, String header) {
718 synchronized (sSurfaces) {
719 final int N = sSurfaces.size();
723 if (header != null) {
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(")");
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 + ")";
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;
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;
780 mAppToken.addSurfaceViewBackground(this);
784 public void setAlpha(float alpha) {
785 super.setAlpha(alpha);
786 mBackgroundControl.setAlpha(alpha);
790 public void setLayer(int zorder) {
791 super.setLayer(zorder);
792 mBackgroundControl.setLayer(zorder - 1);
793 if (mLayer != zorder) {
795 mAppToken.updateSurfaceViewBackgroundVisibilities();
800 public void setPosition(float x, float y) {
801 super.setPosition(x, y);
802 mBackgroundControl.setPosition(x, y);
806 public void setSize(int w, int h) {
808 mBackgroundControl.setSize(w, h);
812 public void setWindowCrop(Rect crop) {
813 super.setWindowCrop(crop);
814 mBackgroundControl.setWindowCrop(crop);
818 public void setFinalCrop(Rect crop) {
819 super.setFinalCrop(crop);
820 mBackgroundControl.setFinalCrop(crop);
824 public void setLayerStack(int layerStack) {
825 super.setLayerStack(layerStack);
826 mBackgroundControl.setLayerStack(layerStack);
830 public void setOpaque(boolean isOpaque) {
831 super.setOpaque(isOpaque);
833 updateBackgroundVisibility(mAppForcedInvisible);
837 public void setSecure(boolean isSecure) {
838 super.setSecure(isSecure);
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);
852 mAppToken.updateSurfaceViewBackgroundVisibilities();
861 mAppToken.updateSurfaceViewBackgroundVisibilities();
866 public void destroy() {
868 mBackgroundControl.destroy();
869 mAppToken.removeSurfaceViewBackground(this);
873 public void release() {
875 mBackgroundControl.release();
879 public void setTransparentRegionHint(Region region) {
880 super.setTransparentRegionHint(region);
881 mBackgroundControl.setTransparentRegionHint(region);
885 public void deferTransactionUntil(IBinder handle, long frame) {
886 super.deferTransactionUntil(handle, frame);
887 mBackgroundControl.deferTransactionUntil(handle, frame);
890 void updateBackgroundVisibility(boolean forcedInvisible) {
891 mAppForcedInvisible = forcedInvisible;
892 if (mOpaque && mVisible && !mAppForcedInvisible) {
893 mBackgroundControl.show();
895 mBackgroundControl.hide();