Библиотека Jetpack WindowManager позволяет разработчикам приложений поддерживать новые форм-факторы устройств и многооконные среды.
WindowManager Extensions (Extensions) — это модуль платформы Android, который можно включить по желанию и который обеспечивает работу различных функций Jetpack WindowManager. Модуль реализован в AOSP в frameworks/base/libs/WindowManager/Jetpack и поставляется на устройствах, поддерживающих функции WindowManager.
Распространение модулей расширений
Расширения компилируются в библиотеку .jar и размещаются в разделе system_ext на устройстве, если в файле makefile устройства включена поддержка расширений.
Чтобы включить расширения на устройстве, добавьте следующее в makefile продукта:
$(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, что делает ее работу аналогичной коду клиентской части фреймворка, как показано на следующем рисунке:

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

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 автоматически загружает расширения в процесс приложения и оборачивает низкоуровневые API расширений в высокоуровневые абстракции и более сфокусированные интерфейсы. API WindowManager Jetpack соответствуют стандартам современной разработки приложений для Android и предназначены для обеспечения удобной совместимости за счет хорошей интеграции с кодовыми базами, использующими другие библиотеки AndroidX.
Версии и обновления расширений
Модуль расширений можно обновлять вместе с ежегодными или ежеквартальными обновлениями платформы Android. Ежеквартальные обновления позволяют повышать уровень API расширений между обновлениями API платформы Android, что ускоряет итерации и предоставляет производителям оборудования возможность добавить официальный доступ к API для новых функций незадолго до запуска аппаратного обеспечения.
В таблице ниже перечислены версии API androidx.window.extensions для различных версий Android.
| версия платформы Android | Уровень API расширений WindowManager | androidx.window.extensions API version |
|---|---|---|
| Android 15 | 6 | 1.5.0 (скоро будет доступно) |
| Android 14 QPR3 | 5 | 1.4.0 (скоро будет доступно) |
| 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 |
Уровень API расширений (центральный столбец) повышается каждый раз, когда добавляется что-либо к существующему стабильному API (правый столбец).
Обратная и прямая совместимость
Jetpack WindowManager справляется со сложностями, связанными с частыми обновлениями уровня API, быстрой эволюцией API и обратной совместимостью. Когда код библиотеки выполняется в процессе приложения, библиотека проверяет объявленный уровень API расширений и предоставляет доступ к функциям в соответствии с объявленным уровнем.
Для защиты приложения от сбоев во время выполнения WindowManager также выполняет проверку доступности API расширений в соответствии с объявленным уровнем API расширений с помощью Java Reflection. В случае несоответствия WindowManager может отключить использование расширений (частично или полностью) и сообщить, что соответствующие функции недоступны для приложения.
Расширения WindowManager реализованы в виде модуля system_ext , который использует частные API платформы для вызова ядра WindowManager, DeviceStateManager и других системных служб при реализации функций расширений.
Совместимость может не сохраняться с предварительными версиями расширений, выпущенными до соответствующего ежеквартального или ежегодного релиза платформы Android, с которым эти версии окончательно согласованы. Полную историю API расширений можно найти в текстовых файлах API window:extensions:extensions релизов.
Более новые версии расширений должны продолжать работать со старыми версиями WindowManager, скомпилированными в приложения, для обеспечения обратной совместимости. Для этого любая новая версия API расширений добавляет только новые API и не удаляет старые. В результате приложения со старыми версиями WindowManager могут продолжать использовать старые API расширений, с которыми они были скомпилированы.
Проверка CTS гарантирует, что для любой заявленной версии API расширений на устройстве все API для этой и предыдущих версий присутствуют и функционируют.
Производительность
Начиная с Android 14 (уровень API 34), модуль Extensions по умолчанию кэшируется в системных загрузчиках классов, не использующих bootclasspath, поэтому загрузка модуля в память при запуске приложения не оказывает влияния на производительность. Использование отдельных функций модуля может незначительно повлиять на характеристики производительности приложений при выполнении дополнительных межпроцессных вызовов между клиентом и сервером.
Модули
Встраивание активности
Компонент встраивания активности позволяет приложениям оптимизировать свой пользовательский интерфейс для устройств с большими экранами и внешних дисплеев. Встраивание активности позволяет отображать две активности рядом в многопанельном макете, что упрощает адаптивную разработку приложений для устаревших систем.
Компонент встраивания активности должен быть доступен на всех устройствах со встроенным дисплеем размером не меньше sw600dp . Встраивание активности также должно быть включено на устройствах, поддерживающих подключение внешних дисплеев, поскольку при подключении внешних дисплеев во время выполнения приложение может отображаться в большем размере.
Конфигурация устройства
Никакой специальной настройки устройства, кроме включения модуля расширений, не требуется, как описано в разделе распространения модуля расширений . Целесообразно включать расширения на всех устройствах, поддерживающих многооконный режим. В будущих версиях Android, вероятно, потребуется включить расширения на распространенных портативных устройствах и устройствах с большими экранами.
Информация о расположении окон
Компонент информации о расположении окна определяет положение и состояние шарнира на складном устройстве, когда шарнир пересекает окно приложения. Информация о расположении окна позволяет приложениям реагировать на оптимизированные макеты и отображать их в настольном режиме на складных устройствах. См. раздел «Как сделать ваше приложение совместимым со складными устройствами» для получения подробной информации об использовании.
Складные устройства Android, в которых используется шарнир, соединяющий отдельные или непрерывные области дисплейной панели, должны предоставлять приложениям информацию о шарнире через WindowLayoutComponent .
Положение и границы шарнира должны быть указаны относительно окна приложения, идентифицированного Context , переданным в API. Если границы окна приложения не пересекаются с границами шарнира, параметр DisplayFeature шарнира указывать не следует. Также допустимо не указывать параметры отображения, если их положение может быть ненадежно определено, например, когда окно приложения может свободно перемещаться пользователем в многооконном режиме или режиме совместимости с черными полосами сверху и снизу.
Для функций складывания необходимо сообщать об обновлениях состояния при изменении положения шарнира между стабильными состояниями. По умолчанию в плоском состоянии дисплея API должен сообщать FoldingFeature.State.FLAT . Если аппаратное обеспечение устройства может оставаться в полусложенном состоянии в стабильном режиме, API должен сообщать FoldingFeature.State.HALF_OPENED . В API нет закрытого состояния, поскольку в таком случае окно приложения либо не будет видно, либо не будет выходить за пределы шарнира.
Конфигурация устройства
Для поддержки реализации функции складывания производители оборудования должны выполнить следующие действия:
Настройте состояния устройства в файле
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 (как определено в Android CDD по таким атрибутам, как размер, плотность и доступные функции навигации) внешний дисплей, совпадающий с задними камерами устройства, должны обеспечивать доступ к режиму заднего дисплея.
В Android 14 режим двойного дисплея позволяет приложениям, работающим на внутреннем дисплее складного устройства, отображать дополнительный контент на внешнем дисплее, обращенном к другим пользователям; например, внешний дисплей может показывать предварительный просмотр камеры человеку, которого фотографируют или снимают.
Конфигурация устройства
Для поддержки реализации функции складывания производители оборудования должны выполнить следующие действия:
Настройте состояния устройства в файле
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, чтобы сделать его доступным для приложений.
- Установите для
Проверка
Производители оборудования должны проверять свои реализации, чтобы обеспечить ожидаемое поведение в типичных сценариях. Для проверки реализаций производителям оборудования доступны тесты CTS и тесты с использованием Jetpack WindowManager.
Тесты CTS
Для запуска тестов CTS см. раздел «Запуск тестов CTS» . Тесты CTS, относящиеся к Jetpack WindowManager, находятся в папке cts/tests/framework/base/windowmanager/jetpack/ . Имя тестового модуля — CtsWindowManagerJetpackTestCases .
Тесты WindowManager
Чтобы загрузить тесты Jetpack WindowManager, следуйте инструкциям Android Jetpack . Тесты находятся в библиотеке window в модуле window:window : window/window/src/androidTest/ .
Чтобы запустить тесты устройства для модуля window:window из командной строки, выполните следующие действия:
- Подключите устройство, на котором включены параметры разработчика и отладка по USB.
- Разрешите компьютеру отладку устройства.
- Откройте командную оболочку в корневом каталоге репозитория androidx.
- Перейдите в каталог
framework/support. - Выполните следующую команду:
./gradlew window:window:connectedAndroidTest. - Проанализируйте результаты.
Чтобы запустить тесты из Android Studio, выполните следующие действия:
- Откройте Android Studio.
- Подключите устройство, на котором включены параметры разработчика и отладка по USB.
- Разрешите компьютеру отладку устройства.
- Перейдите к тесту в библиотеке окон модуля window.
- Откройте тестовый класс и запустите его, используя зеленые стрелки в правой части редактора.
В качестве альтернативы, вы можете создать конфигурацию в Android Studio для запуска тестового метода, тестового класса или всех тестов в модуле.
Результаты можно анализировать вручную, просматривая вывод командной строки. Некоторые тесты пропускаются, если устройство не соответствует определенным предположениям. Результаты сохраняются в стандартном месте, и аналитики могут написать скрипт для автоматизации анализа результатов.