Broadcast radio HAL

The following sections describe how to work with the hardware abstraction layer (HAL) to implement broadcast radio.

Broadcast radio HAL interface

The Broadcast radio HAL provides data structures and interfaces at the hardware level to implement broadcast radio, such as AM/FM and DAB radio.

HIDL 2.0 and AIDL interfaces

The broadcast radio HAL uses the interfaces described in the following sections.

IAnnouncementListener

IAnnouncementListener is the callback interface for the announcement listener, which can be registered on broadcast radio HAL to receive announcements. The interface has the following methods:

IAnnouncementListener
Description: Called whenever the announcement list has changed.
HIDL 2.0 oneway onListUpdated(vec<Announcement> announcements)
AIDL oneway void onListUpdated(in Announcement[] announcements)

ICloseHandle

ICloseHandle is the generic close handle to remove a callback that doesn't need an active interface.

ICloseHandle
Description: Close the handle.
HIDL 2.0 close()
AIDL void close()

ITunerCallback

ITunerCallback is the callback interface called by the broadcast radio HAL to send updates to HAL client service.

ITunerCallback
Description: Called by the HAL when a tuning operation (tune, seek (in AIDL) or scan (in HIDL) and step succeeds) fails asynchronously.
HIDL 2.0 oneway onCurrentProgramInfoChanged(ProgramInfo info)
AIDL void onCurrentProgramInfoChanged(in ProgramInfo info)
Description: Called when tune, seek (in AIDL) or scan (in HIDL), or step succeeds.
HIDL 2.0 oneway onTuneFailed(Result result, ProgramSelector selector)
AIDL void onTuneFailed(in Result result, in ProgramSelector selector)
Description: Called when tune, seek (in AIDL) or scan (in HIDL), or step succeeds.
HIDL 2.0 oneway onCurrentProgramInfoChanged(ProgramInfo info)
AIDL void onCurrentProgramInfoChanged(in ProgramInfo info)
Description: Called when the program list is updated; the size of each chunk should be limited to 500kiB.
HIDL 2.0 oneway onProgramListUpdated(ProgramListChunk chunk)
AIDL oneway onProgramListUpdated(ProgramListChunk chunk)
Description: Called when the antenna is connected or disconnected.
HIDL 2.0 oneway onAntennaStateChange(bool connected)
AIDL void onCurrentProgramInfoChanged(in ProgramInfo info)
Description: Called when vendor-specific parameter values are updated internally in HAL (do not invoke after calling setParameters by HAL client).
HIDL 2.0 oneway onParametersUpdated(vec<VendorKeyValue> parameters)
AIDL void onParametersUpdated(in VendorKeyValue[] parameters)
Description: New in AIDL. Called when the config flag is updated internally in the HAL (should not be invoked after calling setConfigFlag by HAL client).
HIDL 2.0 Not applicable.
AIDL void onConfigFlagUpdated(in ConfigFlag flag, in boolean value)

IBroadcastRadio

IBroadcastRadio is the primary interface for the broadcast radio HAL. In the HIDL 2.0 HAL, use the ITunerSession interface to the tuner to call operations. However, at most one tuner is active at one time (provided each broadcast radio HAL instance only has one tuner chip). ITunerSession was removed from the AIDL interfaces and its interfaces moved to IBroadcastRadio.

IBroadcastRadio
Description: Get the description of a module and its capabilities.
HIDL 2.0 getProperties() generates (Properties properties)
AIDL Properties getProperties()
Description: Fetches the current or possible AM/FM region configuration.
HIDL 2.0 getAmFmRegionConfig(bool full) generates (Result result, AmFmRegionConfig config)
AIDL AmFmRegionConfig getAmFmRegionConfig(bool full)
Description: Fetches the current DAB region configuration.
HIDL 2.0 getDabRegionConfig() generates (Result result, vec<DabTableEntry> config)
AIDL DabTableEntry[] getDabRegionConfig()
Description: Gets an image from the radio module cache. In AIDL, the image size must be less than 1MB due to a hard limit on the binder transaction buffer.
HIDL 2.0 getImage(uint32_t id) generates (vec<uint8_t> image)
AIDL byte[] getImage(in int id)
Description: Registers the announcement listener.
HIDL 2.0 registerAnnouncementListener(vec<AnnouncementType> enabled,IAnnouncementListener listener) generates (Result result, ICloseHandle closeHandle)
AIDL ICloseHandle registerAnnouncementListener(in IAnnouncementListener listener, in AnnouncementType[] enabled)
Description:
  • HIDL HAL: When a new tuner session is opened, the old session must be terminated.
  • AIDL HAL: Since no tuner session is available, only the tuner callback needs to be set. If it exists, the old callback should be unset.
