Горячее подключение

Возможности отображения (такие как режимы отображения и поддерживаемые типы HDR) могут динамически изменяться на устройствах с внешним подключением дисплеев (через HDMI или DisplayPort), таких как телевизионные приставки Android TV (STB) и устройства с поддержкой технологии OTT. Это изменение может происходить в результате сигнала горячего подключения HDMI, например, когда пользователь переключается с одного дисплея на другой или загружает устройство без подключенного дисплея. В Android 12 и более поздних версиях внесены изменения в фреймворк для поддержки горячего подключения и динамических возможностей отображения.

На этой странице описывается обработка горячего подключения дисплеев и изменения в возможностях дисплея в реализации Composer HAL. Кроме того, здесь обсуждается управление связанным буфером кадров и предотвращение состояний гонки в таких ситуациях.

Обновление возможностей отображения

В этом разделе описывается, как платформа Android обрабатывает изменения в возможностях отображения, инициированные Composer HAL.

Прежде чем Android сможет корректно обрабатывать изменения в возможностях отображения, OEM-производитель должен реализовать Composer HAL таким образом, чтобы он использовал onHotplug(display, connection=CONNECTED) для уведомления фреймворка о любых изменениях в возможностях отображения. После этого Android обрабатывает изменения в возможностях отображения следующим образом:

  1. При обнаружении изменения в возможностях отображения фреймворк получает уведомление onHotplug(display, connection=CONNECTED) .
  2. Получив уведомление, фреймворк сбрасывает свое состояние отображения и воссоздает его с новыми возможностями из HAL, используя методы getActiveConfig , getDisplayConfigs , getDisplayAttribute , getColorModes , getHdrCapabilities и getDisplayCapabilities .
  3. После того как фреймворк воссоздает новое состояние отображения, он отправляет обратный вызов onDisplayChanged приложениям, которые прослушивают такие события.

Фреймворк перераспределяет фреймбуферы при последующих событиях onHotplug(display, connection=CONNECTED) . Подробнее о том, как правильно управлять памятью фреймбуфера, чтобы избежать сбоев при выделении новых фреймбуферов, см. в разделе Управление фреймбуфером клиента .

Обработка распространенных сценариев подключения

В этом разделе описывается, как правильно обрабатывать различные сценарии подключения в ваших реализациях, когда основной дисплей подключен и отключен.

Разработанный для мобильных устройств, фреймворк Android не имеет встроенной поддержки отключённого основного дисплея. Вместо этого HAL должен заменять основной дисплей на дисплей-заглушку при взаимодействии с фреймворком в случае физического отключения основного дисплея.

В приставках STB и ТВ-адаптерах с внешними дисплеями, которые можно отключить, могут возникнуть следующие сценарии. Для реализации поддержки этих сценариев используйте информацию из таблицы ниже:

Сценарий Умение обращаться
Нет подключенного дисплея во время загрузки
  • Отправьте сигнал onHotplug(display, connection=CONNECTED) из Composer HAL в фреймворк.
  • Замените физическое состояние отображения внутри Composer HAL на состояние отображения-заполнителя.
Основной дисплей физически подключен
  • Отправьте еще одно событие onHotplug(display, connection=CONNECTED) из Composer HAL во фреймворк.

    Это заставляет фреймворк перезагружать все возможности отображения.

Основной дисплей физически отключен
  • Отправьте еще одно событие onHotplug(display, connection=CONNECTED) из Composer HAL во фреймворк.
  • Замените состояние физического дисплея в HAL-уровне Composer на состояние отображения-заполнителя. У отображения-заполнителя должен быть один режим отображения, чтобы фреймворк отправлял обратный вызов onDisplayChanged приложениям (поскольку набор поддерживаемых режимов изменился). Этот режим отображения должен соответствовать последнему активному режиму физического дисплея перед отключением, чтобы приложения не получали события изменения конфигурации .

Рекомендации по подключению без HDMI

Android TV поддерживает только следующие разрешения:

  • 720x1280
  • 1080x1920
  • 2160x3840
  • 4320x7680

Когда STB или телевизионный адаптер пытается отобразить неподдерживаемое разрешение, например 480i, по соединению CVBS, пользователю отображается сообщение об ошибке.

Если у STB или TV-адаптера есть как HDMI-, так и не-HDMI-подключения, HDMI-подключение является основным дисплеем, а не-HDMI-подключение неактивно. В результате, если HDMI-подключение отключается, а не-HDMI-подключение всё ещё подключено, событие отправляется в SurfaceFlinger, и возможности не-HDMI-дисплея должны быть отражены через getDisplayAttribute и другие API iComposerClient (например, getHdrCapabilities ).

