Google стремится продвигать расовую справедливость для черных сообществ. Смотри как.
Эта страница была переведа с помощью Cloud Translation API.
Switch to English

Использование Binder IPC

На этой странице описываются изменения в драйвере связывателя в Android 8, приводятся сведения об использовании связующего IPC и указывается требуемая политика SELinux.

Изменения в связующем драйвере

Начиная с Android 8, фреймворк Android и HAL теперь связываются друг с другом с помощью связующего. Поскольку эта связь значительно увеличивает трафик связующего устройства, Android 8 включает в себя несколько улучшений, разработанных для обеспечения быстрого связывания IPC. Производители SoC и OEM-производители должны объединяться непосредственно из соответствующих веток android-4.4, android-4.9 и выше ядра / общего проекта.

Несколько доменов связывания (контексты)

Common-4.4 и выше, включая апстрим

Чтобы аккуратно разделить трафик связующего между структурным (независимым от устройства) и вендорским (специфичным для устройства) кодом, Android 8 представил концепцию связующего контекста . Каждый связующий контекст имеет свой собственный узел устройства и свой собственный диспетчер контекста (службы). Вы можете получить доступ к диспетчеру контекста только через узел устройства, к которому он принадлежит, и при прохождении узла подшивки через определенный контекст он доступен из этого же контекста только другим процессом, что полностью изолирует домены друг от друга. Подробнее об использовании смотрите vndbinder и vndservicemanager .

Scatter-собирать

Common-4.4 и выше, включая апстрим

В предыдущих выпусках Android каждый фрагмент данных в вызове связывателя копировался три раза:

  • Один раз для сериализации в Parcel в процессе вызова
  • Один раз в драйвере ядра скопировать Parcel в целевой процесс
  • Один раз для десериализации Parcel в целевом процессе

Android 8 использует оптимизацию сбора разброса, чтобы уменьшить количество копий с 3 до 1. Вместо того, чтобы сначала сериализовать данные в Parcel , данные остаются в своей первоначальной структуре и структуре памяти, и драйвер немедленно копирует их в целевой процесс. После того, как данные находятся в целевом процессе, структура и структура памяти остаются теми же, и данные могут быть прочитаны без дополнительной копии.

Мелкозернистая блокировка

Common-4.4 и выше, включая апстрим

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

Первоначальные попытки решить эту проблему включали отключение вытеснения при удержании глобальной блокировки. Однако, это было скорее взломом, чем истинным решением, и в конечном итоге было отвергнуто вышестоящими и отброшено. Последующие попытки были направлены на то, чтобы сделать блокировку более детальной, версия которой работает на устройствах Pixel с января 2017 года. Хотя большинство этих изменений было опубликовано, в последующих версиях были внесены существенные улучшения.

После выявления мелких проблем в реализации детальной блокировки, мы разработали улучшенное решение с другой архитектурой блокировки и представили изменения во всех общих ветвях ядра. Мы продолжаем тестировать эту реализацию на большом количестве различных устройств; поскольку мы не знаем о каких-либо нерешенных проблемах, это рекомендуемая реализация для устройств, поставляемых с Android 8.

Наследование приоритетов в реальном времени

Common-4.4 и common-4.9 (скоро будет апстрим)

Драйвер связывателя всегда поддерживал хорошее наследование приоритетов. Поскольку все большее число процессов в Android выполняется с приоритетом в реальном времени, в некоторых случаях теперь имеет смысл, что, если поток в реальном времени выполняет вызов связывателя, поток в процессе, который обрабатывает этот вызов, также выполняется с приоритетом в реальном времени. , Для поддержки этих вариантов использования Android 8 теперь реализует наследование приоритетов в реальном времени в драйвере связывателя.

В дополнение к наследованию приоритетов на уровне транзакций наследование приоритетов узлов позволяет узлу (объекту службы связывания) указывать минимальный приоритет, при котором должны выполняться вызовы в этот узел. Предыдущие версии Android уже поддерживали наследование приоритетов узлов с хорошими значениями, но в Android 8 добавлена ​​поддержка наследования узлов политик планирования в реальном времени.

Изменения в пользовательском пространстве

Android 8 включает все изменения пользовательского пространства, необходимые для работы с текущим драйвером связывателя в общем ядре, с одним исключением: в первоначальной реализации для отключения наследования приоритетов в реальном времени для /dev/binder использовался ioctl . Последующее развитие переключило управление наследованием приоритетов на более мелкозернистый метод, который находится в режиме привязки (а не в контексте). Таким образом, ioctl не входит в общую ветку Android и вместо этого представлен в наших общих ядрах .

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

SHA для общих ядер

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

  • Common-3,18
    cc8b90c121de ANDROID: binder: не проверять разрешения prio при восстановлении.
  • Common-4,4
    76b376eac7a2 ANDROID: binder: не проверять разрешения prio при восстановлении.
  • Common-4,9
    ecd972d4f9b5 ANDROID: binder: не проверять разрешения prio при восстановлении.

