STATUS KinesisVideoClientWrapper::tagResourceFunc()

in src/JNI/com/amazonaws/kinesis/video/producer/jni/KinesisVideoClientWrapper.cpp [2202:2317]


STATUS KinesisVideoClientWrapper::tagResourceFunc(UINT64 customData,
                                            PCHAR streamArn,
                                            UINT32 tagCount,
                                            PTag tags,
                                            PServiceCallContext pCallbackContext)
{
    JNIEnv *env;
    BOOL detached = FALSE;
    STATUS retStatus = STATUS_SUCCESS;
    jstring jstrStreamArn = NULL, jstrTagName = NULL, jstrTagValue = NULL;
    jbyteArray authByteArray = NULL;
    jobjectArray tagArray = NULL;
    jobject tag = NULL;
    jmethodID methodId = NULL;
    jclass tagClass = NULL;
    INT32 envState;
    UINT32 i;

    DLOGS("TID 0x%016" PRIx64 " tagResourceFunc called.", GETTID());

    KinesisVideoClientWrapper *pWrapper = FROM_WRAPPER_HANDLE(customData);
    CHECK(pWrapper != NULL);

    // Early return if no tags
    CHK(tagCount != 0 && tags != NULL, STATUS_SUCCESS);

    // Get the ENV from the JavaVM and ensure we have a JVM thread
    envState = pWrapper->mJvm->GetEnv((PVOID*) &env, JNI_VERSION_1_6);
    if (envState == JNI_EDETACHED) {
        ATTACH_CURRENT_THREAD_TO_JVM(env);

        // Store the detached so we can detach the thread after the call
        detached = TRUE;
    }

    // Call the Java func to create a new string
    jstrStreamArn = env->NewStringUTF(streamArn);

    // Allocate a new byte array
    authByteArray = env->NewByteArray(pCallbackContext->pAuthInfo->size);

    // Get the class object for tags
    tagClass = env->FindClass("com/amazonaws/kinesisvideo/producer/Tag");
    CHK(tagClass != NULL, STATUS_INVALID_OPERATION);

    // Get the Tag constructor method id
    methodId = env->GetMethodID(tagClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
    CHK(methodId != NULL, STATUS_INVALID_OPERATION);

    // Allocate a new object array for tags
    tagArray = env->NewObjectArray((jsize) tagCount, tagClass, NULL);

    if (jstrStreamArn == NULL || authByteArray == NULL || tagArray == NULL) {
        retStatus = STATUS_NOT_ENOUGH_MEMORY;
        goto CleanUp;
    }

    for (i = 0; i < tagCount; i++) {
        // Create the strings
        jstrTagName = env->NewStringUTF(tags[i].name);
        jstrTagValue = env->NewStringUTF(tags[i].value);
        CHK(jstrTagName != NULL && jstrTagValue != NULL, STATUS_NOT_ENOUGH_MEMORY);

        // Create a new tag object
        tag = env->NewObject(tagClass, methodId, jstrTagName, jstrTagValue);
        CHK(tag != NULL, STATUS_NOT_ENOUGH_MEMORY);

        // Set the value of the array index
        env->SetObjectArrayElement(tagArray, i, tag);

        // Remove the references to the constructed strings
        env->DeleteLocalRef(jstrTagName);
        env->DeleteLocalRef(jstrTagValue);
    }

    // Copy the bits into the managed array
    env->SetByteArrayRegion(authByteArray,
                            0,
                            pCallbackContext->pAuthInfo->size,
                            (const jbyte*) pCallbackContext->pAuthInfo->data);

    // Invoke the callback
    retStatus = env->CallIntMethod(pWrapper->mGlobalJniObjRef,
                                   pWrapper->mTagResourceMethodId,
                                   jstrStreamArn,
                                   tagArray,
                                   pCallbackContext->callAfter,
                                   pCallbackContext->timeout,
                                   authByteArray,
                                   pCallbackContext->pAuthInfo->type,
                                   pCallbackContext->customData
    );

    CHK_JVM_EXCEPTION(env);

CleanUp:

    if (jstrStreamArn != NULL) {
        env->DeleteLocalRef(jstrStreamArn);
    }

    if (authByteArray != NULL) {
        env->DeleteLocalRef(authByteArray);
    }

    if (tagArray != NULL) {
        env->DeleteLocalRef(tagArray);
    }

    // Detach the thread if we have attached it to JVM
    if (detached) {
        pWrapper->mJvm->DetachCurrentThread();
    }

    return retStatus;
}