В следующих разделах описывается, как работать с уровнем аппаратной абстракции (HAL) для реализации широковещательного радио.
Интерфейс HAL для вещательного радио
HAL вещательного радио предоставляет структуры данных и интерфейсы на аппаратном уровне для реализации вещательного радио, такого как AM/FM и DAB-радио.
Интерфейсы HIDL 2.0 и AIDL
Радиовещательная система HAL использует интерфейсы, описанные в следующих разделах.
IAnnouncementListener
 IAnnouncementListener — это интерфейс обратного вызова для прослушивателя объявлений, который можно зарегистрировать на HAL-уровне вещательного радио для получения объявлений. Интерфейс имеет следующие методы:
| IAnnouncementListener | ||
|---|---|---|
| Описание: Вызывается всякий раз, когда изменяется список объявлений. | ||
| HIDL 2.0 | oneway onListUpdated(vec<Announcement> announcements) | |
| AIDL | oneway void onListUpdated(in Announcement[] announcements) | |
ICloseHandle
 ICloseHandle — это универсальный дескриптор закрытия, позволяющий удалить обратный вызов, которому не нужен активный интерфейс.
| ICloseHandle | ||
|---|---|---|
| Описание: Закройте ручку. | ||
| HIDL 2.0 | close() | |
| AIDL | void close() | |
ITunerCallback
 ITunerCallback — это интерфейс обратного вызова, вызываемый вещательным радио HAL для отправки обновлений клиентской службе HAL.
| ITunerCallback | ||
|---|---|---|
| Описание: Вызывается HAL, когда операция настройки (настройка, поиск (в AIDL) или сканирование (в HIDL) и шаг выполнены успешно) асинхронно завершается неудачей. | ||
| HIDL 2.0 | oneway onCurrentProgramInfoChanged(ProgramInfo info) | |
| AIDL | void onCurrentProgramInfoChanged(in ProgramInfo info) | |
| Описание: Вызывается при успешной настройке, поиске (в AIDL) или сканировании (в HIDL) или шаге. | ||
| HIDL 2.0 | oneway onTuneFailed(Result result, ProgramSelector selector) | |
| AIDL | void onTuneFailed(in Result result, in ProgramSelector selector) | |
| Описание: Вызывается при успешной настройке, поиске (в AIDL) или сканировании (в HIDL) или шаге. | ||
| HIDL 2.0 | oneway onCurrentProgramInfoChanged(ProgramInfo info) | |
| AIDL | void onCurrentProgramInfoChanged(in ProgramInfo info) | |
| Описание: Вызывается при обновлении списка программ; размер каждого фрагмента должен быть ограничен 500 КБ. | ||
| HIDL 2.0 | oneway onProgramListUpdated(ProgramListChunk chunk) | |
| AIDL | void onProgramListUpdated(ProgramListChunk chunk) | |
| Описание: Вызывается при подключении или отключении антенны. | ||
| HIDL 2.0 | oneway onAntennaStateChange(bool connected) | |
| AIDL | void onCurrentProgramInfoChanged(in ProgramInfo info) | |
| Описание: Вызывается, когда значения параметров, специфичных для поставщика, обновляются внутри HAL (не вызывать после вызова setParametersклиентом HAL). | ||
| HIDL 2.0 | oneway onParametersUpdated(vec<VendorKeyValue> parameters) | |
| AIDL | void onParametersUpdated(in VendorKeyValue[] parameters) | |
| Описание: Новое в AIDL. Вызывается при внутреннем обновлении флага конфигурации в HAL (не следует вызывать после вызова setConfigFlagклиентом HAL). | ||
| HIDL 2.0 | Непригодный. | |
| AIDL | void onConfigFlagUpdated(in ConfigFlag flag, in boolean value) | |
IBroadcastRadio
 IBroadcastRadio — основной интерфейс для HAL вещательного радио. В HAL HIDL 2.0 для вызова операций тюнера используется интерфейс ITunerSession . Однако одновременно может быть активен только один тюнер (при условии, что каждый экземпляр HAL вещательного радио имеет только один чип тюнера). ITunerSession был удалён из интерфейсов AIDL, а его интерфейсы перенесены в IBroadcastRadio .
