Расширения оконного менеджера

Библиотека Jetpack WindowManager позволяет разработчикам приложений поддерживать новые форм-факторы устройств и многооконные среды.

WindowManager Extensions (Extensions) — это дополнительный модуль платформы Android, который позволяет использовать множество функций Jetpack WindowManager. Модуль реализован в AOSP в frameworks/base/libs/WindowManager/Jetpack и поставляется на устройствах, поддерживающих функции WindowManager.

Распределение модулей расширений

Расширения компилируются в библиотеку .jar и помещаются в раздел system_ext на устройстве, если расширения включены в make-файле устройства.

Чтобы включить расширения на устройстве, добавьте следующее в файл сборки устройства:

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

Это включает пакеты androidx.window.extensions и androidx.window.sidecar на устройстве и устанавливает свойство persist.wm.extensions.enabled . Включение этих пакетов в makefile также помещает объявления в etc/permissions/ , делая их доступными для процессов приложений. Обычно модули загружаются и выполняются как часть процесса приложения во время выполнения при использовании библиотеки Jetpack WindowManager, что делает ее работу похожей на код клиентской платформы, как показано на следующем рисунке:

Рисунок 1. Расширения WindowManager загружаются в процесс приложения аналогично коду платформы.

Модуль androidx.window.extensions — это текущий модуль Extensions, находящийся в активной разработке. Модуль androidx.window.sidecar — это устаревший модуль, включенный для совместимости с самыми ранними версиями Jetpack WindowManager, но sidecar больше не поддерживается активно.

На следующем рисунке показана логика определения использования androidx.window.extensions или androidx.window.sidecar .

Рисунок 2. Дерево решений для доступа androidx.window.extensions или androidx.window.sidecar .

Модули расширения

Расширения обеспечивают функции окон для складных устройств с большим экраном и устройств, которые поддерживают окна на внешних дисплеях. Области функций включают:

Реализации OEM расширений могут предоставлять пустые компоненты или компоненты с реализациями по умолчанию или заглушками методов в интерфейсе WindowExtensions , если аппаратное обеспечение устройства не поддерживает соответствующие функции, если только эта функция специально не запрошена в документе определения совместимости (CDD) 7.1.1.1 .

Расширения и API Jetpack

Модуль WindowManager Extensions предоставляет собственную API-поверхность в дополнение к API публичной платформы. Модуль Extensions разрабатывается публично в библиотеке Jetpack androidx.window.extensions , не предназначенной для разработчиков, так что Jetpack WindowManager ( androidx.window ) может подключаться к нему во время компиляции. Поверхность API Extensions обычно предоставляет API более низкого уровня.

API, предоставляемые Extensions, предназначены для использования только библиотекой Jetpack WindowManager. API Extensions не предназначены для прямого вызова разработчиками приложений. Библиотека Extensions не должна добавляться в качестве зависимости для приложения в файле сборки Gradle для обеспечения корректной функциональности. Избегайте предварительной компиляции библиотеки Extensions непосредственно в приложение; вместо этого полагайтесь на загрузку во время выполнения, чтобы предотвратить случай загрузки смеси предварительно скомпилированных и предоставленных во время выполнения классов Extensions.

Jetpack WindowManager ( androidx.window ) предназначен для добавления в качестве зависимости приложения и предоставляет общедоступные API для разработчиков, включая API для функций WindowManager Extensions. Библиотека WindowManager автоматически загружает Extensions в процесс приложения и оборачивает низкоуровневые API Extensions в высокоуровневые абстракции и более специализированные интерфейсы. API WindowManager Jetpack соответствуют стандартам современной разработки приложений Android и предназначены для обеспечения удобного взаимодействия за счет хорошей интеграции с кодовыми базами, использующими другие библиотеки AndroidX.

Версии расширений и обновления

Модуль Extensions может обновляться вместе с ежегодными или ежеквартальными обновлениями платформы Android. Ежеквартальные обновления позволяют повысить уровень API Extensions между обновлениями API платформы Android, что позволяет ускорить итерацию и предоставляет OEM-производителям возможность добавлять официальный доступ API к новым функциям ближе к запуску оборудования.

