Set-Top-Box y experimentos con Android en el contenedor LXC

Cómo surgió una extraña necesidad de ejecutar Android en un contenedor de Linux y qué surgió

Antecedentes


Ejecutar Android en el contenedor LXC, en mi opinión, es una decisión lógica si desea tener transparencia y confiabilidad de Bare Linux y utilizar el enorme potencial de buenas (y no tan buenas) aplicaciones de Android de terceros. Además, esta configuración es de interés como plataforma para depurar su propia imagen AOSP en condiciones lo más cercanas posible al combate.
Para los experimentos, se seleccionó un decodificador chino progresivo y económico basado en ARMv8 de 64 bits de Amlogic S905x (CPU - 4 núcleos, RAM - 2GB, MMC - 8GB). Además, un buen argumento (en comparación con otros proveedores) fue la base del código en OpenSource y la presencia del controlador del núcleo del núcleo fuente para Mali-450. Una biblioteca de espacio de usuario Mali hoy en el dominio público en el sitio web oficial de ARM Limited. Bibliotecas de acceso binario para Linux-FB, Linux-Wayland y Android.

El objetivo principal de los experimentos fue la aplicación de cines en línea y aplicaciones para trabajar con alojamiento de medios de red. Por ejemplo, con Youtube en Linux, los problemas comenzaron de inmediato. En primer lugar: el método hacker de obtener enlaces al contenido al analizar un script JS y generar una firma (previamente implementado en minitubo de Tordini y en youtube-dl) comenzó a romperse regularmente debido a la lucha despiadada de Google con los métodos de rastreo de anuncios. En segundo lugar: la resolución máxima del contenido era 720p, no se emitió más API de Google. En tercer lugar: WebKit ha perdido el soporte normal y recientemente ha sido respaldado solo por un pequeño grupo de entusiastas. El mismo destino le sucedió a su puerto Qt. Como resultado, en un momento, la página de youtube / tv se negó a funcionar, citando la vejez del motor web. Bueno, al final, trajo una sorpresa WebEngine (Qt-Chromium). Resulta que esta belleza no es compatible con la aceleración de hardware. Solo se hace una excepción para su puerto Android y la rama marginal VAAPI en Linux. Callejón sin salida. En general, no encontré una manera simple de habilitar la decodificación de video acelerada por hardware para Chromium en Linux. Implementar VAAPI para Amlogic me pareció un trabajo duro e inútil. También sentí el complemento de pimienta, desafortunadamente PPAPI no permite reproducir videos fuera de pantalla.

Android


¿Por qué no ejecutar Android en un contenedor? El proyecto Anbox inspiró la hazaña. Un estudio exhaustivo de Anbox ha demostrado que no nos conviene. Pero la idea era clara. Los artículos de otros autores afirman que ejecutar Android en un contenedor es una tarea tonta. Pero, de hecho, todo resultó ser mucho más complicado. Simplemente configurando los archivos de configuración, no pudimos salir.

Entonces, recopilo LXC y lo instalo en el sistema. La prueba de configuración del núcleo revela problemas: debe habilitar el soporte de espacio de nombres. Como la plataforma está integrada, se deshabilitaron todo tipo de cosas innecesarias. Tuve que identificar estos necesarios innecesarios.

La primera prueba fue verificar Busybox en el contenedor. Después de asegurarme de que todo funciona, comencé a experimentar.

La vista inicial es /var/lib/lxc/abox.conf:

lxc.rootfs = /var/lib/lxc/abox/rootfs lxc.rootfs.backend = dir lxc.utsname = abox lxc.pts = 1024 lxc.cap.drop = mac_admin mac_override 

Descargar el botín chino manos AOSP 6.0.19. Se diferencia de la versión vainilla por la presencia de un lanzador normal, agudizado por distash y revestimiento superficial rígido con soporte para algunas características de la plataforma de hardware Amlogic. El AOSP de vainilla también fue probado posteriormente.

Una pequeña desviación del tema: los chinos, al adaptar el software, escupen todas las reglas establecidas por la comunidad. Por ejemplo, el núcleo 3.14.29. Este número de versión de kernel silencioso se usa en casi todo el hardware en los procesadores Amlogic S8xx y S9xx. Pero, casi siempre, son muy diferentes entre sí, hasta la incompatibilidad completa de los módulos antiguos con nuevas imágenes y viceversa. Parece que el núcleo se corrigió de acuerdo con el principio: "lo más rápido posible la entrada del producto al mercado". El código no solo es sucio, es de una calidad desagradable. Cambiar la configuración generalmente conduce a errores al compilar o vincular la imagen o los módulos. Android parcheado es de la misma calidad, y los principios de adaptación son similares. Casi todas las recomendaciones del equipo de AOSP son ignoradas.

Pues a donde ir! Nosotros recogemos

Intento No. 1 Instale la imagen en el contenedor, ejecute. No funciona El análisis muestra que no hay objetos del núcleo: aglutinante y ashmem. Agregamos módulos de kernel.

Intento No. 2 Comenzamos de nuevo. Installd se bloquea. Resulta que el archivador original no conoce los espacios de nombres. Saca la carpeta de Anbox.

El intento número 3 comienza e inmediatamente se reinicia. Resulta que init quiere SELinux y se niega a trabajar sin él.