| IBroadcastRadio | ||
|---|---|---|
| Описание: Получите описание модуля и его возможностей. | ||
| HIDL 2.0 | getProperties() generates (Properties properties) | |
| AIDL | Properties getProperties() | |
| Описание: Извлекает текущую или возможную конфигурацию региона AM/FM. | ||
| HIDL 2.0 | getAmFmRegionConfig(bool full) generates (Result result, AmFmRegionConfig config) | |
| AIDL | AmFmRegionConfig getAmFmRegionConfig(bool full) | |
| Описание: Извлекает текущую конфигурацию региона DAB. | ||
| HIDL 2.0 | getDabRegionConfig() generates (Result result, vec<DabTableEntry> config) | |
| AIDL | DabTableEntry[] getDabRegionConfig() | |
| Описание: Получает изображение из кэша радиомодуля. В AIDL размер изображения должен быть меньше 1 МБ из-за жёсткого ограничения на буфер транзакций связующего устройства. | ||
| HIDL 2.0 | getImage(uint32_t id) generates (vec<uint8_t> image) | |
| AIDL | byte[] getImage(in int id) | |
| Описание: Регистрирует прослушиватель объявлений. | ||
| HIDL 2.0 | registerAnnouncementListener(vec<AnnouncementType> enabled,IAnnouncementListener listener) generates (Result result, ICloseHandle closeHandle) | |
| AIDL | ICloseHandle registerAnnouncementListener(in IAnnouncementListener listener, in AnnouncementType[] enabled) | |
| Описание: 
 | ||
| HIDL 2.0 | openSession(ITunerCallback callback)генерирует(Result result, ITunerSession session) | |
| AIDL | void setTunerCallback(in ITunerCallback callback) | |
| Описание: 
 | ||
| HIDL 2.0 | close() | |
| AIDL | unsetTunerCallback() | |
| Описание: Настраивает на указанную программу. | ||
| HIDL 2.0 | tune(ProgramSelector program) generates (Result result) | |
| AIDL | void tune(in ProgramSelector program) | |
| Описание: Ищет следующую допустимую программу в эфире . Во избежание путаницы в AIDL, scanпереименован вseek. | ||
| HIDL 2.0 | scan(bool directionUp, bool skipSubChannel) generates (Result result) | |
| AIDL | void seek(in boolean directionUp, in boolean skipSubChannel) | |
| Описание: Переход на соседний канал, который не может быть занят какой-либо программой. | ||
| HIDL 2.0 | step(bool directionUp) generates (Result result) | |
| AIDL | void step(in boolean directionUp) | |
| Описание: Отменяет отложенные операции настройки, сканирования (в HIDL) или поиска (в AIDL), а также пошаговые операции. | ||
| HIDL 2.0 | cancel() | |
| AIDL | void cancel() | |
| Описание: Применяет фильтр к списку программ и начинает отправлять обновления списка программ через обратный вызов onProgramListUpdated. | ||
| HIDL 2.0 | startProgramListUpdates(ProgramFilter filter) generates (Result result) | |
| AIDL | void startProgramListUpdates(in ProgramFilter filter) | |
| Описание: Прекращает отправку обновлений списка программ. | ||
| HIDL 2.0 | stopProgramListUpdates() | |
| AIDL | void stopProgramListUpdates() | |
| Описание: Извлекает текущую настройку заданного флага конфигурации. | ||
| HIDL 2.0 | isConfigFlagSet(ConfigFlag flag) generates (Result result, bool value) | |
| AIDL | boolean isConfigFlagSet(in ConfigFlag flag) | |
| Описание: Устанавливает заданный флаг конфигурации. | ||
| HIDL 2.0 | setConfigFlag(ConfigFlag flag, bool value) generates (Result result) | |
| AIDL | void setConfigFlag(in ConfigFlag flag, boolean value) | |
| Описание: Устанавливает значения параметров, специфичные для поставщика. | ||
| HIDL 2.0 | setParameters(vec<VendorKeyValue> parameters)генерирует , (vec<VendorKeyValue> results) | |
| AIDL | VendorKeyValue[] setParameters(in VendorKeyValue[] parameters) | |
| Описание: Извлекает значения параметров, специфичные для поставщика. | ||
| HIDL 2.0 | getParameters(vec<string> keys) generates (vec<VendorKeyValue> parameters) | |
| AIDL | VendorKeyValue[] getParameters(in String[] keys) | |
Уточнения интерфейса
Асинхронное поведение
Поскольку каждая операция настройки (например, настройка, сканирование (в HIDL) или поиск (в AIDL) и шаг) может занимать много времени, а поток не должен блокироваться надолго, операция должна планировать выполнение длительных операций на более позднее время и быстро возвращать состояние или результат. В частности, каждая операция должна:
- Отмените все запланированные операции по настройке.
- Проверьте, может ли операция быть выполнена на основе входных данных метода и состояния тюнера.
-  Запланируйте задачу настройки и немедленно верните Result(в HIDL) илиstatus(в AIDL). ЕслиResultилиstatus—OK, необходимо вызвать функцию обратного вызова тюнераtuneFailedилиcurrentProgramInfoChangedпосле сбоя задачи настройки (например, из-за тайм-аута) или её завершения.
 Аналогично, startProgramListUpdates также планирует выполнение трудоёмкой задачи обновления списка программ на более позднее время и быстро возвращает статус или результат. Метод сначала отменяет ожидающие запросы на обновление, а затем планирует задачу обновления и быстро возвращает результат.