HIDL 2.0 openSession(ITunerCallback callback) generates (Result result, ITunerSession session)
AIDL void setTunerCallback(in ITunerCallback callback)
Description:
  • HIDL HAL: Closing a tuner session must not fail and must only be issued once.
  • AIDL HAL: There is no tuner and only the tuner callback needs to be unset.
HIDL 2.0 close()
AIDL unsetTunerCallback()
Description: Tunes to a specified program.
HIDL 2.0 tune(ProgramSelector program) generates (Result result)
AIDL void tune(in ProgramSelector program)
Description: Seeks the next valid program on the air. To avoid confusion in AIDL, scan is renamed to seek.
HIDL 2.0 scan(bool directionUp, bool skipSubChannel) generates (Result result)
AIDL void seek(in boolean directionUp, in boolean skipSubChannel)
Description: Steps to the adjacent channel, which may not be occupied by any program.
HIDL 2.0 step(bool directionUp) generates (Result result)
AIDL void step(in boolean directionUp)
Description: Cancels pending tune, scan (in HIDL) or seek (in AIDL), or step operations.
HIDL 2.0 cancel()
AIDL void cancel()
Description: Applies a filter to the program list and starts sending program list updates over onProgramListUpdated callback.
HIDL 2.0 startProgramListUpdates(ProgramFilter filter) generates (Result result)
AIDL void startProgramListUpdates(in ProgramFilter filter)
Description: Stops sending program list updates.
HIDL 2.0 stopProgramListUpdates()
AIDL void stopProgramListUpdates()
Description: Fetches the current setting of a given config flag.
HIDL 2.0 isConfigFlagSet(ConfigFlag flag) generates (Result result, bool value)
AIDL boolean isConfigFlagSet(in ConfigFlag flag)
Description: Sets the given config flag.
HIDL 2.0 setConfigFlag(ConfigFlag flag, bool value) generates (Result result)
AIDL void setConfigFlag(in ConfigFlag flag, boolean value)
Description: Sets vendor-specific parameter values.
HIDL 2.0 setParameters(vec<VendorKeyValue> parameters)

generates,

(vec<VendorKeyValue> results)
AIDL VendorKeyValue[] setParameters(in VendorKeyValue[] parameters)
Description: Retrieves vendor-specific parameter values.
HIDL 2.0 getParameters(vec<string> keys) generates (vec<VendorKeyValue> parameters)
AIDL VendorKeyValue[] getParameters(in String[] keys)

Interface clarifications

Asynchronous behavior

Since each tuning operation (for example, tune, scan (in HIDL) or seek (in AIDL), and step) might be time-consuming and the thread should not be blocked for a long time, the operation should schedule time-consuming operations to occur later and quickly return a status or result. In detail, each operation should:

  • Cancel all pending tuning operations.
  • Check if the operation can be processed based on the method inputs and the status of the tuner.
  • Schedule the tuning task and then return the Result (in HIDL) or status (in AIDL) immediately. If the Result or status is OK, the tuner callback tuneFailed or currentProgramInfoChanged must be called when the tuning task has failed (for example, due to a timeout) or is complete.

Similarly, startProgramListUpdates also schedules the time-consuming task of updating the program list to take place later and to quickly return a status or result. The method first cancels pending update requests and then schedules the updating task and quickly returns the result.

Race condition

Due to the asynchronous behavior of tuning operations (for example, tune, scan (in HIDL) or seek (in AIDL), and step), there exists a race condition between canceling the operation and the tuning operations. If cancel is called after the HAL completes a tuning operation and before the callback completes, the cancel can be ignored and the callback should complete and be received by the HAL client.

Similarly, if stopProgramListUpdates is called after the HAL completes a program list update and before the onCurrentProgramInfoChanged callback completes, stopProgramListUpdates can be ignored and the callback should complete.

Data size limit

Since there is a hard limit on the binder transaction buffer, the data limit for some interface methods passing data of a potentially large size are clarified in the AIDL HAL.

  • getImage requires the image returned less than 1 MB.
  • onProgramListUpdate requires each chunk to be less than 500kiB. Larger program lists must be split by the HAL implementation into multiple chunks and sent through multiple callbacks.

Changes in AIDL HAL data structures

