Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Uso de Binder IPC

Esta página describe los cambios en el controlador de binder en Android 8, proporciona detalles sobre el uso de Binder IPC y enumera la política de SELinux requerida.

Cambios en el controlador de la carpeta

A partir de Android 8, el marco de Android y las HAL ahora se comunican entre sí mediante binder. Dado que esta comunicación aumenta drásticamente el tráfico de Binder, Android 8 incluye varias mejoras diseñadas para mantener el Binder IPC rápido. SoC los proveedores y fabricantes de equipos originales debe fusionarse directamente de las ramas relevantes del androide 4.4, androide-4,9, y más alto del kernel / común del proyecto.

Varios dominios de enlace (contextos)

Common-4.4 y superior, incluido upstream

Para dividir limpiamente el tráfico entre ligante marco (dispositivo específico) código (independiente del dispositivo) y el proveedor, Android 8 introdujo el concepto de un contexto aglutinante. Cada contexto de enlace tiene su propio nodo de dispositivo y su propio administrador de contexto (servicio). Puede acceder al administrador de contexto solo a través del nodo de dispositivo al que pertenece y, al pasar un nodo de enlace a través de un contexto determinado, es accesible desde ese mismo contexto solo por otro proceso, aislando así completamente los dominios entre sí. Para más detalles sobre el uso, consulte vndbinder y vndservicemanager .

Dispersar-reunir

Common-4.4 y superior, incluido upstream

En versiones anteriores de Android, todos los datos de una llamada de carpeta se copiaban tres veces:

  • Una vez serializar en una Parcel en el proceso llamando
  • Una vez en el controlador de núcleo para copiar el Parcel para el proceso de destino
  • Una vez que unserialize el Parcel en el proceso de destino

Android 8 usos dispersión de optimización se reúnen para reducir el número de copias de 3 a 1. En lugar de la serialización de datos en un Parcel en primer lugar, los restos de datos en su estructura y la memoria disposición original y el conductor inmediatamente lo copia en el proceso de destino. Una vez que los datos están en el proceso de destino, la estructura y el diseño de la memoria son los mismos y los datos se pueden leer sin requerir otra copia.

Bloqueo de grano fino

Common-4.4 y superior, incluido upstream

En versiones anteriores de Android, el controlador Binder usaba un bloqueo global para proteger contra el acceso concurrente a estructuras de datos críticas. Si bien hubo una contención mínima por el bloqueo, el problema principal era que si un subproceso de baja prioridad obtenía el bloqueo y luego se adelantaba, podría retrasar seriamente los subprocesos de mayor prioridad que necesitaban obtener el mismo bloqueo. Esto provocó un tirón en la plataforma.

Los intentos iniciales de resolver este problema implicaron deshabilitar la preferencia mientras se mantenía el bloqueo global. Sin embargo, esto fue más un truco que una verdadera solución, y finalmente fue rechazado por upstream y descartado. Los intentos posteriores se centraron en hacer que el bloqueo sea más detallado, una versión del cual se ha estado ejecutando en dispositivos Pixel desde enero de 2017. Si bien la mayoría de esos cambios se hicieron públicos, se realizaron mejoras sustanciales en las versiones posteriores.

Después de identificar pequeños problemas en la implementación de bloqueo de grano fino, ideamos una solución mejorada con una arquitectura de bloqueo diferente y enviamos los cambios en todas las ramas comunes del kernel. Seguimos probando esta implementación en una gran cantidad de dispositivos diferentes; Como no tenemos conocimiento de ningún problema pendiente, esta es la implementación recomendada para los dispositivos que se envían con Android 8.

Herencia de prioridad en tiempo real

Common-4.4 y common-4.9 (upstream próximamente)

El controlador Binder siempre ha sido compatible con la herencia de prioridad agradable. Dado que un número cada vez mayor de procesos en Android se ejecutan con prioridad en tiempo real, en algunos casos ahora tiene sentido que si un subproceso en tiempo real realiza una llamada de enlace, el subproceso en el proceso que maneja esa llamada también se ejecute con prioridad en tiempo real. . Para admitir estos casos de uso, Android 8 ahora implementa la herencia de prioridad en tiempo real en el controlador de binder.

Además de la herencia de prioridad de nivel de transacción, la herencia prioridad de nodo permite a un nodo (aglutinante objeto de servicio) para especificar una prioridad mínima a la que se deben ejecutar llamadas en este nodo. Las versiones anteriores de Android ya admitían la herencia de prioridad de nodo con buenos valores, pero Android 8 agrega soporte para la herencia de nodos de políticas de programación en tiempo real.

Cambios en el espacio de usuario

Android 8 incluye todo el espacio de usuario cambia necesario para el trabajo con el conductor aglutinante de corriente en el núcleo común con una excepción: La implementación original para desactivar la herencia de prioridad en tiempo real para /dev/binder utilizado un ioctl . El desarrollo posterior cambió el control de la herencia de prioridad a un método más detallado que es por modo de enlace (y no por contexto). Por lo tanto, la ioctl no está en la rama común Android y en su lugar se presentó en nuestros núcleos comunes .

El efecto de este cambio es que la herencia de prioridad en tiempo real está desactivado por defecto para cada nodo. El equipo de rendimiento de Android se ha encontrado que es beneficioso para permitir la herencia de prioridad en tiempo real para todos los nodos del hwbinder dominio. Para lograr ese mismo efecto, cereza-escoge este cambio en el espacio de usuario.

SHA para kernels comunes