Состояние гонки
 Из-за асинхронности операций настройки (например, настройки, сканирования (в HIDL) или поиска (в AIDL) и пошагового выполнения) возникает состояние гонки между отменой операции и операциями настройки. Если cancel вызывается после того, как HAL завершает операцию настройки, но до завершения обратного вызова, отмену можно проигнорировать, а обратный вызов должен быть выполнен и принят клиентом HAL.
 Аналогично, если stopProgramListUpdates вызывается после того, как HAL завершает обновление списка программ и до завершения обратного вызова onCurrentProgramInfoChanged , stopProgramListUpdates можно игнорировать, и обратный вызов должен быть завершен.
Ограничение размера данных
Поскольку на буфер транзакций связующего устройства наложено жесткое ограничение, в AIDL HAL разъясняются ограничения по объему данных для некоторых методов интерфейса, передающих данные потенциально большого размера.
-  getImageтребует, чтобы возвращаемое изображение имело размер менее 1 МБ.
-  Для onProgramListUpdateтребуется, чтобы каждыйchunkбыл меньше 500 КБ. Более крупные списки программ должны быть разделены реализацией HAL на несколько фрагментов и отправлены через несколько обратных вызовов.
Изменения в структурах данных AIDL HAL
Помимо изменений в интерфейсах, эти изменения были применены к структурам данных, определенным в вещательном радио AIDL HAL, который использует преимущества AIDL.
-  Constantперечисление удалено из AIDL и определено как const int вIBroadcastRadio. В то же время,ANTENNA_DISCONNECTED_TIMEOUT_MSпереименована вANTENNA_STATE_CHANGE_TIMEOUT_MS. Добавлен новый const intTUNER_TIMEOUT_MS. Все операции настройки, поиска и шага должны быть завершены в течение этого времени.
-  Перечисления RDSиDeemphasisудалены из AIDL и определены как const int вAmFmRegionConfig. Соответственно,fmDeemphasisиfmRdsвProgramInfoобъявлены как int, что является результатом битового вычисления соответствующих флагов. При этомD50иD75переименованы вDEEMPHASIS_D50иDEEMPHASIS_D75соответственно.
-  Перечисление ProgramInfoFlagsудалено из AIDL и определено как const int вProgramInfoс добавлением префиксаFLAG_. Соответственно,infoFlagsвProgramInfoобъявлен как int, результат битового вычисления флагов.TUNEDтакже переименован вFLAG_TUNABLE, чтобы лучше описать определение, на которое можно настроить станцию.
-  В AmFmBandRangescanSpacingпереименован вseekSpacing, поскольку в AIDLscanпереименован вseek.
-  С появлением концепции объединения в AIDL, MetadataKeyиMetadataопределённые в HIDL HAL, больше не используются. В AIDL HAL определено объединениеMetadataAIDL. Каждое значение перечисления, ранее входившее вMetadataKeyтеперь является полем вMetadataсо строковым или целочисленным типом, в зависимости от определения.
Поддержка DAB-радио
В этом разделе описывается поддержка DAB-радио.
Идентификаторы
 Основным типом идентификатора для радио DAB и DMB в AIDL Broadcast Radio HAL является DAB_SID_EXT . DAB_SID_EXT использует 32-битные идентификаторы служб (SID), поэтому он может представлять SID как радио DAB, так и DMB.
 Помимо основных идентификаторов, поддерживаются вторичные идентификаторы, такие как DAB_ENSEMBLE и DAB_FREQUENCY_KHZ . Это важно, поскольку несколько DAB-станций могут иметь один и тот DAB_SID_EXT , но при этом иметь разные значения DAB_ENSEMBLE или DAB_FREQUENCY_KHZ . Для обеспечения корректного обновления списка программ станции с одинаковым DAB_SID_EXT обновляются одновременно с помощью ITunerCallback#onProgramListUpdated . Затем это обновление передается в службу вещательного радио и диспетчер радиостанций, а затем в приложение радиостанции через android.hardware.radio.ProgramList .
