Loading api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -17386,6 +17386,8 @@ package android.hardware.radio { method public java.lang.String getVersion(); method public boolean isBackgroundScanningSupported(); method public boolean isCaptureSupported(); method public boolean isProgramIdentifierSupported(int); method public boolean isProgramTypeSupported(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.hardware.radio.RadioManager.ModuleProperties> CREATOR; } core/java/android/hardware/radio/RadioManager.java +44 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * The RadioManager class allows to control a broadcast radio tuner present on the device. Loading Loading @@ -132,11 +134,15 @@ public class RadioManager { private final boolean mIsCaptureSupported; private final BandDescriptor[] mBands; private final boolean mIsBgScanSupported; private final Set<Integer> mSupportedProgramTypes; private final Set<Integer> mSupportedIdentifierTypes; private final String mVendorExension; ModuleProperties(int id, String serviceName, int classId, String implementor, String product, String version, String serial, int numTuners, int numAudioSources, boolean isCaptureSupported, BandDescriptor[] bands, boolean isBgScanSupported, @ProgramSelector.ProgramType int[] supportedProgramTypes, @ProgramSelector.IdentifierType int[] supportedIdentifierTypes, String vendorExension) { mId = id; mServiceName = TextUtils.isEmpty(serviceName) ? "default" : serviceName; Loading @@ -150,9 +156,18 @@ public class RadioManager { mIsCaptureSupported = isCaptureSupported; mBands = bands; mIsBgScanSupported = isBgScanSupported; mSupportedProgramTypes = arrayToSet(supportedProgramTypes); mSupportedIdentifierTypes = arrayToSet(supportedIdentifierTypes); mVendorExension = vendorExension; } private static Set<Integer> arrayToSet(int[] arr) { return Arrays.stream(arr).boxed().collect(Collectors.toSet()); } private static int[] setToArray(Set<Integer> set) { return set.stream().mapToInt(Integer::intValue).toArray(); } /** Unique module identifier provided by the native service. * For use with {@link #openTuner(int, BandConfig, boolean, Callback, Handler)}. Loading Loading @@ -244,6 +259,31 @@ public class RadioManager { return mIsBgScanSupported; } /** * Checks, if a given program type is supported by this tuner. * * If a program type is supported by radio module, it means it can tune * to ProgramSelector of a given type. * * @return {@code true} if a given program type is supported. */ public boolean isProgramTypeSupported(@ProgramSelector.ProgramType int type) { return mSupportedProgramTypes.contains(type); } /** * Checks, if a given program identifier is supported by this tuner. * * If an identifier is supported by radio module, it means it can use it for * tuning to ProgramSelector with either primary or secondary Identifier of * a given type. * * @return {@code true} if a given program type is supported. */ public boolean isProgramIdentifierSupported(@ProgramSelector.IdentifierType int type) { return mSupportedIdentifierTypes.contains(type); } /** * Opaque vendor-specific string, passed from HAL without changes. * Format of this string can vary across vendors. Loading Loading @@ -283,6 +323,8 @@ public class RadioManager { mBands[i] = (BandDescriptor) tmp[i]; } mIsBgScanSupported = in.readInt() == 1; mSupportedProgramTypes = arrayToSet(in.createIntArray()); mSupportedIdentifierTypes = arrayToSet(in.createIntArray()); mVendorExension = in.readString(); } Loading Loading @@ -311,6 +353,8 @@ public class RadioManager { dest.writeInt(mIsCaptureSupported ? 1 : 0); dest.writeParcelableArray(mBands, flags); dest.writeInt(mIsBgScanSupported ? 1 : 0); dest.writeIntArray(setToArray(mSupportedProgramTypes)); dest.writeIntArray(setToArray(mSupportedIdentifierTypes)); dest.writeString(mVendorExension); } Loading services/core/jni/com_android_server_radio_convert.cpp +51 −25 Original line number Diff line number Diff line Loading @@ -185,6 +185,44 @@ void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg) { ALOGE_IF(res != JNI_OK, "Couldn't throw parcelable runtime exception"); } static JavaRef<jintArray> ArrayFromHal(JNIEnv *env, const hidl_vec<uint32_t>& vec) { auto jArr = make_javaref(env, env->NewIntArray(vec.size())); auto jArrElements = env->GetIntArrayElements(jArr.get(), nullptr); for (size_t i = 0; i < vec.size(); i++) { jArrElements[i] = vec[i]; } env->ReleaseIntArrayElements(jArr.get(), jArrElements, 0); return jArr; } static JavaRef<jlongArray> ArrayFromHal(JNIEnv *env, const hidl_vec<uint64_t>& vec) { auto jArr = make_javaref(env, env->NewLongArray(vec.size())); auto jArrElements = env->GetLongArrayElements(jArr.get(), nullptr); for (size_t i = 0; i < vec.size(); i++) { jArrElements[i] = vec[i]; } env->ReleaseLongArrayElements(jArr.get(), jArrElements, 0); return jArr; } template <typename T> static JavaRef<jobjectArray> ArrayFromHal(JNIEnv *env, const hidl_vec<T>& vec, jclass jElementClass, std::function<JavaRef<jobject>(JNIEnv*, const T&)> converter) { auto jArr = make_javaref(env, env->NewObjectArray(vec.size(), jElementClass, nullptr)); for (size_t i = 0; i < vec.size(); i++) { auto jElement = converter(env, vec[i]); env->SetObjectArrayElement(jArr.get(), i, jElement.get()); } return jArr; } template <typename T> static JavaRef<jobjectArray> ArrayFromHal(JNIEnv *env, const hidl_vec<T>& vec, jclass jElementClass, JavaRef<jobject>(*converter)(JNIEnv*, const T&)) { return ArrayFromHal(env, vec, jElementClass, std::function<JavaRef<jobject>(JNIEnv*, const T&)>(converter)); } static Rds RdsForRegion(bool rds, Region region) { if (!rds) return Rds::NONE; Loading Loading @@ -220,6 +258,7 @@ static Deemphasis DeemphasisForRegion(Region region) { static JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &prop10, const V1_1::Properties *prop11, jint moduleId, const std::string& serviceName) { ALOGV("ModulePropertiesFromHal()"); using namespace std::placeholders; auto jServiceName = make_javastr(env, serviceName); auto jImplementor = make_javastr(env, prop10.implementor); Loading @@ -228,21 +267,19 @@ static JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Propert auto jSerial = make_javastr(env, prop10.serial); bool isBgScanSupported = prop11 ? prop11->supportsBackgroundScanning : false; auto jVendorExtension = prop11 ? make_javastr(env, prop11->vendorExension) : nullptr; auto jBands = make_javaref(env, env->NewObjectArray(prop10.bands.size(), gjni.BandDescriptor.clazz, nullptr)); int i = 0; for (auto &&band : prop10.bands) { // ITU_1 is the default region just because its index is 0. auto jBand = BandDescriptorFromHal(env, band, Region::ITU_1); env->SetObjectArrayElement(jBands.get(), i++, jBand.get()); } auto jBands = ArrayFromHal<V1_0::BandConfig>(env, prop10.bands, gjni.BandDescriptor.clazz, std::bind(BandDescriptorFromHal, _1, _2, Region::ITU_1)); auto jSupportedProgramTypes = prop11 ? ArrayFromHal(env, prop11->supportedProgramTypes) : nullptr; auto jSupportedIdentifierTypes = prop11 ? ArrayFromHal(env, prop11->supportedIdentifierTypes) : nullptr; return make_javaref(env, env->NewObject(gjni.ModuleProperties.clazz, gjni.ModuleProperties.cstor, moduleId, jServiceName.get(), prop10.classId, jImplementor.get(), jProduct.get(), jVersion.get(), jSerial.get(), prop10.numTuners, prop10.numAudioSources, prop10.supportsCapture, jBands.get(), isBgScanSupported, jVendorExtension.get())); jSupportedProgramTypes.get(), jSupportedIdentifierTypes.get(), jVendorExtension.get())); } JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &properties, Loading Loading @@ -411,20 +448,9 @@ static JavaRef<jobject> ProgramIdentifierFromHal(JNIEnv *env, const ProgramIdent static JavaRef<jobject> ProgramSelectorFromHal(JNIEnv *env, const ProgramSelector &selector) { ALOGV("ProgramSelectorFromHal()"); auto jPrimary = ProgramIdentifierFromHal(env, selector.primaryId); auto jSecondary = make_javaref(env, env->NewObjectArray(selector.secondaryIds.size(), gjni.ProgramSelector.Identifier.clazz, nullptr)); for (size_t i = 0; i < selector.secondaryIds.size(); i++) { auto jId = ProgramIdentifierFromHal(env, selector.secondaryIds[i]); env->SetObjectArrayElement(jSecondary.get(), i, jId.get()); } auto jVendor = make_javaref(env, env->NewLongArray(selector.vendorIds.size())); auto jVendorElements = env->GetLongArrayElements(jVendor.get(), nullptr); for (size_t i = 0; i < selector.vendorIds.size(); i++) { jVendorElements[i] = selector.vendorIds[i]; } env->ReleaseLongArrayElements(jVendor.get(), jVendorElements, 0); auto jSecondary = ArrayFromHal(env, selector.secondaryIds, gjni.ProgramSelector.Identifier.clazz, ProgramIdentifierFromHal); auto jVendor = ArrayFromHal(env, selector.vendorIds); return make_javaref(env, env->NewObject(gjni.ProgramSelector.clazz, gjni.ProgramSelector.cstor, selector.programType, jPrimary.get(), jSecondary.get(), jVendor.get())); Loading Loading @@ -554,7 +580,7 @@ void register_android_server_radio_convert(JNIEnv *env) { gjni.ModuleProperties.cstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>", "(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;" "Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;Z" "Ljava/lang/String;)V"); "[I[ILjava/lang/String;)V"); auto programInfoClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ProgramInfo"); gjni.ProgramInfo.clazz = MakeGlobalRefOrDie(env, programInfoClass); Loading Loading
api/system-current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -17386,6 +17386,8 @@ package android.hardware.radio { method public java.lang.String getVersion(); method public boolean isBackgroundScanningSupported(); method public boolean isCaptureSupported(); method public boolean isProgramIdentifierSupported(int); method public boolean isProgramTypeSupported(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.hardware.radio.RadioManager.ModuleProperties> CREATOR; }
core/java/android/hardware/radio/RadioManager.java +44 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * The RadioManager class allows to control a broadcast radio tuner present on the device. Loading Loading @@ -132,11 +134,15 @@ public class RadioManager { private final boolean mIsCaptureSupported; private final BandDescriptor[] mBands; private final boolean mIsBgScanSupported; private final Set<Integer> mSupportedProgramTypes; private final Set<Integer> mSupportedIdentifierTypes; private final String mVendorExension; ModuleProperties(int id, String serviceName, int classId, String implementor, String product, String version, String serial, int numTuners, int numAudioSources, boolean isCaptureSupported, BandDescriptor[] bands, boolean isBgScanSupported, @ProgramSelector.ProgramType int[] supportedProgramTypes, @ProgramSelector.IdentifierType int[] supportedIdentifierTypes, String vendorExension) { mId = id; mServiceName = TextUtils.isEmpty(serviceName) ? "default" : serviceName; Loading @@ -150,9 +156,18 @@ public class RadioManager { mIsCaptureSupported = isCaptureSupported; mBands = bands; mIsBgScanSupported = isBgScanSupported; mSupportedProgramTypes = arrayToSet(supportedProgramTypes); mSupportedIdentifierTypes = arrayToSet(supportedIdentifierTypes); mVendorExension = vendorExension; } private static Set<Integer> arrayToSet(int[] arr) { return Arrays.stream(arr).boxed().collect(Collectors.toSet()); } private static int[] setToArray(Set<Integer> set) { return set.stream().mapToInt(Integer::intValue).toArray(); } /** Unique module identifier provided by the native service. * For use with {@link #openTuner(int, BandConfig, boolean, Callback, Handler)}. Loading Loading @@ -244,6 +259,31 @@ public class RadioManager { return mIsBgScanSupported; } /** * Checks, if a given program type is supported by this tuner. * * If a program type is supported by radio module, it means it can tune * to ProgramSelector of a given type. * * @return {@code true} if a given program type is supported. */ public boolean isProgramTypeSupported(@ProgramSelector.ProgramType int type) { return mSupportedProgramTypes.contains(type); } /** * Checks, if a given program identifier is supported by this tuner. * * If an identifier is supported by radio module, it means it can use it for * tuning to ProgramSelector with either primary or secondary Identifier of * a given type. * * @return {@code true} if a given program type is supported. */ public boolean isProgramIdentifierSupported(@ProgramSelector.IdentifierType int type) { return mSupportedIdentifierTypes.contains(type); } /** * Opaque vendor-specific string, passed from HAL without changes. * Format of this string can vary across vendors. Loading Loading @@ -283,6 +323,8 @@ public class RadioManager { mBands[i] = (BandDescriptor) tmp[i]; } mIsBgScanSupported = in.readInt() == 1; mSupportedProgramTypes = arrayToSet(in.createIntArray()); mSupportedIdentifierTypes = arrayToSet(in.createIntArray()); mVendorExension = in.readString(); } Loading Loading @@ -311,6 +353,8 @@ public class RadioManager { dest.writeInt(mIsCaptureSupported ? 1 : 0); dest.writeParcelableArray(mBands, flags); dest.writeInt(mIsBgScanSupported ? 1 : 0); dest.writeIntArray(setToArray(mSupportedProgramTypes)); dest.writeIntArray(setToArray(mSupportedIdentifierTypes)); dest.writeString(mVendorExension); } Loading
services/core/jni/com_android_server_radio_convert.cpp +51 −25 Original line number Diff line number Diff line Loading @@ -185,6 +185,44 @@ void ThrowParcelableRuntimeException(JNIEnv *env, const std::string& msg) { ALOGE_IF(res != JNI_OK, "Couldn't throw parcelable runtime exception"); } static JavaRef<jintArray> ArrayFromHal(JNIEnv *env, const hidl_vec<uint32_t>& vec) { auto jArr = make_javaref(env, env->NewIntArray(vec.size())); auto jArrElements = env->GetIntArrayElements(jArr.get(), nullptr); for (size_t i = 0; i < vec.size(); i++) { jArrElements[i] = vec[i]; } env->ReleaseIntArrayElements(jArr.get(), jArrElements, 0); return jArr; } static JavaRef<jlongArray> ArrayFromHal(JNIEnv *env, const hidl_vec<uint64_t>& vec) { auto jArr = make_javaref(env, env->NewLongArray(vec.size())); auto jArrElements = env->GetLongArrayElements(jArr.get(), nullptr); for (size_t i = 0; i < vec.size(); i++) { jArrElements[i] = vec[i]; } env->ReleaseLongArrayElements(jArr.get(), jArrElements, 0); return jArr; } template <typename T> static JavaRef<jobjectArray> ArrayFromHal(JNIEnv *env, const hidl_vec<T>& vec, jclass jElementClass, std::function<JavaRef<jobject>(JNIEnv*, const T&)> converter) { auto jArr = make_javaref(env, env->NewObjectArray(vec.size(), jElementClass, nullptr)); for (size_t i = 0; i < vec.size(); i++) { auto jElement = converter(env, vec[i]); env->SetObjectArrayElement(jArr.get(), i, jElement.get()); } return jArr; } template <typename T> static JavaRef<jobjectArray> ArrayFromHal(JNIEnv *env, const hidl_vec<T>& vec, jclass jElementClass, JavaRef<jobject>(*converter)(JNIEnv*, const T&)) { return ArrayFromHal(env, vec, jElementClass, std::function<JavaRef<jobject>(JNIEnv*, const T&)>(converter)); } static Rds RdsForRegion(bool rds, Region region) { if (!rds) return Rds::NONE; Loading Loading @@ -220,6 +258,7 @@ static Deemphasis DeemphasisForRegion(Region region) { static JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &prop10, const V1_1::Properties *prop11, jint moduleId, const std::string& serviceName) { ALOGV("ModulePropertiesFromHal()"); using namespace std::placeholders; auto jServiceName = make_javastr(env, serviceName); auto jImplementor = make_javastr(env, prop10.implementor); Loading @@ -228,21 +267,19 @@ static JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Propert auto jSerial = make_javastr(env, prop10.serial); bool isBgScanSupported = prop11 ? prop11->supportsBackgroundScanning : false; auto jVendorExtension = prop11 ? make_javastr(env, prop11->vendorExension) : nullptr; auto jBands = make_javaref(env, env->NewObjectArray(prop10.bands.size(), gjni.BandDescriptor.clazz, nullptr)); int i = 0; for (auto &&band : prop10.bands) { // ITU_1 is the default region just because its index is 0. auto jBand = BandDescriptorFromHal(env, band, Region::ITU_1); env->SetObjectArrayElement(jBands.get(), i++, jBand.get()); } auto jBands = ArrayFromHal<V1_0::BandConfig>(env, prop10.bands, gjni.BandDescriptor.clazz, std::bind(BandDescriptorFromHal, _1, _2, Region::ITU_1)); auto jSupportedProgramTypes = prop11 ? ArrayFromHal(env, prop11->supportedProgramTypes) : nullptr; auto jSupportedIdentifierTypes = prop11 ? ArrayFromHal(env, prop11->supportedIdentifierTypes) : nullptr; return make_javaref(env, env->NewObject(gjni.ModuleProperties.clazz, gjni.ModuleProperties.cstor, moduleId, jServiceName.get(), prop10.classId, jImplementor.get(), jProduct.get(), jVersion.get(), jSerial.get(), prop10.numTuners, prop10.numAudioSources, prop10.supportsCapture, jBands.get(), isBgScanSupported, jVendorExtension.get())); jSupportedProgramTypes.get(), jSupportedIdentifierTypes.get(), jVendorExtension.get())); } JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &properties, Loading Loading @@ -411,20 +448,9 @@ static JavaRef<jobject> ProgramIdentifierFromHal(JNIEnv *env, const ProgramIdent static JavaRef<jobject> ProgramSelectorFromHal(JNIEnv *env, const ProgramSelector &selector) { ALOGV("ProgramSelectorFromHal()"); auto jPrimary = ProgramIdentifierFromHal(env, selector.primaryId); auto jSecondary = make_javaref(env, env->NewObjectArray(selector.secondaryIds.size(), gjni.ProgramSelector.Identifier.clazz, nullptr)); for (size_t i = 0; i < selector.secondaryIds.size(); i++) { auto jId = ProgramIdentifierFromHal(env, selector.secondaryIds[i]); env->SetObjectArrayElement(jSecondary.get(), i, jId.get()); } auto jVendor = make_javaref(env, env->NewLongArray(selector.vendorIds.size())); auto jVendorElements = env->GetLongArrayElements(jVendor.get(), nullptr); for (size_t i = 0; i < selector.vendorIds.size(); i++) { jVendorElements[i] = selector.vendorIds[i]; } env->ReleaseLongArrayElements(jVendor.get(), jVendorElements, 0); auto jSecondary = ArrayFromHal(env, selector.secondaryIds, gjni.ProgramSelector.Identifier.clazz, ProgramIdentifierFromHal); auto jVendor = ArrayFromHal(env, selector.vendorIds); return make_javaref(env, env->NewObject(gjni.ProgramSelector.clazz, gjni.ProgramSelector.cstor, selector.programType, jPrimary.get(), jSecondary.get(), jVendor.get())); Loading Loading @@ -554,7 +580,7 @@ void register_android_server_radio_convert(JNIEnv *env) { gjni.ModuleProperties.cstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>", "(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;" "Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;Z" "Ljava/lang/String;)V"); "[I[ILjava/lang/String;)V"); auto programInfoClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ProgramInfo"); gjni.ProgramInfo.clazz = MakeGlobalRefOrDie(env, programInfoClass); Loading