Fix incorrect exception handling in JNI code

This commit is contained in:
Cameron Gutman 2020-03-21 14:30:31 -07:00
parent d113878613
commit b6e8389544

View File

@ -98,12 +98,9 @@ int BridgeDrSetup(int videoFormat, int width, int height, int redrawRate, void*
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
int err; int err;
if ((*env)->ExceptionCheck(env)) {
return -1;
}
err = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeDrSetupMethod, videoFormat, width, height, redrawRate); err = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeDrSetupMethod, videoFormat, width, height, redrawRate);
if ((*env)->ExceptionCheck(env)) { if ((*env)->ExceptionCheck(env)) {
// This is called on a Java thread, so it's safe to return
return -1; return -1;
} }
else if (err != 0) { else if (err != 0) {
@ -119,20 +116,12 @@ int BridgeDrSetup(int videoFormat, int width, int height, int redrawRate, void*
void BridgeDrStart(void) { void BridgeDrStart(void) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeDrStartMethod); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeDrStartMethod);
} }
void BridgeDrStop(void) { void BridgeDrStop(void) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeDrStopMethod); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeDrStopMethod);
} }
@ -141,10 +130,6 @@ void BridgeDrCleanup(void) {
(*env)->DeleteGlobalRef(env, DecodedFrameBuffer); (*env)->DeleteGlobalRef(env, DecodedFrameBuffer);
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeDrCleanupMethod); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeDrCleanupMethod);
} }
@ -152,10 +137,6 @@ int BridgeDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
int ret; int ret;
if ((*env)->ExceptionCheck(env)) {
return DR_OK;
}
// Increase the size of our frame data buffer if our frame won't fit // Increase the size of our frame data buffer if our frame won't fit
if ((*env)->GetArrayLength(env, DecodedFrameBuffer) < decodeUnit->fullLength) { if ((*env)->GetArrayLength(env, DecodedFrameBuffer) < decodeUnit->fullLength) {
(*env)->DeleteGlobalRef(env, DecodedFrameBuffer); (*env)->DeleteGlobalRef(env, DecodedFrameBuffer);
@ -178,6 +159,8 @@ int BridgeDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
DecodedFrameBuffer, currentEntry->length, currentEntry->bufferType, DecodedFrameBuffer, currentEntry->length, currentEntry->bufferType,
decodeUnit->frameNumber, decodeUnit->receiveTimeMs); decodeUnit->frameNumber, decodeUnit->receiveTimeMs);
if ((*env)->ExceptionCheck(env)) { if ((*env)->ExceptionCheck(env)) {
// We will crash here
(*JVM)->DetachCurrentThread(JVM);
return DR_OK; return DR_OK;
} }
else if (ret != DR_OK) { else if (ret != DR_OK) {
@ -192,22 +175,27 @@ int BridgeDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
currentEntry = currentEntry->next; currentEntry = currentEntry->next;
} }
return (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeDrSubmitDecodeUnitMethod, ret = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeDrSubmitDecodeUnitMethod,
DecodedFrameBuffer, offset, BUFFER_TYPE_PICDATA, DecodedFrameBuffer, offset, BUFFER_TYPE_PICDATA,
decodeUnit->frameNumber, decodeUnit->frameNumber,
decodeUnit->receiveTimeMs); decodeUnit->receiveTimeMs);
if ((*env)->ExceptionCheck(env)) {
// We will crash here
(*JVM)->DetachCurrentThread(JVM);
return DR_OK;
}
else {
return ret;
}
} }
int BridgeArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int flags) { int BridgeArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int flags) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
int err; int err;
if ((*env)->ExceptionCheck(env)) {
return -1;
}
err = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeArInitMethod, audioConfiguration, opusConfig->sampleRate, opusConfig->samplesPerFrame); err = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeArInitMethod, audioConfiguration, opusConfig->sampleRate, opusConfig->samplesPerFrame);
if ((*env)->ExceptionCheck(env)) { if ((*env)->ExceptionCheck(env)) {
// This is called on a Java thread, so it's safe to return
err = -1; err = -1;
} }
if (err == 0) { if (err == 0) {
@ -233,20 +221,12 @@ int BridgeArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusCon
void BridgeArStart(void) { void BridgeArStart(void) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeArStartMethod); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeArStartMethod);
} }
void BridgeArStop(void) { void BridgeArStop(void) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeArStopMethod); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeArStopMethod);
} }
@ -257,20 +237,12 @@ void BridgeArCleanup() {
(*env)->DeleteGlobalRef(env, DecodedAudioBuffer); (*env)->DeleteGlobalRef(env, DecodedAudioBuffer);
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeArCleanupMethod); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeArCleanupMethod);
} }
void BridgeArDecodeAndPlaySample(char* sampleData, int sampleLength) { void BridgeArDecodeAndPlaySample(char* sampleData, int sampleLength) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
jshort* decodedData = (*env)->GetShortArrayElements(env, DecodedAudioBuffer, 0); jshort* decodedData = (*env)->GetShortArrayElements(env, DecodedAudioBuffer, 0);
int decodeLen = opus_multistream_decode(Decoder, int decodeLen = opus_multistream_decode(Decoder,
@ -284,6 +256,10 @@ void BridgeArDecodeAndPlaySample(char* sampleData, int sampleLength) {
(*env)->ReleaseShortArrayElements(env, DecodedAudioBuffer, decodedData, 0); (*env)->ReleaseShortArrayElements(env, DecodedAudioBuffer, decodedData, 0);
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeArPlaySampleMethod, DecodedAudioBuffer); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeArPlaySampleMethod, DecodedAudioBuffer);
if ((*env)->ExceptionCheck(env)) {
// We will crash here
(*JVM)->DetachCurrentThread(JVM);
}
} }
else { else {
// We can abort here to avoid the copy back since no data was modified // We can abort here to avoid the copy back since no data was modified
@ -294,71 +270,56 @@ void BridgeArDecodeAndPlaySample(char* sampleData, int sampleLength) {
void BridgeClStageStarting(int stage) { void BridgeClStageStarting(int stage) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClStageStartingMethod, stage); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClStageStartingMethod, stage);
} }
void BridgeClStageComplete(int stage) { void BridgeClStageComplete(int stage) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClStageCompleteMethod, stage); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClStageCompleteMethod, stage);
} }
void BridgeClStageFailed(int stage, int errorCode) { void BridgeClStageFailed(int stage, int errorCode) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClStageFailedMethod, stage, errorCode); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClStageFailedMethod, stage, errorCode);
} }
void BridgeClConnectionStarted(void) { void BridgeClConnectionStarted(void) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClConnectionStartedMethod); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClConnectionStartedMethod);
} }
void BridgeClConnectionTerminated(int errorCode) { void BridgeClConnectionTerminated(int errorCode) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClConnectionTerminatedMethod, errorCode); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClConnectionTerminatedMethod, errorCode);
if ((*env)->ExceptionCheck(env)) {
// We will crash here
(*JVM)->DetachCurrentThread(JVM);
}
} }
void BridgeClRumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor) { void BridgeClRumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
if ((*env)->ExceptionCheck(env)) {
return;
}
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClRumbleMethod, controllerNumber, lowFreqMotor, highFreqMotor); (*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClRumbleMethod, controllerNumber, lowFreqMotor, highFreqMotor);
if ((*env)->ExceptionCheck(env)) {
// We will crash here
(*JVM)->DetachCurrentThread(JVM);
}
} }
void BridgeClConnectionStatusUpdate(int connectionStatus) { void BridgeClConnectionStatusUpdate(int connectionStatus) {
JNIEnv* env = GetThreadEnv(); JNIEnv* env = GetThreadEnv();
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClConnectionStatusUpdateMethod, connectionStatus);
if ((*env)->ExceptionCheck(env)) { if ((*env)->ExceptionCheck(env)) {
// We will crash here
(*JVM)->DetachCurrentThread(JVM);
return; return;
} }
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClConnectionStatusUpdateMethod, connectionStatus);
} }
void BridgeClLogMessage(const char* format, ...) { void BridgeClLogMessage(const char* format, ...) {