Obsługa dekoracji systemu

Aktualizacje wprowadzone w tych obszarach specyficznych dla wyświetlacza są przedstawione poniżej:

Dekoracje systemowe

W systemie Android 10 dodano obsługę konfigurowania dodatkowych wyświetlaczy w celu wyświetlania niektórych dekoracji systemowych, takich jak tapeta, pasek nawigacyjny i program uruchamiający. Domyślnie główny wyświetlacz pokazuje wszystkie dekoracje systemu, a wyświetlacze dodatkowe pokazują te opcjonalnie włączone. Obsługa edytora Input Method Editor (IME) może być ustawiona oddzielnie od innych dekoracji systemu.

Zastosowanie DisplayWindowSettings#setShouldShowSystemDecorsLocked() aby dodać wsparcie dla systemu dekoracji na wyświetlaczu specyficznego lub podać wartość domyślną w /data/system/display_settings.xml . Do przykładów można znaleźć ustawienia okna wyświetlacza .

Realizacja

DisplayWindowSettings#setShouldShowSystemDecorsLocked() jest również wystawiony w WindowManager#setShouldShowSystemDecors() do testowania. Wyzwolenie tej metody z zamiarem włączenia dekorów systemowych nie powoduje dodania okien dekorów, których wcześniej brakowało, ani usunięcia ich, jeśli były wcześniej obecne. W większości przypadków zmiana obsługi dekoracji systemu zaczyna obowiązywać dopiero po ponownym uruchomieniu urządzenia.

Sprawdza wsparciu dekoracjami systemowych w bazie kodu managerem okien zazwyczaj przechodzą DisplayContent#supportsSystemDecorations() natomiast sprawdza usług zewnętrznych (takich jak system UI, aby sprawdzić, czy pasek nawigacyjny powinien być pokazany) używać WindowManager#shouldShowSystemDecors() . Aby zrozumieć, co jest kontrolowane przez to ustawienie, zapoznaj się z punktami wywołania tych metod.

Okna ozdobne UI systemu

System Android 10 dodaje wystrój wsparcie dla jedynego okna na pasku nawigacyjnym, ponieważ pasek nawigacyjny jest niezbędna do nawigowania pomiędzy działaniami i aplikacji. Domyślnie pasek nawigacyjny pokazuje afordancje Wstecz i Dom. To jest zawarte tylko wtedy, gdy wyświetlacz docelowy obsługuje dekoracje systemowej (patrz DisplayWindowSettings ).

Pasek stanu jest bardziej skomplikowane okno systemu, ponieważ zawiera również obszar powiadomień, Szybkie ustawienia, i zablokować ekran. W systemie Android 10 pasek stanu nie jest obsługiwany na dodatkowych wyświetlaczach. Dlatego powiadomienia, ustawienia i pełna ochrona klawiatury są dostępne tylko na głównym wyświetlaczu.

Okno System Przegląd / Niedawnych nie jest obsługiwane na ekranach wtórnych. W systemie Android 10 AOSP wyświetla tylko ostatnie na domyślnym ekranie i zawiera działania ze wszystkich ekranów. Po uruchomieniu z Ostatnich aktywność, która była na dodatkowym wyświetlaczu, jest domyślnie przenoszona na pierwszy ekran tego wyświetlacza. To podejście ma kilka znanych problemów, takich jak brak aktualizacji natychmiast, gdy aplikacje pojawiają się na innych ekranach.

Realizacja

Aby zaimplementować dodatkowe funkcje interfejsu systemu, producenci urządzeń powinni używać jednego składnika interfejsu systemu, który nasłuchuje dodawania/usuwania ekranów i przedstawia odpowiednią zawartość.

Komponent System UI obsługujący Multi-Display (MD) powinien obsługiwać następujące przypadki:

  • Inicjalizacja wielu wyświetlaczy podczas uruchamiania
  • Wyświetlacz dodany w czasie wykonywania
  • Wyświetlacz został usunięty w czasie wykonywania

