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

Commit bc9beab8 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Remove SurfaceControl#getHandle from JAVA apis 2/2

Holding on to a reference of the handle in Java will keep the server-side surface alive until
the reference is removed by GC. This may cause surfaces to be kept alive longer than necessary.
Instead hold on the surface control and call SurfaceControl#release which will release the local
reference to the server-side surface.

Bug: 136004147
Test: go/wm-smoke

Change-Id: Iff7d48ae1593cea2e188aa07c417f4c5a98887d5
parent 4bcd152a
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -109,10 +109,10 @@ public final class InputWindowHandle {
     * bounds of a parent window. That is the window should receive touch events outside its
     * window but be limited to its stack bounds, such as in the case of split screen.
     */
    public WeakReference<IBinder> touchableRegionCropHandle = new WeakReference<>(null);
    public WeakReference<SurfaceControl> touchableRegionSurfaceControl = new WeakReference<>(null);

    /**
     * Replace {@link touchableRegion} with the bounds of {@link touchableRegionCropHandle}. If
     * Replace {@link touchableRegion} with the bounds of {@link touchableRegionSurfaceControl}. If
     * the handle is {@code null}, the bounds of the surface associated with this window is used
     * as the touchable region.
     */
@@ -164,8 +164,6 @@ public final class InputWindowHandle {
     * Crop the window touchable region to the bounds of the surface provided.
     */
    public void setTouchableRegionCrop(@Nullable SurfaceControl bounds) {
        if (bounds != null) {
            touchableRegionCropHandle = new WeakReference<>(bounds.getHandle());
        }
        touchableRegionSurfaceControl = new WeakReference<>(bounds);
    }
}
+25 −28
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ public final class SurfaceControl implements Parcelable {
            Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
            boolean captureSecureLayers);
    private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder displayToken,
            IBinder layerHandleToken, Rect sourceCrop, float frameScale, IBinder[] excludeLayers);
            long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects);

    private static native long nativeCreateTransaction();
    private static native long nativeGetNativeTransactionFinalizer();
@@ -103,7 +103,7 @@ public final class SurfaceControl implements Parcelable {

    private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder);
    private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject,
            IBinder relativeTo, int zorder);
            long relativeToObject, int zorder);
    private static native void nativeSetPosition(long transactionObj, long nativeObject,
            float x, float y);
    private static native void nativeSetGeometryAppliesWithResize(long transactionObj,
@@ -173,18 +173,17 @@ public final class SurfaceControl implements Parcelable {
    private static native void nativeSetDisplayPowerMode(
            IBinder displayToken, int mode);
    private static native void nativeDeferTransactionUntil(long transactionObj, long nativeObject,
            IBinder handle, long frame);
            long barrierObject, long frame);
    private static native void nativeDeferTransactionUntilSurface(long transactionObj,
            long nativeObject,
            long surfaceObject, long frame);
    private static native void nativeReparentChildren(long transactionObj, long nativeObject,
            IBinder handle);
            long newParentObject);
    private static native void nativeReparent(long transactionObj, long nativeObject,
            long newParentNativeObject);
    private static native void nativeSeverChildren(long transactionObj, long nativeObject);
    private static native void nativeSetOverrideScalingMode(long transactionObj, long nativeObject,
            int scalingMode);
    private static native IBinder nativeGetHandle(long nativeObject);
    private static native boolean nativeGetTransformToDisplayInverse(long nativeObject);

    private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken);
