На этой странице представлены несколько механизмов, которые производители Android-устройств могут использовать для создания общего образа системы (SSI) для разных линеек продуктов. Также предлагается процедура создания принадлежащего производителю образа SSI на основе универсального образа системы (GSI), созданного с помощью AOSP.
Фон
Фреймворк Android Open Source Project (AOSP) соответствует архитектуре Mainline , что обеспечивает обратную совместимость со старыми реализациями от разных производителей. Например, универсальный образ системы (GSI), собранный из исходного кода Android 10 AOSP, может работать на любом устройстве, совместимом с Treble и работающем под управлением Android 8 или выше.
В основной ветке Android это достигается за счет разделения на две отдельные части: аппаратно-специфическую реализацию от производителя и общую структуру ОС Android. Каждый компонент устанавливается в отдельный раздел — раздел производителя для аппаратно-специфического программного обеспечения и системный раздел для общей ОС. Между ними используется версионированный интерфейс, называемый интерфейсом производителя ( VINTF ). Эта система разделения позволяет производителям оборудования изменять системный раздел, не затрагивая раздел производителя, и наоборот.
Исторически сложилось так, что производители SoC и OEM-производители значительно модифицировали версию фреймворка Android, поставляемую на потребительских устройствах (подробнее см. «Жизнь релиза Android» ). Поскольку эти расширения фреймворка редко разрабатывались с учетом обратной совместимости, модификации, специфичные для конкретных устройств, значительно увеличивали сложность и финансовые затраты на последующие обновления ОС. В Android 10 (уровень API 29) и более ранних версиях экосистема не имела четкой, стандартизированной архитектуры, позволяющей партнерам создавать модульные расширения для фреймворка Android.
На этой странице описано, как производители SoC и OEM-производители могут создавать общий образ системы (SSI). SSI — это унифицированный образ платформы, созданный на основе исходных кодов ОС Android, который можно повторно использовать на нескольких устройствах. Поддерживая чистую обратную совместимость с реализациями поставщиков благодаря этой разделенной архитектуре, SSI значительно снижает стоимость и сложность обновления ОС Android.
Подробности реализации см. в разделе «Рекомендуемые шаги для SSI на основе GSI» . Шаги являются модульными; в зависимости от вашей архитектуры вы можете выбрать реализацию отдельных этапов (например, Шаг 1: Наследование generic_system.mk для образа системы OEM (OEM GSI) ), а не всех этапов.
Обзор SSI
При использовании SSI программные компоненты, специфичные для конкретного продукта, и расширения OEM-производителей размещаются в новом разделе /product . Компоненты в разделе /product используют четко определенный, стабильный интерфейс для взаимодействия с компонентами в разделе /system . OEM-производители могут либо создать один SSI, либо иметь небольшое количество SSI для использования на нескольких моделях устройств. При выпуске новой версии ОС Android OEM-производители инвестируют средства только один раз в обновление своих SSI до последней версии Android. Они могут повторно использовать SSI для обновления нескольких устройств без обновления раздела /product .
Производители оригинального оборудования (OEM) и поставщики SoC могут создавать SSI-модули, включающие пользовательские функции и модификации. Механизмы и лучшие практики, представленные на этой странице, предназначены для использования производителями оригинального оборудования для достижения следующих ключевых целей:
- Используйте SSI повторно для нескольких моделей устройств.
- Обновите систему Android с помощью модульных расширений, чтобы упростить обновление ОС.
Основная идея разделения компонентов, специфичных для продукта, на разделы, относящиеся к продукту, аналогична разделению компонентов, специфичных для SoC, в разделе, относящемся к производителю, в рамках Mainline. Интерфейс продукта (подобный VINTF ) обеспечивает связь между SSI и разделом продукта. В отношении SSI термин «компоненты» описывает все ресурсы, бинарные файлы, тексты и библиотеки, которые устанавливаются в образы, становящиеся разделами.
Разделы вокруг SSI
На рисунке 1 показаны разделы вокруг SSI, а также версионированные интерфейсы в этих разделах и политики на этих интерфейсах. В этом разделе подробно описаны каждый из разделов и интерфейсов.

