Obsługa hotplug

Możliwości wyświetlania (takie jak tryby wyświetlania i obsługiwane typy HDR) mogą zmieniać się dynamicznie na urządzeniach z podłączonymi zewnętrznie wyświetlaczami (z HDMI lub DisplayPort), takimi jak dekodery z systemem Android TV (STB) i urządzenia typu over-the-top (OTT) urządzenia. Ta zmiana może nastąpić w wyniku sygnału HDMI typu hotplug, na przykład 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 frameworku obsługującym możliwości podłączania podczas pracy i dynamicznego wyświetlania.

Na tej stronie opisano obsługę wtyczek wyświetlacza i zmiany w możliwościach wyświetlania w implementacji Composer HAL. Dodatkowo omówiono, jak zarządzać powiązanym buforem ramki i zapobiegać warunkom wyścigowym w takich sytuacjach.

Zaktualizuj możliwości wyświetlania

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

Zanim system Android będzie mógł prawidłowo obsłużyć zmiany w możliwościach wyświetlania, producent OEM musi zaimplementować Composer HAL w taki sposób, aby korzystał z onHotplug(display, connection=CONNECTED) w celu powiadamiania struktury o wszelkich zmianach w możliwościach wyświetlania. Po zaimplementowaniu Android obsługuje zmiany w możliwościach wyświetlania w następujący sposób:

  1. Po wykryciu zmiany w możliwościach wyświetlania platforma otrzymuje powiadomienie onHotplug(display, connection=CONNECTED) .
  2. Po otrzymaniu powiadomienia platforma porzuca swój stan wyświetlania i odtwarza go z nowymi możliwościami z warstwy HAL, używając metod getActiveConfig , getDisplayConfigs , getDisplayAttribute , getColorModes , getHdrCapabilities i getDisplayCapabilities .
  3. Gdy struktura odtworzy nowy stan wyświetlania, wysyła wywołanie zwrotne onDisplayChanged do aplikacji, które nasłuchują takich zdarzeń.

Struktura ponownie przydziela bufory ramki po kolejnych zdarzeniach onHotplug(display, connection=CONNECTED) . Więcej informacji na temat prawidłowego zarządzania pamięcią bufora ramki w celu uniknięcia błędów podczas alokacji nowych buforów ramki można znaleźć w sekcji Zarządzanie buforami ramki klienta .

Obsługuj typowe scenariusze połączeń

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

Platforma Android, stworzona z myślą o urządzeniach mobilnych, nie ma wbudowanej obsługi odłączonego wyświetlacza głównego. Zamiast tego warstwa HAL musi zastąpić wyświetlacz główny wyświetlaczem zastępczym w swoich interakcjach ze strukturą w przypadku, gdy wyświetlacz główny jest fizycznie odłączony.

Poniższe scenariusze mogą wystąpić w przypadku dekoderów i kluczy telewizyjnych, które mają podłączone zewnętrznie wyświetlacze, które można odłączyć. Aby zaimplementować obsługę tych scenariuszy, skorzystaj z informacji zawartych w poniższej tabeli:

Scenariusz Obsługiwanie
Brak podłączonego wyświetlacza w czasie uruchamiania
  • Wyślij sygnał onHotplug(display, connection=CONNECTED) z Composer HAL do frameworka.
  • Zamień fizyczny stan wyświetlania w Composer HAL na zastępczy stan wyświetlania.
Główny wyświetlacz jest fizycznie podłączony
Główny wyświetlacz jest fizycznie odłączony
  • Wyślij kolejne zdarzenie onHotplug(display, connection=CONNECTED) z warstwy Composer HAL do platformy.
  • Zamień fizyczny stan wyświetlania w Composer HAL na zastępczy stan wyświetlania. Wyświetlanie symboli zastępczych musi mieć pojedynczy 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 fizycznego wyświetlacza przed rozłączeniem, aby aplikacje nie otrzymywały zdarzeń zmiany konfiguracji .

Użyj sekwencyjnych identyfikatorów konfiguracji, aby zapobiec warunkom wyścigowym

Warunki wyścigu mogą wystąpić, jeśli Composer HAL aktualizuje obsługiwane konfiguracje wyświetlania jednocześnie ze strukturą wywołującą setActiveConfig lub setActiveConfigWithConstraints . Rozwiązaniem jest wdrożenie Composer HAL, aby używać sekwencyjnych identyfikatorów i zapobiegać temu problemowi.

W tej sekcji opisano, w jaki sposób mogą wystąpić warunki wyścigu, a następnie podano szczegółowe informacje na temat implementacji Composer HAL, aby korzystał z identyfikatorów sekwencyjnych w celu zapobiegania takim warunkom.

Rozważ następującą sekwencję zdarzeń, gdy nowe, sekwencyjne identyfikatory NIE są przypisane do nowych konfiguracji wyświetlania, co powoduje sytuację wyścigu:

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

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

  3. Jednocześnie Composer HAL 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 w celu powiadomienia o zmianie zestawu obsługiwanych trybów.

  5. Composer HAL odbiera setActiveConfig(display, config=1) (z kroku 2).

  6. HAL interpretuje, że framework zażądał zmiany konfiguracji na 2160x3840 60 Hz , chociaż w rzeczywistości pożądana była rozdzielczość 1080x1920 60 Hz .

Proces wykorzystujący niesekwencyjne przypisania identyfikatorów kończy się tutaj błędną interpretacją pożądanej zmiany konfiguracji.

Skonfiguruj Composer HAL do używania identyfikatorów sekwencyjnych

Aby uniknąć takich sytuacji wyścigowych, producent OEM musi wdrożyć Composer HAL w następujący sposób:

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

Te kroki służą zapobieganiu warunkom wyścigowym, jak pokazano w poniższym omówieniu.

Gdy do nowych konfiguracji wyświetlania zostaną przypisane nowe, kolejne identyfikatory, należy wziąć pod uwagę następującą sekwencję zdarzeń:

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

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

  3. Kiedy przetwarzana jest zmiana konfiguracji wyświetlania, przypisywany jest kolejny zestaw identyfikatorów konfiguracji, zaczynając od następnej niewykorzystanej liczby całkowitej, pokazanej w następujący sposób:

    • 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 w celu powiadomienia o zmianie zestawu obsługiwanych trybów.

  5. Composer HAL odbiera setActiveConfig(display, config=1) (z kroku 2).

  6. Kompozytor HAL ignoruje wywołanie, ponieważ identyfikator nie jest już ważny.

  7. Struktura odbiera i przetwarza zdarzenie onHotplug z kroku 4. Wywołuje warstwę Composer HAL za pomocą funkcji getDisplayConfigs i getDisplayAttribute . 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. Struktura wysyła kolejne zdarzenie setActiveConfig ze zaktualizowanym identyfikatorem 5.

  9. Composer HAL odbiera setActiveConfig(display, config=5) z kroku 5.

  10. HAL poprawnie interpretuje, że platforma zażądała zmiany konfiguracji na 1080x1920 60 Hz.

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