Previr Rangroo | 58822be | 2017-11-28 17:53:54 +1100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2018, The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #ifndef _ANDROID_MEDIA_AUDIO_PRESENTATION_H_ |
| 18 | #define _ANDROID_MEDIA_AUDIO_PRESENTATION_H_ |
| 19 | |
| 20 | #include "jni.h" |
| 21 | |
| 22 | #include <media/AudioPresentationInfo.h> |
| 23 | #include <media/stagefright/foundation/ADebug.h> |
| 24 | #include <media/stagefright/foundation/AMessage.h> |
| 25 | |
| 26 | #include <nativehelper/ScopedLocalRef.h> |
| 27 | |
| 28 | namespace android { |
| 29 | |
| 30 | struct JAudioPresentationInfo { |
| 31 | struct fields_t { |
| 32 | jclass clazz; |
| 33 | jmethodID constructID; |
| 34 | |
| 35 | // list parameters |
| 36 | jclass listclazz; |
| 37 | jmethodID listConstructId; |
| 38 | jmethodID listAddId; |
| 39 | |
| 40 | void init(JNIEnv *env) { |
| 41 | jclass lclazz = env->FindClass("android/media/AudioPresentation"); |
| 42 | if (lclazz == NULL) { |
| 43 | return; |
| 44 | } |
| 45 | |
| 46 | clazz = (jclass)env->NewGlobalRef(lclazz); |
| 47 | if (clazz == NULL) { |
| 48 | return; |
| 49 | } |
| 50 | |
| 51 | constructID = env->GetMethodID(clazz, "<init>", |
| 52 | "(IILjava/util/Map;Ljava/lang/String;IZZZ)V"); |
| 53 | env->DeleteLocalRef(lclazz); |
| 54 | |
| 55 | // list objects |
| 56 | jclass llistclazz = env->FindClass("java/util/ArrayList"); |
| 57 | CHECK(llistclazz != NULL); |
| 58 | listclazz = static_cast<jclass>(env->NewGlobalRef(llistclazz)); |
| 59 | CHECK(listclazz != NULL); |
| 60 | listConstructId = env->GetMethodID(listclazz, "<init>", "()V"); |
| 61 | CHECK(listConstructId != NULL); |
| 62 | listAddId = env->GetMethodID(listclazz, "add", "(Ljava/lang/Object;)Z"); |
| 63 | CHECK(listAddId != NULL); |
| 64 | env->DeleteLocalRef(llistclazz); |
| 65 | } |
| 66 | |
| 67 | void exit(JNIEnv *env) { |
| 68 | env->DeleteGlobalRef(clazz); |
| 69 | clazz = NULL; |
| 70 | env->DeleteGlobalRef(listclazz); |
| 71 | listclazz = NULL; |
| 72 | } |
| 73 | }; |
| 74 | |
| 75 | static status_t ConvertMessageToMap(JNIEnv *env, const sp<AMessage> &msg, jobject *map) { |
| 76 | ScopedLocalRef<jclass> hashMapClazz(env, env->FindClass("java/util/HashMap")); |
| 77 | |
| 78 | if (hashMapClazz.get() == NULL) { |
| 79 | return -EINVAL; |
| 80 | } |
| 81 | jmethodID hashMapConstructID = |
| 82 | env->GetMethodID(hashMapClazz.get(), "<init>", "()V"); |
| 83 | |
| 84 | if (hashMapConstructID == NULL) { |
| 85 | return -EINVAL; |
| 86 | } |
| 87 | jmethodID hashMapPutID = |
| 88 | env->GetMethodID( |
| 89 | hashMapClazz.get(), |
| 90 | "put", |
| 91 | "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); |
| 92 | |
| 93 | if (hashMapPutID == NULL) { |
| 94 | return -EINVAL; |
| 95 | } |
| 96 | |
| 97 | jobject hashMap = env->NewObject(hashMapClazz.get(), hashMapConstructID); |
| 98 | |
| 99 | for (size_t i = 0; i < msg->countEntries(); ++i) { |
| 100 | AMessage::Type valueType; |
| 101 | const char *key = msg->getEntryNameAt(i, &valueType); |
| 102 | |
| 103 | if (!strncmp(key, "android._", 9)) { |
| 104 | // don't expose private keys (starting with android._) |
| 105 | continue; |
| 106 | } |
| 107 | |
| 108 | jobject valueObj = NULL; |
| 109 | |
| 110 | AString val; |
| 111 | CHECK(msg->findString(key, &val)); |
| 112 | |
| 113 | valueObj = env->NewStringUTF(val.c_str()); |
| 114 | |
| 115 | if (valueObj != NULL) { |
| 116 | jstring keyObj = env->NewStringUTF(key); |
| 117 | |
| 118 | env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj); |
| 119 | |
| 120 | env->DeleteLocalRef(keyObj); keyObj = NULL; |
| 121 | env->DeleteLocalRef(valueObj); valueObj = NULL; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | *map = hashMap; |
| 126 | |
| 127 | return OK; |
| 128 | } |
| 129 | |
| 130 | jobject asJobject(JNIEnv *env, const fields_t& fields, const AudioPresentationInfo &info) { |
| 131 | jobject list = env->NewObject(fields.listclazz, fields.listConstructId); |
| 132 | |
| 133 | for (size_t i = 0; i < info.countPresentations(); ++i) { |
| 134 | const sp<AudioPresentation> &ap = info.getPresentation(i); |
| 135 | jobject jLabelObject; |
| 136 | |
| 137 | sp<AMessage> labelMessage = new AMessage(); |
| 138 | for (size_t i = 0; i < ap->mLabels.size(); ++i) { |
| 139 | labelMessage->setString(ap->mLabels.keyAt(i).string(), |
| 140 | ap->mLabels.valueAt(i).string()); |
| 141 | } |
| 142 | if (ConvertMessageToMap(env, labelMessage, &jLabelObject) != OK) { |
| 143 | return NULL; |
| 144 | } |
| 145 | jstring jLanguage = env->NewStringUTF(ap->mLanguage.string()); |
| 146 | |
| 147 | jobject jValueObj = env->NewObject(fields.clazz, fields.constructID, |
| 148 | static_cast<jint>(ap->mPresentationId), |
| 149 | static_cast<jint>(ap->mProgramId), |
| 150 | jLabelObject, |
| 151 | jLanguage, |
| 152 | static_cast<jint>(ap->mMasteringIndication), |
| 153 | static_cast<jboolean>((ap->mAudioDescriptionAvailable == 1) ? |
| 154 | 1 : 0), |
| 155 | static_cast<jboolean>((ap->mSpokenSubtitlesAvailable == 1) ? |
| 156 | 1 : 0), |
| 157 | static_cast<jboolean>((ap->mDialogueEnhancementAvailable == 1) ? |
| 158 | 1 : 0)); |
| 159 | if (jValueObj == NULL) { |
| 160 | env->DeleteLocalRef(jLanguage); jLanguage = NULL; |
| 161 | return NULL; |
| 162 | } |
| 163 | |
| 164 | env->CallBooleanMethod(list, fields.listAddId, jValueObj); |
| 165 | env->DeleteLocalRef(jValueObj); jValueObj = NULL; |
| 166 | env->DeleteLocalRef(jLanguage); jLanguage = NULL; |
| 167 | } |
| 168 | return list; |
| 169 | } |
| 170 | }; |
| 171 | } // namespace android |
| 172 | |
| 173 | #endif // _ANDROID_MEDIA_AUDIO_PRESENTATION_H_ |