Рисунок 1. Разделения и интерфейсы вокруг SSI.
Изображения и перегородки
Информация в этом разделе различает термины «образ» и «раздел» .
- Образ — это концептуальный фрагмент программного обеспечения, который можно обновлять независимо.
- Раздел — это физическое место хранения данных, которое можно обновлять независимо.
Разделы на рисунке 1 определены следующим образом:
SSI: Образ, общий для OEM-производителя и который может существовать на нескольких устройствах. Он не содержит компонентов, специфичных для конкретного оборудования или продукта. Все содержимое данного SSI, по определению, является общим для всех устройств, использующих этот SSI. SSI состоит либо из одного образа
/system, либо из разделов/systemи/system_ext.Образ продукта: набор компонентов, специфичных для продукта или устройства, представляющих собой модификации и расширения ОС Android от OEM-производителей. Компоненты, специфичные для SoC, следует размещать в разделе
/vendor. Производители SoC также могут использовать раздел/productдля соответствующих компонентов, например, независимых от SoC. Например, если производитель SoC предоставляет своим OEM-клиентам компонент, независимый от SoC (который не является обязательным для поставки продукта), производитель SoC может включить этот компонент в образ продукта. Местоположение компонента определяется его назначением, а не его владельцем.Изображение от производителя: Набор компонентов, специфичных для SoC.
Образ ODM: набор компонентов, специфичных для платы, которые не предоставляются SoC. Как правило, производитель SoC владеет образом поставщика, а производитель устройства — образом ODM. Если отдельного раздела
/odmнет, образы поставщика SoC и ODM объединяются в разделе/vendor.
Раздел /system_ext
Раздел /system_ext является необязательным. Используйте этот раздел для любых пользовательских функций и расширений, тесно связанных с компонентами на основе AOSP. Предполагается, что этот раздел является расширением, специфичным для OEM-производителя, по отношению к разделу /system , без интерфейса, определенного между двумя разделами. Компоненты в разделе /system_ext могут выполнять частные вызовы API к разделу /system , а компоненты в разделе /system могут выполнять частные вызовы API к разделу /system_ext .
Поскольку эти два раздела тесно связаны, при выпуске новой версии Android они обновляются одновременно. Раздел /system_ext , созданный для предыдущей версии Android, не обязательно должен быть совместим с разделом /system в следующей версии Android.
Чтобы установить модуль в раздел /system_ext , добавьте system_ext_specific: true в файл Android.bp . На устройствах, не имеющих раздела /system_ext , такие модули следует устанавливать в подкаталог ./system_ext в разделе /system .
История: Первоначальная цель создания раздела /system_ext заключалась в размещении всех компонентов, специфичных для конкретного производителя, независимо от того, являются ли они общими, в разделе /product . Однако перемещение всех компонентов одновременно оказалось нецелесообразным, особенно когда некоторые из них были тесно связаны с разделом /system . Для перемещения тесно связанного компонента в раздел /product необходимо было расширить интерфейс продукта. Это часто требовало значительной переработки самого компонента, что отнимало много времени и усилий. Раздел /system_ext изначально создавался как место для временного размещения тех компонентов, которые еще не готовы к перемещению в раздел /product . Целью SSI было в конечном итоге ликвидировать раздел /system_ext .
Однако раздел /system_ext полезен для того, чтобы максимально приблизить раздел /system к AOSP. При использовании SSI большая часть усилий по обновлению тратится на компоненты в разделах /system и /system_ext . Когда образ системы создается из исходных кодов, максимально похожих на исходные коды AOSP, можно сосредоточить усилия по обновлению на образе system_ext .
Интерфейсы между изображениями
В рамках SSI существует два основных интерфейса для образов поставщиков и продуктов:
Интерфейс поставщика (VINTF) : VINTF — это интерфейс для компонентов, находящихся в образах поставщика и ODM. Компоненты в образах продукта и системы могут взаимодействовать с образами поставщика и ODM только через этот интерфейс. Например, образ поставщика не может зависеть от частной части образа системы, и наоборот. Это определено в архитектуре Treble (теперь являющейся частью более широкой архитектуры Mainline), которая разделяет образы на системные и поставщиковые разделы. Интерфейс описывается с помощью следующих механизмов:
- HIDL (сквозная передача HAL доступна только для модулей
systemиsystem_ext) - Стабильный AIDL
- Конфигурации
- API свойств системы
- API схемы файла конфигурации
- ВНДК
- API Android SDK
- Библиотека Java SDK
- HIDL (сквозная передача HAL доступна только для модулей
Интерфейсы продукта: Интерфейс продукта — это интерфейс между SSI и образом продукта. Определение стабильного интерфейса позволяет отделить компоненты продукта от системных компонентов в SSI.
Включить SSI
В этом разделе объясняется, как обеспечить поддержку SSI в Android 11 и более поздних версиях.
Разделение компонентов
Для того чтобы отделить раздел /product от системных компонентов, раздел /product должен иметь ту же политику применения, что и раздел /vendor , который уже был отделен вместе с Mainline.
- Встроенные интерфейсы: Встроенные модули в разделе
/productдолжны быть отделены от других разделов. Единственными допустимыми зависимостями от модулей продукта являются некоторые библиотеки VNDK (включая LLNDK) из раздела/system. Библиотеки JNI, от которых зависят приложения продукта, должны быть библиотеками NDK. - Интерфейсы Java: Модули Java (приложения) в разделе
/productне могут использовать скрытые API, поскольку они нестабильны. Эти модули должны использовать только общедоступные API и системные API из раздела/system, а также библиотеки Java SDK из разделов/systemили/system_ext. Вы можете определить библиотеки Java SDK для пользовательских API.
Обеспечить корректное взаимодействие с интерфейсами продуктов.
Чтобы гарантировать отсутствие компонентов в разделе /product , производители оборудования могут настроить свои устройства на принудительное использование интерфейсов продукта, установив PRODUCT_PRODUCT_VNDK_VERSION:= current для встроенных модулей и PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE:= true для модулей Java. Эти переменные устанавливаются автоматически, если PRODUCT_SHIPPING_API_LEVEL устройства больше или равно 30 Для получения подробной информации см. раздел «Принудительное использование интерфейсов раздела продукта» .
Рекомендуемые шаги для SSI на основе GSI

Рисунок 2. Предлагаемые варианты разделения данных для SSI на основе GSI.
Универсальный образ системы (GSI) — это образ системы, созданный непосредственно на основе AOSP. Он используется для тестов на соответствие стандартам (например, CTS-on-GSI) и в качестве эталонной платформы, которую разработчики приложений могут использовать для проверки совместимости своих приложений, когда у них нет реального устройства с необходимой версией Android.
Производители оборудования также могут использовать GSI для создания своего SSI. Как поясняется в разделе «Образы и разделы» , SSI состоит из образа системы для компонентов, определенных AOSP, и образа system_ext для компонентов, определенных производителем оборудования. При использовании GSI в качестве образа system производитель оборудования может сосредоточиться на образе system_ext для обновления.
В этом разделе представлены рекомендации для OEM-производителей, желающих модульно разместить свои настройки в разделах /system_ext и /product используя при этом образ системы AOSP или близкий к AOSP. Если OEM-производители создают образ системы из исходных кодов AOSP, они могут заменить созданный ими образ системы на GSI, предоставляемый AOSP. Однако OEM-производителям не обязательно сразу доходить до заключительного этапа (использование GSI в исходном виде).
Шаг 1: Наследуйте generic_system.mk для образа системы OEM (OEM GSI)
Благодаря наследованию файла generic_system.mk (который в Android 11 назывался mainline_system.mk , а в AOSP был переименован в generic_system.mk ), образ системы (OEM GSI) включает все файлы, имеющиеся в AOSP GSI. Эти файлы могут быть изменены производителями оборудования, так что OEM GSI может содержать как собственные файлы производителя, так и файлы AOSP GSI.

Рисунок 3. Наследование файла generic_system.mk для образа системы OEM-производителя.
Шаг 2: Убедитесь, что OEM GSI содержит тот же список файлов, что и AOSP GSI.
На данном этапе OEM GSI не может содержать дополнительных файлов, поэтому переместите файлы, являющиеся собственностью OEM, в разделы system_ext или product .

Рисунок 4. Перемещение добавленных файлов из OEM GSI.
Шаг 3: Определите список разрешенных файлов, чтобы ограничить количество изменяемых файлов в OEM GSI.
Для проверки измененных файлов производители оборудования могут использовать инструмент compare_images и сравнить AOSP GSI с OEM GSI. Получите AOSP GSI из целевого объекта запуска AOSP generic_system_* .
Периодически запуская инструмент compare_images с параметром allowlist , вы можете отслеживать различия, выходящие за рамки разрешенного списка. Это предотвратит дальнейшие изменения в OEM GSI-файле.

Рисунок 5. Определение списка разрешенных файлов для сокращения списка измененных файлов в OEM GSI.
Шаг 4: Убедитесь, что OEM GSI содержит те же бинарные файлы, что и AOSP GSI.
Очистка списка разрешенных файлов позволяет производителям оборудования использовать AOSP GSI в качестве образа системы для своих собственных продуктов. Для очистки списка разрешенных файлов производители оборудования могут либо отказаться от своих изменений в OEM GSI, либо включить свои изменения в основной репозиторий AOSP, чтобы AOSP GSI включал их.

Рисунок 6. Убедитесь, что OEM GSI содержит те же бинарные файлы, что и AOSP GSI.
Определить SSI
Производители оригинального оборудования (OEM) могут использовать следующие рекомендации для определения своего SSI.
Защитите раздел /system во время сборки.
Чтобы избежать каких-либо изменений, специфичных для продукта, в разделе /system и определить OEM GSI, производители оборудования могут использовать макрос makefile под названием require-artifacts-in-path , чтобы предотвратить объявление системных модулей после вызова макроса. См. пример в шаге 1: Создайте makefile и включите проверку пути к артефактам .
Производители оборудования могут определить список, разрешающий временную установку модулей, специфичных для конкретного продукта, в раздел /system . Однако этот список должен быть пустым, чтобы GSI-файл производителя оборудования был общим для всех продуктов производителя. Этот процесс предназначен для определения GSI-файла производителя оборудования и может выполняться независимо от шагов, необходимых для определения GSI-файла AOSP .
Сделайте раздел /system_ext общим
Раздел /system_ext может отличаться на разных устройствах, поскольку он может содержать специфические для устройства системные модули. Поскольку SSI состоит из разделов /system и /system_ext , различия в разделе /system_ext затрудняют определение SSI производителями оборудования. Производители могут иметь свой собственный SSI и использовать его совместно на нескольких устройствах, устранив любые различия и сделав раздел /system_ext общим.
В этом разделе приведены рекомендации по созданию общего раздела /system_ext .
Раскройте скрытые API в системном разделе.
Многие приложения, предназначенные для конкретного устройства, нельзя установить в раздел, посвященный продукту, поскольку они используют скрытые API, использование которых запрещено в этом разделе. Чтобы переместить приложения, предназначенные для конкретного устройства, в раздел, посвященный продукту, необходимо удалить использование скрытых API.
Предпочтительный способ удаления скрытых API из приложений — это поиск альтернативных общедоступных или системных API для их замены. Если таких API нет, производители оборудования могут внести свой вклад в AOSP, чтобы определить новые системные API для своих устройств.
В качестве альтернативы производители оборудования могут определять собственные API, создавая свою библиотеку Java SDK в разделе /system_ext . Эта библиотека может использовать скрытые API в системном разделе и предоставлять эти API приложениям в разделе продукта или поставщика. Для обеспечения обратной совместимости производители оборудования должны зафиксировать API, доступные для продукта .
Заменить отключение приложения, специфичного для конкретного артикула.
В Android 16 был упразднен и удален устаревший механизм выборочного отключения APK-файлов в зависимости от аппаратного SKU с использованием наложений ресурсов фреймворка ( config_disableApksUnlessMatchedSku_apk_list и config_disableApkUnlessMatchedSku_skus_list ). Подробности см. в aosp/3444399 .
Рекомендуемая альтернатива — использование системной конфигурации install-in-user-type в каталогах, специфичных для конкретного SKU. Такой подход предотвращает установку пакета для любого пользователя в рамках определенного SKU, а не просто отключает его после установки.
Включите в образ все APK-файлы (расширенный набор всех потенциальных приложений для всех SKU в образе вашей системы), как правило, в раздел
/product.Убедитесь, что артикул устройства правильно указан в системном свойстве
ro.boot.hardware.sku(используется системой для идентификации артикула устройства во время загрузки).Создайте подкаталоги sysconfig, специфичные для каждого SKU, в каталоге
/product/etc/sysconfig/, используя соглашение об именованииsku_<SKU_NAME>. Система автоматически загрузит конфигурации из каталога, соответствующего свойствуro.boot.hardware.sku. Пример пути:/product/etc/sysconfig/sku_basic_model/.Настройте предотвращение установки приложений. В каталоге, соответствующем конкретной модели приложения, создайте XML-файл конфигурации (например,
disabled_apps.xml) и используйте тег<do-not-install-in>для исключения определенных пакетов.
Пример XML-файла ( /product/etc/sysconfig/sku_basic_model/disabled_apps.xml ):
<?xml version="1.0" encoding="utf-8"?>
<config>
<!-- Prevents this package from being installed for ANY user on this SKU -->
<install-in-user-type package="com.example.premium.feature.app" >
<do-not-install-in user-type="FULL" />
<do-not-install-in user-type="SYSTEM" />
</install-in-user-type>
</config>
Вот сравнение двух методов:
| Особенность | Android 15 и ниже | Android 16 и выше |
|---|---|---|
| Метод конфигурации | Наложения ресурсов фреймворка | XML-файлы SystemConfig |
| Расположение логики | config.xml (наложение ресурсов) | /product/etc/sysconfig/sku_<name>/ |
| Исход | Отключает приложение с помощью PackageManager | Предотвращает установку приложения для пользователя. |
| Прочность | Может быть повторно включена системными службами. | Этот пакет никогда не устанавливается для пользователя. |
В случаях, требующих более детального контроля (то есть отключения приложения, которое обычно устанавливается по умолчанию для всех версий Android), Android также поддерживает теги disabled-in-sku и enabled-in-sku-override в sysconfig:
<disabled-in-sku package="com.example.app" />отключает приложение глобально.<enabled-in-sku-override package="com.example.app" />повторно включает приложение для определенного SKU при размещении в соответствующем каталогеsku_<name>.
Вместо использования статического наложения ресурсов определите RRO.
Статическое наложение ресурсов управляет наложенными пакетами. Однако оно может препятствовать определению SSI, поэтому убедитесь, что свойства для RRO включены и правильно настроены. Установив следующие свойства, производители оборудования могут использовать все автоматически сгенерированные наложения в качестве RRO.
PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS := # leave it empty
Если требуется подробная конфигурация, определите RRO вручную, вместо того чтобы полагаться на автоматически сгенерированный. Подробную информацию см. в разделе «Изменение значения ресурсов приложения во время выполнения» . Производители оборудования также могут определять условные RRO, зависящие от системных свойств, используя атрибуты android:requiredSystemPropertyName и android:requiredSystemPropertyValue .
Часто задаваемые вопросы (FAQ)
Ниже приведены часто задаваемые вопросы о программе SSI.
Можно ли определить несколько SSI?
Это зависит от общности и характеристик устройств (или группы устройств). Производители оборудования могут попытаться сделать раздел system_ext общим, как описано в разделе «Сделать раздел system_ext общим» . Если группа устройств имеет много различий, то лучше определить несколько SSI.
Могу ли я удалить из файла generic_system.mk модули, которые конфликтуют с моей реализацией?
Нет. GSI имеет минимальный набор загружаемых и тестируемых модулей. Если вы считаете, что какой-либо модуль не является необходимым, сообщите об ошибке , чтобы обновить файл generic_system.mk .