summaryrefslogtreecommitdiff
path: root/core/java/android/view/SurfaceView.java
diff options
context:
space:
mode:
authorVishnu Nair <vishnun@google.com>2019-06-18 11:14:01 -0700
committerArthur Hsu <arthurhsu@google.com>2019-06-18 12:49:24 -0700
commitf7645aa9a968e2da227f1edceaa2b83054b451dd (patch)
treeb1aa5d7b87c7b9890a17091ca7a25dd59f53b123 /core/java/android/view/SurfaceView.java
parent22dd194d6d1edc111f58e552d4bb2c8a45c09daa (diff)
Prevent SurfaceView from drawing over parent surface insets
Parent SurfaceView to a bounds layer that enforces a crop preventing it from drawing over the surface insets. The bounds layer crop is set to the surface insets and updated when the parent surface size changes or the parent surface insets change. If the SurfaceView children are reparented to another client surface then ensure the SurfaceView relative layer info is updated correctly. Bug: 132205507 Test: go/wm-smoke Test: test preserve surfaces codepath with split screen and ensure relative z is preserved Test: test surfaceview apps, youtube, maps & camera. Test: try to repro maps pip issue described in bug Change-Id: I14c2f7603345ad89f0af4db48150b05d8ada602a
Diffstat (limited to 'core/java/android/view/SurfaceView.java')
-rw-r--r--core/java/android/view/SurfaceView.java54
1 files changed, 40 insertions, 14 deletions
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 353544779086..4891b43c829e 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -98,7 +98,8 @@ import java.util.concurrent.locks.ReentrantLock;
* artifacts may occur on previous versions of the platform when its window is
* positioned asynchronously.</p>
*/
-public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback {
+public class SurfaceView extends View
+ implements ViewRootImpl.WindowStoppedCallback, ViewRootImpl.SurfaceChangedCallback {
private static final String TAG = "SurfaceView";
private static final boolean DEBUG = false;
@@ -120,7 +121,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
boolean mDrawFinished = false;
final Rect mScreenRect = new Rect();
- SurfaceSession mSurfaceSession;
+ final SurfaceSession mSurfaceSession = new SurfaceSession();
SurfaceControl mSurfaceControl;
// In the case of format changes we switch out the surface in-place
@@ -266,11 +267,22 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
updateSurface();
}
+ /** @hide */
+ @Override
+ public void surfaceChangedCallback(SurfaceControl.Transaction transaction) {
+ if (getViewRootImpl() != null && mBackgroundControl != null && mSurfaceControl != null) {
+ SurfaceControl sc = getViewRootImpl().getSurfaceControl();
+ transaction.setRelativeLayer(mBackgroundControl, sc, Integer.MIN_VALUE);
+ transaction.setRelativeLayer(mSurfaceControl, sc, mSubLayer);
+ }
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
getViewRootImpl().addWindowStoppedCallback(this);
+ getViewRootImpl().addSurfaceChangedCallback(this);
mWindowStopped = false;
mViewVisibility = getVisibility() == VISIBLE;
@@ -356,6 +368,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
// the SurfaceHolder forward, most live wallpapers do it.
if (viewRoot != null) {
viewRoot.removeWindowStoppedCallback(this);
+ viewRoot.removeSurfaceChangedCallback(this);
}
mAttachedToWindow = false;
@@ -637,21 +650,34 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
if (creating) {
- viewRoot.createBoundsSurface(mSubLayer);
- mSurfaceSession = new SurfaceSession();
mDeferredDestroySurfaceControl = mSurfaceControl;
updateOpaqueFlag();
+ // SurfaceView hierarchy
+ // ViewRootImpl surface
+ // - bounds layer (crops all child surfaces to parent surface insets)
+ // - SurfaceView surface (drawn relative to ViewRootImpl surface)
+ // - Background color layer (drawn behind all SurfaceView surfaces)
+ //
+ // The bounds layer is used to crop the surface view so it does not draw into
+ // the parent surface inset region. Since there can be multiple surface views
+ // below or above the parent surface, one option is to create multiple bounds
+ // layer for each z order. The other option, the one implement is to create
+ // a single bounds layer and set z order for each child surface relative to the
+ // parent surface.
+ // When creating the surface view, we parent it to the bounds layer and then
+ // set the relative z order. When the parent surface changes, we have to
+ // make sure to update the relative z via ViewRootImpl.SurfaceChangedCallback.
final String name = "SurfaceView - " + viewRoot.getTitle().toString();
-
- mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
- .setName(name)
- .setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
- .setBufferSize(mSurfaceWidth, mSurfaceHeight)
- .setFormat(mFormat)
- .setParent(viewRoot.getSurfaceControl())
- .setFlags(mSurfaceFlags)
- .build();
+ mSurfaceControl =
+ new SurfaceControl.Builder(mSurfaceSession)
+ .setName(name)
+ .setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
+ .setBufferSize(mSurfaceWidth, mSurfaceHeight)
+ .setFormat(mFormat)
+ .setParent(viewRoot.getBoundsLayer())
+ .setFlags(mSurfaceFlags)
+ .build();
mBackgroundControl = new SurfaceControl.Builder(mSurfaceSession)
.setName("Background for -" + name)
.setOpaque(true)
@@ -674,7 +700,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
SurfaceControl.openTransaction();
try {
- mSurfaceControl.setLayer(mSubLayer);
+ mSurfaceControl.setRelativeLayer(viewRoot.getSurfaceControl(), mSubLayer);
if (mViewVisibility) {
mSurfaceControl.show();