@@ -1023,9 +1022,9 @@ public final class SurfaceControl implements Parcelable {
    /**
     * @hide
     */
    public void deferTransactionUntil(IBinder handle, long frame) {
    public void deferTransactionUntil(SurfaceControl barrier, long frame) {
        synchronized(SurfaceControl.class) {
            sGlobalTransaction.deferTransactionUntil(this, handle, frame);
            sGlobalTransaction.deferTransactionUntil(this, barrier, frame);
        }
    }

@@ -1041,9 +1040,9 @@ public final class SurfaceControl implements Parcelable {
    /**
     * @hide
     */
    public void reparentChildren(IBinder newParentHandle) {
    public void reparentChildren(SurfaceControl newParent) {
        synchronized(SurfaceControl.class) {
            sGlobalTransaction.reparentChildren(this, newParentHandle);
            sGlobalTransaction.reparentChildren(this, newParent);
        }
    }

@@ -1075,13 +1074,6 @@ public final class SurfaceControl implements Parcelable {
        }
    }

    /**
     * @hide
     */
    public IBinder getHandle() {
        return nativeGetHandle(mNativeObject);
    }

    /**
     * @hide
     */
@@ -1989,7 +1981,7 @@ public final class SurfaceControl implements Parcelable {
    /**
     * Captures a layer and its children and returns a {@link GraphicBuffer} with the content.
     *
     * @param layerHandleToken The root layer to capture.
     * @param layer            The root layer to capture.
     * @param sourceCrop       The portion of the root surface to capture; caller may pass in 'new
     *                         Rect()' or null if no cropping is desired.
     * @param frameScale       The desired scale of the returned buffer; the raw
@@ -1998,20 +1990,25 @@ public final class SurfaceControl implements Parcelable {
     * @return Returns a GraphicBuffer that contains the layer capture.
     * @hide
     */
    public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
    public static ScreenshotGraphicBuffer captureLayers(SurfaceControl layer, Rect sourceCrop,
            float frameScale) {
        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
        return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, null);
        return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale, null);
    }

    /**
     * Like {@link captureLayers} but with an array of layer handles to exclude.
     * @hide
     */
    public static ScreenshotGraphicBuffer captureLayersExcluding(IBinder layerHandleToken,
            Rect sourceCrop, float frameScale, IBinder[] exclude) {
    public static ScreenshotGraphicBuffer captureLayersExcluding(SurfaceControl layer,
            Rect sourceCrop, float frameScale, SurfaceControl[] exclude) {
        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
        return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, exclude);
        long[] nativeExcludeObjects = new long[exclude.length];
        for (int i = 0; i < exclude.length; i++) {
            nativeExcludeObjects[i] = exclude[i].mNativeObject;
        }
        return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale,
                nativeExcludeObjects);
    }

    /**
@@ -2228,8 +2225,7 @@ public final class SurfaceControl implements Parcelable {
         */
        public Transaction setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z) {
            sc.checkNotReleased();
            nativeSetRelativeLayer(mNativeObject, sc.mNativeObject,
                    relativeTo.getHandle(), z);
            nativeSetRelativeLayer(mNativeObject, sc.mNativeObject, relativeTo.mNativeObject, z);
            return this;
        }