В следующей таблице перечислены версии API androidx.window.extensions для различных выпусков Android.

Версия платформы Android Уровень API расширений WindowManager androidx.window.extensions версия API
Андроид 15 6 1.5.0 (скоро)
Android 14 QPR3 5 1.4.0 (скоро)
Android 14 QPR1 4 1.3.0
Андроид 14 3 1.2.0
Android 13 QPR3 2 1.1.0
Андроид 13 1 1.0.0
Андроид 12L 1 1.0.0

Уровень API расширений (центральный столбец) увеличивается каждый раз при добавлении к существующей стабильной поверхности API (правый столбец).

Обратная и прямая совместимость

Jetpack WindowManager справляется со сложностью работы с частыми обновлениями уровня API, быстрой эволюцией API и обратной совместимостью. Когда код библиотеки выполняется в процессе приложения, библиотека проверяет объявленный уровень API расширений и предоставляет доступ к функциям в соответствии с объявленным уровнем.

Чтобы защитить приложение от сбоя во время выполнения, WindowManager также выполняет проверку отражения Java во время выполнения доступных API расширений в соответствии с заявленным уровнем API расширений. Если есть несоответствие, WindowManager может отключить использование расширений (частично или полностью) и сообщить о том, что соответствующие функции недоступны приложению.

Расширения WindowManager реализованы как модуль system_ext , который использует частные API платформы для вызова ядра WindowManager, DeviceStateManager и других системных служб при реализации функций расширений.

Совместимость может не поддерживаться с предварительными версиями Extensions до соответствующего квартального или ежегодного выпуска платформы Android, с которым версии завершаются. Полную историю API Extensions можно найти в window:extensions:extensions Текстовые файлы API .

Новые версии Extensions должны продолжать работать со старыми версиями WindowManager, скомпилированными в приложения, чтобы поддерживать прямую совместимость. Чтобы обеспечить это, любая новая версия Extensions API только добавляет новые API и не удаляет старые. В результате приложения со старыми версиями WindowManager могут продолжать использовать старые Extensions API, с которыми были скомпилированы приложения.

Проверка CTS гарантирует, что для любой заявленной версии API расширений на устройстве присутствуют и работоспособны все API для этой и предыдущих версий.

Производительность

Модуль Extensions по умолчанию кэшируется в загрузчиках системных классов non‑bootclasspath, начиная с Android 14 (уровень API 34), поэтому загрузка модуля в память при запуске приложения не влияет на производительность. Использование отдельных функций модуля может немного повлиять на характеристики производительности приложений, когда между клиентом и сервером выполняются дополнительные вызовы IPC.

Модули

Внедрение активности

Компонент внедрения активности позволяет приложениям оптимизировать свой пользовательский интерфейс для устройств с большим экраном и внешних дисплеев. Внедрение активности позволяет отображать две активности рядом в многопанельном макете, облегчая разработку адаптивных приложений для устаревших приложений.

Компонент внедрения активности должен быть доступен на всех устройствах, имеющих встроенный дисплей, равный или больший, чем sw600dp . Внедрение активности также должно быть включено на устройствах, которые поддерживают подключение внешнего дисплея, поскольку приложение может отображаться в большем размере, если внешние дисплеи подключены во время выполнения.

Конфигурация устройства

Никакой конкретной конфигурации устройства не требуется, кроме включения модуля Extensions, как описано в разделе Распространение модуля Extensions . Имеет смысл включить Extensions на всех устройствах, которые поддерживают многооконный режим. Будущие версии Android, вероятно, сделают Extensions обязательными на обычных портативных и больших экранных конфигурациях устройств.

Информация о расположении окон

Компонент информации о макете окна определяет положение и состояние шарнира на складном устройстве, когда шарнир пересекает окно приложения. Информация о макете окна позволяет приложениям реагировать и отображать оптимизированные макеты в настольном режиме на складных устройствах. Подробности использования см. в разделе Сделайте так, чтобы ваше приложение распознавало сворачивание .

Складные устройства Android, включающие шарнир, соединяющий отдельные или непрерывные области панели дисплея, должны предоставлять информацию о шарнире приложениям через WindowLayoutComponent .

