Android 11 разделяет раздел product , делая его независимым от раздела system и vendor . В рамках этих изменений теперь вы можете контролировать доступ раздела product к собственному интерфейсу и интерфейсу Java (что аналогично тому, как принудительное применение интерфейса работает для разделов vendor ).
Обеспечение нативных интерфейсов
Чтобы включить принудительное применение собственного интерфейса, установите для PRODUCT_PRODUCT_VNDK_VERSION значение current . (Версия автоматически устанавливается как current , когда уровень API доставки для целевого объекта выше 29.) Применение позволяет:
- Нативные модули в разделе
productдля ссылки:- Статически или динамически к другим модулям в разделе
product, которые включают статические, общие библиотеки или библиотеки заголовков. - Динамически в библиотеки VNDK в
systemразделе.
- Статически или динамически к другим модулям в разделе
- Библиотеки JNI в несвязанных APK в разделе
productдля ссылки на библиотеки в/product/libили/product/lib64(это в дополнение к библиотекам NDK).
Применение не разрешает другие ссылки на разделы, кроме раздела product .
Контроль времени сборки (Android.bp)
В Android 11 системные модули могут создавать вариант образа продукта в дополнение к вариантам образа ядра и поставщика. Когда принудительное использование собственного интерфейса включено (для PRODUCT_PRODUCT_VNDK_VERSION установлено значение current ):
Собственные модули в разделе
productнаходятся в варианте продукта, а не в основном варианте.Модули с
vendor_available: trueв своих файлахAndroid.bpдоступны для варианта продукта и варианта поставщика.Библиотеки или двоичные файлы, в которых указано
product_specific: true, могут ссылаться на другие библиотеки, в которых указаноproduct_specific: trueилиvendor_available: trueв своих файлахAndroid.bp.Библиотеки VNDK должны иметь
vendor_available: trueв своих файлахAndroid.bp, чтобы двоичные файлыproductмогли ссылаться на библиотеки VNDK.
В следующей таблице приведены свойства Android.bp , используемые для создания вариантов изображения.
| Свойства в Android.bp | Созданные варианты | |
|---|---|---|
| До исполнения | После исполнения | |
| по умолчанию (нет) | основной (включает | основной (включает |
system_ext_specific: true | основной | основной |
product_specific: true | основной | товар |
vendor: true | продавец | продавец |
vendor_available: true | ядро, поставщик | ядро, продукт, поставщик |
system_ext_specific: true И vendor_available: true | ядро, поставщик | ядро, продукт, поставщик |
product_specific: true AND vendor_available: true | ядро, поставщик | продукт, продавец |
Контроль времени сборки (Android.mk)
Когда принудительное применение собственного интерфейса включено, собственные модули, установленные в раздел product , имеют тип ссылки native:product , который может ссылаться только на другие модули native:product или native:vndk . Попытка связать с любыми модулями, кроме этих, приводит к тому, что система сборки генерирует ошибку проверки типа ссылки.
Применение во время выполнения
Когда принудительное использование собственного интерфейса включено, конфигурация компоновщика для бионического компоновщика не позволяет системным процессам использовать библиотеки product , создавая раздел product для процессов product , который не может связываться с библиотеками за пределами раздела product (однако такие процессы могут ссылка на библиотеки VNDK). Попытки нарушить конфигурацию ссылки во время выполнения приводят к сбою процесса и генерации сообщения об ошибке CANNOT LINK EXECUTABLE .
Применение интерфейсов Java
Чтобы включить принудительное использование интерфейса Java, задайте для PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE значение true . (Это значение автоматически устанавливается равным true , если уровень API доставки для целевого объекта выше 29.) Если включено, принудительное применение разрешает/запрещает следующий доступ.
| API | /система | /system_ext | /товар | /продавец | /данные |
|---|---|---|---|---|---|
| Публичный API | |||||
| @SystemApi | |||||
| @скрыть API |
Как и в разделе vendor , приложению или библиотеке Java в разделе product разрешено использовать только общедоступные и системные API; ссылка на библиотеку, которая использует скрытые API, не разрешена. Это ограничение включает связывание во время сборки и отражение во время выполнения.
Контроль времени сборки
Во время сборки Make и Soong проверяют, что модули Java в разделе product не используют скрытые API, проверяя поля platform_apis и sdk_version . В sdk_version приложений в разделе product должна быть указана current , system_current или числовая версия API, а поле platform_apis должно быть пустым.
Применение во время выполнения
Среда выполнения Android проверяет, что приложения в разделе product не используют скрытые API, включая отражение. Дополнительные сведения см. в разделе Ограничения для интерфейсов, отличных от SDK .
Включение принудительного применения интерфейса продукта
Используйте шаги, описанные в этом разделе, чтобы включить принудительное применение интерфейса продукта.
| Шаг | Задача | Необходимый |
|---|---|---|
| 1 | Определите свой собственный системный make-файл, в котором указаны пакеты для system раздела, а затем установите проверку требований пути к артефактам в device.mk (чтобы предотвратить установку несистемных модулей в system раздел). | Н |
| 2 | Очистите разрешенный список. | Н |
| 3 | Внедряйте нативные интерфейсы и выявляйте сбои ссылок во время выполнения (может работать параллельно с принудительным применением Java). | Д |
| 4 | Принудительно применяйте интерфейсы Java и проверяйте поведение во время выполнения (можно выполнять параллельно с собственным применением). | Д |
| 5 | Проверьте поведение во время выполнения. | Д |
| 6 | Обновите device.mk с принудительным применением интерфейса продукта. | Д |
Шаг 1. Создайте make-файл и включите проверку пути к артефакту.
На этом этапе вы определяете system make-файл.
Создайте make-файл, определяющий пакеты для
systemраздела. Например, создайте файлoem_system.mkсо следующим:$(call inherit-product, $(SRC_TARGET_DIR)/product/handheld_system.mk) $(call inherit-product, $(SRC_TARGET_DIR)/product/telephony_system.mk) # Applications PRODUCT_PACKAGES += \ CommonSystemApp1 \ CommonSystemApp2 \ CommonSystemApp3 \ # Binaries PRODUCT_PACKAGES += \ CommonSystemBin1 \ CommonSystemBin2 \ CommonSystemBin3 \ # Libraries PRODUCT_PACKAGES += \ CommonSystemLib1 \ CommonSystemLib2 \ CommonSystemLib3 \ PRODUCT_SYSTEM_NAME := oem_system PRODUCT_SYSTEM_BRAND := Android PRODUCT_SYSTEM_MANUFACTURER := Android PRODUCT_SYSTEM_MODEL := oem_system PRODUCT_SYSTEM_DEVICE := generic # For system-as-root devices, system.img should be mounted at /, so we # include ROOT here. _my_paths := \ $(TARGET_COPY_OUT_ROOT)/ \ $(TARGET_COPY_OUT_SYSTEM)/ \ $(call require-artifacts-in-path, $(_my_paths),)В файле
device.mkунаследуйте общий make-файл дляsystemраздела и включите проверку требований к пути к артефакту. Например:$(call inherit-product, $(SRC_TARGET_DIR)/product/oem_system.mk) # Enable artifact path requirements checking PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict
О требованиях к пути артефакта
Когда PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS имеет значение true или strict , система сборки запрещает установку пакетов, определенных в других make-файлах, по путям, определенным в require-artifacts-in-path и не позволяет пакетам, определенным в текущем make-файле, устанавливать артефакты вне путей, определенных в require-artifacts-in-path .
В приведенном выше примере, когда PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS имеет значение strict , make-файлы вне oem_system.mk не могут включать модули, установленные в root или system разделе. Чтобы включить эти модули, вы должны либо определить их в самом файле oem_system.mk , либо во включенном make-файле. Попытки установить модули по запрещенным путям приводят к разрыву сборки. Чтобы исправить разрывы, выполните одно из следующих действий:
Вариант 1. Включите системный модуль в make-файлы, включенные в
oem_system.mk. Это позволяет выполнить требование к пути артефакта (поскольку модули теперь существуют во включенном make-файле) и, таким образом, позволяет установку по набору путей в `require-artifacts-in-path.Вариант 2. Установите модули в
system_extилиproduct(и не устанавливайте модули вsystemраздел).Вариант 3. Добавьте модули в
PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST. В этом списке перечислены разрешенные модули для установки.
Шаг 2. Очистите список разрешенных
На этом шаге вы делаете PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST пустым, чтобы все устройства, использующие oem_system.mk , также могли совместно использовать один образ system . Чтобы очистить список разрешенных, переместите любые модули из списка в system_ext или product или добавьте их в system make-файлы. Этот шаг является необязательным, поскольку определение общего образа system не требуется для включения принудительного применения интерфейса продукта. Однако очистка разрешенного списка полезна для определения границы system с помощью system_ext .
Шаг 3. Внедрите нативные интерфейсы
На этом шаге вы устанавливаете PRODUCT_PRODUCT_VNDK_VERSION := current , затем ищете ошибки сборки и времени выполнения и устраняете их. Чтобы проверить загрузку устройства и журналы, а также найти и исправить сбои связи во время выполнения:
Установите
PRODUCT_PRODUCT_VNDK_VERSION := current.Соберите устройство и найдите ошибки сборки. Скорее всего, вы увидите несколько перерывов в сборке из-за отсутствующих вариантов продукта или основных вариантов. К общим перерывам относятся:
- Любой модуль
hidl_interfaceсо значениемproduct_specific: trueне будет доступен для системных модулей. Чтобы исправить это, заменитеproduct_specific: trueнаsystem_ext_specfic: true. - В модулях может отсутствовать вариант продукта, необходимый для модулей продукта. Чтобы исправить это, сделайте этот модуль доступным для раздела
product, установивvendor_available: true, или переместите модуль в разделproduct, установивproduct_specific: true.
- Любой модуль
Устраните ошибки сборки и убедитесь, что сборка устройства прошла успешно.
Прошейте образ и найдите ошибки времени выполнения в загрузке устройства и журналах.
- Если тег
linkerиз журнала тестовых случаев показывает сообщениеCANNOT LINK EXECUTABLE, в файле make отсутствует зависимость (и она не была зафиксирована во время сборки). - Чтобы проверить это из системы сборки, добавьте требуемую библиотеку в поле
shared_libs:илиrequired:
- Если тег
Устраните отсутствующие зависимости, используя приведенные выше рекомендации.
Шаг 4. Внедрение интерфейсов Java
На этом шаге вы устанавливаете PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true , затем находите и исправляете полученные ошибки сборки. Ищите два конкретных типа ошибок:
Ошибки типа ссылки. Эта ошибка указывает на то, что приложение ссылается на модули Java с более широким
sdk_version. Чтобы исправить это, вы можете расширитьsdk_versionприложения или ограничитьsdk_versionбиблиотеки. Пример ошибки:error: frameworks/base/packages/SystemUI/Android.bp:138:1: module "SystemUI" variant "android_common": compiles against system API, but dependency "telephony-common" is compiling against private API.Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.Ошибки символов. Эта ошибка указывает на то, что символ не может быть найден, поскольку он находится в скрытом API. Чтобы исправить, используйте видимый (не скрытый) API или найдите альтернативу. Пример ошибки:
frameworks/opt/net/voip/src/java/com/android/server/sip/SipSessionGroup.java:1051: error: cannot find symbol ProxyAuthenticate proxyAuth = (ProxyAuthenticate)response.getHeader( ^ symbol: class ProxyAuthenticate location: class SipSessionGroup.SipSessionImpl
Шаг 5. Проверьте поведение во время выполнения
На этом шаге вы проверяете ожидаемое поведение во время выполнения. Для приложений, которые можно отлаживать, вы можете отслеживать использование скрытого API с помощью журнала, используя StrictMode.detectNonSdkApiUsage (который создает журнал, когда приложение использует скрытый API). В качестве альтернативы вы можете использовать инструмент статического анализа Veridex , чтобы узнать тип использования (связывание или отражение), уровень ограничений и стек вызовов.
Синтаксис Veridex:
./art/tools/veridex/appcompat.sh --dex-file={apk file}Пример результата проверки:
#1: Linking greylist-max-o Landroid/animation/AnimationHandler;-><init>()V use(s): Lcom/android/systemui/pip/phone/PipMotionHelper;-><init>(Landroid/content/Context;Landroid/app/IActivityManager;Landroid/app/IActivityTaskManager;Lcom/android/systemui/pip/phone/PipMenuActivityController;Lcom/android/internal/policy/PipSnapAlgorithm;Lcom/android/systemui/statusbar/FlingAnimationUtils;)V #1332: Reflection greylist Landroid/app/Activity;->mMainThread use(s): Landroidx/core/app/ActivityRecreator;->getMainThreadField()Ljava/lang/reflect/Field;
Подробнее об использовании veridex см. в разделе Тестирование с помощью инструмента veridex .
Шаг 6: Обновите файл device.mk
После исправления всех сбоев сборки и выполнения и проверки ожидаемого поведения во время выполнения установите в device.mk следующее:
-
PRODUCT_PRODUCT_VNDK_VERSION := current -
PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE := true