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

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

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

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

Множественные домены связывания (контексты)

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

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

Разбросать

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:

  • Обычный-3.18
    cc8b90c121de ANDROID: binder: не проверять приоритетные разрешения при восстановлении.
  • Обычный-4.4
    76b376eac7a2 ANDROID: binder: не проверять приоритетные разрешения при восстановлении.
  • Обычный-4.9
    ecd972d4f9b5 ANDROID: binder: не проверять приоритетные разрешения при восстановлении.

Использование связующего 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 ; при открытии процесса поставщика / dev/vndbinder , сервис поиски автоматически переходит в vndservicemanager .

vndservicemanager двоичный входят в Makefiles устройства по умолчанию Android.

Политика SELinux

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

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

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

vndbinder_use(some_vendor_process_domain);

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

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

Более подробную информацию о SELinux см Security-Enhanced Linux в Android . Более подробную информацию о SELinux в Android 8.0 см SELinux для Android 8.0 .

Названия сервисов

Ранее процессы поставщика зарегистрированных имен службы в service_contexts файле и добавлены соответствующие правила для доступа к этому файлу. Example 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;