Положение и границы шарнира должны сообщаться относительно окна приложения, идентифицированного Context , переданным в API. Если границы окна приложения не пересекаются с границами шарнира, DisplayFeature шарнира не должен сообщаться. Также приемлемо не сообщать о функциях отображения, когда их положение может быть сообщено ненадежно, например, когда окно приложения может свободно перемещаться пользователем в многооконном режиме или в режиме совместимости letterboxing.

Для складных функций обновления состояния должны сообщаться, когда положение шарнира изменяется между стабильными состояниями. По умолчанию в плоском состоянии отображения API должен сообщать FoldingFeature.State.FLAT . Если аппаратное обеспечение устройства может оставаться в полусложенном состоянии в стабильном состоянии, API должен сообщать FoldingFeature.State.HALF_OPENED . В API нет закрытого состояния, поскольку в таком случае окно приложения либо не будет видно, либо не будет пересекать границы шарнира.

Конфигурация устройства

Для поддержки реализации функции складывания OEM-производители должны выполнить следующие действия:

  • Настройте состояния устройства в device_state_configuration.xml для использования DeviceStateManagerService . См. DeviceStateProviderImpl.java для справки.

    Если реализации DeviceStateProvider или DeviceStatePolicy по умолчанию не подходят для устройства, можно использовать пользовательскую реализацию.

  • Включите модуль расширений, как описано в разделе «Распространение модулей расширений» .

  • Укажите расположение функций отображения в строковом ресурсе com.android.internal.R.string.config_display_features (обычно в frameworks/base/core/res/res/values/config.xml в наложении устройства).

    Ожидаемый формат строки:

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

    type может быть либо fold , либо hinge . Значения left , top , right и bottom являются целочисленными пиксельными координатами в пространстве координат дисплея в естественной ориентации дисплея. Строка конфигурации может содержать несколько функций дисплея, разделенных точкой с запятой.

    Например:

    <!-- Jetpack WindowManager display features -->
    <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>
    
  • Определите соответствие между внутренними идентификаторами состояния устройства, используемыми в DeviceStateManager и публичными константами состояния, отправляемыми разработчикам в com.android.internal.R.array.config_device_state_postures .

    Ожидаемый формат для каждой записи:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    Поддерживаемые идентификаторы состояний:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1 : Состояние не имеет складных функций для отчета. Например, это может быть закрытое состояние типичного складного устройства с основным экраном на внутренней стороне.
    • COMMON_STATE_HALF_OPENED = 2 : Складная часть открыта наполовину.
    • COMMON_STATE_FLAT = 3 : Функция складывания плоская. Например, это может быть открытое состояние типичного складного устройства с основным экраном на внутренней стороне.
    • COMMON_STATE_USE_BASE_STATE = 1000 : в Android 14 это значение, которое можно использовать для эмулируемых состояний, где состояние шарнира выводится с использованием базового состояния, как определено в CommonFoldingFeature.java

    Для получения дополнительной информации см. DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int) .

    Например:

    <!-- 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>
    

Площадь окна

Компонент области окна предоставляет набор функций, которые предоставляют приложениям доступ к дополнительным дисплеям и областям отображения на некоторых складных и многодисплейных устройствах.

Режим заднего дисплея позволяет приложению отображать пользовательский интерфейс предварительного просмотра камеры на дисплее крышки складного устройства, чтобы разрешить использование основной камеры устройства для селфи и видео. Устройства, которые имеют совместимый с Android (как определено в CDD Android с точки зрения таких атрибутов, как размер, плотность и доступные возможности навигации) дисплей крышки, который совпадает с камерами заднего устройства, должны предоставлять доступ к режиму заднего дисплея.

В Android 14 режим двойного дисплея позволяет приложениям, работающим на внутреннем дисплее складного устройства, отображать дополнительный контент на внешнем дисплее, обращенном к другим пользователям; например, внешний дисплей может отображать предварительный просмотр камеры для человека, которого фотографируют или снимают.

Конфигурация устройства

