Rozszerzenia WindowManager

Biblioteka Jetpack WindowManager umożliwia deweloperom aplikacji obsługę nowych formatów urządzeń i środowisk z wieloma oknami.

WindowManager Extensions (Rozszerzenia) to moduł platformy Android, który wymaga akceptacji przez użytkownika i umożliwia korzystanie z różnych funkcji Jetpack WindowManager. Moduł jest zaimplementowany w AOSP w frameworks/base/libs/WindowManager/Jetpack i dostarczany na urządzeniach, które obsługują funkcje WindowManager.

Dystrybucja modułu rozszerzeń

Rozszerzenia są kompilowane w .jar bibliotece i umieszczane w system_ext partycji na urządzeniu, jeśli są włączone w pliku makefile urządzenia.

Aby włączyć rozszerzenia na urządzeniu, dodaj do pliku makefile urządzenia te informacje:

$(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)

Spowoduje to włączenie pakietów androidx.window.extensionsandroidx.window.sidecar na urządzeniu oraz ustawienie właściwości persist.wm.extensions.enabled. Umieszczenie tych pakietów w pliku makefile powoduje też umieszczenie deklaracji w etc/permissions/, dzięki czemu są one dostępne dla procesów aplikacji. Zwykle moduły są wczytywane i wykonywane w ramach procesu aplikacji w czasie działania, gdy są używane przez bibliotekę Jetpack WindowManager. Sprawia to, że ich działanie jest podobne do kodu platformy po stronie klienta, jak pokazano na poniższym rysunku:

Rysunek 1. Rozszerzenia WindowManager są ładowane do procesu aplikacji podobnie jak kod platformy.

Moduł androidx.window.extensions to obecny moduł rozszerzeń, który jest w fazie aktywnego rozwoju. Moduł androidx.window.sidecar to starszy moduł dołączony w celu zapewnienia zgodności z najwcześniejszymi wersjami Jetpack WindowManager, ale komponent dodatkowy nie jest już aktywnie rozwijany.

Na poniższym rysunku przedstawiono logikę określania, czy użyć znaku androidx.window.extensions czy androidx.window.sidecar.

Rysunek 2. Drzewo decyzyjne dotyczące dostępu do androidx.window.extensions lub androidx.window.sidecar.

Moduły rozszerzeń

Rozszerzenia zapewniają funkcje okien na składanych urządzeniach z dużym ekranem i urządzeniach, które obsługują okna na wyświetlaczach zewnętrznych. Obszary funkcji obejmują:

Implementacje rozszerzeń przez producentów OEM mogą udostępniać komponenty zerowe lub komponenty z domyślnymi implementacjami metod w interfejsie WindowExtensions, jeśli sprzęt urządzenia nie obsługuje odpowiednich funkcji, chyba że funkcja jest wyraźnie wymagana w dokumencie Compatibility Definition Document (CDD) w sekcji 7.1.1.1.

Rozszerzenia i interfejsy API Jetpack

Moduł WindowManager Extensions udostępnia własny interfejs API oprócz publicznych interfejsów API platformy. Moduł Extensions jest opracowywany publicznie w bibliotece Jetpack androidx.window.extensions, która nie jest przeznaczona dla deweloperów, dzięki czemu Jetpack WindowManager (androidx.window) może się z nią łączyć w czasie kompilacji. Interfejs API rozszerzeń zwykle udostępnia interfejsy API niższego poziomu.

Interfejsy API udostępniane przez rozszerzenia są przeznaczone do używania tylko przez bibliotekę Jetpack WindowManager. Interfejsy API rozszerzeń nie są przeznaczone do bezpośredniego wywoływania przez deweloperów aplikacji. Aby zapewnić prawidłowe działanie, biblioteki Extensions nie można dodać jako zależności aplikacji w pliku kompilacji Gradle. Unikaj wstępnego kompilowania biblioteki Extensions bezpośrednio w aplikacji. Zamiast tego korzystaj z ładowania w czasie działania, aby uniknąć sytuacji, w której ładowane są klasy Extensions wstępnie skompilowane i dostarczone w czasie działania.

