• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
initJAudioPresentationInfo::fields_t40         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 
exitJAudioPresentationInfo::fields_t67         void exit(JNIEnv *env) {
68             env->DeleteGlobalRef(clazz);
69             clazz = NULL;
70             env->DeleteGlobalRef(listclazz);
71             listclazz = NULL;
72         }
73     };
74 
ConvertMessageToMapJAudioPresentationInfo75     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 
asJobjectJAudioPresentationInfo130     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_
174