Obsługa hotplug

Możliwości wyświetlania (np. tryby wyświetlania i obsługiwane typy HDR) mogą się dynamicznie zmieniać na urządzeniach z zewnętrznymi wyświetlaczami (z HDMI lub DisplayPort), takich jak dekodery Android TV i urządzenia OTT. Ta zmiana może nastąpić w wyniku sygnału hotplug HDMI, np. gdy użytkownik przełącza się z jednego wyświetlacza na inny lub uruchamia urządzenie bez podłączonego wyświetlacza. Android 12 i nowsze wersje zawierają zmiany w strukturze, które umożliwiają obsługę podłączania na gorąco i dynamicznych funkcji wyświetlania.

Na tej stronie opisujemy obsługę podłączania i odłączania wyświetlaczy podczas pracy oraz zmian w ich możliwościach w implementacji HAL kompozytora. Opisuje też, jak zarządzać powiązanym buforem ramki i zapobiegać sytuacjom wyścigu w tych przypadkach.

Aktualizowanie możliwości wyświetlania

W tej sekcji opisano, jak platforma Androida obsługuje zmiany w możliwościach wyświetlania zainicjowane przez Composer HAL.

Zanim Android będzie mógł prawidłowo obsługiwać zmiany w możliwościach wyświetlania, producent OEM musi wdrożyć Composer HAL w taki sposób, aby używał onHotplug(display, connection=CONNECTED) do powiadamiania platformy o wszelkich zmianach w możliwościach wyświetlania. Po wdrożeniu tej funkcji Android obsługuje zmiany możliwości wyświetlania w ten sposób:

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

Framework ponownie przydziela bufory klatek podczas kolejnych zdarzeń onHotplug(display, connection=CONNECTED). Więcej informacji o prawidłowym zarządzaniu pamięcią bufora ramki klienta, aby uniknąć błędów podczas przydzielania nowych buforów ramki, znajdziesz w artykule Zarządzanie buforem ramki klienta.

Obsługa typowych scenariuszy połączeń

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

Platforma Android została stworzona z myślą o urządzeniach mobilnych, dlatego nie ma wbudowanej obsługi odłączonego wyświetlacza głównego. Zamiast tego HAL musi zastąpić wyświetlacz podstawowy wyświetlaczem zastępczym w interakcjach z platformą w przypadku fizycznego odłączenia wyświetlacza podstawowego.

Poniższe sytuacje mogą wystąpić w przypadku dekoderów i dongli TV z zewnętrznymi wyświetlaczami, które można odłączyć. Aby zaimplementować obsługę tych scenariuszy, skorzystaj z informacji w tabeli poniżej:

Scenariusz Obsługa
Brak podłączonego wyświetlacza podczas uruchamiania
  • Wysyłanie onHotplug(display, connection=CONNECTED)sygnału z warstwy HAL kompozytora do platformy.
  • Zastąp stan fizycznego wyświetlacza w Composer HAL stanem wyświetlacza symbolu zastępczego.
Wyświetlacz główny jest fizycznie podłączony
Wyświetlacz główny jest fizycznie odłączony
  • Wysyłanie kolejnego onHotplug(display, connection=CONNECTED) zdarzenia z Composer HAL do platformy.
  • Zastąp stan fizycznego wyświetlacza w Composer HAL stanem wyświetlacza symbolu zastępczego. Wyświetlacz zastępczy musi mieć jeden tryb wyświetlania, aby platforma wysyłała do aplikacji wywołanie zwrotne onDisplayChanged (ponieważ zmienił się zestaw obsługiwanych trybów). Ten pojedynczy tryb wyświetlania musi być zgodny z ostatnim aktywnym trybem wyświetlania fizycznego przed odłączeniem, aby aplikacje nie otrzymywały zdarzeń zmiany konfiguracji.

Uwagi dotyczące połączeń innych niż HDMI

Android TV obsługuje tylko te rozdzielczości:

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

Gdy dekoder lub klucz sprzętowy do telewizora próbuje wyświetlić nieobsługiwaną rozdzielczość, np. 480i przez połączenie CVBS, użytkownikowi wyświetla się komunikat o błędzie.

Jeśli dekoder lub klucz sprzętowy telewizora ma zarówno złącze HDMI, jak i inne, złącze HDMI jest głównym wyświetlaczem, a inne złącze jest nieaktywne. W związku z tym, jeśli połączenie HDMI zostanie odłączone, a połączenie inne niż HDMI pozostanie aktywne, do SurfaceFlinger zostanie wysłane zdarzenie, a możliwości wyświetlacza innego niż HDMI muszą być odzwierciedlone w getDisplayAttribute i innych interfejsach API iComposerClient (np. getHdrCapabilities).