Jetpack WindowManager (androidx.window) ma być dodawany jako zależność aplikacji i udostępnia publiczne interfejsy API dla programistów, w tym interfejsy API funkcji rozszerzeń WindowManager. Biblioteka WindowManager automatycznie wczytuje rozszerzenia do procesu aplikacji i zawiera interfejsy API rozszerzeń niższego poziomu w abstrakcjach wyższego poziomu i bardziej ukierunkowanych interfejsach. Interfejsy API Jetpack WindowManager są zgodne ze standardami nowoczesnego programowania aplikacji na Androida i mają zapewniać wygodną interoperacyjność dzięki dobrej integracji z bazami kodu, które korzystają z innych bibliotek AndroidX.

Wersje rozszerzeń i aktualizacje

Moduł rozszerzeń może być aktualizowany wraz z platformą Android w ramach rocznych lub kwartalnych aktualizacji. Kwartalne aktualizacje umożliwiają zwiększanie poziomu interfejsu Extensions API między aktualizacjami interfejsu API platformy Android, co pozwala na szybsze iteracje i daje producentom OEM możliwość dodania oficjalnego dostępu do interfejsu API nowych funkcji w pobliżu wprowadzenia sprzętu na rynek.

W tabeli poniżej znajdziesz wersje interfejsu androidx.window.extensions API dla różnych wersji Androida.

wersja platformy Androida, Poziom interfejsu API rozszerzeń WindowManager Wersja interfejsu API androidx.window.extensions
Android 15 6 1.5.0 (wkrótce)
Android 14 QPR3 5 1.4.0 (wkrótce)
Android 14 QPR1 4 1.3.0
Android 14 3 1.2.0
Android 13 QPR3 2 1.1.0
Android 13 1 1.0.0
Android 12L 1 1.0.0

Poziom interfejsu Extensions API (środkowa kolumna) jest zwiększany za każdym razem, gdy do istniejącego stabilnego interfejsu API (prawa kolumna) dodawane są nowe funkcje.

Zgodność wsteczna i w przód

Biblioteka Jetpack WindowManager radzi sobie ze złożonością związaną z częstymi aktualizacjami poziomu interfejsu API, szybkim rozwojem interfejsu API i kompatybilnością wsteczną. Gdy kod biblioteki jest wykonywany w procesie aplikacji, biblioteka sprawdza zadeklarowany poziom interfejsu Extensions API i zapewnia dostęp do funkcji zgodnie z zadeklarowanym poziomem.

Aby chronić aplikację przed awarią w czasie działania, WindowManager przeprowadza też w czasie działania sprawdzanie dostępnych interfejsów Extensions API za pomocą refleksji w języku Java zgodnie z zadeklarowanym poziomem interfejsu Extensions API. Jeśli wystąpi niezgodność, WindowManager może wyłączyć korzystanie z rozszerzeń (częściowo lub całkowicie) i zgłosić odpowiednie funkcje jako niedostępne dla aplikacji.

Rozszerzenia WindowManager są wdrażane jako moduł system_ext, który używa prywatnych interfejsów API platformy do wywoływania podstawowych funkcji WindowManager, DeviceStateManager i innych usług systemowych w ramach implementacji funkcji rozszerzeń.

Zgodność może nie być zachowana w przypadku wersji rozszerzeń przed premierą przed odpowiednią kwartalną lub roczną wersją platformy Android, z którą wersje są finalizowane. Pełną historię interfejsów API rozszerzeń znajdziesz w gałęzi window:extensions:extensions plików tekstowych interfejsu API.

Nowsze wersje rozszerzeń muszą nadal działać ze starszymi wersjami menedżera okien skompilowanymi w aplikacjach, aby zachować zgodność z przyszłymi wersjami. Aby to zapewnić, każda nowa wersja interfejsu Extensions API dodaje tylko nowe interfejsy API i nie usuwa starszych. Dzięki temu aplikacje ze starszymi wersjami WindowManager mogą nadal korzystać ze starszych interfejsów API rozszerzeń, z którymi zostały skompilowane.

Weryfikacja CTS zapewnia, że w przypadku każdej zadeklarowanej wersji interfejsów API rozszerzeń na urządzeniu wszystkie interfejsy API w tej i poprzednich wersjach są obecne i działają prawidłowo.

Wydajność

