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ętrznie podłączonymi wyświetlaczami (przez HDMI lub DisplayPort), takich jak dekodery Android TV i urządzenia OTT. Ta zmiana może nastąpić w wyniku sygnału HDMI hotplug, 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 platformie, które umożliwiają obsługę hotpluggów i dynamicznych możliwości wyświetlania.

Na tej stronie opisujemy obsługę hotpluggów wyświetlacza i zmian w możliwościach wyświetlania w implementacji HAL usługi Composer. Omawiamy też, jak zarządzać powiązanym buforem ramki i zapobiegać sytuacjom wyścigu w takich przypadkach.

Aktualizowanie możliwości wyświetlania

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

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

  1. Po wykryciu zmiany w możliwościach wyświetlania platforma otrzymuje powiadomienie onHotplug(display, connection=CONNECTED).
  2. Po otrzymaniu powiadomienia platforma usuwa stan wyświetlania i tworzy go ponownie z nowymi możliwościami z HAL za pomocą metod getActiveConfig, getDisplayConfigs, getDisplayAttribute, getColorModes, getHdrCapabilities i getDisplayCapabilities.
  3. Gdy platforma utworzy nowy stan wyświetlania, wysyła wywołanie zwrotne onDisplayChanged do aplikacji, które nasłuchują takich zdarzeń.

Platforma ponownie przydziela bufory ramki w kolejnych onHotplug(display, connection=CONNECTED) zdarzeniach. Więcej informacji o prawidłowym zarządzaniu pamięcią bufora ramki, 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 Androida została stworzona z myślą o urządzeniach mobilnych, dlatego nie ma wbudowanej obsługi odłączonego wyświetlacza głównego. Zamiast tego, w przypadku fizycznego odłączenia wyświetlacza głównego, HAL musi zastąpić go wyświetlaczem zastępczym w interakcjach z platformą.

W dekoderach i kluczach sprzętowych TV z zewnętrznie podłączonymi wyświetlaczami, które można odłączyć, mogą wystąpić te scenariusze: Aby zaimplementować obsługę tych scenariuszy, skorzystaj z informacji w tej tabeli:

Scenariusz Obsługa
Brak podłączonego wyświetlacza podczas uruchamiania
  • Wyślij sygnał onHotplug(display, connection=CONNECTED) z HAL usługi Composer do platformy.
  • Zastąp stan fizycznego wyświetlacza w HAL usługi Composer stanem wyświetlacza zastępczego.
Wyświetlacz główny jest fizycznie podłączony
Wyświetlacz główny jest fizycznie odłączony
  • Wyślij kolejne zdarzenie onHotplug(display, connection=CONNECTED) z HAL usługi Composer do platformy.
  • Zastąp stan fizycznego wyświetlacza w HAL usługi Composer stanem wyświetlacza 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 pojedynczy tryb wyświetlania musi być zgodny z ostatnim aktywnym trybem fizycznego wyświetlacza przed odłączeniem, aby aplikacje nie otrzymywały zdarzeń zmiany konfiguracji.

Wskazówki dotyczące połączeń innych niż HDMI

Android TV obsługuje tylko te rozdzielczości:

  • 720x1280
  • 1080x1920
  • 2160x3840
  • 4320 x 7680

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

Jeśli dekoder lub klucz sprzętowy TV ma połączenie HDMI i inne niż HDMI, połączenie HDMI jest wyświetlaczem głównym, a połączenie inne niż HDMI jest nieaktywne. W rezultacie, jeśli połączenie HDMI zostanie odłączone, gdy połączenie inne niż HDMI jest nadal aktywne, do SurfaceFlinger zostanie wysłane zdarzenie, a możliwości wyświetlacza innego niż HDMI muszą być odzwierciedlone przez getDisplayAttribute i inne IComposerClient interfejsy API (np. getHdrCapabilities).

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

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

W tej sekcji opisujemy, jak mogą wystąpić sytuacje wyścigu, a następnie szczegóły dotyczące implementacji HAL usługi Composer, aby używał sekwencyjnych identyfikatorów i zapobiegał takim sytuacjom.

Rozważmy tę sekwencję zdarzeń, gdy do nowych konfiguracji wyświetlania NIE są przypisywane nowe, sekwencyjne identyfikatory, co powoduje sytuację 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. Jednocześnie HAL usługi Composer przetwarza zmianę konfiguracji wyświetlania i aktualizuje swój stan wewnętrzny do nowego zestawu konfiguracji wyświetlania, jak pokazano poniżej:

    • 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ć że zmienił się zestaw obsługiwanych trybów.

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

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

Proces korzystający z przypisywania niesekwencyjnych identyfikatorów kończy się tutaj błędną interpretacją wybranej zmiany konfiguracji.

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

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

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

Te kroki służą do zapobiegania sytuacjom wyścigu, jak pokazano w poniższej dyskusji.

Rozważmy tę sekwencję zdarzeń, gdy do nowych konfiguracji wyświetlania są przypisywane nowe, sekwencyjne identyfikatory:

  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. Gdy przetwarzana jest zmiana konfiguracji wyświetlania, następny zestaw identyfikatorów konfiguracji jest przypisywany od następnej nieużywanej liczby całkowitej, jak pokazano poniżej:

    • id=3, 2160 x 3840 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 usługi Composer wysyła do platformy zdarzenie onHotplug, aby powiadomić że zmienił się zestaw obsługiwanych trybów.

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

  6. HAL usługi Composer ignoruje wywołanie, ponieważ identyfikator jest już nieprawidłowy.

  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 1080 x 1920 i 60 Hz.

    getActiveConfigsetActiveConfig()
  8. Platforma wysyła kolejne setActiveConfig zdarzenie z zaktualizowanym identyfikatorem 5.

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

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

Jak pokazano w poprzednim przykładzie, proces korzystający z przypisywania sekwencyjnych identyfikatorów sprawdza, czy sytuacja wyścigu została wyeliminowana, a prawidłowa zmiana konfiguracji wyświetlania została zaktualizowana.