Gdy systemowy interfejs użytkownika wykryje dodanie ekranu przed WindowManagerem, tworzy sytuację wyścigu. Można tego uniknąć poprzez wdrożenie niestandardowych zwrotnego z managerem okien do systemu UI, gdy wyświetlany jest dodawany zamiast subskrybowania DISPLAYMANAGER .DisplayListener wydarzeń. Dla implementacji referencyjnej, patrz CommandQueue.Callbacks#onDisplayReady wsparcia pasku nawigacyjnym i WallpaperManagerInternal#onDisplayReady do tapet.

Ponadto Android 10 zapewnia następujące aktualizacje:

  • NavigationBarController klasa kontroluje wszystkie funkcje specyficzne dla pasków nawigacyjnych.
  • Aby wyświetlić pasek nawigacji dostosowanej patrz CarStatusBar .
  • TYPE_NAVIGATION_BAR nie jest już ograniczona do jednej instancji i może być używany na wyświetlaczu.
  • IWindowManager#hasNavigationBar() jest aktualizowany do włączenia displayId parametr jedyny system UI.

Wyrzutnia

W Androidzie 10, każdy wyświetlacz skonfigurowany do dekoracji Support System posiada dedykowany domu stos dla wyrzutni typu działań z WindowConfiguration#ACTIVITY_TYPE_HOME domyślnie. Każdy wyświetlacz wykorzystuje osobną instancję aktywności programu uruchamiającego.

Rysunek 1. Przykład wyświetlacz Multi-wyrzutnia dla platform/development/samples/MultiDisplay

Większość istniejących programów uruchamiających nie obsługuje wielu wystąpień i nie jest zoptymalizowana pod kątem dużych rozmiarów ekranu. Ponadto często oczekuje się innego rodzaju wrażeń na wyświetlaczach drugorzędnych/zewnętrznych. Aby zapewnić specjalną aktywność na ekranach wtórnych, Android 10 wprowadza SECONDARY_HOME kategorii filtrów intencyjny. Instancje tego działania są wykorzystywane na wszystkich wyświetlaczach obsługujących dekoracje systemowe, po jednym na wyświetlacz.

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

Działanie musi mieć tryb uruchamiania, który nie zapobiega wielu instancjom i powinien dostosowywać się do różnych rozmiarów ekranu. Tryb uruchomienie nie może być singleInstance lub singleTask .

Realizacja

W Androidzie 10, RootActivityContainer#startHomeOnDisplay() automatycznie wybiera żądany element i intencji w zależności od wyświetlacza, gdzie ekran główny jest uruchomiona. RootActivityContainer#resolveSecondaryHomeActivity() zawiera logikę patrzeć wyrzutni komponentu aktywności w zależności od aktualnie wybranego wyrzutni i może korzystać z domyślnego systemu, w razie potrzeby (patrz ActivityTaskManagerService#getSecondaryHomeIntent() ).

Ograniczenia bezpieczeństwa

Oprócz ograniczeń, które odnoszą się do działań na wyświetlaczach drugorzędnych, aby uniknąć możliwości złośliwa aplikacja tworząc wirtualny wyświetlacz z włączonymi dekoracjami systemowe i odczyt informacji użytkownika wrażliwych z powierzchni pojawia się wyrzutnia tylko na wirtualnych ekranów posiadanych przez system. Program uruchamiający nie wyświetla zawartości na niesystemowych ekranach wirtualnych.

Tapety

W systemie Android 10 (i nowszym) tapety są obsługiwane na dodatkowych wyświetlaczach:

Rysunek 2. Wyniki tapety na wewnętrznych ekranów (powyżej) i zewnętrznych (poniżej)

Programiści mogą deklarują wsparcie dla funkcji tapety poprzez dostarczenie android:supportsMultipleDisplays="true" w WallpaperInfo definicji XML. Oczekuje się również deweloperzy tapety do ładowania zasobów z wykorzystaniem kontekstu wyświetlacza w WallpaperService.Engine#getDisplayContext() .

