Allow MediaCodecs to be created on behalf of other client processes.
Use case is for TV Input Service which creates MediaCodecs when tuning
to TV channels on behalf of operator and OEM apps. Requires the
MEDIA_RESOURCE_PID_OVERRIDE permission.
Bug: 217746837
Test: atest MediaCodecResourceTest
Change-Id: I191ff13c5730970664a818a9333c160e6e773c7d
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index f694482..c8d2d1e 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -202,7 +202,7 @@
JMediaCodec::JMediaCodec(
JNIEnv *env, jobject thiz,
- const char *name, bool nameIsType, bool encoder)
+ const char *name, bool nameIsType, bool encoder, int pid, int uid)
: mClass(NULL),
mObject(NULL) {
jclass clazz = env->GetObjectClass(thiz);
@@ -220,12 +220,12 @@
ANDROID_PRIORITY_VIDEO);
if (nameIsType) {
- mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus);
+ mCodec = MediaCodec::CreateByType(mLooper, name, encoder, &mInitStatus, pid, uid);
if (mCodec == nullptr || mCodec->getName(&mNameAtCreation) != OK) {
mNameAtCreation = "(null)";
}
} else {
- mCodec = MediaCodec::CreateByComponentName(mLooper, name, &mInitStatus);
+ mCodec = MediaCodec::CreateByComponentName(mLooper, name, &mInitStatus, pid, uid);
mNameAtCreation = name;
}
CHECK((mCodec != NULL) != (mInitStatus != OK));
@@ -3136,7 +3136,7 @@
static void android_media_MediaCodec_native_setup(
JNIEnv *env, jobject thiz,
- jstring name, jboolean nameIsType, jboolean encoder) {
+ jstring name, jboolean nameIsType, jboolean encoder, int pid, int uid) {
if (name == NULL) {
jniThrowException(env, "java/lang/NullPointerException", NULL);
return;
@@ -3148,24 +3148,33 @@
return;
}
- sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder);
+ sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder, pid, uid);
const status_t err = codec->initCheck();
if (err == NAME_NOT_FOUND) {
// fail and do not try again.
jniThrowException(env, "java/lang/IllegalArgumentException",
- String8::format("Failed to initialize %s, error %#x", tmp, err));
+ String8::format("Failed to initialize %s, error %#x (NAME_NOT_FOUND)", tmp, err));
env->ReleaseStringUTFChars(name, tmp);
return;
- } if (err == NO_MEMORY) {
+ }
+ if (err == NO_MEMORY) {
throwCodecException(env, err, ACTION_CODE_TRANSIENT,
- String8::format("Failed to initialize %s, error %#x", tmp, err));
+ String8::format("Failed to initialize %s, error %#x (NO_MEMORY)", tmp, err));
env->ReleaseStringUTFChars(name, tmp);
return;
- } else if (err != OK) {
+ }
+ if (err == PERMISSION_DENIED) {
+ jniThrowException(env, "java/lang/SecurityException",
+ String8::format("Failed to initialize %s, error %#x (PERMISSION_DENIED)", tmp,
+ err));
+ env->ReleaseStringUTFChars(name, tmp);
+ return;
+ }
+ if (err != OK) {
// believed possible to try again
jniThrowException(env, "java/io/IOException",
- String8::format("Failed to find matching codec %s, error %#x", tmp, err));
+ String8::format("Failed to find matching codec %s, error %#x (?)", tmp, err));
env->ReleaseStringUTFChars(name, tmp);
return;
}
@@ -3174,7 +3183,7 @@
codec->registerSelf();
- setMediaCodec(env,thiz, codec);
+ setMediaCodec(env, thiz, codec);
}
static void android_media_MediaCodec_native_finalize(
@@ -3478,7 +3487,7 @@
{ "native_init", "()V", (void *)android_media_MediaCodec_native_init },
- { "native_setup", "(Ljava/lang/String;ZZ)V",
+ { "native_setup", "(Ljava/lang/String;ZZII)V",
(void *)android_media_MediaCodec_native_setup },
{ "native_finalize", "()V",