Используйте последовательные идентификаторы конфигураций для предотвращения состояний гонки

Состояние гонки может возникнуть, если Composer HAL обновляет поддерживаемые конфигурации отображения одновременно с вызовом фреймворком setActiveConfig или setActiveConfigWithConstraints . Решение заключается в реализации Composer HAL для использования последовательных идентификаторов и предотвращения этой проблемы.

В этом разделе описывается, как могут возникнуть условия гонки, а затем приводятся сведения о том, как реализовать Composer HAL таким образом, чтобы он использовал последовательные идентификаторы для предотвращения таких условий.

Рассмотрим следующую последовательность событий, когда новые последовательные идентификаторы НЕ назначаются новым конфигурациям отображения, что приводит к состоянию гонки:

  1. Поддерживаемые идентификаторы конфигураций дисплея:

    • id=1 , 1080x1920 60 Гц
    • id=2 , 1080x1920 50 Гц
  2. Фреймворк вызывает setActiveConfig(display, config=1) .

  3. Одновременно с этим Composer HAL обрабатывает изменение конфигураций дисплея и обновляет свое внутреннее состояние новым набором конфигураций дисплея, как показано ниже:

    • id=1 , 2160x3840 60 Гц
    • id=2 , 2160x3840 50 Гц
    • id=3 , 1080x1920 60 Гц
    • id=4 , 1080x1920 50 Гц
  4. Composer HAL отправляет событие onHotplug фреймворку, чтобы уведомить об изменении набора поддерживаемых режимов.

  5. Composer HAL получает setActiveConfig(display, config=1) (из шага 2).

  6. HAL интерпретирует это так, что фреймворк запросил изменение конфигурации на 2160x3840 60 Гц , хотя на самом деле требовалось 1080x1920 60 Гц .

Процесс с использованием непоследовательного назначения идентификаторов заканчивается здесь неверной интерпретацией желаемого изменения конфигурации.

Настройте Composer HAL для использования последовательных идентификаторов

Чтобы избежать подобных условий гонки, OEM-производитель должен реализовать Composer HAL следующим образом:

  • Когда Composer HAL обновляет поддерживаемые конфигурации отображения, он назначает новые последовательные идентификаторы новым конфигурациям отображения.
  • Когда фреймворк вызывает setActiveConfig или setActiveConfigWithConstraints с недопустимым идентификатором конфигурации, Composer HAL игнорирует вызов.

Эти шаги позволяют предотвратить возникновение состояний гонки, как показано в следующем обсуждении.

Рассмотрим следующую последовательность событий, когда новым конфигурациям отображения присваиваются новые последовательные идентификаторы:

  1. Поддерживаемые идентификаторы конфигураций дисплея:

    • id=1 , 1080x1920 60 Гц
    • id=2 , 1080x1920 50 Гц
  2. Фреймворк вызывает setActiveConfig(display, config=1) .

  3. При обработке изменения конфигураций отображения следующий набор идентификаторов конфигураций назначается, начиная со следующего неиспользованного целого числа, как показано ниже:

    • id=3 , 2160x3840 60 Гц

    • id=4 , 2160x3840 50 Гц

    • id=5 , 1080x1920 60 Гц

    • id=6 , 1080x1920 50 Гц

  4. Composer HAL отправляет фреймворку событие onHotplug , чтобы уведомить об изменении набора поддерживаемых режимов.

  5. Composer HAL получает setActiveConfig(display, config=1) (из шага 2).

  6. Composer HAL игнорирует вызов, поскольку идентификатор больше не действителен.

  7. Фреймворк получает и обрабатывает событие onHotplug из шага 4. Он обращается к HAL-компоненту Composer, используя функции getDisplayConfigs и getDisplayAttribute . С помощью этих функций фреймворк идентифицирует новый идентификатор (5) для требуемого разрешения и частоты обновления 1080x1920 и 60 Гц.

  8. Фреймворк отправляет еще одно событие setActiveConfig с обновленным идентификатором 5.

  9. Composer HAL получает setActiveConfig(display, config=5) из шага 5.

  10. HAL правильно интерпретирует, что фреймворк запросил изменение конфигурации на 1080x1920 60 Гц.

Как показано в примере выше, процесс, использующий последовательное назначение идентификаторов, гарантирует предотвращение состояния гонки и обновление правильного изменения конфигурации дисплея.