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

Commit 2c38153e authored by Weilin Xu's avatar Weilin Xu
Browse files

Add radio API for HD radio and program list

Added radio APIs to improve HD radio support, and allow multiple DAB
radio stations with the same primary identifiers in program list.

Bug: 280300929
Test: atest CtsBroadcastRadioTestCases
Change-Id: I2e772cba88c4ffaeba09f74351a978adf3e85f13
parent e3f6f95c
Loading
Loading
Loading
Loading
+29 −5
Original line number Diff line number Diff line
@@ -5581,7 +5581,8 @@ package android.hardware.radio {
    method public void addOnCompleteListener(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.radio.ProgramList.OnCompleteListener);
    method public void addOnCompleteListener(@NonNull android.hardware.radio.ProgramList.OnCompleteListener);
    method public void close();
    method @Nullable public android.hardware.radio.RadioManager.ProgramInfo get(@NonNull android.hardware.radio.ProgramSelector.Identifier);
    method @Deprecated @Nullable public android.hardware.radio.RadioManager.ProgramInfo get(@NonNull android.hardware.radio.ProgramSelector.Identifier);
    method @FlaggedApi("android.hardware.radio.hd_radio_improved") @NonNull public java.util.List<android.hardware.radio.RadioManager.ProgramInfo> getProgramInfos(@NonNull android.hardware.radio.ProgramSelector.Identifier);
    method public void registerListCallback(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.radio.ProgramList.ListCallback);
    method public void registerListCallback(@NonNull android.hardware.radio.ProgramList.ListCallback);
    method public void removeOnCompleteListener(@NonNull android.hardware.radio.ProgramList.OnCompleteListener);
@@ -5635,12 +5636,13 @@ package android.hardware.radio {
    field @Deprecated public static final int IDENTIFIER_TYPE_DRMO_MODULATION = 11; // 0xb
    field public static final int IDENTIFIER_TYPE_DRMO_SERVICE_ID = 9; // 0x9
    field public static final int IDENTIFIER_TYPE_HD_STATION_ID_EXT = 3; // 0x3
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int IDENTIFIER_TYPE_HD_STATION_LOCATION = 15; // 0xf
    field public static final int IDENTIFIER_TYPE_HD_STATION_NAME = 10004; // 0x2714
    field @Deprecated public static final int IDENTIFIER_TYPE_HD_SUBCHANNEL = 4; // 0x4
    field public static final int IDENTIFIER_TYPE_INVALID = 0; // 0x0
    field public static final int IDENTIFIER_TYPE_RDS_PI = 2; // 0x2
    field public static final int IDENTIFIER_TYPE_SXM_CHANNEL = 13; // 0xd
    field public static final int IDENTIFIER_TYPE_SXM_SERVICE_ID = 12; // 0xc
    field @Deprecated public static final int IDENTIFIER_TYPE_SXM_CHANNEL = 13; // 0xd
    field @Deprecated public static final int IDENTIFIER_TYPE_SXM_SERVICE_ID = 12; // 0xc
    field public static final int IDENTIFIER_TYPE_VENDOR_END = 1999; // 0x7cf
    field @Deprecated public static final int IDENTIFIER_TYPE_VENDOR_PRIMARY_END = 1999; // 0x7cf
    field @Deprecated public static final int IDENTIFIER_TYPE_VENDOR_PRIMARY_START = 1000; // 0x3e8
@@ -5655,6 +5657,14 @@ package android.hardware.radio {
    field @Deprecated public static final int PROGRAM_TYPE_SXM = 7; // 0x7
    field @Deprecated public static final int PROGRAM_TYPE_VENDOR_END = 1999; // 0x7cf
    field @Deprecated public static final int PROGRAM_TYPE_VENDOR_START = 1000; // 0x3e8
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int SUB_CHANNEL_HD_1 = 1; // 0x1
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int SUB_CHANNEL_HD_2 = 2; // 0x2
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int SUB_CHANNEL_HD_3 = 4; // 0x4
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int SUB_CHANNEL_HD_4 = 8; // 0x8
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int SUB_CHANNEL_HD_5 = 16; // 0x10
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int SUB_CHANNEL_HD_6 = 32; // 0x20
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int SUB_CHANNEL_HD_7 = 64; // 0x40
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int SUB_CHANNEL_HD_8 = 128; // 0x80
  }
  public static final class ProgramSelector.Identifier implements android.os.Parcelable {
@@ -5667,7 +5677,7 @@ package android.hardware.radio {
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.radio.ProgramSelector.Identifier> CREATOR;
  }
  @IntDef(prefix={"IDENTIFIER_TYPE_"}, value={android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_INVALID, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_RDS_PI, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_HD_STATION_ID_EXT, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_HD_SUBCHANNEL, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_HD_STATION_NAME, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_SIDECC, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_SCID, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DRMO_SERVICE_ID, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DRMO_FREQUENCY, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DRMO_MODULATION, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_SXM_SERVICE_ID, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_SXM_CHANNEL, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT}) @IntRange(from=android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_VENDOR_START, to=android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_VENDOR_END) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ProgramSelector.IdentifierType {
  @IntDef(prefix={"IDENTIFIER_TYPE_"}, value={android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_INVALID, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_RDS_PI, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_HD_STATION_ID_EXT, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_HD_SUBCHANNEL, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_HD_STATION_NAME, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_SIDECC, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_SCID, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DRMO_SERVICE_ID, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DRMO_FREQUENCY, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DRMO_MODULATION, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_SXM_SERVICE_ID, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_SXM_CHANNEL, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT, android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_HD_STATION_LOCATION}) @IntRange(from=android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_VENDOR_START, to=android.hardware.radio.ProgramSelector.IDENTIFIER_TYPE_VENDOR_END) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ProgramSelector.IdentifierType {
  }
  @Deprecated @IntDef(prefix={"PROGRAM_TYPE_"}, value={android.hardware.radio.ProgramSelector.PROGRAM_TYPE_INVALID, android.hardware.radio.ProgramSelector.PROGRAM_TYPE_AM, android.hardware.radio.ProgramSelector.PROGRAM_TYPE_FM, android.hardware.radio.ProgramSelector.PROGRAM_TYPE_AM_HD, android.hardware.radio.ProgramSelector.PROGRAM_TYPE_FM_HD, android.hardware.radio.ProgramSelector.PROGRAM_TYPE_DAB, android.hardware.radio.ProgramSelector.PROGRAM_TYPE_DRMO, android.hardware.radio.ProgramSelector.PROGRAM_TYPE_SXM}) @IntRange(from=android.hardware.radio.ProgramSelector.PROGRAM_TYPE_VENDOR_START, to=android.hardware.radio.ProgramSelector.PROGRAM_TYPE_VENDOR_END) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ProgramSelector.ProgramType {
@@ -5691,7 +5701,9 @@ package android.hardware.radio {
    field public static final int CONFIG_DAB_DAB_SOFT_LINKING = 8; // 0x8
    field public static final int CONFIG_DAB_FM_LINKING = 7; // 0x7
    field public static final int CONFIG_DAB_FM_SOFT_LINKING = 9; // 0x9
    field public static final int CONFIG_FORCE_ANALOG = 2; // 0x2
    field @Deprecated public static final int CONFIG_FORCE_ANALOG = 2; // 0x2
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int CONFIG_FORCE_ANALOG_AM = 11; // 0xb
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final int CONFIG_FORCE_ANALOG_FM = 10; // 0xa
    field public static final int CONFIG_FORCE_DIGITAL = 3; // 0x3
    field public static final int CONFIG_FORCE_MONO = 1; // 0x1
    field public static final int CONFIG_RDS_AF = 4; // 0x4
@@ -5819,8 +5831,11 @@ package android.hardware.radio {
    method @Deprecated public int getSubChannel();
    method @NonNull public java.util.Map<java.lang.String,java.lang.String> getVendorInfo();
    method @Deprecated public boolean isDigital();
    method @FlaggedApi("android.hardware.radio.hd_radio_improved") public boolean isHdAudioAvailable();
    method @FlaggedApi("android.hardware.radio.hd_radio_improved") public boolean isHdSisAvailable();
    method public boolean isLive();
    method public boolean isMuted();
    method @FlaggedApi("android.hardware.radio.hd_radio_improved") public boolean isSignalAcquired();
    method public boolean isStereo();
    method public boolean isTrafficAnnouncementActive();
    method public boolean isTrafficProgram();
@@ -5836,6 +5851,7 @@ package android.hardware.radio {
    method public android.hardware.radio.RadioMetadata.Clock getClock(String);
    method public int getInt(String);
    method public String getString(String);
    method @FlaggedApi("android.hardware.radio.hd_radio_improved") @NonNull public String[] getStringArray(@NonNull String);
    method public java.util.Set<java.lang.String> keySet();
    method public int size();
    method public void writeToParcel(android.os.Parcel, int);
@@ -5844,6 +5860,9 @@ package android.hardware.radio {
    field public static final String METADATA_KEY_ART = "android.hardware.radio.metadata.ART";
    field public static final String METADATA_KEY_ARTIST = "android.hardware.radio.metadata.ARTIST";
    field public static final String METADATA_KEY_CLOCK = "android.hardware.radio.metadata.CLOCK";
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final String METADATA_KEY_COMMENT_ACTUAL_TEXT = "android.hardware.radio.metadata.COMMENT_ACTUAL_TEXT";
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final String METADATA_KEY_COMMENT_SHORT_DESCRIPTION = "android.hardware.radio.metadata.COMMENT_SHORT_DESCRIPTION";
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final String METADATA_KEY_COMMERCIAL = "android.hardware.radio.metadata.COMMERCIAL";
    field public static final String METADATA_KEY_DAB_COMPONENT_NAME = "android.hardware.radio.metadata.DAB_COMPONENT_NAME";
    field public static final String METADATA_KEY_DAB_COMPONENT_NAME_SHORT = "android.hardware.radio.metadata.DAB_COMPONENT_NAME_SHORT";
    field public static final String METADATA_KEY_DAB_ENSEMBLE_NAME = "android.hardware.radio.metadata.DAB_ENSEMBLE_NAME";
@@ -5851,6 +5870,9 @@ package android.hardware.radio {
    field public static final String METADATA_KEY_DAB_SERVICE_NAME = "android.hardware.radio.metadata.DAB_SERVICE_NAME";
    field public static final String METADATA_KEY_DAB_SERVICE_NAME_SHORT = "android.hardware.radio.metadata.DAB_SERVICE_NAME_SHORT";
    field public static final String METADATA_KEY_GENRE = "android.hardware.radio.metadata.GENRE";
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final String METADATA_KEY_HD_STATION_NAME_LONG = "android.hardware.radio.metadata.HD_STATION_NAME_LONG";
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final String METADATA_KEY_HD_STATION_NAME_SHORT = "android.hardware.radio.metadata.HD_STATION_NAME_SHORT";
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final String METADATA_KEY_HD_SUBCHANNELS_AVAILABLE = "android.hardware.radio.metadata.HD_SUBCHANNELS_AVAILABLE";
    field public static final String METADATA_KEY_ICON = "android.hardware.radio.metadata.ICON";
    field public static final String METADATA_KEY_PROGRAM_NAME = "android.hardware.radio.metadata.PROGRAM_NAME";
    field public static final String METADATA_KEY_RBDS_PTY = "android.hardware.radio.metadata.RBDS_PTY";
@@ -5859,6 +5881,7 @@ package android.hardware.radio {
    field public static final String METADATA_KEY_RDS_PTY = "android.hardware.radio.metadata.RDS_PTY";
    field public static final String METADATA_KEY_RDS_RT = "android.hardware.radio.metadata.RDS_RT";
    field public static final String METADATA_KEY_TITLE = "android.hardware.radio.metadata.TITLE";
    field @FlaggedApi("android.hardware.radio.hd_radio_improved") public static final String METADATA_KEY_UFIDS = "android.hardware.radio.metadata.UFIDS";
  }
  public static final class RadioMetadata.Builder {
@@ -5869,6 +5892,7 @@ package android.hardware.radio {
    method public android.hardware.radio.RadioMetadata.Builder putClock(String, long, int);
    method public android.hardware.radio.RadioMetadata.Builder putInt(String, int);
    method public android.hardware.radio.RadioMetadata.Builder putString(String, String);
    method @FlaggedApi("android.hardware.radio.hd_radio_improved") @NonNull public android.hardware.radio.RadioMetadata.Builder putStringArray(@NonNull String, @NonNull String[]);
  }
  public static final class RadioMetadata.Clock implements android.os.Parcelable {
+41 −16
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.hardware.radio;

import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -45,7 +46,7 @@ public final class ProgramList implements AutoCloseable {
    private final Object mLock = new Object();

    @GuardedBy("mLock")
    private final Map<ProgramSelector.Identifier, Map<UniqueProgramIdentifier,
    private final ArrayMap<ProgramSelector.Identifier, ArrayMap<UniqueProgramIdentifier,
            RadioManager.ProgramInfo>> mPrograms = new ArrayMap<>();

    @GuardedBy("mLock")
@@ -203,11 +204,11 @@ public final class ProgramList implements AutoCloseable {
            listCallbacksCopied = new ArrayList<>(mListCallbacks);

            if (chunk.isPurge()) {
                Iterator<Map.Entry<ProgramSelector.Identifier, Map<UniqueProgramIdentifier,
                        RadioManager.ProgramInfo>>> programsIterator =
                        mPrograms.entrySet().iterator();
                Iterator<Map.Entry<ProgramSelector.Identifier,
                        ArrayMap<UniqueProgramIdentifier, RadioManager.ProgramInfo>>>
                        programsIterator = mPrograms.entrySet().iterator();
                while (programsIterator.hasNext()) {
                    Map.Entry<ProgramSelector.Identifier, Map<UniqueProgramIdentifier,
                    Map.Entry<ProgramSelector.Identifier, ArrayMap<UniqueProgramIdentifier,
                            RadioManager.ProgramInfo>> removed = programsIterator.next();
                    if (removed.getValue() != null) {
                        removedList.add(removed.getKey());
@@ -270,8 +271,7 @@ public final class ProgramList implements AutoCloseable {
        if (!mPrograms.containsKey(primaryKey)) {
            return;
        }
        Map<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries = mPrograms
                .get(primaryKey);
        Map<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries = mPrograms.get(primaryKey);
        RadioManager.ProgramInfo removed = entries.remove(Objects.requireNonNull(key));
        if (removed == null) return;
        if (entries.size() == 0) {
@@ -287,15 +287,10 @@ public final class ProgramList implements AutoCloseable {
    public @NonNull List<RadioManager.ProgramInfo> toList() {
        List<RadioManager.ProgramInfo> list = new ArrayList<>();
        synchronized (mLock) {
            Iterator<Map.Entry<ProgramSelector.Identifier, Map<UniqueProgramIdentifier,
                    RadioManager.ProgramInfo>>> listIterator = mPrograms.entrySet().iterator();
            while (listIterator.hasNext()) {
                Iterator<Map.Entry<UniqueProgramIdentifier,
                        RadioManager.ProgramInfo>> prorgramsIterator = listIterator.next()
                        .getValue().entrySet().iterator();
                while (prorgramsIterator.hasNext()) {
                    list.add(prorgramsIterator.next().getValue());
                }
            for (int index = 0; index < mPrograms.size(); index++) {
                ArrayMap<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries =
                        mPrograms.valueAt(index);
                list.addAll(entries.values());
            }
        }
        return list;
@@ -304,9 +299,16 @@ public final class ProgramList implements AutoCloseable {
    /**
     * Returns the program with a specified primary identifier.
     *
     * <p>This method only returns the first program from the list return from
     * {@link #getProgramInfos}
     *
     * @param id primary identifier of a program to fetch
     * @return the program info, or null if there is no such program on the list
     *
     * @deprecated Use {@link #getProgramInfos(ProgramSelector.Identifier)} to get all programs
     * with the given primary identifier
     */
    @Deprecated
    public @Nullable RadioManager.ProgramInfo get(@NonNull ProgramSelector.Identifier id) {
        Map<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries;
        synchronized (mLock) {
@@ -319,6 +321,29 @@ public final class ProgramList implements AutoCloseable {
        return entries.entrySet().iterator().next().getValue();
    }

    /**
     * Returns the program list with a specified primary identifier.
     *
     * @param id primary identifier of a program to fetch
     * @return the program info list with the primary identifier, or empty list if there is no such
     * program identifier on the list
     * @throws NullPointerException if primary identifier is {@code null}
     */
    @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED)
    public @NonNull List<RadioManager.ProgramInfo> getProgramInfos(
            @NonNull ProgramSelector.Identifier id) {
        Objects.requireNonNull(id, "Primary identifier can not be null");
        ArrayMap<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries;
        synchronized (mLock) {
            entries = mPrograms.get(id);
        }

        if (entries == null) {
            return new ArrayList<>();
        }
        return new ArrayList<>(entries.values());
    }

    /**
     * Filter for the program list.
     */
+131 −15
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.hardware.radio;

import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -124,6 +125,86 @@ public final class ProgramSelector implements Parcelable {
    @Retention(RetentionPolicy.SOURCE)
    public @interface ProgramType {}

    /**
     * Bitmask for HD radio subchannel 1
     *
     * <p>There are at most 8 HD radio subchannels of 1-based om HD radio standard. It is
     * converted to 0-based index. 0 is the index of main program service (MPS). 1 to 7 are
     * indexes of additional supplemental program services (SPS).
     */
    @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED)
    public static final int SUB_CHANNEL_HD_1 = 1 << 0;

    /**
     * Bitmask for HD radio subchannel 2
     *
     * <p>For further reference, see {@link #SUB_CHANNEL_HD_1}
     */
    @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED)
    public static final int SUB_CHANNEL_HD_2 = 1 << 1;

    /**
     * Bitmask for HD radio subchannel 3
     *
     * <p>For further reference, see {@link #SUB_CHANNEL_HD_1}
     */
    @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED)
    public static final int SUB_CHANNEL_HD_3 = 1 << 2;

    /**
     * Bitmask for HD radio subchannel 4
     *
     * <p>For further reference, see {@link #SUB_CHANNEL_HD_1}
     */
    @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED)
    public static final int SUB_CHANNEL_HD_4 = 1 << 3;

    /**
     * Bitmask for HD radio subchannel 5
     *
     * <p>For further reference, see {@link #SUB_CHANNEL_HD_1}
     */
    @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED)
    public static final int SUB_CHANNEL_HD_5 = 1 << 4;

    /**
     * Bitmask for HD radio subchannel 6
     *
     * <p>For further reference, see {@link #SUB_CHANNEL_HD_1}
     */
    @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED)
    public static final int SUB_CHANNEL_HD_6 = 1 << 5;

    /**
     * Bitmask for HD radio subchannel 7
     *
     * <p>For further reference, see {@link #SUB_CHANNEL_HD_1}
     */
    @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED)
    public static final int SUB_CHANNEL_HD_7 = 1 << 6;

    /**
     * Bitmask for HD radio subchannel 8
     *
     * <p>For further reference, see {@link #SUB_CHANNEL_HD_1}
     */
    @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED)
    public static final int SUB_CHANNEL_HD_8 = 1 << 7;

    /** @hide */
    @IntDef(prefix = { "SUB_CHANNEL_HD_" }, value = {
            SUB_CHANNEL_HD_1,
            SUB_CHANNEL_HD_2,
            SUB_CHANNEL_HD_3,
            SUB_CHANNEL_HD_4,
            SUB_CHANNEL_HD_5,
            SUB_CHANNEL_HD_6,
            SUB_CHANNEL_HD_7,
            SUB_CHANNEL_HD_8,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface HdSubChannel {}

    public static final int IDENTIFIER_TYPE_INVALID = 0;
    /**
     * Primary identifier for analog (without RDS) AM/FM stations:
@@ -147,19 +228,15 @@ public final class ProgramSelector implements Parcelable {
     *
     * <p>Consists of (from the LSB):
     * <li>
     *     <ul>32bit: Station ID number.
     *     <ul>4bit: HD_SUBCHANNEL.
     *     <ul>18bit: AMFM_FREQUENCY.
     *     <ul>32bit: Station ID number.</ul>
     *     <ul>4bit: HD subchannel, see {@link #SUB_CHANNEL_HD_1}.</ul>
     *     <ul>18bit: AMFM_FREQUENCY.</ul>
     * </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).
     * a best-effort - see {@link #IDENTIFIER_TYPE_HD_STATION_NAME}.
     *
     * <p>The remaining bits should be set to zeros when writing on the chip side
     * and ignored when read.
@@ -202,9 +279,9 @@ public final class ProgramSelector implements Parcelable {
     *
     * <p>Consists of (from the LSB):
     * <li>
     *     <ul>16bit: SId.
     *     <ul>8bit: ECC code.
     *     <ul>4bit: SCIdS.
     *     <ul>16bit: SId.</ul>
     *     <ul>8bit: ECC code.</ul>
     *     <ul>4bit: SCIdS.</ul>
     * </li>
     *
     * <p>SCIdS (Service Component Identifier within the Service) value
@@ -238,18 +315,26 @@ public final class ProgramSelector implements Parcelable {
    public static final int IDENTIFIER_TYPE_DRMO_MODULATION = 11;
    /**
     * 32bit primary identifier for SiriusXM Satellite Radio.
     *
     * @deprecated SiriusXM Satellite Radio is not supported
     */
    public static final int IDENTIFIER_TYPE_SXM_SERVICE_ID = 12;
    /** 0-999 range */
    /**
     * 0-999 range
     *
     * @deprecated SiriusXM Satellite Radio is not supported
     */
    public static final int IDENTIFIER_TYPE_SXM_CHANNEL = 13;
    /**
     * 44bit compound primary identifier for Digital Audio Broadcasting and
     * Digital Multimedia Broadcasting.
     *
     * <p>Consists of (from the LSB):
     * - 32bit: SId;
     * - 8bit: ECC code;
     * - 4bit: SCIdS.
     * <li>
     *     <ul>32bit: SId;</ul>
     *     <ul>8bit: ECC code;</ul>
     *     <ul>4bit: SCIdS.</ul>
     * </li>
     *
     * <p>SCIdS (Service Component Identifier within the Service) value
     * of 0 represents the main service, while 1 and above represents
@@ -259,6 +344,36 @@ public final class ProgramSelector implements Parcelable {
     * side and ignored when read.
     */
    public static final int IDENTIFIER_TYPE_DAB_DMB_SID_EXT = 14;
    /**
     * 64bit additional identifier for HD Radio representing station location.
     *
     * <p>Consists of (from the LSB):
     * <li>
     *     <ul>4 bit: Bits 0:3 of altitude</ul>
     *     <ul>13 bit: Fractional bits of longitude</ul>
     *     <ul>8 bit: Integer bits of longitude</ul>
     *     <ul>1 bit: 0 for east and 1 for west for longitude</ul>
     *     <ul>1 bit: 0, representing longitude</ul>
     *     <ul>5 bit: pad of zeros separating longitude and latitude</ul>
     *     <ul>4 bit: Bits 4:7 of altitude</ul>
     *     <ul>13 bit: Fractional bits of latitude</ul>
     *     <ul>8 bit: Integer bits of latitude</ul>
     *     <ul>1 bit: 0 for north and 1 for south for latitude</ul>
     *     <ul>1 bit: 1, representing latitude</ul>
     *     <ul>5 bit: pad of zeros</ul>
     * </li>
     *
     * <p>This format is defined in NRSC-5-C document: SY_IDD_1020s.
     *
     * <p>Due to Station ID abuse, some
     * {@link #IDENTIFIER_TYPE_HD_STATION_ID_EXT} identifiers may be not
     * globally unique. To provide a best-effort solution, the station’s
     * broadcast antenna containing the latitude and longitude may be
     * carried as additional identifier and may be used by the tuner hardware
     * to double-check tuning.
     */
    @FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED)
    public static final int IDENTIFIER_TYPE_HD_STATION_LOCATION = 15;
    /**
     * Primary identifier for vendor-specific radio technology.
     * The value format is determined by a vendor.
@@ -300,6 +415,7 @@ public final class ProgramSelector implements Parcelable {
        IDENTIFIER_TYPE_SXM_SERVICE_ID,
        IDENTIFIER_TYPE_SXM_CHANNEL,
        IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
        IDENTIFIER_TYPE_HD_STATION_LOCATION,
    })
    @IntRange(from = IDENTIFIER_TYPE_VENDOR_START, to = IDENTIFIER_TYPE_VENDOR_END)
    @Retention(RetentionPolicy.SOURCE)
+61 −4

File changed.

Preview size limit exceeded, changes collapsed.

+167 −4

File changed.

Preview size limit exceeded, changes collapsed.

Loading