diff options
author | Wonsik Kim <wonsik@google.com> | 2018-09-13 13:15:59 -0700 |
---|---|---|
committer | Wonsik Kim <wonsik@google.com> | 2018-09-14 14:37:10 -0700 |
commit | 61796fdaa16ea6c8567215c255fc43c43cf4ee38 (patch) | |
tree | 263fddd15060905cd93b1a04b3097de8dd11319c /media/jni/android_media_MediaCodec.cpp | |
parent | 79a85ae200d8d30bfa41a607b4acdf3b34d72814 (diff) |
media: fix race condition around release
Protect native context for MediaCodec object from concurrent access.
Bug: 112863346
Bug: 112913410
Test: atest frameworks/av/media/libstagefright:postsubmit
Change-Id: Icacdd45bd6dcb0b03e2760a3441d2e7c7587d3ec
Diffstat (limited to 'media/jni/android_media_MediaCodec.cpp')
-rw-r--r-- | media/jni/android_media_MediaCodec.cpp | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index 3490ff8fcf43..503720939113 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -108,8 +108,9 @@ static struct { } gCodecInfo; struct fields_t { - jfieldID context; jmethodID postEventFromNativeID; + jmethodID lockAndGetContextID; + jmethodID setAndUnlockContextID; jfieldID cryptoInfoNumSubSamplesID; jfieldID cryptoInfoNumBytesOfClearDataID; jfieldID cryptoInfoNumBytesOfEncryptedDataID; @@ -931,7 +932,7 @@ using namespace android; static sp<JMediaCodec> setMediaCodec( JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) { - sp<JMediaCodec> old = (JMediaCodec *)env->GetLongField(thiz, gFields.context); + sp<JMediaCodec> old = (JMediaCodec *)env->CallLongMethod(thiz, gFields.lockAndGetContextID); if (codec != NULL) { codec->incStrong(thiz); } @@ -944,13 +945,15 @@ static sp<JMediaCodec> setMediaCodec( old->release(); old->decStrong(thiz); } - env->SetLongField(thiz, gFields.context, (jlong)codec.get()); + env->CallVoidMethod(thiz, gFields.setAndUnlockContextID, (jlong)codec.get()); return old; } static sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) { - return (JMediaCodec *)env->GetLongField(thiz, gFields.context); + sp<JMediaCodec> codec = (JMediaCodec *)env->CallLongMethod(thiz, gFields.lockAndGetContextID); + env->CallVoidMethod(thiz, gFields.setAndUnlockContextID, (jlong)codec.get()); + return codec; } static void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { @@ -1876,15 +1879,21 @@ static void android_media_MediaCodec_native_init(JNIEnv *env) { env, env->FindClass("android/media/MediaCodec")); CHECK(clazz.get() != NULL); - gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J"); - CHECK(gFields.context != NULL); - gFields.postEventFromNativeID = env->GetMethodID( clazz.get(), "postEventFromNative", "(IIILjava/lang/Object;)V"); - CHECK(gFields.postEventFromNativeID != NULL); + gFields.lockAndGetContextID = + env->GetMethodID( + clazz.get(), "lockAndGetContext", "()J"); + CHECK(gFields.lockAndGetContextID != NULL); + + gFields.setAndUnlockContextID = + env->GetMethodID( + clazz.get(), "setAndUnlockContext", "(J)V"); + CHECK(gFields.setAndUnlockContextID != NULL); + jfieldID field; field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_UNENCRYPTED", "I"); CHECK(field != NULL); |