Intento No. 4 Encienda SELinux. Tenemos un montón de problemas para el sistema host. Tuve que apagarlo, al menos por ahora, hasta que se aclarara la esencia y la teoría del proceso. SELinux también se puede deshabilitar en la línea de comando al cargar el kernel, pero aún no entiendo cómo pasar parámetros al contenedor. Tuve que entrar en la fuente init y corregir aproximadamente su comportamiento. Esta fue la primera y última intervención quirúrgica que me llegó más tarde.

Intento No. 5 El proceso de arranque llegó al cigoto. En los registros, jurando desde el núcleo en el UID init. En la carpeta (y la carpeta de Anbox), el UID del proceso del propietario se compara fácilmente con la unidad. La única forma es deshabilitar la verificación, especialmente porque esta verificación no tiene sentido en el contenedor.

Intento No. 6 Surgieron conflictos relacionados con el acceso compartido a la gestión de equipos. Comento sobre los controles USB y Bluetooth en los guiones de inicio. Elimino todas las entradas de fstab y prohíbo el montaje y la verificación de todos los medios en scripts. Ahora agregue la tarjeta de montaje a la configuración del contenedor. Contiene solo una línea. El directorio /mnt/lxc.data está montado en el host en una partición MMC real.

 lxc.mount.entry = /mnt/lxc.data data auto rw,bind 0 0 

Intento No. 7 Bouncing balls apareció en la pantalla, la descarga lleva mucho tiempo, porque la imagen de Android está montada en NFS, y dexx también se está generando en el directorio / data. La recarga es muchas veces más rápida. Y finalmente, apareció el lanzador.
Consideraremos que este es el último intento, porque, en general, todo funciona y debes terminar los detalles.

La red no funciona, funciona con mayor precisión, pero algunas aplicaciones evalúan su rendimiento por el estado de las interfaces de red. Manos torcidas, en una palabra. Para eliminar este inconveniente en el host, elevamos el puente de red (bridge) y la interfaz virtual (veth).

 lxc.network.type = veth lxc.network.flags = up lxc.network.name = eth1 lxc.network.link = br0 lxc.network.veth.pair = veth-01 lxc.network.ipv4 = 10.0.0.10/24 lxc.network.ipv4.gateway = 10.0.0.1 lxc.network.hwaddr = 00:FE:CD:BA:09:87 

También necesita elevar el servidor DHCP, de lo contrario habrá problemas con el DNS. Desafortunadamente, Android no analiza resolv.conf y su ubicación en el sistema de archivos no juega ningún papel. Puede configurar la conexión de red manualmente, pero si elimina datos de la sección de datos, se restablecerán todas las configuraciones.

Resumen


Todas las aplicaciones de stock funcionan. Con instalado desde el mercado hay problemas. Por ejemplo: Youtube.tv versión 3 exigió actualizar el marco de servicio de Google, después de lo cual el sistema se bloqueó. Surgió un problema con el almacén de claves (aún no resuelto). TEE también está temporalmente desactivado, por lo que widevine no funciona. Los juguetes y las aplicaciones funcionan bien sin requisitos especiales de hardware. Chrome tuerce el video HTML5 con un decodificador de software, se niega a conectar un decodificador de hardware. En esta ocasión, hay una opinión sobre el AOSP torcidamente arrastrado por los chinos. Pero Vanilla AOSP lanza un lanzador con una pantalla táctil: es imposible controlar la distancia.

Epílogo


En un futuro cercano: hacer un lanzador para lanzar aplicaciones de Android directamente desde Linux. Un ejemplo de esto está disponible en la fuente wpa-supplicant. También puede echar un vistazo a cómo se hace esto en Anbox.

Gracias por su atencion!

Adición 1


El otro día verifiqué la escalabilidad de las aplicaciones Qt. Inicialmente, la aplicación cliente de IPTV está escrita en QML para Linux. El reproductor funciona a través del complemento QtMultimedia. Durante la compilación, surgieron dependencias problemáticas. Afortunadamente, todo estaba limitado a QtDbus, que no está en Android. Todavía no entiendo por qué Android necesitaba reinventar la carpeta. ¿Qué no les gustó a los desarrolladores de DBus? ¿Que funciona en el espacio de usuario? O consideraciones de licencia?
DBus desconectado. Esto fue sencillo, ya que el canal era necesario para un poco de funcionalidad relacionada con el sistema operativo. APK reunido No hay dificultad con el ensamblaje, ya que uso QtCreator (y se lo recomiendo).
En AOSP, tuve que dibujar un puente Mediaplayer, un heredero de android :: MediaPlayerInterface. Los métodos setDataSource () y stop () se implementaron en él. Los enchufes están hechos para el resto. setDataSource tiene tres interfaces. Se requería implementar solo:
 setDataSource(const sp<IMediaHTTPService> &httpService, const char *uri, const KeyedVector<String8, String8> *headers) 


Si desea torcer archivos de medios, debe jugar con
 setDataSource(int fd, int64_t offset, int64_t length) 

El nombre del archivo deberá obtenerse a través de "/ proc / self / fd /" + fd;

Después de la instalación, la aplicación ganó y la transmisión se fue. Genial Esperaba muchos problemas, pero casi no hay ninguno. ¡Gracias a los desarrolladores de Qt y QtCreator por el excelente y útil trabajo!
Como resultado, obtuve un montón: el jugador del demonio anfitrión. En el contenedor, hay un programa de cliente y una tira que transmite llamadas de android :: Mediaplayer al host. El paquete funciona a través de un socket UDP.

Source: https://habr.com/ru/post/es413809/


All Articles