Ramy tworzy jeden WallpaperService.Engine instancji za wyświetlaczem, więc każdy silnik ma swoją własną powierzchnię i wyświetlania kontekst. Deweloper musi upewnić się, że każdy silnik może rysować niezależnie, z różnymi częstotliwościami klatek, z poszanowaniem VSYNC.

Wybór tapet dla poszczególnych ekranów

Android 10 nie zapewnia bezpośredniej obsługi platform do wybierania tapet dla poszczególnych ekranów. Aby to osiągnąć, potrzebny jest stabilny identyfikator wyświetlacza, aby zachować ustawienia tapety na ekranie. Display#getDisplayId() jest dynamiczna, więc nie ma gwarancji, że fizyczna Wyświetlacz będzie miał tego samego identyfikatora po ponownym uruchomieniu komputera.

Jednak Android 10 dodaje DisplayInfo.mAddress , który zawiera stabilne identyfikatory dla monitorów fizycznych i może być używany do pełnego wdrożenia w przyszłości. Niestety na zaimplementowanie logiki dla Androida 10 jest już za późno. Sugerowane rozwiązanie:

  1. Użyj WallpaperManager API ustawić tapety.
  2. WallpaperManager otrzymuje się z Context obiekcie, a każdy z Context przedmiot ma informację o odpowiednim wyświetlaczem ( Context#getDisplay()/getDisplayId() ). Dlatego można uzyskać displayId z WallpaperManager przykład bez dodawania nowych metod.
  3. Na stronie ramowej użycie displayId uzyskane z Context obiektu i mapować go do statycznego identyfikatora (np portem fizycznym wyświetlaczu). Użyj statycznego identyfikatora, aby zachować wybraną tapetę.

To obejście wykorzystuje istniejące implementacje dla selektorów tapet. Jeśli został otwarty na konkretnym wyświetlaczu i korzysta z odpowiedniego kontekstu, to przy wywołaniu ustawienia tapety system może automatycznie zidentyfikować wyświetlacz.

Jeśli istnieje potrzeba, aby ustawić tapetę na wyświetlaczu innego niż bieżący wyświetlaczu, a następnie utworzyć nową Context obiektu na wyświetlaczu docelowej ( Context#createDisplayContext ) i uzyskać WallpaperManager wystąpienie z takim wyświetlaczem.

Ograniczenia bezpieczeństwa

System nie wyświetla tapet na wirtualnych wyświetlaczach, których nie posiada. Wynika to z obawy o bezpieczeństwo, że złośliwa aplikacja może utworzyć wirtualny wyświetlacz z włączoną obsługą dekoracji systemu i odczytać z powierzchni informacje wrażliwe dla użytkownika (takie jak osobiste zdjęcie).

Realizacja

W Androidzie 10, IWallpaperConnection#attachEngine() i IWallpaperService#attach() interfejsy zaakceptować displayId parametr do tworzenia połączeń na-ekranie. WallpaperManagerService.DisplayConnector obudowuje silnik i połączenie tapety z ekranami. W managerem okien, tapety kontrolery są tworzone dla każdego DisplayContent obiektu przy budowie zamiast pojedynczego WallpaperController dla wszystkich wyświetlaczy.

Niektóre z publicznych WallpaperManager implementacje metod (takich jak WallpaperManager#getDesiredMinimumWidth() ) zostały zaktualizowane do obliczania i przekazywania informacji dla odpowiednich wyświetlaczy. WallpaperInfo#supportsMultipleDisplays() oraz atrybut zasobów odpowiadających zostały dodane, tak że programiści aplikacji mogą zgłaszać który tapety są gotowe na wielu ekranach.

Jeśli usługa tapet wyświetlana na domyślnym wyświetlaczu nie obsługuje wielu wyświetlaczy, system wyświetla domyślną tapetę na wyświetlaczach dodatkowych.

Logika Rysunek 3. Tapety awaryjnej dla wyświetlaczy wtórnych