Para obtener los cambios necesarios en el controlador de carpeta, sincronice con el SHA apropiado:

  • Común-3.18
    cc8b90c121de ANDROID: binder: no verifique los permisos de prio en la restauración.
  • Común-4.4
    76b376eac7a2 ANDROID: binder: no verifique los permisos de prio en la restauración.
  • Común-4.9
    ecd972d4f9b5 ANDROID: binder: no verifique los permisos prio en la restauración.

Uso de Binder IPC

Históricamente, los procesos de los proveedores han utilizado la comunicación entre procesos de enlace (IPC) para comunicarse. En Android 8, el /dev/binder nodo de dispositivo se convierte en exclusiva a los procesos de marco, es decir, los procesos de los proveedores ya no tienen acceso a ella. Procesos de los proveedores pueden acceder a /dev/hwbinder , pero deben convertir sus interfaces AIDL al uso HIDL. Para los proveedores que desean continuar usando interfaces AIDL entre procesos de proveedores, Android admite Binder IPC como se describe a continuación.

vndbinder

Android 8 soportes un nuevo dominio ligante para su uso por los servicios de los proveedores, accede utilizando /dev/vndbinder en lugar de /dev/binder . Con la adición de /dev/vndbinder , Android ahora tiene las siguientes tres dominios IPC:

Dominio IPC Descripción
/dev/binder IPC entre procesos de framework / app con interfaces AIDL
/dev/hwbinder IPC entre procesos marco / proveedor con interfaces HIDL
IPC entre procesos de proveedores con interfaces HIDL
/dev/vndbinder IPC entre proveedores / procesos de proveedores con interfaces AIDL

Para /dev/vndbinder a aparecer, asegurar el elemento de configuración del kernel CONFIG_ANDROID_BINDER_DEVICES se establece en "binder,hwbinder,vndbinder" (este es el valor por defecto en los árboles del núcleo comunes de Android).

Normalmente, los procesos de los proveedores no se abren directamente el conductor de aglutinante y en su lugar enlazan contra la libbinder biblioteca de espacio de usuario, que se abre al conductor aglutinante. Adición de un método para ::android::ProcessState() selecciona el controlador de aglutinante para libbinder . Procesos de los proveedores deben llamar a este método antes de poner en ProcessState, IPCThreadState , o antes de hacer llamadas de aglutinante en general. Para su uso, coloque la siguiente llamada después del main() de un proceso de proveedor (cliente y servidor):

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

vndservicemanager

Anteriormente, los servicios de aglutinante se registraron con servicemanager , donde podrían ser recuperados por otros procesos. En Android 8, servicemanager ahora se utiliza exclusivamente por procesos de marco y de aplicaciones y procesos de los proveedores no puedan acceder TI.

Sin embargo, los servicios de proveedores ahora pueden usar vndservicemanager , una nueva instancia de servicemanager que los usos /dev/vndbinder en lugar de /dev/binder y que se construye a partir de las mismas fuentes que el marco servicemanager . Procesos de los proveedores no necesitan realizar cambios en hablar con vndservicemanager ; cuando se abre un proceso de proveedor / dev/vndbinder , Consultas de servicios pasan automáticamente a vndservicemanager .

El vndservicemanager binaria se incluye en los archivos make dispositivo por defecto de Android.

Política de SELinux

Los procesos de proveedores que desean utilizar la funcionalidad de enlace para comunicarse entre sí necesitan lo siguiente:

  1. El acceso a /dev/vndbinder .
  2. Carpeta {transfer, call} engancha en vndservicemanager .
  3. binder_call(A, B) para cualquier dominio Un vendedor que quiere llamar en el dominio del proveedor B por la interfaz de aglutinante vendedor.
  4. El permiso para {add, find} de servicios en vndservicemanager .

Para cumplir con los requisitos 1 y 2, utilice el vndbinder_use() macro:

vndbinder_use(some_vendor_process_domain);

Para cumplir con el requisito 3, el binder_call(A, B) para el proveedor procesa A y B que necesidad de hablar sobre aglutinante puede permanecer en el lugar, y no es necesario el cambio de nombre.

Para cumplir con el requisito 4, debe realizar cambios en la forma en que se manejan los nombres de los servicios, las etiquetas de los servicios y las reglas.

Para más detalles sobre SELinux, consulte Security-Enhanced Linux en Android . Para más detalles sobre SELinux en Android 8.0, consulte SELinux para Android 8.0 .

Nombres de servicios

Anteriormente, los procesos de los proveedores registrados los nombres de servicio en un service_contexts archivo y añade reglas de acceso a ese archivo correspondiente. Ejemplo service_contexts archivo de 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

En Android 8, vndservicemanager cargas de los vndservice_contexts archivo en lugar. Los servicios de proveedores que migran a vndservicemanager (y que ya están en la edad service_contexts archivo), debe añadirse a la nueva vndservice_contexts archivo.

Etiquetas de servicio

Anteriormente, etiquetas, tales como el servicio u:object_r:atfwd_service:s0 se define en una service.te archivo. Ejemplo:

type atfwd_service,      service_manager_type;

En Android 8, debe cambiar el tipo de vndservice_manager_type y mover la regla a la vndservice.te archivo. Ejemplo:

type atfwd_service,      vndservice_manager_type;

Reglas del administrador de servicios

Anteriormente, las reglas otorgado dominios de acceso para añadir o encontrar los servicios de servicemanager . Ejemplo:

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

En Android 8, estas reglas pueden permanecer en su lugar y usar la misma clase. Ejemplo:

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