Moduł rozszerzeń jest domyślnie buforowany w ładowarkach klas systemowych spoza ścieżki rozruchowej od Androida 14 (poziom API 34), więc wczytywanie modułu do pamięci podczas uruchamiania aplikacji nie ma wpływu na wydajność. Korzystanie z poszczególnych funkcji modułu może mieć niewielki wpływ na wydajność aplikacji, gdy między klientem a serwerem wykonywane są dodatkowe wywołania IPC.

Moduły

Wektor dystrybucyjny aktywności

Komponent osadzania aktywności umożliwia aplikacjom optymalizowanie interfejsu na urządzeniach z dużym ekranem i wyświetlaczach zewnętrznych. Osadzanie aktywności umożliwia wyświetlanie dwóch aktywności obok siebie w układzie wielopanelowym, co ułatwia tworzenie adaptacyjnych aplikacji na potrzeby starszych aplikacji.

Komponent osadzania aktywności musi być dostępny na wszystkich urządzeniach z wbudowanym wyświetlaczem o rozmiarze co najmniej sw600dp. Osadzanie aktywności musi być też włączone na urządzeniach obsługujących połączenia z wyświetlaczami zewnętrznymi, ponieważ aplikacja może być wyświetlana w większym rozmiarze, gdy wyświetlacze zewnętrzne są podłączone w czasie działania.

Konfiguracja urządzenia

Nie jest wymagana żadna specjalna konfiguracja urządzenia poza włączeniem modułu rozszerzeń zgodnie z opisem w sekcji Dystrybucja modułu rozszerzeń. Warto włączyć rozszerzenia na wszystkich urządzeniach, które obsługują tryb wielu okien. W przyszłych wersjach Androida rozszerzenia prawdopodobnie będą wymagane w przypadku popularnych konfiguracji urządzeń przenośnych i urządzeń z dużym ekranem.

Informacje o układzie okna

Komponent informacji o układzie okien określa położenie i stan zawiasu na urządzeniu składanym, gdy zawias przecina okno aplikacji. Informacje o układzie okna umożliwiają aplikacjom reagowanie na zoptymalizowane układy i wyświetlanie ich w trybie stołowym na urządzeniach składanych. Szczegółowe informacje o korzystaniu z niej znajdziesz w artykule Dostosowywanie aplikacji do urządzeń składanych.

Składane urządzenia z Androidem, które mają zawias łączący oddzielne lub ciągłe obszary panelu wyświetlacza, muszą udostępniać aplikacjom informacje o zawiasie za pomocą interfejsu WindowLayoutComponent.

Położenie i granice zawiasu muszą być podawane w odniesieniu do okna aplikacji zidentyfikowanego przez wartość Context przekazaną do interfejsu API. Jeśli granice okna aplikacji nie przecinają się z granicami zawiasu, nie należy zgłaszać zawiasuDisplayFeature. Można też nie zgłaszać funkcji wyświetlania, gdy ich położenie może nie być zgłaszane w wiarygodny sposób, np. gdy okno aplikacji może być swobodnie przenoszone przez użytkownika w trybie wielu okien lub w trybie letterboxingu zgodności.

W przypadku funkcji składania aktualizacje stanu muszą być zgłaszane, gdy pozycja zawiasu zmienia się między stanami stabilnymi. W domyślnym stanie płaskiego wyświetlacza interfejs API musi zgłaszać FoldingFeature.State.FLAT. Jeśli sprzęt urządzenia może pozostać w połowie złożony w stabilnym stanie, interfejs API musi zgłosić wartość FoldingFeature.State.HALF_OPENED. W interfejsie API nie ma stanu zamkniętego, ponieważ w takim przypadku okno aplikacji nie byłoby widoczne lub nie przekraczałoby granic zawiasu.

Konfiguracja urządzenia

