Obsługa Hotpluga

Możliwości wyświetlacza (np. tryby wyświetlania i obsługiwane typy HDR) mogą się zmieniać dynamicznie na urządzeniach z zewnętrznie podłączonymi wyświetlaczami (za pomocą HDMI lub DisplayPort), takich jak dekodery Android TV i urządzenia OTT. Może to być spowodowane sygnałem połączenia HDMI, na przykład przełączeniem się z jednego wyświetlacza na drugi lub uruchomieniem urządzenia bez podłączonego wyświetlacza. Android 12 i nowsze zawiera zmiany w ramach, które umożliwiają obsługę funkcji dynamicznego podłączania i dynamicznego wyświetlania.

Na tej stronie opisujemy obsługę wtyczek typu „displayowe wtyczki” i zmieniamy możliwości wyświetlania w implementacji HAL Composer. Dodatkowo omawia on, jak zarządzać powiązanym framebufferem i zapobiegać sytuacjom wyścigu w takich przypadkach.

Aktualizowanie możliwości wyświetlania

W tej sekcji opisano, jak platforma Android obsługuje zmiany w możliwościach wyświetlania inicjowane przez interfejs HAL usługi Composer.

Zanim Android będzie mógł prawidłowo obsługiwać zmiany w możliwościach wyświetlania, OEM musi zaimplementować interfejs Composer HAL, który używa onHotplug(display, connection=CONNECTED) do powiadamiania platformy o wszelkich zmianach w możliwościach wyświetlania. Po jego wdrożenia Android obsługuje zmiany w możliwościach wyświetlania w ten sposób:

  1. Po wykryciu zmiany możliwości wyświetlania framework otrzymuje powiadomienie onHotplug(display, connection=CONNECTED).
  2. Po otrzymaniu powiadomienia platforma usuwa stan wyświetlania i tworzy go z nowymi możliwościami z HAL przy użyciu metod getActiveConfig, getDisplayConfigs, getDisplayAttribute, getColorModes, getHdrCapabilities i getDisplayCapabilities.
  3. Po odtworzeniu nowego stanu wyświetlania platforma wysyła wywołanie zwrotne onDisplayChanged do aplikacji, które nasłuchują takich zdarzeń.

Platforma ponownie przydziela bufory ramek w kolejnych zdarzeniach onHotplug(display, connection=CONNECTED). Więcej informacji o prawidłowym zarządzaniu pamięcią framebuffera, aby uniknąć błędów podczas przydzielania nowych framebufferów, znajdziesz w artykule Zarządzanie framebufferem klienta.

Obsługa typowych scenariuszy połączeń

W tej sekcji wyjaśniamy, jak prawidłowo obsługiwać różne scenariusze połączeń w implementacjach, gdy wyświetlacz główny jest podłączony lub odłączony.

Platforma Android została stworzona z myślą o urządzeniach mobilnych i nie obsługuje wbudowanego wyświetlacza głównego. Zamiast tego HAL musi zastąpić wyświetlacz główny wyświetlaczem zastępczym w swoich interakcjach z platformą w przypadku, gdy wyświetlacz główny jest fizycznie odłączony.

Poniższe sytuacje mogą wystąpić w przypadku STB i kluczy sprzętowych TV z podłączonymi zewnętrznymi wyświetlaczami, które można odłączyć. Aby wdrożyć obsługę tych scenariuszy, skorzystaj z informacji w tabeli poniżej:

Scenariusz Obsługa
Brak podłączonego wyświetlacza podczas uruchamiania
  • Wysyłanie sygnału onHotplug(display, connection=CONNECTED) z poziomu interfejsu programowania sprzętowego usługi komponowania do platformy.
  • Zastąp stan wyświetlania w komponencie HAL w komponiecie Composer stanem wyświetlania symbolu zastępczego.
Ekran główny jest fizycznie podłączony
Wyświetlacz główny jest fizycznie odłączony.
  • Wyślij kolejne zdarzenie onHotplug(display, connection=CONNECTED) z interfejsu HAL usługi Composer do platformy.
  • Zastąp stan wyświetlania w komponencie HAL w komponie kompozytorze stanem wyświetlania symbolu zastępczego. Wyświetlacz zastępczy musi mieć jeden tryb wyświetlania, aby platforma wysyłała wywołanie zwrotne onDisplayChanged do aplikacji (ponieważ zmienił się zestaw obsługiwanych trybów). Ten tryb pojedynczego wyświetlacza musi odpowiadać ostatniemu aktywnemu trybowi wyświetlacza fizycznego przed odłączeniem, aby aplikacje nie otrzymywały zdarzeń zmiany konfiguracji.

Informacje o połączeniach innych niż HDMI

Android TV obsługuje tylko te rozdzielczości:

  • 720 x 1280
  • 1080 x 1920
  • 2160 x 3840
  • 4320 x 7680

Gdy dekoder STB lub dongle TV próbuje wyświetlić rozdzielczość niedostępną dla danego urządzenia, np. 480i przez połączenie CVBS, użytkownik widzi komunikat o błędzie.

Jeśli dekoder lub urządzenie do telewizji ma zarówno złącza HDMI, jak i inne niż HDMI, złącze HDMI jest głównym wyświetlaczem, a inne niż HDMI jest nieaktywne. Jeśli więc połączenie HDMI zostanie przerwane, a połączenie nie-HDMI nadal będzie aktywne, do SurfaceFlinger zostanie wysłane zdarzenie, a funkcje wyświetlacza nie-HDMI muszą być odzwierciedlone za pomocą interfejsu getDisplayAttribute i innych interfejsów iComposerClient (takich jak getHdrCapabilities).

