summaryrefslogtreecommitdiff
path: root/media/jni/android_media_MediaCodec.cpp
diff options
context:
space:
mode:
authorWonsik Kim <wonsik@google.com>2018-09-13 13:15:59 -0700
committerWonsik Kim <wonsik@google.com>2018-09-14 14:37:10 -0700
commit61796fdaa16ea6c8567215c255fc43c43cf4ee38 (patch)
tree263fddd15060905cd93b1a04b3097de8dd11319c /media/jni/android_media_MediaCodec.cpp
parent79a85ae200d8d30bfa41a607b4acdf3b34d72814 (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.cpp25
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);