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

Commit fdfec366 authored by Eino-Ville Talvala's avatar Eino-Ville Talvala
Browse files

Camera NDK: New lifecycle for ACameraMetadata_fromCameraMetadata

Instead of requiring the user to call NewGlobalRef/DeleteGlobalRef
for keeping the java object alive when creating an NDK view into it,
reference count the real native data instead, so that there's no need
to keep track of the Java object lifecycle.

- Switch CameraMetadataNative use std::shared_ptr

Test: New CTS tests pass, fail without this CL
Bug: 148972471
Change-Id: I9a00fc1daa1beac35a15484960048facb90499a6
parent 825f041a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ public abstract class CameraMetadata<TKey> {
    }

    /**
     * Retrieves the native CameraMetadata* as a Java long.
     * Retrieves the native std::shared_ptr<CameraMetadata*>* as a Java long.
     * Returns 0 if mNativeInstance is null.
     *
     * @hide
+1 −1
Original line number Diff line number Diff line
@@ -1680,7 +1680,7 @@ public class CameraMetadataNative implements Parcelable {
    }

    @UnsupportedAppUsage
    private long mMetadataPtr; // native CameraMetadata*
    private long mMetadataPtr; // native std::shared_ptr<CameraMetadata>*

    private native long nativeAllocate();
    private native long nativeAllocateCopy(CameraMetadataNative other)
+23 −18
Original line number Diff line number Diff line
@@ -89,13 +89,13 @@ status_t CameraMetadata_getNativeMetadata(JNIEnv* env, jobject thiz,
        ALOGE("%s: Invalid output metadata object.", __FUNCTION__);
        return BAD_VALUE;
    }
    CameraMetadata* nativePtr = reinterpret_cast<CameraMetadata*>(env->GetLongField(thiz,
            fields.metadata_ptr));
    auto nativePtr = reinterpret_cast<std::shared_ptr<CameraMetadata> *>(
            env->GetLongField(thiz, fields.metadata_ptr));
    if (nativePtr == NULL) {
        ALOGE("%s: Invalid native pointer in java metadata object.", __FUNCTION__);
        return BAD_VALUE;
    }
    *metadata = *nativePtr;
    *metadata = *(nativePtr->get());
    return OK;
}

@@ -171,12 +171,15 @@ static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject t

// Less safe access to native pointer. Does NOT throw any Java exceptions if NULL.
static CameraMetadata* CameraMetadata_getPointerNoThrow(JNIEnv *env, jobject thiz) {

    if (thiz == NULL) {
        return NULL;
    if (thiz == nullptr) {
        return nullptr;
    }

    return reinterpret_cast<CameraMetadata*>(env->GetLongField(thiz, fields.metadata_ptr));
    auto metadata = reinterpret_cast<std::shared_ptr<CameraMetadata> *>(
            env->GetLongField(thiz, fields.metadata_ptr));
    if (metadata == nullptr) {
        return nullptr;
    }
    return metadata->get();
}

// Safe access to native pointer from object. Throws if not possible to access.
@@ -205,7 +208,7 @@ static CameraMetadata* CameraMetadata_getPointerThrow(JNIEnv *env, jobject thiz,
static jlong CameraMetadata_allocate(JNIEnv *env, jobject thiz) {
    ALOGV("%s", __FUNCTION__);

    return reinterpret_cast<jlong>(new CameraMetadata());
    return reinterpret_cast<jlong>(new std::shared_ptr<CameraMetadata>(new CameraMetadata()));
}

static jlong CameraMetadata_allocateCopy(JNIEnv *env, jobject thiz,
@@ -214,12 +217,12 @@ static jlong CameraMetadata_allocateCopy(JNIEnv *env, jobject thiz,

    CameraMetadata* otherMetadata =
            CameraMetadata_getPointerThrow(env, other, "other");

    // In case of exception, return
    if (otherMetadata == NULL) return NULL;

    // Clone native metadata and return new pointer
    return reinterpret_cast<jlong>(new CameraMetadata(*otherMetadata));
    // Clone native metadata and return new pointer.
    auto clonedMetadata = new CameraMetadata(*otherMetadata);
    return reinterpret_cast<jlong>(new std::shared_ptr<CameraMetadata>(clonedMetadata));
}


@@ -256,14 +259,16 @@ static jint CameraMetadata_getEntryCount(JNIEnv *env, jobject thiz) {
static void CameraMetadata_close(JNIEnv *env, jobject thiz) {
    ALOGV("%s", __FUNCTION__);

    CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz);

    if (metadata != NULL) {
    if (thiz != nullptr) {
        auto metadata = reinterpret_cast<std::shared_ptr<CameraMetadata> *>(
                env->GetLongField(thiz, fields.metadata_ptr));
        if (metadata != nullptr) {
            delete metadata;
            env->SetLongField(thiz, fields.metadata_ptr, 0);
        }
    }

    LOG_ALWAYS_FATAL_IF(CameraMetadata_getPointerNoThrow(env, thiz) != NULL,
    LOG_ALWAYS_FATAL_IF(CameraMetadata_getPointerNoThrow(env, thiz) != nullptr,
                        "Expected the native ptr to be 0 after #close");
}