@@ -2416,13 +2412,14 @@ public final class SurfaceControl implements Parcelable {
         * @hide
         */
        @UnsupportedAppUsage
        public Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle,
        public Transaction deferTransactionUntil(SurfaceControl sc, SurfaceControl barrier,
                long frameNumber) {
            if (frameNumber < 0) {
                return this;
            }
            sc.checkNotReleased();
            nativeDeferTransactionUntil(mNativeObject, sc.mNativeObject, handle, frameNumber);
            nativeDeferTransactionUntil(mNativeObject, sc.mNativeObject, barrier.mNativeObject,
                    frameNumber);
            return this;
        }

@@ -2444,9 +2441,9 @@ public final class SurfaceControl implements Parcelable {
        /**
         * @hide
         */
        public Transaction reparentChildren(SurfaceControl sc, IBinder newParentHandle) {
        public Transaction reparentChildren(SurfaceControl sc, SurfaceControl newParent) {
            sc.checkNotReleased();
            nativeReparentChildren(mNativeObject, sc.mNativeObject, newParentHandle);
            nativeReparentChildren(mNativeObject, sc.mNativeObject, newParent.mNativeObject);
            return this;
        }

+32 −16
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <utils/threads.h>

#include <android/graphics/Region.h>
#include <gui/SurfaceControl.h>
#include <ui/Region.h>

#include "android_hardware_input_InputWindowHandle.h"
@@ -32,8 +33,9 @@
namespace android {

struct WeakRefHandleField {
    jfieldID handle;
    jfieldID ctrl;
    jmethodID get;
    jfieldID mNativeObject;
};

static struct {
@@ -63,7 +65,7 @@ static struct {
    jfieldID displayId;
    jfieldID portalToDisplayId;
    jfieldID replaceTouchableRegionWithCrop;
    WeakRefHandleField touchableRegionCropHandle;
    WeakRefHandleField touchableRegionSurfaceControl;
} gInputWindowHandleClassInfo;

static Mutex gHandleMutex;
@@ -172,19 +174,27 @@ bool NativeInputWindowHandle::updateInfo() {
    mInfo.replaceTouchableRegionWithCrop = env->GetBooleanField(obj,
            gInputWindowHandleClassInfo.replaceTouchableRegionWithCrop);

    jobject handleObj = env->GetObjectField(obj,
            gInputWindowHandleClassInfo.touchableRegionCropHandle.handle);
    if (handleObj) {
    jobject weakSurfaceCtrl = env->GetObjectField(obj,
            gInputWindowHandleClassInfo.touchableRegionSurfaceControl.ctrl);
    bool touchableRegionCropHandleSet = false;
    if (weakSurfaceCtrl) {
        // Promote java weak reference.
        jobject strongHandleObj = env->CallObjectMethod(handleObj,
                gInputWindowHandleClassInfo.touchableRegionCropHandle.get);
        if (strongHandleObj) {
            mInfo.touchableRegionCropHandle = ibinderForJavaObject(env, strongHandleObj);
            env->DeleteLocalRef(strongHandleObj);
        } else {
            mInfo.touchableRegionCropHandle.clear();
        jobject strongSurfaceCtrl = env->CallObjectMethod(weakSurfaceCtrl,
                gInputWindowHandleClassInfo.touchableRegionSurfaceControl.get);
        if (strongSurfaceCtrl) {
            jlong mNativeObject = env->GetLongField(strongSurfaceCtrl,
                    gInputWindowHandleClassInfo.touchableRegionSurfaceControl.mNativeObject);
            if (mNativeObject) {
                auto ctrl = reinterpret_cast<SurfaceControl *>(mNativeObject);
                mInfo.touchableRegionCropHandle = ctrl->getHandle();
                touchableRegionCropHandleSet = true;
            }
        env->DeleteLocalRef(handleObj);
            env->DeleteLocalRef(strongSurfaceCtrl);
        }
        env->DeleteLocalRef(weakSurfaceCtrl);
    }
    if (!touchableRegionCropHandleSet) {
        mInfo.touchableRegionCropHandle.clear();
    }

    env->DeleteLocalRef(obj);
@@ -340,11 +350,17 @@ int register_android_view_InputWindowHandle(JNIEnv* env) {
    jclass weakRefClazz;
    FIND_CLASS(weakRefClazz, "java/lang/ref/Reference");

    GET_METHOD_ID(gInputWindowHandleClassInfo.touchableRegionCropHandle.get, weakRefClazz,
    GET_METHOD_ID(gInputWindowHandleClassInfo.touchableRegionSurfaceControl.get, weakRefClazz,
             "get", "()Ljava/lang/Object;")

    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegionCropHandle.handle, clazz,
            "touchableRegionCropHandle", "Ljava/lang/ref/WeakReference;");
    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegionSurfaceControl.ctrl, clazz,
            "touchableRegionSurfaceControl", "Ljava/lang/ref/WeakReference;");

    jclass surfaceControlClazz;
    FIND_CLASS(surfaceControlClazz, "android/view/SurfaceControl");
    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegionSurfaceControl.mNativeObject,
        surfaceControlClazz, "mNativeObject", "J");

    return 0;
}

+32 −51
Original line number Diff line number Diff line
@@ -272,11 +272,11 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
}

static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj,
        jobject layerHandleToken, jobject sourceCropObj, jfloat frameScale,
        jobjectArray excludeArray) {
        jlong layerObject, jobject sourceCropObj, jfloat frameScale,
        jlongArray excludeObjectArray) {

    sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken);
    if (layerHandle == NULL) {
    auto layer = reinterpret_cast<SurfaceControl *>(layerObject);
    if (layer == NULL) {
        return NULL;
    }

@@ -286,19 +286,20 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTok
    }

    std::unordered_set<sp<IBinder>,ISurfaceComposer::SpHash<IBinder>> excludeHandles;
    if (excludeArray != NULL) {
        const jsize len = env->GetArrayLength(excludeArray);
    if (excludeObjectArray != NULL) {
        const jsize len = env->GetArrayLength(excludeObjectArray);
        excludeHandles.reserve(len);

        const jlong* objects = env->GetLongArrayElements(excludeObjectArray, nullptr);
        for (jsize i = 0; i < len; i++) {
            jobject obj = env->GetObjectArrayElement(excludeArray, i);
            if (obj == nullptr) {
            auto excludeObject = reinterpret_cast<SurfaceControl *>(objects[i]);
            if (excludeObject == nullptr) {
                jniThrowNullPointerException(env, "Exclude layer is null");
                return NULL;
            }
            sp<IBinder> excludeHandle = ibinderForJavaObject(env, obj);
            excludeHandles.emplace(excludeHandle);
            excludeHandles.emplace(excludeObject->getHandle());
        }
        env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT);
    }

    sp<GraphicBuffer> buffer;
@@ -308,7 +309,7 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTok
        const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
        dataspace = pickDataspaceFromColorMode(colorMode);
    }
    status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace,
    status_t res = ScreenshotClient::captureChildLayers(layer->getHandle(), dataspace,
                                                        ui::PixelFormat::RGBA_8888, sourceCrop,
                                                        excludeHandles, frameScale, &buffer);
    if (res != NO_ERROR) {
@@ -360,15 +361,12 @@ static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,

static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
        jlong nativeObject,
        jobject relativeTo, jint zorder) {
        jlong relativeToObject, jint zorder) {

    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
    sp<IBinder> handle = ibinderForJavaObject(env, relativeTo);

    {
    auto relative = reinterpret_cast<SurfaceControl *>(relativeToObject);
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
        transaction->setRelativeLayer(ctrl, handle, zorder);
    }
    transaction->setRelativeLayer(ctrl, relative->getHandle(), zorder);
}

static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -465,7 +463,7 @@ static void nativeSetInputWindowInfo(JNIEnv* env, jclass clazz, jlong transactio
            env, inputWindow);
    handle->updateInfo();

    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
    transaction->setInputWindowInfo(ctrl, *handle->getInfo());
}

@@ -1109,15 +1107,11 @@ static jboolean nativeGetAnimationFrameStats(JNIEnv* env, jclass clazz, jobject
}

static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong transactionObj,
        jlong nativeObject,
        jobject handleObject, jlong frameNumber) {
        jlong nativeObject, jlong barrierObject, jlong frameNumber) {
    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
    sp<IBinder> handle = ibinderForJavaObject(env, handleObject);

    {
    auto barrier = reinterpret_cast<SurfaceControl *>(barrierObject);
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
        transaction->deferTransactionUntil_legacy(ctrl, handle, frameNumber);
    }
    transaction->deferTransactionUntil_legacy(ctrl, barrier->getHandle(), frameNumber);
}

static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -1133,15 +1127,12 @@ static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong

static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
        jlong nativeObject,
        jobject newParentObject) {
        jlong newParentObject) {

    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
    sp<IBinder> handle = ibinderForJavaObject(env, newParentObject);

    {
    auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject);
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
        transaction->reparentChildren(ctrl, handle);
    }
    transaction->reparentChildren(ctrl, newParent->getHandle());
}