Aby obsługiwać wdrożenie funkcji składania, producenci OEM muszą wykonać te czynności:

  • Skonfiguruj stany urządzenia w device_state_configuration.xml, aby były używane przez DeviceStateManagerService. Więcej informacji znajdziesz w sekcji DeviceStateProviderImpl.java.

    Jeśli domyślne implementacje funkcji DeviceStateProvider lub DeviceStatePolicy nie są odpowiednie dla urządzenia, można użyć implementacji niestandardowej.

  • Włącz moduł Rozszerzenia zgodnie z opisem w sekcji Dystrybucja modułu Rozszerzenia.

  • Określ lokalizację funkcji wyświetlania w com.android.internal.R.string.config_display_featureszasobie ciągu znakówcom.android.internal.R.string.config_display_features (zwykle w frameworks/base/core/res/res/values/config.xml w nakładce urządzenia).

    Oczekiwany format ciągu znaków:

    <type>-[<left>,<top>,<right>,<bottom>]

    Wartość type może wynosić fold lub hinge. Wartości left, top, rightbottom to współrzędne pikseli w przestrzeni współrzędnych wyświetlacza w naturalnej orientacji wyświetlacza. Ciąg konfiguracji może zawierać wiele funkcji wyświetlania rozdzielonych średnikami.

    Na przykład:

    <!-- Jetpack WindowManager display features -->
    <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>
    
  • Określ mapowanie między wewnętrznymi identyfikatorami stanu urządzenia używanymi w DeviceStateManager a publicznymi stałymi stanu wysyłanymi do deweloperów w com.android.internal.R.array.config_device_state_postures.

    Wymagany format każdego wpisu to:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    Obsługiwane identyfikatory stanów:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1: Stan nie ma funkcji składania, o których można by poinformować. Może to być np. stan zamknięty typowego urządzenia składanego do wewnątrz z ekranem głównym po wewnętrznej stronie.
    • COMMON_STATE_HALF_OPENED = 2: funkcja składania jest w połowie otwarta.
    • COMMON_STATE_FLAT = 3: funkcja składania jest płaska. Może to być na przykład stan otwarcia typowego urządzenia składanego do wewnątrz, w którym główny ekran znajduje się po wewnętrznej stronie.
    • COMMON_STATE_USE_BASE_STATE = 1000: w Androidzie 14 wartość, która może być używana w przypadku emulowanych stanów, w których stan zawiasu jest określany na podstawie stanu podstawowego zdefiniowanego w CommonFoldingFeature.java.

    Więcej informacji znajdziesz w sekcji DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int).

    Na przykład:

    <!-- Map of System DeviceState supplied by DeviceStateManager to WindowManager posture.-->
    <string-array name="config_device_state_postures" translatable="false">
      <item>0:1</item>    <!-- CLOSED       : COMMON_STATE_NO_FOLDING_FEATURES -->
      <item>1:2</item>    <!-- HALF_OPENED  : COMMON_STATE_HALF_OPENED -->
      <item>2:3</item>    <!-- OPENED       : COMMON_STATE_FLAT -->
      <item>3:1</item>    <!-- REAR_DISPLAY : COMMON_STATE_NO_FOLDING_FEATURES -->
      <item>4:1000</item> <!-- CONCURRENT   : COMMON_STATE_USE_BASE_STATE -->
    </string-array>
    

Powierzchnia okna

Komponent obszaru okna udostępnia zestaw funkcji, które zapewniają aplikacjom dostęp do dodatkowych wyświetlaczy i obszarów wyświetlania na niektórych urządzeniach składanych i wielowyświetlaczowych.

Tryb tylnego wyświetlacza umożliwia aplikacji wyświetlanie interfejsu podglądu kamery na ekranie zewnętrznym urządzenia składanego, aby można było używać głównego aparatu urządzenia do robienia selfie i nagrywania filmów. Urządzenia z wyświetlaczem na zewnątrz, który jest zgodny z Androidem (zgodnie z definicją w CDD Androida pod względem atrybutów takich jak rozmiar, gęstość i dostępne funkcje nawigacji) i jest ustawiony w linii z tylnymi aparatami urządzenia, muszą zapewniać dostęp do trybu wyświetlacza na zewnątrz.

W Androidzie 14 tryb podwójnego wyświetlania umożliwia aplikacjom działającym na wewnętrznym wyświetlaczu urządzenia składanego wyświetlanie dodatkowych treści na zewnętrznym wyświetlaczu skierowanym do innych użytkowników. Na przykład zewnętrzny wyświetlacz może pokazywać podgląd z aparatu osobie, która jest fotografowana lub nagrywana.

Konfiguracja urządzenia

