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: trueANDvendor_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
