Home | History | Annotate | Download | only in jni
      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_AUDIOPRESENTATION_H_
     18 #define _ANDROID_MEDIA_AUDIOPRESENTATION_H_
     19 
     20 #include "jni.h"
     21 
     22 #include <media/stagefright/foundation/ADebug.h>  // CHECK
     23 #include <media/stagefright/foundation/AudioPresentationInfo.h>
     24 #include <nativehelper/ScopedLocalRef.h>
     25 
     26 namespace android {
     27 
     28 struct JAudioPresentationInfo {
     29     struct fields_t {
     30         jclass      clazz = NULL;
     31         jmethodID   constructID;
     32 
     33         // list parameters
     34         jclass listClazz = NULL;
     35         jmethodID listConstructId;
     36         jmethodID listAddId;
     37 
     38         // hashmap parameters
     39         jclass hashMapClazz = NULL;
     40         jmethodID hashMapConstructID;
     41         jmethodID hashMapPutID;
     42 
     43         // ulocale parameters
     44         jclass ulocaleClazz = NULL;
     45         jmethodID ulocaleConstructID;
     46 
     47         void init(JNIEnv *env) {
     48             jclass lclazz = env->FindClass("android/media/AudioPresentation");
     49             CHECK(lclazz != NULL);
     50             clazz = (jclass)env->NewGlobalRef(lclazz);
     51             CHECK(clazz != NULL);
     52             constructID = env->GetMethodID(clazz, "<init>",
     53                     "(IILandroid/icu/util/ULocale;IZZZLjava/util/Map;)V");
     54             CHECK(constructID != NULL);
     55 
     56             // list objects
     57             jclass llistClazz = env->FindClass("java/util/ArrayList");
     58             CHECK(llistClazz != NULL);
     59             listClazz = static_cast<jclass>(env->NewGlobalRef(llistClazz));
     60             CHECK(listClazz != NULL);
     61             listConstructId = env->GetMethodID(listClazz, "<init>", "()V");
     62             CHECK(listConstructId != NULL);
     63             listAddId = env->GetMethodID(listClazz, "add", "(Ljava/lang/Object;)Z");
     64             CHECK(listAddId != NULL);
     65 
     66             // hashmap objects
     67             jclass lhashMapClazz = env->FindClass("java/util/HashMap");
     68             CHECK(lhashMapClazz != NULL);
     69             hashMapClazz = (jclass)env->NewGlobalRef(lhashMapClazz);
     70             CHECK(hashMapClazz != NULL);
     71             hashMapConstructID = env->GetMethodID(hashMapClazz, "<init>", "()V");
     72             CHECK(hashMapConstructID != NULL);
     73             hashMapPutID = env->GetMethodID(
     74                     hashMapClazz,
     75                     "put",
     76                     "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
     77             CHECK(hashMapPutID != NULL);
     78 
     79             jclass lulocaleClazz = env->FindClass("android/icu/util/ULocale");
     80             CHECK(lulocaleClazz != NULL);
     81             ulocaleClazz = (jclass)env->NewGlobalRef(lulocaleClazz);
     82             CHECK(ulocaleClazz != NULL);
     83             ulocaleConstructID = env->GetMethodID(ulocaleClazz, "<init>", "(Ljava/lang/String;)V");
     84             CHECK(ulocaleConstructID != NULL);
     85         }
     86 
     87         void exit(JNIEnv *env) {
     88             env->DeleteGlobalRef(clazz); clazz = NULL;
     89             env->DeleteGlobalRef(listClazz); listClazz = NULL;
     90             env->DeleteGlobalRef(hashMapClazz); hashMapClazz = NULL;
     91             env->DeleteGlobalRef(ulocaleClazz); ulocaleClazz = NULL;
     92         }
     93     };
     94 
     95     static jobject asJobject(JNIEnv *env, const fields_t& fields) {
     96         return env->NewObject(fields.listClazz, fields.listConstructId);
     97     }
     98 
     99     static void addPresentations(JNIEnv *env, const fields_t& fields,
    100                     const AudioPresentationCollection& presentations, jobject presentationsJObj) {
    101         for (const auto& ap : presentations) {
    102             ScopedLocalRef<jobject> jLabelObject = convertLabelsToMap(env, fields, ap.mLabels);
    103             if (jLabelObject == nullptr) return;
    104             ScopedLocalRef<jstring> jLanguage(env, env->NewStringUTF(ap.mLanguage.c_str()));
    105             if (jLanguage == nullptr) return;
    106             ScopedLocalRef<jobject> jLocale(env, env->NewObject(
    107                             fields.ulocaleClazz, fields.ulocaleConstructID, jLanguage.get()));
    108             ScopedLocalRef<jobject> jValueObj(env, env->NewObject(fields.clazz, fields.constructID,
    109                             static_cast<jint>(ap.mPresentationId),
    110                             static_cast<jint>(ap.mProgramId),
    111                             jLocale.get(),
    112                             static_cast<jint>(ap.mMasteringIndication),
    113                             static_cast<jboolean>((ap.mAudioDescriptionAvailable == 1) ? 1 : 0),
    114                             static_cast<jboolean>((ap.mSpokenSubtitlesAvailable == 1) ? 1 : 0),
    115                             static_cast<jboolean>((ap.mDialogueEnhancementAvailable == 1) ? 1 : 0),
    116                             jLabelObject.get()));
    117             if (jValueObj != nullptr) {
    118                 env->CallBooleanMethod(presentationsJObj, fields.listAddId, jValueObj.get());
    119             }
    120         }
    121     }
    122 
    123   private:
    124     static ScopedLocalRef<jobject> convertLabelsToMap(
    125             JNIEnv *env, const fields_t& fields, const std::map<std::string, std::string> &labels) {
    126         ScopedLocalRef<jobject> nullMap(env, nullptr);
    127         ScopedLocalRef<jobject> hashMap(env, env->NewObject(
    128                         fields.hashMapClazz, fields.hashMapConstructID));
    129         if (hashMap == nullptr) {
    130             return nullMap;
    131         }
    132 
    133         for (const auto& label : labels) {
    134             ScopedLocalRef<jstring> jLanguage(env, env->NewStringUTF(label.first.c_str()));
    135             if (jLanguage == nullptr) return nullMap;
    136             ScopedLocalRef<jobject> jLocale(env, env->NewObject(
    137                             fields.ulocaleClazz,
    138                             fields.ulocaleConstructID,
    139                             jLanguage.get()));
    140             if (jLocale == nullptr) return nullMap;
    141             ScopedLocalRef<jobject> jValue(env, env->NewStringUTF(label.second.c_str()));
    142             if (jValue == nullptr) return nullMap;
    143             env->CallObjectMethod(hashMap.get(), fields.hashMapPutID, jLocale.get(), jValue.get());
    144         }
    145         return hashMap;
    146     }
    147 };
    148 }  // namespace android
    149 
    150 #endif  // _ANDROID_MEDIA_AUDIO_PRESENTATION_H_
    151