Używanie kolejnych identyfikatorów konfiguracji, aby zapobiegać sytuacjom wyścigu

Sytuacje wyścigu mogą wystąpić, jeśli warstwa HAL kompozytora aktualizuje obsługiwane konfiguracje wyświetlania jednocześnie z wywoływaniem przez platformę funkcji setActiveConfig lub setActiveConfigWithConstraints. Rozwiązaniem jest wdrożenie warstwy HAL usługi Composer, aby używać sekwencyjnych identyfikatorów i zapobiegać temu problemowi.

W tej sekcji opisujemy, jak mogą wystąpić warunki wyścigu, a następnie podajemy szczegółowe informacje o tym, jak wdrożyć HAL kompozytora, aby używał sekwencyjnych identyfikatorów i zapobiegał takim sytuacjom.

Rozważmy następującą sekwencję zdarzeń, w której nowe, kolejne identyfikatory NIE są przypisywane do nowych konfiguracji wyświetlania, co powoduje sytuację wyścigu:

  1. Obsługiwane identyfikatory konfiguracji wyświetlania to:

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

  3. Równocześnie warstwa HAL kompozytora przetwarza zmianę konfiguracji wyświetlania i aktualizuje swój stan wewnętrzny do nowego zestawu konfiguracji wyświetlania, jak pokazano poniżej:

    • id=1, 2160x3840 60 Hz
    • id=2, 2160x3840 50 Hz
    • id=3, 1080x1920 60 Hz
    • id=4, 1080x1920 50 Hz
  4. Composer HAL wysyła do frameworka zdarzenie onHotplug, aby powiadomić o zmianie zestawu obsługiwanych trybów.

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

  6. HAL interpretuje, że platforma zażądała zmiany konfiguracji na 2160x3840 60 Hz, chociaż w rzeczywistości oczekiwano 1080x1920 60 Hz.

Proces wykorzystujący przypisywanie identyfikatorów w sposób niesekwencyjny kończy się w tym miejscu błędną interpretacją żądanej zmiany konfiguracji.

Konfigurowanie warstwy HAL kompozytora do używania kolejnych identyfikatorów

Aby uniknąć takich sytuacji wyścigu, producent OEM musi zaimplementować interfejs HAL Composera w ten sposób:

  • Gdy Composer HAL zaktualizuje obsługiwane konfiguracje wyświetlania, przypisze do nich nowe, kolejne identyfikatory.
  • Gdy framework wywołuje funkcję setActiveConfig lub setActiveConfigWithConstraints z nieprawidłowym identyfikatorem konfiguracji, warstwa HAL Composera ignoruje to wywołanie.

Te kroki zapobiegają wyścigom, co pokazano w dalszej części.

Rozważmy następującą sekwencję zdarzeń, gdy do nowych konfiguracji wyświetlania są przypisywane nowe, kolejne identyfikatory:

  1. Obsługiwane identyfikatory konfiguracji wyświetlania to:

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

  3. Gdy zmiana konfiguracji wyświetlania zostanie przetworzona, następny zestaw identyfikatorów konfiguracji zostanie przypisany, zaczynając od następnej nieużywanej liczby całkowitej, jak pokazano poniżej:

    • id=3, 2160x3840 60 Hz

    • id=4, 2160x3840 50 Hz

    • id=5, 1080x1920 60 Hz

    • id=6, 1080x1920 50 Hz

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

  5. Warstwa HAL narzędzia Composer otrzymuje setActiveConfig(display, config=1) (z kroku 2).

  6. Warstwa HAL kompozytora ignoruje wywołanie, ponieważ identyfikator jest już nieważny.

  7. Platforma odbiera i przetwarza zdarzenie onHotplug z kroku 4. Wywołuje interfejs HAL narzędzia Composer za pomocą funkcji getDisplayConfigsgetDisplayAttribute. Dzięki tym funkcjom platforma identyfikuje nowy identyfikator (5) dla żądanej rozdzielczości i częstotliwości odświeżania 1080x1920 i 60 Hz.

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

  9. Komponent HAL kompozytora otrzymuje setActiveConfig(display, config=5) z kroku 5.

  10. HAL prawidłowo interpretuje, że platforma zażądała zmiany konfiguracji na 1080 x 1920 px przy 60 Hz.

Jak pokazano w przykładzie powyżej, proces wykorzystujący sekwencyjne przypisywanie identyfikatorów zapobiega sytuacji wyścigu i zapewnia aktualizację prawidłowej konfiguracji wyświetlania.