Для поддержки реализации функции складывания OEM-производители должны выполнить следующие действия:

  • Настройте состояния устройства в device_state_configuration.xml для использования DeviceStateManagerService . Для получения дополнительной информации см. DeviceStateProviderImpl.java .

    Если реализация DeviceStateProvider или DeviceStatePolicy по умолчанию не подходит для устройства, можно использовать пользовательскую реализацию.

  • Для складных устройств, поддерживающих открытый или плоский режим, укажите соответствующие идентификаторы состояний в com.android.internal.R.array.config_openDeviceStates .

  • Для складных устройств, поддерживающих сложенные состояния, перечислите соответствующие идентификаторы состояний в com.android.internal.R.array.config_foldedDeviceStates .

  • Для складных устройств, которые поддерживают полусложенное состояние (шарнир наполовину открыт, как у ноутбука), перечислите соответствующие состояния в com.android.internal.R.array.config_halfFoldedDeviceStates .

  • Для устройств, поддерживающих режим заднего дисплея:

    • Перечислите соответствующие состояния в com.android.internal.R.array.config_rearDisplayDeviceStates для DeviceStateManager .
    • Укажите физический адрес заднего дисплея в com.android.internal.R.string.config_rearDisplayPhysicalAddress .
    • Укажите идентификатор состояния в com.android.internal.R.integer.config_deviceStateRearDisplay , который будет использоваться расширениями.
    • Добавьте идентификатор состояния в com.android.internal.R.array.config_deviceStatesAvailableForAppRequests , чтобы сделать его доступным для приложений.
  • На Android 14 для устройств, поддерживающих режим двух (одновременных) дисплеев:

    • Установите com.android.internal.R.bool.config_supportsConcurrentInternalDisplays значение true .
    • Укажите физический адрес заднего дисплея в com.android.internal.R.config_deviceStateConcurrentRearDisplay .
    • Укажите идентификатор состояния в com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay , который будет использоваться расширениями, если идентификатор должен быть доступен для приложений.
    • Добавьте идентификатор состояния в com.android.internal.R.array.config_deviceStatesAvailableForAppRequests , чтобы сделать его доступным для приложений.

Проверка

OEM-производители должны проверить свои реализации, чтобы гарантировать ожидаемое поведение в общих сценариях. Тесты CTS и тесты с использованием Jetpack WindowManager доступны OEM-производителям для тестирования реализаций.

Тесты CTS

Чтобы запустить тесты CTS, см . раздел Запуск тестов CTS . Тесты CTS, связанные с Jetpack WindowManager, находятся в cts/tests/framework/base/windowmanager/jetpack/ . Имя тестового модуля — CtsWindowManagerJetpackTestCases .

Тесты WindowManager

Чтобы загрузить тесты Jetpack WindowManager, следуйте инструкциям Android Jetpack . Тесты находятся в библиотеке окон в модуле window:window : window/window/src/androidTest/ .

Чтобы запустить тесты устройства для модуля window:window из командной строки, выполните следующие действия:

  1. Подключите устройство, на котором включены параметры разработчика и отладка по USB.
  2. Позвольте компьютеру выполнить отладку устройства.
  3. Откройте оболочку в корневом каталоге репозитория androidx.
  4. Измените каталог на framework/support .
  5. Выполните следующую команду: ./gradlew window:window:connectedAndroidTest .
  6. Проанализируйте результаты.

Чтобы запустить тесты из Android Studio, выполните следующие действия:

  1. Откройте Android Studio.
  2. Подключите устройство, на котором включены параметры разработчика и отладка по USB.
  3. Позвольте компьютеру выполнить отладку устройства.
  4. Перейдите к тесту в библиотеке оконного модуля.
  5. Откройте тестовый класс и запустите его, используя зеленые стрелки в правой части редактора.

Кроме того, вы можете создать конфигурацию в Android Studio для запуска тестового метода, тестового класса или всех тестов в модуле.

Результаты можно анализировать вручную, просматривая вывод оболочки. Некоторые тесты пропускаются, если устройство не соответствует определенным предположениям. Результаты сохраняются в стандартном месте, и аналитики могут написать сценарий для автоматизации анализа результатов.