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;
}