SF: Add support for boundless layers 2/2
Size is currently used to bound a layer and its child layers. There are
scenarios where we do not want to restrict a layer or its children to any
specific size but have it expand to fill its parent bounds (in the case of a
color layer) or use the size of its buffer. Currently this is achived by providing
a large enough size so that the layer or its children do not get cropped incorrectly.
To fix this, we start by modifying computeBounds and computeScreenBounds
to ignore a layer's size. We calculate the bounds by using the layer's buffer size
and/or crop. In WM, we set the layer's crop property if we want to crop the layer
or child layer to a particular bounds.
Bug: 114413815
Test: go/wm-smoke
Change-Id: I633669876ae434d996532c4d808badabfe3f6787
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 0d33bbd..3d16eb8 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -572,6 +572,10 @@
* Good practice is to first create the surface with the {@link #HIDDEN} flag
* specified, open a transaction, set the surface layer, layer stack, alpha,
* and position, call {@link #show} if appropriate, and close the transaction.
+ * <p>
+ * Bounds of the surface is determined by its crop and its buffer size. If the
+ * surface has no buffer or crop, the surface is boundless and only constrained
+ * by the size of its parent bounds.
*
* @param session The surface session, must not be null.
* @param name The surface name, must not be null.
@@ -959,6 +963,14 @@
}
}
+ /**
+ * Bounds the surface and its children to the bounds specified. Size of the surface will be
+ * ignored and only the crop and buffer size will be used to determine the bounds of the
+ * surface. If no crop is specified and the surface has no buffer, the surface bounds is only
+ * constrained by the size of its parent bounds.
+ *
+ * @param crop Bounds of the crop to apply.
+ */
public void setWindowCrop(Rect crop) {
checkNotReleased();
synchronized (SurfaceControl.class) {
@@ -966,6 +978,19 @@
}
}
+ /**
+ * Same as {@link SurfaceControl#setWindowCrop(Rect)} but sets the crop rect top left at 0, 0.
+ *
+ * @param width width of crop rect
+ * @param height height of crop rect
+ */
+ public void setWindowCrop(int width, int height) {
+ checkNotReleased();
+ synchronized (SurfaceControl.class) {
+ sGlobalTransaction.setWindowCrop(this, width, height);
+ }
+ }
+
public void setLayerStack(int layerStack) {
checkNotReleased();
synchronized(SurfaceControl.class) {
@@ -1477,6 +1502,12 @@
return this;
}
+ public Transaction setWindowCrop(SurfaceControl sc, int width, int height) {
+ sc.checkNotReleased();
+ nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, width, height);
+ return this;
+ }
+
@UnsupportedAppUsage
public Transaction setLayerStack(SurfaceControl sc, int layerStack) {
sc.checkNotReleased();
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 67f9399..2b68ec0 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -598,6 +598,7 @@
}
if (sizeChanged && !creating) {
mSurfaceControl.setSize(mSurfaceWidth, mSurfaceHeight);
+ mSurfaceControl.setWindowCrop(mSurfaceWidth, mSurfaceHeight);
}
} finally {
SurfaceControl.closeTransaction();
@@ -1169,6 +1170,12 @@
}
@Override
+ public void setWindowCrop(int width, int height) {
+ super.setWindowCrop(width, height);
+ mBackgroundControl.setWindowCrop(width, height);
+ }
+
+ @Override
public void setLayerStack(int layerStack) {
super.setLayerStack(layerStack);
mBackgroundControl.setLayerStack(layerStack);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index e38e229..6773b34 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1738,6 +1738,7 @@
.setName(getSurfaceControl() + " - animation-bounds")
.setSize(getSurfaceWidth(), getSurfaceHeight());
final SurfaceControl boundsLayer = builder.build();
+ t.setWindowCrop(boundsLayer, getSurfaceWidth(), getSurfaceHeight());
t.show(boundsLayer);
return boundsLayer;
}
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index fff1fa4..e5db9b0 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -16,21 +16,18 @@
package com.android.server.wm;
-import static android.graphics.PixelFormat.OPAQUE;
-import static android.view.SurfaceControl.FX_SURFACE_DIM;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import java.io.PrintWriter;
-
import android.graphics.Matrix;
-import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.util.Slog;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
+import java.io.PrintWriter;
+
/**
* Four black surfaces put together to make a black frame.
*/
@@ -55,7 +52,7 @@
.setColorLayer(true)
.setParent(null) // TODO: Work-around for b/69259549
.build();
-
+ transaction.setWindowCrop(surface, w, h);
transaction.setLayerStack(surface, dc.getDisplayId());
transaction.setAlpha(surface, 1);
transaction.setLayer(surface, layer);
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index 65c8e96..3accaf8 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -309,6 +309,7 @@
// TODO: Once we use geometry from hierarchy this falls away.
t.setSize(mDimState.mDimLayer, bounds.width(), bounds.height());
t.setPosition(mDimState.mDimLayer, bounds.left, bounds.top);
+ t.setWindowCrop(mDimState.mDimLayer, bounds.width(), bounds.height());
if (!mDimState.isVisible) {
mDimState.isVisible = true;
t.show(mDimState.mDimLayer);
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 4eb021c..b49d304 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -187,6 +187,7 @@
}
t.setPosition(mSurface, mSurfaceFrame.left, mSurfaceFrame.top);
t.setSize(mSurface, mSurfaceFrame.width(), mSurfaceFrame.height());
+ t.setWindowCrop(mSurface, mSurfaceFrame.width(), mSurfaceFrame.height());
t.show(mSurface);
} else if (mSurface != null) {
t.hide(mSurface);
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index ba3d091..2b78d7b 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -16,12 +16,12 @@
package com.android.server.wm;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.SurfaceAnimatorProto.ANIMATION_ADAPTER;
import static com.android.server.wm.SurfaceAnimatorProto.ANIMATION_START_DELAYED;
import static com.android.server.wm.SurfaceAnimatorProto.LEASH;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -305,6 +305,7 @@
.setName(surface + " - animation-leash")
.setSize(width, height);
final SurfaceControl leash = builder.build();
+ t.setWindowCrop(surface, width, height);
if (!hidden) {
t.show(leash);
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 00caceb..296b85b 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -32,6 +32,7 @@
import static android.view.WindowManager.DOCKED_LEFT;
import static android.view.WindowManager.DOCKED_RIGHT;
import static android.view.WindowManager.DOCKED_TOP;
+
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
import static com.android.server.wm.StackProto.ADJUSTED_BOUNDS;
import static com.android.server.wm.StackProto.ADJUSTED_FOR_IME;
@@ -63,10 +64,12 @@
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl;
+
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
import com.android.internal.policy.DockedDividerUtils;
import com.android.server.EventLogTags;
+
import java.io.PrintWriter;
public class TaskStack extends WindowContainer<Task> implements
@@ -256,6 +259,7 @@
final Rect stackBounds = getBounds();
getPendingTransaction()
.setSize(mAnimationBackgroundSurface, mTmpRect.width(), mTmpRect.height())
+ .setWindowCrop(mAnimationBackgroundSurface, mTmpRect.width(), mTmpRect.height())
.setPosition(mAnimationBackgroundSurface, mTmpRect.left - stackBounds.left,
mTmpRect.top - stackBounds.top);
scheduleAnimation();
@@ -795,6 +799,7 @@
return;
}
transaction.setSize(mSurfaceControl, width, height);
+ transaction.setWindowCrop(mSurfaceControl, width, height);
mLastSurfaceSize.set(width, height);
}