Метаданные
В следующей таблице показаны поддерживаемые метаданные, специфичные для DAB в AIDL Broadcast Radio HAL:
| Поле метаданных | Описание | 
|---|---|
| dabEnsembleName(сокращенная форма:dabEnsembleNameShort) | Название ансамбля станции DAB | 
| dabServiceName(сокращенно отdabServiceNameShort) | Название службы станции DAB | 
| dabComponentName(сокращенно отdabComponentNameShort) | Название компонента станции DAB | 
Поддержка HD-радио
В этом разделе описывается поддержка HD-радио.
Идентификаторы
 HD_STATION_ID_EXT служит основным идентификатором для HD-радиостанций. Для более точной идентификации станций предусмотрены также вторичные идентификаторы, такие как HD_STATION_NAME и HD_STATION_LOCATION . HD_STATION_LOCATION , предоставляющий информацию о местоположении, был представлен в Android 15.
Включить или отключить цифровое радио
 Начиная с Android 15, вы можете включать и отключать цифровое радио (например, HD-радио) с помощью настройки ConfigFlag . Для управления этим параметром для FM-радио используйте флаг FORCE_ANALOG_FM ; для AM-радио — флаг FORCE_ANALOG_AM . Установка флага в false включает HD-радио, а установка в значение true активирует аналоговое AM/FM-радио.
Доступны HD-каналы
 Начиная с Android 15, HD-каналы, доступные для HD-радиостанции, могут быть представлены 8-битной битовой маской Metadata#hdSubChannelsAvailable в ProgramInfo.metadata . Например, значение бита 1 слева указывает, доступен ли подканал HD2 для этой HD-станции.
Статус получения сигнала
В Android 15 и более поздних версиях приложения для прослушивания радио могут показывать пользователям статус приёма сигнала HD-радиостанций. Это полезно, поскольку обнаружение сильного HD-сигнала иногда может занять несколько минут.
 Чтобы предоставить эту информацию, система использует ProgramInfo.infoFlags для отслеживания статуса и обновляет приложение радио через ITunerCallback#onCurrentProgramInfoChanged.
 Вот как статус представлен в ProgramInfo.infoFlags :
- Бит 6: Указывает, получен ли HD-радиосигнал.
- Бит 7: Показывает, доступны ли данные службы информации о станциях (SIS). SIS предоставляет дополнительную информацию о станции и воспроизводимой в данный момент передаче.
- Бит 8: сообщает, доступен ли HD-цифровой звук.
Метаданные
В следующей таблице показаны поддерживаемые метаданные HD-радио для Android 15 и более поздних версий.
| Поле метаданных | Описание | 
|---|---|
| commentShortDescription | Краткое контекстное описание комментария | 
| commentActualText | Текст комментария | 
| commercial | Радиореклама | 
| ufids | Уникальные идентификаторы файлов (UFID), связанные с контентом | 
| hdStationNameShort | Краткое название HD-радиостанции или универсальное короткое название | 
| hdStationNameLong | Длинное название HD-радиостанции, слоган или сообщение от станции. | 
Экстренные оповещения
 В Android 15 и более поздних версиях поддерживаются экстренные оповещения для HD-радиостанций, чтобы информировать пользователей радиоприложения о чрезвычайных оповещениях, отправляемых радиостанциями. Экстренное оповещение ( Alert ) соответствует стандарту Common Alerting Protocol (CAP) 1.2 и поддерживает оповещения, представленные в следующей таблице:
| Информация оповещения | Описание | Доступны значения перечисления | 
|---|---|---|
| AlertStatus | Статус оповещения | ACTUAL,EXERCISE,TEST | 
| AlertMessageType | Тип сообщения о чрезвычайном оповещении | ALERT,UPDATE,CANCEL | 
| AlertCategory | Категория события, о котором идет речь в сообщении о чрезвычайной ситуации | GEO,MET,SAFETY,SECURITY,RESCUE,FIRE,HEALTH,ENV,TRANSPORT,INFRA,CBRNE,OTHER | 
| AlertUrgency | Актуальность события, о котором идет речь в сообщении о чрезвычайной ситуации | IMMEDIATE,EXPECTED,FUTURE,PAST,UNKNOWN | 
| AlertSeverity | Серьезность события, о котором идет речь в сообщении о чрезвычайной ситуации | EXTREME,SEVERE,MODERATE,MINOR,UNKNOWN | 
| AlertCertainty | Достоверность события, о котором идет речь в сообщении о чрезвычайной ситуации | OBSERVED,LIKELY,POSSIBLE,UNLIKELY,UNKNOWN | 
Alert (содержащее информацию из таблицы), текстовые оповещения и AlertArea Alert — необязательное поле в ProgramInfo , которое можно отправлять из Broadcast Radio HAL в радиоприложения через обратные вызовы тюнера для получения информации о текущей программе и обновлений списка программ.
  
  
