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 2.0 | openSession(ITunerCallback callback) generates
(Result result, ITunerSession session) |
|
AIDL | void setTunerCallback(in ITunerCallback callback) |
|
Description:
|
||
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) orstatus
(in AIDL) immediately. If theResult
orstatus
isOK
, the tuner callbacktuneFailed
orcurrentProgramInfoChanged
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 eachchunk
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 inIBroadcastRadio
. Meanwhile,ANTENNA_DISCONNECTED_TIMEOUT_MS
is renamed toANTENNA_STATE_CHANGE_TIMEOUT_MS
. A new const intTUNER_TIMEOUT_MS
is added. All tune, seek, and step operations must be completed within this time.- Enum
RDS
andDeemphasis
are removed in AIDL and defined as const int inAmFmRegionConfig
. Correspondingly, bothfmDeemphasis
andfmRds
inProgramInfo
are declared as int, a bit computation result of the respective flags. Meanwhile,D50
andD75
are renamed toDEEMPHASIS_D50
andDEEMPHASIS_D75
, respectively. - Enum
ProgramInfoFlags
are removed in AIDL and defined as const int inProgramInfo
with a prefixFLAG_
added. Correspondingly,infoFlags
inProgramInfo
is declared as int, a bit computation result of flags.TUNED
is also renamed toFLAG_TUNABLE
, to better describe its definition that the station can be tuned to. - In
AmFmBandRange
,scanSpacing
is renamed toseekSpacing
, sincescan
is renamed toseek
in AIDL. - Since the concept of union is introduced in AIDL,
MetadataKey
andMetadata
defined in HIDL HAL are no longer used. An AIDL unionMetadata
is defined in AIDL HAL. Each enum value previously inMetadataKey
is now a field inMetadata
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
ConfigFlag
s. 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. |