Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72e8ceda authored by Tomasz Wasilczyk's avatar Tomasz Wasilczyk Committed by Android (Google) Code Review
Browse files

Merge "Make it possible to check if a given program/identifier type is supported."

parents b70b9f65 54587ced
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;
  }
+44 −0
Original line number Diff line number Diff line
@@ -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.
@@ -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;
@@ -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)}.
@@ -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.
@@ -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();
        }

@@ -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);
        }

+51 −25
Original line number Diff line number Diff line
@@ -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;

@@ -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);
@@ -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,
@@ -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()));
@@ -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);