summaryrefslogtreecommitdiff
path: root/core/java/android/view/ViewRootImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/view/ViewRootImpl.java')
-rw-r--r--core/java/android/view/ViewRootImpl.java115
1 files changed, 70 insertions, 45 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 30bb2bbd3385..16de906b1085 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -68,6 +68,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
@@ -476,17 +477,19 @@ public final class ViewRootImpl implements ViewParent,
@UnsupportedAppUsage
public final Surface mSurface = new Surface();
private final SurfaceControl mSurfaceControl = new SurfaceControl();
+ private IBinder mPreviousSurfaceControlHandle = null;
+
+ private final Transaction mChangeSurfaceTransaction = new Transaction();
+ private final SurfaceSession mSurfaceSession = new SurfaceSession();
/**
- * Child surface of {@code mSurface} with the same bounds as its parent, and crop bounds
- * are set to the parent's bounds adjusted for surface insets. This surface is created when
- * {@link ViewRootImpl#createBoundsSurface(int)} is called.
- * By parenting to this bounds surface, child surfaces can ensure they do not draw into the
- * surface inset regions set by the parent window.
+ * Child container layer of {@code mSurface} with the same bounds as its parent, and cropped to
+ * the surface insets. This surface is created only if a client requests it via {@link
+ * #getBoundsLayer()}. By parenting to this bounds surface, child surfaces can ensure they do
+ * not draw into the surface inset regions set by the parent window.
*/
- public final Surface mBoundsSurface = new Surface();
- private SurfaceSession mSurfaceSession;
- private SurfaceControl mBoundsSurfaceControl;
+ private SurfaceControl mBoundsLayer;
+
private final Transaction mTransaction = new Transaction();
@UnsupportedAppUsage
@@ -1576,65 +1579,76 @@ public final class ViewRootImpl implements ViewParent,
}
}
- /**
- * Creates a surface as a child of {@code mSurface} with the same bounds as its parent and
- * crop bounds set to the parent's bounds adjusted for surface insets.
- *
- * @param zOrderLayer Z order relative to the parent surface.
- */
- public void createBoundsSurface(int zOrderLayer) {
- if (mSurfaceSession == null) {
- mSurfaceSession = new SurfaceSession();
- }
- if (mBoundsSurfaceControl != null && mBoundsSurface.isValid()) {
- return; // surface control for bounds surface already exists.
+ /** Register callback to be notified when the ViewRootImpl surface changes. */
+ interface SurfaceChangedCallback {
+ void surfaceChangedCallback(SurfaceControl.Transaction transaction);
+ }
+
+ private final ArrayList<SurfaceChangedCallback> mSurfaceChangedCallbacks = new ArrayList<>();
+ void addSurfaceChangedCallback(SurfaceChangedCallback c) {
+ mSurfaceChangedCallbacks.add(c);
+ }
+
+ void removeSurfaceChangedCallback(SurfaceChangedCallback c) {
+ mSurfaceChangedCallbacks.remove(c);
+ }
+
+ private void notifySurfaceChanged(SurfaceControl.Transaction transaction) {
+ for (int i = 0; i < mSurfaceChangedCallbacks.size(); i++) {
+ mSurfaceChangedCallbacks.get(i).surfaceChangedCallback(transaction);
}
+ }
- mBoundsSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
+ /**
+ * Returns a child layer with the same bounds as its parent {@code mSurface} and cropped to the
+ * surface insets. If the layer does not exist, it is created.
+ *
+ * <p>Parenting to this layer will ensure that its children are cropped by the view's surface
+ * insets.
+ */
+ public SurfaceControl getBoundsLayer() {
+ if (mBoundsLayer == null) {
+ mBoundsLayer = new SurfaceControl.Builder(mSurfaceSession)
+ .setContainerLayer()
.setName("Bounds for - " + getTitle().toString())
.setParent(mSurfaceControl)
.build();
- setBoundsSurfaceCrop();
- mTransaction.setLayer(mBoundsSurfaceControl, zOrderLayer)
- .show(mBoundsSurfaceControl)
- .apply();
- mBoundsSurface.copyFrom(mBoundsSurfaceControl);
+ setBoundsLayerCrop(mTransaction);
+ mTransaction.show(mBoundsLayer).apply();
+ }
+ return mBoundsLayer;
}
- private void setBoundsSurfaceCrop() {
+ private void setBoundsLayerCrop(Transaction t) {
// mWinFrame is already adjusted for surface insets. So offset it and use it as
// the cropping bounds.
mTempBoundsRect.set(mWinFrame);
mTempBoundsRect.offsetTo(mWindowAttributes.surfaceInsets.left,
mWindowAttributes.surfaceInsets.top);
- mTransaction.setWindowCrop(mBoundsSurfaceControl, mTempBoundsRect);
+ t.setWindowCrop(mBoundsLayer, mTempBoundsRect);
}
/**
- * Called after window layout to update the bounds surface. If the surface insets have
- * changed or the surface has resized, update the bounds surface.
+ * Called after window layout to update the bounds surface. If the surface insets have changed
+ * or the surface has resized, update the bounds surface.
*/
- private void updateBoundsSurface() {
- if (mBoundsSurfaceControl != null && mSurface.isValid()) {
- setBoundsSurfaceCrop();
- mTransaction.deferTransactionUntilSurface(mBoundsSurfaceControl,
+ private void updateBoundsLayer() {
+ if (mBoundsLayer != null) {
+ setBoundsLayerCrop(mTransaction);
+ mTransaction.deferTransactionUntilSurface(mBoundsLayer,
mSurface, mSurface.getNextFrameNumber())
.apply();
}
}
private void destroySurface() {
+ if (mBoundsLayer != null) {
+ mBoundsLayer.release();
+ mBoundsLayer = null;
+ }
mSurface.release();
mSurfaceControl.release();
-
- mSurfaceSession = null;
-
- if (mBoundsSurfaceControl != null) {
- mBoundsSurfaceControl.remove();
- mBoundsSurface.release();
- mBoundsSurfaceControl = null;
- }
}
/**
@@ -2598,7 +2612,7 @@ public final class ViewRootImpl implements ViewParent,
}
if (surfaceSizeChanged) {
- updateBoundsSurface();
+ updateBoundsLayer();
}
final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
@@ -3438,7 +3452,9 @@ public final class ViewRootImpl implements ViewParent,
private void reportDrawFinished() {
try {
mDrawsNeededToReport = 0;
- mWindowSession.finishDrawing(mWindow);
+ if (mSurfaceControl.isValid()) {
+ mWindowSession.finishDrawing(mWindow, mChangeSurfaceTransaction);
+ }
} catch (RemoteException e) {
// Have fun!
}
@@ -7089,6 +7105,9 @@ public final class ViewRootImpl implements ViewParent,
frameNumber = mSurface.getNextFrameNumber();
}
+ mPreviousSurfaceControlHandle = mSurfaceControl.isValid()
+ ? mSurfaceControl.getHandle() : null;
+
int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
@@ -7102,6 +7121,11 @@ public final class ViewRootImpl implements ViewParent,
destroySurface();
}
+ if (mPreviousSurfaceControlHandle != null && mSurfaceControl.isValid()
+ && mPreviousSurfaceControlHandle != mSurfaceControl.getHandle()) {
+ notifySurfaceChanged(mChangeSurfaceTransaction);
+ }
+
mPendingAlwaysConsumeSystemBars =
(relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
@@ -7326,7 +7350,8 @@ public final class ViewRootImpl implements ViewParent,
try {
if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
& WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
- mWindowSession.finishDrawing(mWindow);
+ mWindowSession.finishDrawing(
+ mWindow, null /* postDrawTransaction */);
}
} catch (RemoteException e) {
}