Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76907eea authored by Robert Carr's avatar Robert Carr
Browse files

Unhide parts of SurfaceControl API in SDK.

In parity with the recently exposed NDK APIs. In addition removing @hide
we make a few changes to prepare the APIs for being public.
1. Use a hidden singleton SurfaceSession
2. Expose a Surface constructor for ANativeWindow inter-op
3. Mark SurfaceControl final
4. Implement setGeometry as public version of setPosition/matrix/crop.
5. Add a visibility toggle method (as opposed to show/hide methods) for
   parity with NDK.

Bug: 111297488
Test: android.view.cts.SurfaceControlTests
Change-Id: Iac043658a360a48086ef4701a6a8ba2396878e81
parent 18a82199
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -49674,6 +49674,7 @@ package android.view {
  }
  public class Surface implements android.os.Parcelable {
    ctor public Surface(android.view.SurfaceControl);
    ctor public Surface(android.graphics.SurfaceTexture);
    method public int describeContents();
    method public boolean isValid();
@@ -49696,6 +49697,38 @@ package android.view {
    ctor public Surface.OutOfResourcesException(String);
  }
  public final class SurfaceControl implements android.os.Parcelable {
    method public int describeContents();
    method public boolean isValid();
    method public void readFromParcel(android.os.Parcel);
    method public void release();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.view.SurfaceControl> CREATOR;
  }
  public static class SurfaceControl.Builder {
    ctor public SurfaceControl.Builder();
    method public android.view.SurfaceControl build();
    method public android.view.SurfaceControl.Builder setBufferSize(@IntRange(from=0) int, @IntRange(from=0) int);
    method @NonNull public android.view.SurfaceControl.Builder setFormat(int);
    method public android.view.SurfaceControl.Builder setName(String);
    method @NonNull public android.view.SurfaceControl.Builder setOpaque(boolean);
    method @NonNull public android.view.SurfaceControl.Builder setParent(@Nullable android.view.SurfaceControl);
  }
  public static class SurfaceControl.Transaction implements java.io.Closeable {
    ctor public SurfaceControl.Transaction();
    method public void apply();
    method public void close();
    method @NonNull public android.view.SurfaceControl.Transaction merge(@NonNull android.view.SurfaceControl.Transaction);
    method @NonNull public android.view.SurfaceControl.Transaction reparent(@NonNull android.view.SurfaceControl, @Nullable android.view.SurfaceControl);
    method @NonNull public android.view.SurfaceControl.Transaction setAlpha(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0, to=1.0) float);
    method @NonNull public android.view.SurfaceControl.Transaction setBufferSize(@NonNull android.view.SurfaceControl, @IntRange(from=0) int, @IntRange(from=0) int);
    method @NonNull public android.view.SurfaceControl.Transaction setGeometry(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, int);
    method @NonNull public android.view.SurfaceControl.Transaction setLayer(@NonNull android.view.SurfaceControl, @IntRange(from=java.lang.Integer.MIN_VALUE, to=java.lang.Integer.MAX_VALUE) int);
    method @NonNull public android.view.SurfaceControl.Transaction setVisibility(@NonNull android.view.SurfaceControl, boolean);
  }
  public interface SurfaceHolder {
    method public void addCallback(android.view.SurfaceHolder.Callback);
    method public android.view.Surface getSurface();
@@ -49740,6 +49773,7 @@ package android.view {
    ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int, int);
    method public boolean gatherTransparentRegion(android.graphics.Region);
    method public android.view.SurfaceHolder getHolder();
    method public android.view.SurfaceControl getSurfaceControl();
    method public void setSecure(boolean);
    method public void setZOrderMediaOverlay(boolean);
    method public void setZOrderOnTop(boolean);
+12 −1
Original line number Diff line number Diff line
@@ -184,6 +184,18 @@ public class Surface implements Parcelable {
    public Surface() {
    }

    /**
     * Create a Surface assosciated with a given {@link SurfaceControl}. Buffers submitted to this
     * surface will be displayed by the system compositor according to the parameters
     * specified by the control. Multiple surfaces may be constructed from one SurfaceControl,
     * but only one can be connected (e.g. have an active EGL context) at a time.
     *
     * @param from The SurfaceControl to assosciate this Surface with
     */
    public Surface(SurfaceControl from) {
        copyFrom(from);
    }

    /**
     * Create Surface from a {@link SurfaceTexture}.
     *
@@ -494,7 +506,6 @@ public class Surface implements Parcelable {
     * in to it.
     *
     * @param other {@link SurfaceControl} to copy from.
     *
     * @hide
     */
    @UnsupportedAppUsage
+135 −59
Original line number Diff line number Diff line
@@ -27,6 +27,10 @@ import static android.view.Surface.ROTATION_90;
import static android.view.SurfaceControlProto.HASH_CODE;
import static android.view.SurfaceControlProto.NAME;

import android.annotation.FloatRange;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
import android.annotation.UnsupportedAppUsage;
import android.graphics.Bitmap;
@@ -58,10 +62,16 @@ import libcore.util.NativeAllocationRegistry;
import java.io.Closeable;

/**
 * SurfaceControl
 * @hide
 * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is
 * a combination of a buffer source, and metadata about how to display the buffers.
 * By constructing a {@link Surface} from this SurfaceControl you can submit buffers to be
 * composited. Using {@link SurfaceControl.Transaction} you can manipulate various
 * properties of how the buffer will be displayed on-screen. SurfaceControl's are
 * arranged into a scene-graph like hierarchy, and as such any SurfaceControl may have
 * a parent. Geometric properties like transform, crop, and Z-ordering will be inherited
 * from the parent, as if the child were content in the parents buffer stream.
 */
public class SurfaceControl implements Parcelable {
public final class SurfaceControl implements Parcelable {
    private static final String TAG = "SurfaceControl";

    private static native long nativeCreate(SurfaceSession session, String name,
@@ -103,6 +113,8 @@ public class SurfaceControl implements Parcelable {
            float dtdy, float dsdy);
    private static native void nativeSetColorTransform(long transactionObj, long nativeObject,
            float[] matrix, float[] translation);
    private static native void nativeSetGeometry(long transactionObj, long nativeObject,
            Rect sourceCrop, Rect dest, long orientation);
    private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color);
    private static native void nativeSetFlags(long transactionObj, long nativeObject,
            int flags, int mask);
@@ -331,8 +343,7 @@ public class SurfaceControl implements Parcelable {
     */
    public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;

    /* Display power modes * /

    // Display power modes.
    /**
     * Display power mode off: used while blanking the screen.
     * Use only with {@link SurfaceControl#setDisplayPowerMode}.
@@ -403,7 +414,6 @@ public class SurfaceControl implements Parcelable {

    /**
     * Builder class for {@link SurfaceControl} objects.
     * @hide
     */
    public static class Builder {
        private SurfaceSession mSession;
@@ -427,8 +437,14 @@ public class SurfaceControl implements Parcelable {
        }

        /**
         * Construct a new {@link SurfaceControl} with the set parameters.
         * @hide
         * Begin building a SurfaceControl.
         */
        public Builder() {
        }

        /**
         * Construct a new {@link SurfaceControl} with the set parameters. The builder
         * remains valid.
         */
        public SurfaceControl build() {
            if (mWidth < 0 || mHeight < 0) {
@@ -447,7 +463,6 @@ public class SurfaceControl implements Parcelable {
         * Set a debugging-name for the SurfaceControl.
         *
         * @param name A name to identify the Surface in debugging.
         * @hide
         */
        public Builder setName(String name) {
            mName = name;
@@ -459,9 +474,9 @@ public class SurfaceControl implements Parcelable {
         *
         * @param width The buffer width in pixels.
         * @param height The buffer height in pixels.
         * @hide
         */
        public Builder setBufferSize(int width, int height) {
        public Builder setBufferSize(@IntRange(from = 0) int width,
                @IntRange(from = 0) int height) {
            if (width < 0 || height < 0) {
                throw new IllegalArgumentException(
                        "width and height must be positive");
@@ -474,8 +489,8 @@ public class SurfaceControl implements Parcelable {
        /**
         * Set the pixel format of the controlled surface's buffers, using constants from
         * {@link android.graphics.PixelFormat}.
         * @hide
         */
        @NonNull
        public Builder setFormat(@PixelFormat.Format int format) {
            mFormat = format;
            return this;
@@ -490,6 +505,7 @@ public class SurfaceControl implements Parcelable {
         * @param protectedContent Whether to require a protected sink.
         * @hide
         */
        @NonNull
        public Builder setProtected(boolean protectedContent) {
            if (protectedContent) {
                mFlags |= PROTECTED_APP;
@@ -506,6 +522,7 @@ public class SurfaceControl implements Parcelable {
         * not a complete prevention of readback as {@link #setProtected}.
         * @hide
         */
        @NonNull
        public Builder setSecure(boolean secure) {
            if (secure) {
                mFlags |= SECURE;
@@ -537,8 +554,8 @@ public class SurfaceControl implements Parcelable {
         * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true)
         * were set automatically.
         * @param opaque Whether the Surface is OPAQUE.
         * @hide
         */
        @NonNull
        public Builder setOpaque(boolean opaque) {
            if (opaque) {
                mFlags |= OPAQUE;
@@ -556,9 +573,9 @@ public class SurfaceControl implements Parcelable {
         * of the parent.
         *
         * @param parent The parent control.
         * @hide
         */
        public Builder setParent(SurfaceControl parent) {
        @NonNull
        public Builder setParent(@Nullable SurfaceControl parent) {
            mParent = parent;
            return this;
        }
@@ -673,9 +690,6 @@ public class SurfaceControl implements Parcelable {
    private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
            SurfaceControl parent, int windowType, int ownerUid)
                    throws OutOfResourcesException, IllegalArgumentException {
        if (session == null) {
            throw new IllegalArgumentException("session must not be null");
        }
        if (name == null) {
            throw new IllegalArgumentException("name must not be null");
        }
@@ -729,9 +743,6 @@ public class SurfaceControl implements Parcelable {
        mCloseGuard.open("release");
    }

    /**
     * @hide
     */
    public void readFromParcel(Parcel in) {
        if (in == null) {
            throw new IllegalArgumentException("source must not be null");
@@ -748,17 +759,11 @@ public class SurfaceControl implements Parcelable {
        assignNativeObject(object);
    }

    /**
     * @hide
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * @hide
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mName);
@@ -791,9 +796,6 @@ public class SurfaceControl implements Parcelable {
        proto.end(token);
    }

    /**
     * @hide
     */
    public static final Creator<SurfaceControl> CREATOR
            = new Creator<SurfaceControl>() {
        public SurfaceControl createFromParcel(Parcel in) {
@@ -823,10 +825,12 @@ public class SurfaceControl implements Parcelable {
    }

    /**
     * Release the local reference to the server-side surface.
     * Always call release() when you're done with a Surface.
     * This will make the surface invalid.
     * @hide
     * Release the local reference to the server-side surface. The surface
     * may continue to exist on-screen as long as its parent continues
     * to exist. To explicitly remove a surface from the screen use
     * {@link Transaction#reparent} with a null-parent.
     *
     * Always call release() when you're done with a SurfaceControl.
     */
    public void release() {
        if (mNativeObject != 0) {
@@ -866,7 +870,10 @@ public class SurfaceControl implements Parcelable {
    }

    /**
     * @hide
     * Check whether this instance points to a valid layer with the system-compositor. For
     * example this may be false if construction failed, or the layer was released.
     *
     * @return Whether this SurfaceControl is valid.
     */
    public boolean isValid() {
        return mNativeObject != 0;
@@ -1270,9 +1277,6 @@ public class SurfaceControl implements Parcelable {
        }
    }

    /**
     * @hide
     */
    @Override
    public String toString() {
        return "Surface(name=" + mName + ")/@0x" +
@@ -1286,6 +1290,7 @@ public class SurfaceControl implements Parcelable {

    /**
     * Describes the properties of a physical display known to surface flinger.
     * @hide
     */
    public static final class PhysicalDisplayInfo {
        /**
@@ -1777,9 +1782,12 @@ public class SurfaceControl implements Parcelable {
    }

    /**
     * @hide
     * An atomic set of changes to a set of SurfaceControl.
     */
    public static class Transaction implements Closeable {
        /**
         * @hide
         */
        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
                Transaction.class.getClassLoader(),
                nativeGetNativeTransactionFinalizer(), 512);
@@ -1789,9 +1797,12 @@ public class SurfaceControl implements Parcelable {
        Runnable mFreeNativeResources;

        /**
         * @hide
         * Open a new transaction object. The transaction may be filed with commands to
         * manipulate {@link SurfaceControl} instances, and then applied atomically with
         * {@link #apply}. Eventually the user should invoke {@link #close}, when the object
         * is no longer required. Note however that re-using a transaction after a call to apply
         * is allowed as a convenience.
         */
        @UnsupportedAppUsage
        public Transaction() {
            mNativeObject = nativeCreateTransaction();
            mFreeNativeResources
@@ -1801,9 +1812,7 @@ public class SurfaceControl implements Parcelable {
        /**
         * Apply the transaction, clearing it's state, and making it usable
         * as a new transaction.
         * @hide
         */
        @UnsupportedAppUsage
        public void apply() {
            apply(false);
        }
@@ -1811,7 +1820,6 @@ public class SurfaceControl implements Parcelable {
        /**
         * Close the transaction, if the transaction was not already applied this will cancel the
         * transaction.
         * @hide
         */
        @Override
        public void close() {
@@ -1841,6 +1849,27 @@ public class SurfaceControl implements Parcelable {
        }

        /**
         * Toggle the visibility of a given Layer and it's sub-tree.
         *
         * @param sc The SurfaceControl for which to set the visibility
         * @param visible The new visibility
         * @return This transaction object.
         */
        @NonNull
        public Transaction setVisibility(@NonNull SurfaceControl sc, boolean visible) {
            sc.checkNotReleased();
            if (visible) {
                return show(sc);
            } else {
                return hide(sc);
            }
        }

        /**
         * Request that a given surface and it's sub-tree be shown.
         *
         * @param sc The surface to show.
         * @return This transaction.
         * @hide
         */
        @UnsupportedAppUsage
@@ -1851,6 +1880,10 @@ public class SurfaceControl implements Parcelable {
        }

        /**
         * Request that a given surface and it's sub-tree be hidden.
         *
         * @param sc The surface to hidden.
         * @return This transaction.
         * @hide
         */
        @UnsupportedAppUsage
@@ -1871,10 +1904,17 @@ public class SurfaceControl implements Parcelable {
        }

        /**
         * @hide
         * Set the default buffer size for the SurfaceControl, if there is an
         * {@link Surface} assosciated with the control, then
         * this will be the default size for buffers dequeued from it.
         * @param sc The surface to set the buffer size for.
         * @param w The default width
         * @param h The default height
         * @return This Transaction
         */
        @UnsupportedAppUsage
        public Transaction setBufferSize(SurfaceControl sc, int w, int h) {
        @NonNull
        public Transaction setBufferSize(@NonNull SurfaceControl sc,
                @IntRange(from = 0) int w, @IntRange(from = 0) int h) {
            sc.checkNotReleased();
            mResizedSurfaces.put(sc, new Point(w, h));
            nativeSetSize(mNativeObject, sc.mNativeObject, w, h);
@@ -1882,10 +1922,17 @@ public class SurfaceControl implements Parcelable {
        }

        /**
         * @hide
         * Set the Z-order for a given SurfaceControl, relative to it's siblings.
         * If two siblings share the same Z order the ordering is undefined. Surfaces
         * with a negative Z will be placed below the parent surface.
         *
         * @param sc The SurfaceControl to set the Z order on
         * @param z The Z-order
         * @return This Transaction.
         */
        @UnsupportedAppUsage
        public Transaction setLayer(SurfaceControl sc, int z) {
        @NonNull
        public Transaction setLayer(@NonNull SurfaceControl sc,
                @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE) int z) {
            sc.checkNotReleased();
            nativeSetLayer(mNativeObject, sc.mNativeObject, z);
            return this;
@@ -1912,10 +1959,15 @@ public class SurfaceControl implements Parcelable {
        }

        /**
         * @hide
         * Set the alpha for a given surface. If the alpha is non-zero the SurfaceControl
         * will be blended with the Surfaces under it according to the specified ratio.
         *
         * @param sc The given SurfaceControl.
         * @param alpha The alpha to set.
         */
        @UnsupportedAppUsage
        public Transaction setAlpha(SurfaceControl sc, float alpha) {
        @NonNull
        public Transaction setAlpha(@NonNull SurfaceControl sc,
                @FloatRange(from = 0.0, to = 1.0) float alpha) {
            sc.checkNotReleased();
            nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha);
            return this;
@@ -1946,6 +1998,25 @@ public class SurfaceControl implements Parcelable {
            return this;
        }

        /**
         * Specify how the buffer assosciated with this Surface is mapped in to the
         * parent coordinate space. The source frame will be scaled to fit the destination
         * frame, after being rotated according to the orientation parameter.
         *
         * @param sc The SurfaceControl to specify the geometry of
         * @param sourceCrop The source rectangle in buffer space. Or null for the entire buffer.
         * @param destFrame The destination rectangle in parent space. Or null for the source frame.
         * @param orientation The buffer rotation
         * @return This transaction object.
         */
        @NonNull
        public Transaction setGeometry(@NonNull SurfaceControl sc, @Nullable Rect sourceCrop,
                @Nullable Rect destFrame, @Surface.Rotation int orientation) {
            sc.checkNotReleased();
            nativeSetGeometry(mNativeObject, sc.mNativeObject, sourceCrop, destFrame, orientation);
            return this;
        }

        /**
         * @hide
         */
@@ -2023,20 +2094,20 @@ public class SurfaceControl implements Parcelable {
            return this;
        }

        @UnsupportedAppUsage
        /**
         * @hide
         */
        @UnsupportedAppUsage
        public Transaction setLayerStack(SurfaceControl sc, int layerStack) {
            sc.checkNotReleased();
            nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack);
            return this;
        }

        @UnsupportedAppUsage
        /**
         * @hide
         */
        @UnsupportedAppUsage
        public Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle,
                long frameNumber) {
            if (frameNumber < 0) {
@@ -2047,10 +2118,10 @@ public class SurfaceControl implements Parcelable {
            return this;
        }

        @UnsupportedAppUsage
        /**
         * @hide
         */
        @UnsupportedAppUsage
        public Transaction deferTransactionUntilSurface(SurfaceControl sc, Surface barrierSurface,
                long frameNumber) {
            if (frameNumber < 0) {
@@ -2080,7 +2151,9 @@ public class SurfaceControl implements Parcelable {
         * @param newParent The new parent for the given control.
         * @return This Transaction
         */
        public Transaction reparent(SurfaceControl sc, SurfaceControl newParent) {
        @NonNull
        public Transaction reparent(@NonNull SurfaceControl sc,
                @Nullable SurfaceControl newParent) {
            sc.checkNotReleased();
            long otherObject = 0;
            if (newParent != null) {
@@ -2255,9 +2328,12 @@ public class SurfaceControl implements Parcelable {
        /**
         * Merge the other transaction into this transaction, clearing the
         * other transaction as if it had been applied.
         * @hide
         *
         * @param other The transaction to merge in to this one.
         * @return This transaction.
         */
        public Transaction merge(Transaction other) {
        @NonNull
        public Transaction merge(@NonNull Transaction other) {
            mResizedSurfaces.putAll(other.mResizedSurfaces);
            other.mResizedSurfaces.clear();
            nativeMergeTransaction(mNativeObject, other.mNativeObject);
+4 −1
Original line number Diff line number Diff line
@@ -1171,7 +1171,10 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
    };

    /**
     * @hide
     * Return a SurfaceControl which can be used for parenting Surfaces to
     * this SurfaceView.
     *
     * @return The SurfaceControl for this SurfaceView.
     */
    public SurfaceControl getSurfaceControl() {
        return mSurfaceControl;
+23 −1
Original line number Diff line number Diff line
@@ -126,7 +126,12 @@ static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
        jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
        jint windowType, jint ownerUid) {
    ScopedUtfChars name(env, nameStr);
    sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
    sp<SurfaceComposerClient> client;
    if (sessionObj != NULL) {
        client = android_view_SurfaceSession_getClient(env, sessionObj);
    } else {
        client = SurfaceComposerClient::getDefault();
    }
    SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
    sp<SurfaceControl> surface;
    status_t err = client->createSurfaceChecked(
@@ -277,6 +282,21 @@ static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj,
    transaction->setPosition(ctrl, x, y);
}

static void nativeSetGeometry(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
        jobject sourceObj, jobject dstObj, jlong orientation) {
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);

    Rect source, dst;
    if (sourceObj != NULL) {
        source = rectFromObj(env, sourceObj);
    }
    if (dstObj != NULL) {
        dst = rectFromObj(env, dstObj);
    }
    transaction->setGeometry(ctrl, source, dst, orientation);
}

static void nativeSetGeometryAppliesWithResize(JNIEnv* env, jclass clazz,
jlong transactionObj,
        jlong nativeObject) {
@@ -1087,6 +1107,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
    {"nativeGetDisplayedContentSample",
            "(Landroid/os/IBinder;JJ)Landroid/hardware/display/DisplayedContentSample;",
            (void*)nativeGetDisplayedContentSample },
    {"nativeSetGeometry", "(JJLandroid/graphics/Rect;Landroid/graphics/Rect;J)V",
            (void*)nativeSetGeometry }
};

int register_android_view_SurfaceControl(JNIEnv* env)