Używaj sekwencyjnych identyfikatorów konfiguracji, aby zapobiegać warunkom wyścigu

Warunki wyścigu mogą wystąpić, jeśli HAL usługi Composer zaktualizuje obsługiwane konfiguracje wyświetlania jednocześnie z wywoływaniem platformy setActiveConfig lub setActiveConfigWithConstraints. Rozwiązaniem jest wdrożenie HAL usługi Composer, aby używać identyfikatorów sekwencyjnych i uniknąć tego problemu.

W tej sekcji opisano, jak mogą wystąpić warunki wyścigu, a następnie przedstawiono szczegóły implementacji interfejsu Composer HAL, który używa identyfikatorów sekwencyjnych, aby zapobiegać takim warunkom.

Rozważ tę sekwencję zdarzeń. Gdy nowe identyfikatory sekwencyjne NIE są przypisane do nowych konfiguracji wyświetlania, spowoduje to powstanie warunku wyścigu:

  1. Obsługiwane identyfikatory konfiguracji wyświetlania:

    • id=1, 1080 x 1920 60 Hz
    • id=2, 1080 x 1920, 50 Hz
  2. Platforma wywołuje funkcję setActiveConfig(display, config=1).

  3. Równocześnie interfejs HAL usługi komponowania przetwarza zmiany konfiguracji wyświetlacza i aktualizuje stan wewnętrzny na nowy zestaw konfiguracji wyświetlacza w ten sposób:

    • id=1, 2160 x 3840 60 Hz
    • id=2, 2160 x 3840 50 Hz
    • id=3, 1080 x 1920 60 Hz
    • id=4, 1080 x 1920 50 Hz
  4. HAL usługi Composer wysyła do platformy zdarzenie onHotplug, aby powiadomić o zmianie zestawu obsługiwanych trybów.

  5. HAL usługi Composer otrzymuje setActiveConfig(display, config=1) (z etapu 2).

  6. HAL interpretuje to jako prośbę o zmianę konfiguracji na 2160x3840 60 Hz, chociaż w rzeczywistości chodziło o 1080x1920 60 Hz.

Proces przypisywania identyfikatorów niesekwencyjnych kończy się tu błędnym zinterpretowaniem żądanej zmiany konfiguracji.

Konfigurowanie HAL usługi Composer do używania identyfikatorów sekwencyjnych

Aby uniknąć takich warunków wyścigu, OEM musi zaimplementować interfejs HAL usługi Composer w ten sposób:

  • Gdy interfejs HAL usługi tworzenia kompozytowych reklam displayowych aktualizuje obsługiwane konfiguracje wyświetlania, przypisuje do nowych konfiguracji nowe, sekwencyjne identyfikatory.
  • Gdy framework wywołuje metodę setActiveConfig lub setActiveConfigWithConstraints z nieprawidłowym identyfikatorem konfiguracji, interfejs HAL usługi Composer ignoruje to wywołanie.

Te kroki służą do zapobiegania warunkom wyścigu, jak pokazano w tej dyskusji.

Gdy do nowych konfiguracji wyświetlania zostaną przypisane nowe, kolejne identyfikatory, nastąpi następująca sekwencja zdarzeń:

  1. Obsługiwane identyfikatory konfiguracji wyświetlania:

    • id=1, 1080 x 1920 60 Hz
    • id=2, 1080 x 1920 50 Hz
  2. Struktura ta nazywa się setActiveConfig(display, config=1).

  3. Gdy przetwarzana jest zmiana konfiguracji wyświetlania, przypisujemy kolejny zestaw identyfikatorów konfiguracji, zaczynając od kolejnej nieużytej wartości całkowitej, jak pokazano poniżej:

    • id=3, 2160x3840 60 Hz

    • id=4, 2160 x 3840 50 Hz

    • id=5, 1080 x 1920 60 Hz

    • id=6, 1080 x 1920 50 Hz

  4. HAL kompozytora wysyła do frameworku zdarzenie onHotplug, aby powiadomić o zmianie zestawu obsługiwanych trybów.

  5. HAL usługi Composer otrzymuje wartość setActiveConfig(display, config=1) (z kroku 2).

  6. HAL Composer ignoruje wywołanie, ponieważ identyfikator nie jest już prawidłowy.

  7. Framework odbiera i przetwarza zdarzenie onHotplug z kroku 4. Wykonuje wywołanie do interfejsu Composer HAL za pomocą funkcji getDisplayConfigs i getDisplayAttribute. Dzięki tym funkcjom platforma określa nowy identyfikator (5) dla żądanej rozdzielczości i częstotliwości odświeżania 1080 x 1920 i 60 Hz.

  8. Framework wysyła kolejne zdarzenie setActiveConfig z aktualnym identyfikatorem 5.

  9. HAL usługi Composer otrzymuje setActiveConfig(display, config=5) z kroku 5.

  10. HAL prawidłowo interpretuje, że framework poprosił o zmianę konfiguracji na 1080 x 1920 60 Hz.

Jak widać w powyższym przykładzie, proces przy użyciu przypisania identyfikatorów sekwencyjnych zapobiega wystąpieniu warunków wyścigu i zapewnia, że zostanie zastosowana prawidłowa zmiana konfiguracji wyświetlania.