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

Commit 58141fbd authored by Weilin Xu's avatar Weilin Xu
Browse files

Improve DAB support in radio service and manager

The full support for using 44-bit DAB primary identifier in AIDL was
implemented. Whether program selectors and program info sent between
AIDL HAL and HAL client are valid was checked in HAL client. Unit tests
for checking target SDK version and converting program selector and
info broadcast radio were added. In addition, existing unit tests were
updated by using DAB_DMB_SID_EXT identifier type instead and using more
meaningful values for DAB identifiers.

Bug: 261912181
Test: atest com.android.server.broadcastradio
Test: atest android.hardware.radio.tests.unittests
Change-Id: I9e705acafea4fb6c5b77d1ba647097ad43ba7cf9
parent aecdff38
Loading
Loading
Loading
Loading
+59 −28
Original line number Diff line number Diff line
@@ -65,12 +65,12 @@ public final class ProgramSelector implements Parcelable {
     */
    @Deprecated
    public static final int PROGRAM_TYPE_INVALID = 0;
    /** Analogue AM radio (with or without RDS).
    /** Analog AM radio (with or without RDS).
     * @deprecated use {@link ProgramIdentifier} instead
     */
    @Deprecated
    public static final int PROGRAM_TYPE_AM = 1;
    /** analogue FM radio (with or without RDS).
    /** analog FM radio (with or without RDS).
     * @deprecated use {@link ProgramIdentifier} instead
     */
    @Deprecated
@@ -125,25 +125,50 @@ public final class ProgramSelector implements Parcelable {
    public @interface ProgramType {}

    public static final int IDENTIFIER_TYPE_INVALID = 0;
    /** kHz */
    /**
     * Primary identifier for analog (without RDS) AM/FM stations:
     * frequency in kHz.
     *
     * <p>This identifier also contains band information:
     * <li>
     *     <ul><500kHz: AM LW.
     *     <ul>500kHz - 1705kHz: AM MW.
     *     <ul>1.71MHz - 30MHz: AM SW.
     *     <ul>>60MHz: FM.
     * </li>
     */
    public static final int IDENTIFIER_TYPE_AMFM_FREQUENCY = 1;
    /** 16bit */
    /**
     * 16bit primary identifier for FM RDS station.
     */
    public static final int IDENTIFIER_TYPE_RDS_PI = 2;
    /**
     * 64bit compound primary identifier for HD Radio.
     *
     * Consists of (from the LSB):
     * - 32bit: Station ID number;
     * - 4bit: HD_SUBCHANNEL;
     * - 18bit: AMFM_FREQUENCY.
     * The remaining bits should be set to zeros when writing on the chip side
     * <p>Consists of (from the LSB):
     * <li>
     *     <ul>132bit: Station ID number.
     *     <ul>14bit: HD_SUBCHANNEL.
     *     <ul>18bit: AMFM_FREQUENCY.
     * </li>
     *
     * <p>While station ID number should be unique globally, it sometimes gets
     * abused by broadcasters (i.e. not being set at all). To ensure local
     * uniqueness, AMFM_FREQUENCY_KHZ was added here. Global uniqueness is
     * a best-effort - see {@link IDENTIFIER_TYPE_HD_STATION_NAME}.
     *
     * <p>HD Radio subchannel is a value in range of 0-7.
     * This index is 0-based (where 0 is MPS and 1..7 are SPS),
     * as opposed to HD Radio standard (where it's 1-based).
     *
     * <p>The remaining bits should be set to zeros when writing on the chip side
     * and ignored when read.
     */
    public static final int IDENTIFIER_TYPE_HD_STATION_ID_EXT = 3;
    /**
     * HD Radio subchannel - a value of range 0-7.
     * HD Radio subchannel - a value in range of 0-7.
     *
     * The subchannel index is 0-based (where 0 is MPS and 1..7 are SPS),
     * <p>The subchannel index is 0-based (where 0 is MPS and 1..7 are SPS),
     * as opposed to HD Radio standard (where it's 1-based).
     *
     * @deprecated use IDENTIFIER_TYPE_HD_STATION_ID_EXT instead
@@ -153,16 +178,16 @@ public final class ProgramSelector implements Parcelable {
    /**
     * 64bit additional identifier for HD Radio.
     *
     * Due to Station ID abuse, some HD_STATION_ID_EXT identifiers may be not
     * <p>Due to Station ID abuse, some HD_STATION_ID_EXT identifiers may be not
     * globally unique. To provide a best-effort solution, a short version of
     * station name may be carried as additional identifier and may be used
     * by the tuner hardware to double-check tuning.
     *
     * The name is limited to the first 8 A-Z0-9 characters (lowercase letters
     * must be converted to uppercase). Encoded in little-endian ASCII:
     * the first character of the name is the LSB.
     * <p>The name is limited to the first 8 A-Z0-9 characters (lowercase
     * letters must be converted to uppercase). Encoded in little-endian
     * ASCII: the first character of the name is the LSB.
     *
     * For example: "Abc" is encoded as 0x434241.
     * <p>For example: "Abc" is encoded as 0x434241.
     */
    public static final int IDENTIFIER_TYPE_HD_STATION_NAME = 10004;
    /**
@@ -175,17 +200,19 @@ public final class ProgramSelector implements Parcelable {
    /**
     * 28bit compound primary identifier for Digital Audio Broadcasting.
     *
     * Consists of (from the LSB):
     * - 16bit: SId;
     * - 8bit: ECC code;
     * - 4bit: SCIdS.
     * <p>Consists of (from the LSB):
     * <li>
     *     <ul>16bit: SId.
     *     <ul>8bit: ECC code.
     *     <ul>4bit: SCIdS.
     * </li>
     *
     * SCIdS (Service Component Identifier within the Service) value
     * <p>SCIdS (Service Component Identifier within the Service) value
     * of 0 represents the main service, while 1 and above represents
     * secondary services.
     *
     * The remaining bits should be set to zeros when writing on the chip side
     * and ignored when read.
     * <p>The remaining bits should be set to zeros when writing on the chip
     * side and ignored when read.
     *
     * @deprecated use {@link #IDENTIFIER_TYPE_DAB_DMB_SID_EXT} instead
     */
@@ -197,7 +224,9 @@ public final class ProgramSelector implements Parcelable {
    public static final int IDENTIFIER_TYPE_DAB_SCID = 7;
    /** kHz */
    public static final int IDENTIFIER_TYPE_DAB_FREQUENCY = 8;
    /** 24bit */
    /**
     * 24bit primary identifier for Digital Radio Mondiale.
     */
    public static final int IDENTIFIER_TYPE_DRMO_SERVICE_ID = 9;
    /** kHz */
    public static final int IDENTIFIER_TYPE_DRMO_FREQUENCY = 10;
@@ -207,7 +236,9 @@ public final class ProgramSelector implements Parcelable {
     */
    @Deprecated
    public static final int IDENTIFIER_TYPE_DRMO_MODULATION = 11;
    /** 32bit */
    /**
     * 32bit primary identifier for SiriusXM Satellite Radio.
     */
    public static final int IDENTIFIER_TYPE_SXM_SERVICE_ID = 12;
    /** 0-999 range */
    public static final int IDENTIFIER_TYPE_SXM_CHANNEL = 13;
@@ -224,15 +255,15 @@ public final class ProgramSelector implements Parcelable {
     * of 0 represents the main service, while 1 and above represents
     * secondary services.
     *
     * The remaining bits should be set to zeros when writing on the chip side
     * and ignored when read.
     * <p>The remaining bits should be set to zeros when writing on the chip
     * side and ignored when read.
     */
    public static final int IDENTIFIER_TYPE_DAB_DMB_SID_EXT = 14;
    /**
     * Primary identifier for vendor-specific radio technology.
     * The value format is determined by a vendor.
     *
     * It must not be used in any other programType than corresponding VENDOR
     * <p>It must not be used in any other programType than corresponding VENDOR
     * type between VENDOR_START and VENDOR_END (eg. identifier type 1015 must
     * not be used in any program type other than 1015).
     */
+9 −9
Original line number Diff line number Diff line
@@ -72,9 +72,9 @@ public final class ProgramListTest {
                    /* value= */ 94300);
    private static final ProgramSelector.Identifier RDS_IDENTIFIER =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI, 15019);
    private static final ProgramSelector.Identifier DAB_SID_EXT_IDENTIFIER =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT,
                    /* value= */ 0x10000111);
    private static final ProgramSelector.Identifier DAB_DMB_SID_EXT_IDENTIFIER =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
                    /* value= */ 0xA000000111L);
    private static final ProgramSelector.Identifier DAB_ENSEMBLE_IDENTIFIER =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
                    /* value= */ 0x1013);
@@ -89,7 +89,7 @@ public final class ProgramListTest {

    private static final ProgramList.Chunk FM_RDS_ADD_CHUNK = new ProgramList.Chunk(IS_PURGE,
            IS_COMPLETE, Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
            Set.of(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
            Set.of(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
    private static final ProgramList.Chunk FM_ADD_INCOMPLETE_CHUNK = new ProgramList.Chunk(IS_PURGE,
            /* complete= */ false, Set.of(FM_PROGRAM_INFO), new ArraySet<>());
    private static final ProgramList.Filter TEST_FILTER = new ProgramList.Filter(
@@ -216,7 +216,7 @@ public final class ProgramListTest {
    public void isPurge_forChunk() {
        ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
                Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
                Set.of(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
                Set.of(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));

        assertWithMessage("Puring chunk").that(chunk.isPurge()).isEqualTo(IS_PURGE);
    }
@@ -225,7 +225,7 @@ public final class ProgramListTest {
    public void isComplete_forChunk() {
        ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
                Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
                Set.of(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
                Set.of(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));

        assertWithMessage("Complete chunk").that(chunk.isComplete()).isEqualTo(IS_COMPLETE);
    }
@@ -234,7 +234,7 @@ public final class ProgramListTest {
    public void getModified_forChunk() {
        ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
                Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
                Set.of(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
                Set.of(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));

        assertWithMessage("Modified program info in chunk")
                .that(chunk.getModified()).containsExactly(FM_PROGRAM_INFO, RDS_PROGRAM_INFO);
@@ -244,10 +244,10 @@ public final class ProgramListTest {
    public void getRemoved_forChunk() {
        ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
                Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
                Set.of(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
                Set.of(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));

        assertWithMessage("Removed program identifiers in chunk").that(chunk.getRemoved())
                .containsExactly(DAB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER);
                .containsExactly(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER);
    }

    @Test
+20 −20
Original line number Diff line number Diff line
@@ -36,18 +36,18 @@ public final class ProgramSelectorTest {
    private static final long AM_FREQUENCY = 700;
    private static final ProgramSelector.Identifier FM_IDENTIFIER = new ProgramSelector.Identifier(
            ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, FM_FREQUENCY);
    private static final ProgramSelector.Identifier DAB_SID_EXT_IDENTIFIER_1 =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT,
                    /* value= */ 0x1000011);
    private static final ProgramSelector.Identifier DAB_SID_EXT_IDENTIFIER_2 =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT,
                    /* value= */ 0x10000112);
    private static final ProgramSelector.Identifier DAB_DMB_SID_EXT_IDENTIFIER_1 =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
                    /* value= */ 0xA000000111L);
    private static final ProgramSelector.Identifier DAB_DMB_SID_EXT_IDENTIFIER_2 =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
                    /* value= */ 0xA000000112L);
    private static final ProgramSelector.Identifier DAB_ENSEMBLE_IDENTIFIER =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
                    /* value= */ 0x1001);
    private static final ProgramSelector.Identifier DAB_FREQUENCY_IDENTIFIER =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
                    /* value= */ 94500);
                    /* value= */ 220352);

    @Test
    public void getType_forIdentifier() {
@@ -80,13 +80,13 @@ public final class ProgramSelectorTest {
    @Test
    public void equals_withDifferentTypesForIdentifiers_returnsFalse() {
        assertWithMessage("Identifier with different identifier type")
                .that(FM_IDENTIFIER).isNotEqualTo(DAB_SID_EXT_IDENTIFIER_1);
                .that(FM_IDENTIFIER).isNotEqualTo(DAB_DMB_SID_EXT_IDENTIFIER_1);
    }

    @Test
    public void equals_withDifferentValuesForIdentifiers_returnsFalse() {
        assertWithMessage("Identifier with different identifier value")
                .that(DAB_SID_EXT_IDENTIFIER_2).isNotEqualTo(DAB_SID_EXT_IDENTIFIER_1);
                .that(DAB_DMB_SID_EXT_IDENTIFIER_2).isNotEqualTo(DAB_DMB_SID_EXT_IDENTIFIER_1);
    }

    @Test
@@ -168,19 +168,19 @@ public final class ProgramSelectorTest {
    @Test
    public void getFirstId_withIdInSelector() {
        ProgramSelector.Identifier[] secondaryIds = new ProgramSelector.Identifier[]{
                DAB_ENSEMBLE_IDENTIFIER, DAB_SID_EXT_IDENTIFIER_2, DAB_FREQUENCY_IDENTIFIER};
                DAB_ENSEMBLE_IDENTIFIER, DAB_DMB_SID_EXT_IDENTIFIER_2, DAB_FREQUENCY_IDENTIFIER};
        ProgramSelector selector = getDabSelector(secondaryIds, /* vendorIds= */ null);

        long firstIdValue = selector.getFirstId(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT);
        long firstIdValue = selector.getFirstId(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT);

        assertWithMessage("Value of the first DAB_SID_EXT identifier")
                .that(firstIdValue).isEqualTo(DAB_SID_EXT_IDENTIFIER_1.getValue());
                .that(firstIdValue).isEqualTo(DAB_DMB_SID_EXT_IDENTIFIER_1.getValue());
    }

    @Test
    public void getFirstId_withIdNotInSelector() {
        ProgramSelector.Identifier[] secondaryIds = new ProgramSelector.Identifier[]{
                DAB_ENSEMBLE_IDENTIFIER, DAB_SID_EXT_IDENTIFIER_2};
                DAB_ENSEMBLE_IDENTIFIER, DAB_DMB_SID_EXT_IDENTIFIER_2};
        ProgramSelector selector = getDabSelector(secondaryIds, /* vendorIds= */ null);

        int idType = ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY;
@@ -195,13 +195,13 @@ public final class ProgramSelectorTest {
    @Test
    public void getAllIds_withIdInSelector() {
        ProgramSelector.Identifier[] secondaryIds = new ProgramSelector.Identifier[]{
                DAB_ENSEMBLE_IDENTIFIER, DAB_SID_EXT_IDENTIFIER_2, DAB_FREQUENCY_IDENTIFIER};
                DAB_ENSEMBLE_IDENTIFIER, DAB_DMB_SID_EXT_IDENTIFIER_2, DAB_FREQUENCY_IDENTIFIER};
        ProgramSelector.Identifier[] allIdsExpected =
                {DAB_SID_EXT_IDENTIFIER_1, DAB_SID_EXT_IDENTIFIER_2};
                {DAB_DMB_SID_EXT_IDENTIFIER_1, DAB_DMB_SID_EXT_IDENTIFIER_2};
        ProgramSelector selector = getDabSelector(secondaryIds, /* vendorIds= */ null);

        ProgramSelector.Identifier[] allIds =
                selector.getAllIds(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT);
                selector.getAllIds(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT);

        assertWithMessage("All DAB_SID_EXT identifiers in selector")
                .that(allIds).isEqualTo(allIdsExpected);
@@ -244,14 +244,14 @@ public final class ProgramSelectorTest {
    @Test
    public void withSecondaryPreferred() {
        ProgramSelector.Identifier[] secondaryIds = new ProgramSelector.Identifier[]{
                DAB_ENSEMBLE_IDENTIFIER, DAB_SID_EXT_IDENTIFIER_2, DAB_FREQUENCY_IDENTIFIER};
                DAB_ENSEMBLE_IDENTIFIER, DAB_DMB_SID_EXT_IDENTIFIER_2, DAB_FREQUENCY_IDENTIFIER};
        long[] vendorIdsExpected = {12345, 678};
        ProgramSelector selector = getDabSelector(secondaryIds, vendorIdsExpected);
        ProgramSelector.Identifier[] secondaryIdsExpected = new ProgramSelector.Identifier[]{
                DAB_ENSEMBLE_IDENTIFIER, DAB_FREQUENCY_IDENTIFIER, DAB_SID_EXT_IDENTIFIER_1};
                DAB_ENSEMBLE_IDENTIFIER, DAB_FREQUENCY_IDENTIFIER, DAB_DMB_SID_EXT_IDENTIFIER_1};

        ProgramSelector selectorPreferred =
                selector.withSecondaryPreferred(DAB_SID_EXT_IDENTIFIER_1);
                selector.withSecondaryPreferred(DAB_DMB_SID_EXT_IDENTIFIER_1);

        assertWithMessage("Program type")
                .that(selectorPreferred.getProgramType()).isEqualTo(selector.getProgramType());
@@ -458,7 +458,7 @@ public final class ProgramSelectorTest {

    private ProgramSelector getDabSelector(@Nullable ProgramSelector.Identifier[] secondaryIds,
            @Nullable long[] vendorIds) {
        return new ProgramSelector(DAB_PROGRAM_TYPE, DAB_SID_EXT_IDENTIFIER_1, secondaryIds,
        return new ProgramSelector(DAB_PROGRAM_TYPE, DAB_DMB_SID_EXT_IDENTIFIER_1, secondaryIds,
                vendorIds);
    }
}
+9 −9
Original line number Diff line number Diff line
@@ -105,17 +105,17 @@ public final class RadioManagerTest {
    private static final int INFO_FLAGS = 0b110001;
    private static final int SIGNAL_QUALITY = 2;
    private static final ProgramSelector.Identifier DAB_SID_EXT_IDENTIFIER =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT,
                    /* value= */ 0x10000111);
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
                    /* value= */ 0xA000000111L);
    private static final ProgramSelector.Identifier DAB_SID_EXT_IDENTIFIER_RELATED =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT,
                    /* value= */ 0x10000113);
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
                    /* value= */ 0xA000000113L);
    private static final ProgramSelector.Identifier DAB_ENSEMBLE_IDENTIFIER =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
                    /* value= */ 0x1013);
    private static final ProgramSelector.Identifier DAB_FREQUENCY_IDENTIFIER =
            new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
                    /* value= */ 95500);
                    /* value= */ 220352);
    private static final ProgramSelector DAB_SELECTOR =
            new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB, DAB_SID_EXT_IDENTIFIER,
                    new ProgramSelector.Identifier[]{
@@ -859,13 +859,13 @@ public final class RadioManagerTest {
    @Test
    public void getLogicallyTunedTo_forProgramInfo() {
        assertWithMessage("Identifier logically tuned to in DAB program info")
                .that(DAB_PROGRAM_INFO.getLogicallyTunedTo()).isEqualTo(DAB_FREQUENCY_IDENTIFIER);
                .that(DAB_PROGRAM_INFO.getLogicallyTunedTo()).isEqualTo(DAB_SID_EXT_IDENTIFIER);
    }

    @Test
    public void getPhysicallyTunedTo_forProgramInfo() {
        assertWithMessage("Identifier physically tuned to DAB program info")
                .that(DAB_PROGRAM_INFO.getPhysicallyTunedTo()).isEqualTo(DAB_SID_EXT_IDENTIFIER);
                .that(DAB_PROGRAM_INFO.getPhysicallyTunedTo()).isEqualTo(DAB_FREQUENCY_IDENTIFIER);
    }

    @Test
@@ -1104,8 +1104,8 @@ public final class RadioManagerTest {
    }

    private static RadioManager.ProgramInfo createDabProgramInfo(ProgramSelector selector) {
        return new RadioManager.ProgramInfo(selector, DAB_FREQUENCY_IDENTIFIER,
                DAB_SID_EXT_IDENTIFIER, Arrays.asList(DAB_SID_EXT_IDENTIFIER_RELATED), INFO_FLAGS,
        return new RadioManager.ProgramInfo(selector, DAB_SID_EXT_IDENTIFIER,
                DAB_FREQUENCY_IDENTIFIER, Arrays.asList(DAB_SID_EXT_IDENTIFIER_RELATED), INFO_FLAGS,
                SIGNAL_QUALITY, METADATA, /* vendorInfo= */ null);
    }

+25 −9
Original line number Diff line number Diff line
@@ -54,6 +54,13 @@ final class AidlTestUtils {
        return makeProgramInfo(selector, signalQuality);
    }

    static ProgramIdentifier makeHalIdentifier(@IdentifierType int type, long value) {
        ProgramIdentifier halDabId = new ProgramIdentifier();
        halDabId.type = type;
        halDabId.value = value;
        return halDabId;
    }

    static ProgramSelector makeFmSelector(long freq) {
        return makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM,
                new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
@@ -67,15 +74,17 @@ final class AidlTestUtils {
    }

    static android.hardware.broadcastradio.ProgramSelector makeHalFmSelector(int freq) {
        ProgramIdentifier halId = new ProgramIdentifier();
        halId.type = IdentifierType.AMFM_FREQUENCY_KHZ;
        halId.value = freq;
        ProgramIdentifier halId = makeHalIdentifier(IdentifierType.AMFM_FREQUENCY_KHZ, freq);
        return makeHalSelector(halId, /* secondaryIds= */ new ProgramIdentifier[0]);
    }

        android.hardware.broadcastradio.ProgramSelector halSelector =
    static android.hardware.broadcastradio.ProgramSelector makeHalSelector(
            ProgramIdentifier primaryId, ProgramIdentifier[] secondaryIds) {
        android.hardware.broadcastradio.ProgramSelector hwSelector =
                new android.hardware.broadcastradio.ProgramSelector();
        halSelector.primaryId = halId;
        halSelector.secondaryIds = new ProgramIdentifier[0];
        return halSelector;
        hwSelector.primaryId = primaryId;
        hwSelector.secondaryIds = secondaryIds;
        return hwSelector;
    }

    static ProgramInfo programInfoToHalProgramInfo(RadioManager.ProgramInfo info) {
@@ -95,10 +104,17 @@ final class AidlTestUtils {

    static ProgramInfo makeHalProgramInfo(
            android.hardware.broadcastradio.ProgramSelector hwSel, int hwSignalQuality) {
        return makeHalProgramInfo(hwSel, hwSel.primaryId, hwSel.primaryId, hwSignalQuality);
    }

    static ProgramInfo makeHalProgramInfo(
            android.hardware.broadcastradio.ProgramSelector hwSel,
            ProgramIdentifier logicallyTunedTo, ProgramIdentifier physicallyTunedTo,
            int hwSignalQuality) {
        ProgramInfo hwInfo = new ProgramInfo();
        hwInfo.selector = hwSel;
        hwInfo.logicallyTunedTo = hwSel.primaryId;
        hwInfo.physicallyTunedTo = hwSel.primaryId;
        hwInfo.logicallyTunedTo = logicallyTunedTo;
        hwInfo.physicallyTunedTo = physicallyTunedTo;
        hwInfo.signalQuality = hwSignalQuality;
        hwInfo.relatedContent = new ProgramIdentifier[]{};
        hwInfo.metadata = new Metadata[]{};
Loading