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.
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;
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)}.
}
/**
+ * 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.
*
mBands[i] = (BandDescriptor) tmp[i];
}
mIsBgScanSupported = in.readInt() == 1;
+ mSupportedProgramTypes = arrayToSet(in.createIntArray());
+ mSupportedIdentifierTypes = arrayToSet(in.createIntArray());
mVendorExension = in.readString();
}
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);
}
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;
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);
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());
- }
+ // ITU_1 is the default region just because its index is 0.
+ 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,
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()));
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);