Aby obsługiwać wdrożenie funkcji składania, producenci OEM muszą wykonać te czynności:

  • Skonfiguruj stany urządzenia w device_state_configuration.xml, aby były używane przez DeviceStateManagerService. Więcej informacji znajdziesz w sekcji DeviceStateProviderImpl.java.

    Jeśli domyślna implementacja DeviceStateProvider lub DeviceStatePolicy nie jest odpowiednia dla urządzenia, można użyć implementacji niestandardowej.

  • W przypadku urządzeń składanych, które obsługują tryb otwarty lub płaski, podaj odpowiednie identyfikatory stanu w com.android.internal.R.array.config_openDeviceStates.

  • W przypadku urządzeń składanych do wewnątrz, które obsługują stan złożony, podaj odpowiednie identyfikatory stanu w polu com.android.internal.R.array.config_foldedDeviceStates.

  • W przypadku urządzeń składanych do wewnątrz, które obsługują stan półzłożony (zawias jest otwarty w połowie, jak w laptopie), wymień odpowiednie stany w polu com.android.internal.R.array.config_halfFoldedDeviceStates.

  • W przypadku urządzeń obsługujących tryb tylnego wyświetlacza:

    • Wymień odpowiednie stany w polu com.android.internal.R.array.config_rearDisplayDeviceStates dla DeviceStateManager.
    • Określ fizyczny adres wyświetlacza tylnego w com.android.internal.R.string.config_rearDisplayPhysicalAddress.
    • Określ identyfikator stanu w com.android.internal.R.integer.config_deviceStateRearDisplay, który ma być używany przez rozszerzenia.
    • Dodaj identyfikator stanu w  com.android.internal.R.array.config_deviceStatesAvailableForAppRequests, aby udostępnić go aplikacjom.
  • Na urządzeniach z Androidem 14, które obsługują tryb dwóch wyświetlaczy (jednoczesny):

    • Ustaw com.android.internal.R.bool.config_supportsConcurrentInternalDisplays na true.
    • Określ fizyczny adres wyświetlacza tylnego w com.android.internal.R.config_deviceStateConcurrentRearDisplay.
    • Określ identyfikator stanu w com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay, który ma być używany przez rozszerzenia, jeśli identyfikator ma być udostępniany aplikacjom.
    • Dodaj identyfikator stanu w  com.android.internal.R.array.config_deviceStatesAvailableForAppRequests, aby udostępnić go aplikacjom.

Weryfikacja

Producenci OEM muszą zweryfikować swoje implementacje, aby zapewnić oczekiwane działanie w typowych scenariuszach. Testy CTS i testy z użyciem Jetpack WindowManager są dostępne dla producentów OEM do testowania implementacji.

Testy CTS

Aby uruchomić testy CTS, przeczytaj sekcję Uruchamianie testów CTS. Testy CTS związane z Jetpack WindowManager znajdują się w cts/tests/framework/base/windowmanager/jetpack/. Nazwa modułu testowego to CtsWindowManagerJetpackTestCases.

Testy WindowManager

Aby pobrać testy Jetpack WindowManager, postępuj zgodnie z instrukcjami dotyczącymi Androida Jetpack. Testy znajdują się w bibliotece okien w module window:window:window/window/src/androidTest/.

Aby uruchomić testy urządzenia dla modułu window:window z wiersza poleceń, wykonaj te czynności:

  1. Podłącz urządzenie, na którym włączono opcje programisty i debugowanie USB.
  2. Zezwól komputerowi na debugowanie urządzenia.
  3. Otwórz powłokę w katalogu głównym repozytorium androidx.
  4. Przejdź do katalogu framework/support.
  5. Uruchom to polecenie: ./gradlew window:window:connectedAndroidTest.
  6. Przeanalizuj wyniki.

Aby uruchomić testy w Android Studio:

  1. Otwórz Android Studio.
  2. Podłącz urządzenie, na którym włączono opcje programisty i debugowanie USB.
  3. Zezwól komputerowi na debugowanie urządzenia.
  4. Przejdź do testu w bibliotece okien modułu okien.
  5. Otwórz klasę testową i uruchom ją, klikając zielone strzałki po prawej stronie edytora.

Możesz też utworzyć konfigurację w Android Studio, aby uruchomić metodę testową, klasę testową lub wszystkie testy w module.

Wyniki można analizować ręcznie, sprawdzając dane wyjściowe powłoki. Niektóre testy są pomijane, jeśli urządzenie nie spełnia określonych założeń. Wyniki są zapisywane w standardowej lokalizacji, a analitycy mogą napisać skrypt, który zautomatyzuje analizę wyników.