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.

Aby Android mógł prawidłowo obsługiwać zmiany w zakresie możliwości wyświetlania, producent OEM musi zaimplementować Composer HAL w taki sposób, aby używał onHotplug(display, connection=CONNECTED) do powiadamiania platformy o wszelkich zmianach w zakresie możliwości wyświetlania. Po wdrożeniu tej funkcji Android obsługuje zmiany w możliwościach 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 ramki podczas kolejnych zdarzeń onHotplug(display, connection=CONNECTED). Więcej informacji o prawidłowym zarządzaniu pamięcią bufora ramki znajdziesz w artykule Zarządzanie buforem ramki klienta. Dzięki temu unikniesz błędów podczas przydzielania nowych buforów ramki.

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 wdrożyć obsługę tych scenariuszy, skorzystaj z informacji w tej tabeli:

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 interfejsach API 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 HAL kompozytora aktualizuje obsługiwane konfiguracje wyświetlania jednocześnie z wywoływaniem przez platformę funkcji setActiveConfig lub setActiveConfigWithConstraints. Rozwiązaniem jest wdrożenie Composer HAL, aby używać kolejnych 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 platformy zdarzenie onHotplug, aby powiadomić o zmianie zestawu obsługiwanych trybów.

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

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

Proces korzystający z przypisywania identyfikatorów w sposób niesekwencyjny kończy się tutaj błędną interpretacją wybranej 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 platforma wywołuje funkcję setActiveConfig lub setActiveConfigWithConstraints z nieprawidłowym identyfikatorem konfiguracji, interfejs HAL kompozytora 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 usługi Composer otrzymuje wartość setActiveConfig(display, config=1) (z kroku 2).

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

  7. Platforma otrzymuje i przetwarza zdarzenie onHotplug z kroku 4. Wywołuje HAL usługi Composer za pomocą funkcji getDisplayConfigs i getDisplayAttribute. Dzięki tym funkcjom framework identyfikuje nowy identyfikator (5) dla wybranej rozdzielczości i częstotliwości odświeżania 1080x1920 i 60 Hz.

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

  9. Komponent Composer HAL otrzymuje wartość 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 potwierdza, że zapobiega wystąpieniu wyścigu i aktualizuje prawidłową konfigurację wyświetlania.