In addition to changes in the interfaces, these changes have been applied to the data structures defined in broadcast radio AIDL HAL, which takes advantage of the AIDL.

  • Constant enum is removed in AIDL and defined as const int in IBroadcastRadio. Meanwhile, ANTENNA_DISCONNECTED_TIMEOUT_MS is renamed to ANTENNA_STATE_CHANGE_TIMEOUT_MS. A new const int TUNER_TIMEOUT_MS is added. All tune, seek, and step operations must be completed within this time.
  • Enum RDS and Deemphasis are removed in AIDL and defined as const int in AmFmRegionConfig. Correspondingly, both fmDeemphasis and fmRds in ProgramInfo are declared as int, a bit computation result of the respective flags. Meanwhile, D50 and D75 are renamed to DEEMPHASIS_D50 and DEEMPHASIS_D75, respectively.
  • Enum ProgramInfoFlags are removed in AIDL and defined as const int in ProgramInfo with a prefix FLAG_ added. Correspondingly, infoFlags in ProgramInfo is declared as int, a bit computation result of flags. TUNED is also renamed to FLAG_TUNABLE, to better describe its definition that the station can be tuned to.
  • In AmFmBandRange, scanSpacing is renamed to seekSpacing, since scan is renamed to seek in AIDL.
  • Since the concept of union is introduced in AIDL, MetadataKey and Metadata defined in HIDL HAL are no longer used. An AIDL union Metadata is defined in AIDL HAL. Each enum value previously in MetadataKey is now a field in Metadata with type of string or int, depending on their definitions.

DAB radio support

This section describes DAB radio support.

Identifiers

The primary identifier type for DAB and DMB radio in the AIDL Broadcast Radio HAL is DAB_SID_EXT. DAB_SID_EXT uses a 32-bit service identifiers (SIDs) so that it can represent SID of both DAB and DMB radio.

In addition to primary identifiers, secondary identifiers like DAB_ENSEMBLE and DAB_FREQUENCY_KHZ are supported. This is important because multiple DAB stations can share a DAB_SID_EXT while having different DAB_ENSEMBLE or DAB_FREQUENCY_KHZ values. To ensure accurate program list updates, stations with the same DAB_SID_EXT are updated together using ITunerCallback#onProgramListUpdated. This update is then relayed to the Broadcast Radio Service and Radio Manager, and finally to the radio app through android.hardware.radio.ProgramList.

Metadata

The following table shows the supported metadata speficic to DAB in AIDL Broadcast Radio HAL:

Metadata field Description
dabEnsembleName (abbreviated form: dabEnsembleNameShort) DAB station's ensemble name
dabServiceName (abbreviated from dabServiceNameShort) DAB station's service name
dabComponentName (abbreviated from dabComponentNameShort) DAB station's component name

HD radio rupport

This section describes HD radio support.

Identifiers

HD_STATION_ID_EXT serves as the primary identifier for HD radio stations. To further enhance station identification, secondary identifiers like HD_STATION_NAME and HD_STATION_LOCATION are also provided. HD_STATION_LOCATION, which provides location information, was introduced in Android 15.

Enable or disable digital radio

Starting with Android 15, you can enable or disable digital radio (like HD radio) by adjusting ConfigFlags. To control this setting for FM radio, use the FORCE_ANALOG_FM flag; for AM radio, use the FORCE_ANALOG_AM flag. Setting the flag to false enables HD radio, while setting it to true forces analog AM/FM radio.

HD channels available

Starting with Android 15, the HD channels currently available for the an HD radio station can be represented by a bit mask of 8 bits, Metadata#hdSubChannelsAvailable, in ProgramInfo.metadata. For example, the value of bit 1 from the left represents whether the HD2 subchannel is available for this HD station.

Signal acquisition status

In Android 15 and higher versions, radio apps can show users the signal acquisition status of HD radio stations. This is helpful because acquiring a strong HD signal can sometimes take a few moments.

To provide this information, the system uses ProgramInfo.infoFlags to track the status and updates the radio app through ITunerCallback#onCurrentProgramInfoChanged.

Here's how the status is represented within ProgramInfo.infoFlags:

  • Bit 6: Indicates whether the HD radio signal has been acquired.
  • Bit 7: Shows whether Station Information Service (SIS) data is available. SIS provides extra information about the station and what's playing.
  • Bit 8: Tells whether HD digital audio is available.

Metadata

The following table shows the supported HD radio metadata for Android 15 and higher versions.

Metadata field Description
commentShortDescription Short context description of comment
commentActualText Text of comment
commercial Radio commercial
ufids Unique file identifiers (UFIDs) associated with the content
hdStationNameShort The HD radio station's short name or universal short name
hdStationNameLong The HD radio station's long name, slogan, or a message from the station.