Использование связующего IPC

Исторически процессы вендоров использовали связующее межпроцессное взаимодействие (IPC) для связи. В Android 8 узел устройства /dev/binder становится эксклюзивным для процессов платформы, что означает, что процессы поставщика больше не имеют к нему доступа. Процессы поставщика могут обращаться к /dev/hwbinder , но должны конвертировать свои интерфейсы AIDL для использования HIDL. Для поставщиков, которые хотят продолжать использовать интерфейсы AIDL между процессами вендоров, Android поддерживает связующий IPC, как описано ниже.

vndbinder

Android 8 поддерживает новый домен Связующее для использования услуг поставщика, доступ , используя /dev/vndbinder вместо /dev/binder . С добавлением /dev/vndbinder , Android теперь имеет следующие три домена IPC:

Домен IPC Описание
/dev/binder IPC между инфраструктурой / процессами приложения с интерфейсами AIDL
/dev/hwbinder IPC между процессами инфраструктуры / вендора с интерфейсами HIDL
IPC между процессами вендора с интерфейсами HIDL
/dev/vndbinder IPC между вендором / процессами вендора с интерфейсами AIDL

Для /dev/vndbinder убедитесь, что для элемента конфигурации ядра CONFIG_ANDROID_BINDER_DEVICES установлено значение "binder,hwbinder,vndbinder" (это значение по умолчанию в общих деревьях ядра Android).

Обычно процессы вендора не открывают драйвер связывателя напрямую, а вместо этого связываются с библиотекой пространства пользователя libbinder , которая открывает драйвер связывателя. Добавление метода для ::android::ProcessState() выбирает драйвер связывателя для libbinder . Процессы поставщика должны вызывать этот метод перед вызовом ProcessState, IPCThreadState или перед выполнением любых вызовов связывателя в целом. Чтобы использовать, сделайте следующий вызов после main() процесса вендора (клиент и сервер):

ProcessState::initWithDriver("/dev/vndbinder");

vndservicemanager

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

Однако услуги поставщиков могут теперь использовать vndservicemanager , новый экземпляр servicemanager , который использует /dev/vndbinder вместо /dev/binder и который строится из тех же источников, рамочный servicemanager . Процессы поставщика не должны вносить изменения для vndservicemanager с vndservicemanager ; когда процесс поставщика открывает / dev/vndbinder , поиск службы автоматически переходит к vndservicemanager .

vndservicemanager файл vndservicemanager включен в make- vndservicemanager устройств Android по умолчанию.

Политика SELinux

Процессы вендора, которые хотят использовать функциональные возможности связующего для взаимодействия друг с другом, нуждаются в следующем:

  1. Доступ к /dev/vndbinder .
  2. Связыватель {transfer, call} vndservicemanager к vndservicemanager .
  3. binder_call(A, B) для любого домена A вендора, который хочет вызвать домен B вендора через интерфейс binder_call(A, B) вендора.
  4. Разрешение на {add, find} сервисы в vndservicemanager .

Чтобы выполнить требования 1 и 2, используйте vndbinder_use() :

vndbinder_use(some_vendor_process_domain);

Чтобы выполнить требование 3, binder_call(A, B) для процессов A и B вендора, которым необходимо обсудить связующее, может оставаться на месте и не нуждается в переименовании.

Чтобы выполнить требование 4, вы должны внести изменения в способ обработки имен, меток и правил обслуживания.

Подробнее о SELinux см. В разделе « Безопасность Linux в Android» . Подробнее о SELinux в Android 8.0 см. В разделе SELinux для Android 8.0 .

Сервисные имена

Ранее поставщик обрабатывал зарегистрированные имена служб в файле service_contexts и добавлял соответствующие правила для доступа к этому файлу. Пример файла service_contexts с device/google/marlin/sepolicy :

AtCmdFwd                              u:object_r:atfwd_service:s0
cneservice                            u:object_r:cne_service:s0
qti.ims.connectionmanagerservice      u:object_r:imscm_service:s0
rcs                                   u:object_r:radio_service:s0
uce                                   u:object_r:uce_service:s0
vendor.qcom.PeripheralManager         u:object_r:per_mgr_service:s0

В Android 8 vndservicemanager загружает файл vndservice_contexts . Службы поставщика, мигрирующие в vndservicemanager (и которые уже находятся в старом файле service_contexts ), должны быть добавлены в новый файл vndservice_contexts .

Сервисные ярлыки

Ранее метки службы, такие как u:object_r:atfwd_service:s0 были определены в файле service.te . Пример:

type atfwd_service,      service_manager_type;

В Android 8 необходимо изменить тип на vndservice_manager_type и переместить правило в файл vndservice.te . Пример:

type atfwd_service,      vndservice_manager_type;

Правила Servicemanager

Ранее правила предоставляли доменам доступ для добавления или поиска служб из servicemanager . Пример:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;

В Android 8 такие правила могут оставаться на месте и использовать один и тот же класс. Пример:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;