blob: 71b8dacfbdfa287f26ee3eee954ec491ac0b0b42 [file] [log] [blame]
Previr Rangroo58822be2017-11-28 17:53:54 +11001/*
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
28namespace android {
29
30struct 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_