static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -1149,12 +1140,9 @@ static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj,
        jlong newParentObject) {
    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
    auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject);

    {
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
    transaction->reparent(ctrl, newParent != NULL ? newParent->getHandle() : NULL);
}
}

static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
        jlong nativeObject) {
@@ -1173,11 +1161,6 @@ static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong transa
    transaction->setOverrideScalingMode(ctrl, scalingMode);
}

static jobject nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
    return javaObjectForIBinder(env, ctrl->getHandle());
}

static jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) {
    sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
    if (token == NULL) return NULL;
@@ -1313,7 +1296,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeSetEarlyWakeup },
    {"nativeSetLayer", "(JJI)V",
            (void*)nativeSetLayer },
    {"nativeSetRelativeLayer", "(JJLandroid/os/IBinder;I)V",
    {"nativeSetRelativeLayer", "(JJJI)V",
            (void*)nativeSetRelativeLayer },
    {"nativeSetPosition", "(JJFF)V",
            (void*)nativeSetPosition },
@@ -1391,11 +1374,11 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeSetDisplayPowerMode },
    {"nativeGetProtectedContentSupport", "()Z",
            (void*)nativeGetProtectedContentSupport },
    {"nativeDeferTransactionUntil", "(JJLandroid/os/IBinder;J)V",
    {"nativeDeferTransactionUntil", "(JJJJ)V",
            (void*)nativeDeferTransactionUntil },
    {"nativeDeferTransactionUntilSurface", "(JJJJ)V",
            (void*)nativeDeferTransactionUntilSurface },
    {"nativeReparentChildren", "(JJLandroid/os/IBinder;)V",
    {"nativeReparentChildren", "(JJJ)V",
            (void*)nativeReparentChildren } ,
    {"nativeReparent", "(JJJ)V",
            (void*)nativeReparent },
@@ -1403,15 +1386,13 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeSeverChildren } ,
    {"nativeSetOverrideScalingMode", "(JJI)V",
            (void*)nativeSetOverrideScalingMode },
    {"nativeGetHandle", "(J)Landroid/os/IBinder;",
            (void*)nativeGetHandle },
    {"nativeScreenshot",
            "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
            "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
            (void*)nativeScreenshot },
    {"nativeCaptureLayers",
            "(Landroid/os/IBinder;Landroid/os/IBinder;Landroid/graphics/Rect;"
            "F[Landroid/os/IBinder;)"
            "(Landroid/os/IBinder;JLandroid/graphics/Rect;"
            "F[J)"
            "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
            (void*)nativeCaptureLayers },
    {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
+2 −2
Original line number Diff line number Diff line
@@ -100,9 +100,9 @@ public class SeamlessRotator {
        t.setPosition(win.mSurfaceControl, win.mLastSurfacePosition.x, win.mLastSurfacePosition.y);
        if (win.mWinAnimator.mSurfaceController != null && !timeout) {
            t.deferTransactionUntil(win.mSurfaceControl,
                    win.mWinAnimator.mSurfaceController.getHandle(), win.getFrameNumber());
                    win.mWinAnimator.mSurfaceController.mSurfaceControl, win.getFrameNumber());
            t.deferTransactionUntil(win.mWinAnimator.mSurfaceController.mSurfaceControl,
                    win.mWinAnimator.mSurfaceController.getHandle(), win.getFrameNumber());
                    win.mWinAnimator.mSurfaceController.mSurfaceControl, win.getFrameNumber());
        }
    }

Loading