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

Возможности отображения (например, режимы отображения и поддерживаемые типы 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 и TV dongles, которые имеют внешние подключенные дисплеи, которые можно отключить. Для реализации поддержки этих сценариев используйте информацию в таблице ниже:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    • идентификатор=1 , 2160x3840 60 Гц
    • идентификатор=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. Поддерживаемые идентификаторы конфигурации дисплея:

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

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

    • идентификатор=3 , 2160x3840 60 Гц

    • идентификатор=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. Он вызывает Composer HAL, используя функции getDisplayConfigs и getDisplayAttribute . С помощью этих функций фреймворк идентифицирует новый идентификатор (5) для желаемого разрешения и частоты обновления 1080x1920 и 60 Гц.

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

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

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

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