¿Google ha utilizado OTA A/B en algún dispositivo?
Sí. El nombre comercial de las actualizaciones A/B es actualizaciones integradas . Los teléfonos Pixel y Pixel XL de octubre de 2016 se enviaron con A/B, y todos los Chromebooks usan la misma implementación update_engine
de A/B. La implementación del código de plataforma necesaria es pública en Android 7.1 y versiones posteriores.
¿Por qué son mejores las OTA A/B?
Las OTA A/B brindan una mejor experiencia de usuario al recibir actualizaciones. Las mediciones de las actualizaciones de seguridad mensuales muestran que esta característica ya ha demostrado ser un éxito: en mayo de 2017, el 95 % de los propietarios de Pixel están ejecutando la última actualización de seguridad después de un mes en comparación con el 87 % de los usuarios de Nexus, y los usuarios de Pixel actualizan antes que los usuarios de Nexus. Las fallas al actualizar los bloques durante una OTA ya no resultan en un dispositivo que no arranca; Hasta que la nueva imagen del sistema se haya iniciado correctamente, Android conserva la capacidad de recurrir a la imagen anterior del sistema en funcionamiento.
¿Cómo afectó A/B a los tamaños de partición de píxeles de 2016?
La siguiente tabla contiene detalles sobre la configuración A/B de envío versus la configuración no A/B probada internamente:
Tamaños de partición de píxeles | A/B | No A/B |
---|---|---|
Cargador de arranque | 50*2 | 50 |
Bota | 32*2 | 32 |
Recuperación | 0 | 32 |
Cache | 0 | 100 |
Radio | 70*2 | 70 |
Proveedor | 300*2 | 300 |
Sistema | 2048*2 | 4096 |
Total | 5000 | 4680 |
Las actualizaciones A/B requieren un aumento de sólo 320 MiB en flash, con un ahorro de 32 MiB al eliminar la partición de recuperación y otros 100 MiB conservados al eliminar la partición de caché. Esto equilibra el costo de las particiones B para el gestor de arranque, la partición de arranque y la partición de radio. La partición de proveedores duplicó su tamaño (la gran mayoría del tamaño aumentó). La imagen del sistema A/B de Pixel tiene la mitad del tamaño de la imagen original del sistema que no es A/B.
Para las variantes Pixel A/B y no A/B probadas internamente (solo se envía A/B), el espacio utilizado difería solo en 320MiB. En un dispositivo de 32 GiB, esto es poco menos del 1%. Para un dispositivo de 16 GiB, esto sería menos del 2 % y para un dispositivo de 8 GiB, casi el 4 % (suponiendo que los tres dispositivos tuvieran la misma imagen del sistema).
¿Por qué no usaste SquashFS?
Experimentamos con SquashFS pero no pudimos lograr el rendimiento deseado para un dispositivo de alta gama. No utilizamos ni recomendamos SquashFS para dispositivos portátiles.
Más específicamente, SquashFS proporcionó aproximadamente un 50% de ahorro de tamaño en la partición del sistema, pero la inmensa mayoría de los archivos que se comprimieron bien fueron archivos .odex precompilados. Esos archivos tenían índices de compresión muy altos (cerca del 80%), pero el índice de compresión para el resto de la partición del sistema era mucho menor. Además, SquashFS en Android 7.0 planteó las siguientes preocupaciones de rendimiento:
- Pixel tiene un flash muy rápido en comparación con dispositivos anteriores, pero no una gran cantidad de ciclos de CPU adicionales, por lo que leer menos bytes del flash pero necesitar más CPU para E/S era un posible cuello de botella.
- Los cambios de E/S que funcionan bien en una prueba de referencia artificial ejecutada en un sistema descargado a veces no funcionan bien en casos de uso del mundo real bajo carga del mundo real (como criptografía en Nexus 6).
- Las evaluaciones comparativas mostraron regresiones del 85% en algunos lugares.
A medida que SquashFS madure y agregue funciones para reducir el impacto de la CPU (como una lista blanca de archivos de acceso común que no deben comprimirse), continuaremos evaluándolo y ofreciendo recomendaciones a los fabricantes de dispositivos.
¿Cómo redujiste a la mitad el tamaño de la partición del sistema sin SquashFS?
Las aplicaciones se almacenan en archivos .apk, que en realidad son archivos ZIP. Cada archivo .apk tiene en su interior uno o más archivos .dex que contienen el código de bytes Dalvik portátil. Un archivo .odex (.dex optimizado) se encuentra separado del archivo .apk y puede contener código de máquina específico para el dispositivo. Si hay un archivo .odex disponible, Android puede ejecutar aplicaciones a velocidades compiladas previamente sin tener que esperar a que se compile el código cada vez que se inicia la aplicación. Un archivo .odex no es estrictamente necesario: Android puede ejecutar el código .dex directamente mediante interpretación o compilación Just-In-Time (JIT), pero un archivo .odex proporciona la mejor combinación de velocidad de inicio y velocidad de tiempo de ejecución si hay espacio disponible.
Ejemplo: para el archivo install-files.txt de un Nexus 6P con Android 7.1 con un tamaño total de imagen del sistema de 2628 MiB (2755792836 bytes), el desglose de los mayores contribuyentes al tamaño general de la imagen del sistema por tipo de archivo es el siguiente:
.odex | 1391770312 bytes | 50,5% |
.apk | 846878259 bytes | 30,7% |
.so (código nativo C/C++) | 202162479 bytes | 7,3% |
Archivos .oat/imágenes .art | 163892188 bytes | 5,9% |
Fuentes | 38952361 bytes | 1,4% |
datos locales de la UCI | 27468687 bytes | 0,9% |
Estas cifras también son similares para otros dispositivos, por lo que en los dispositivos Nexus/Pixel, los archivos .odex ocupan aproximadamente la mitad de la partición del sistema. Esto significaba que podíamos seguir usando ext4 pero escribir los archivos .odex en la partición B de fábrica y luego copiarlos en /data
en el primer arranque. El almacenamiento real utilizado con ext4 A/B es idéntico al de SquashFS A/B, porque si hubiéramos usado SquashFS habríamos enviado los archivos .odex preoptados en system_a en lugar de system_b.
¿Copiar archivos .odex a/data no significa que el espacio guardado en/system se pierde en/data?
No exactamente. En Pixel, la mayor parte del espacio que ocupan los archivos .odex es para aplicaciones, que normalmente existen en /data
. Estas aplicaciones reciben actualizaciones de Google Play, por lo que los archivos .apk y .odex de la imagen del sistema no se utilizan durante la mayor parte de la vida útil del dispositivo. Dichos archivos pueden excluirse por completo y reemplazarse por pequeños archivos .odex basados en perfiles cuando el usuario realmente usa cada aplicación (por lo tanto, no requieren espacio para las aplicaciones que el usuario no usa). Para obtener más información, consulte la charla de Google I/O 2016 La evolución del arte .
La comparación es difícil por algunas razones clave:
- Las aplicaciones actualizadas por Google Play siempre han tenido sus archivos .odex en
/data
tan pronto como reciben su primera actualización. - Las aplicaciones que el usuario no ejecuta no necesitan ningún archivo .odex.
- La compilación basada en perfiles genera archivos .odex más pequeños que la compilación anticipada (porque la primera optimiza sólo el código crítico para el rendimiento).
Para obtener detalles sobre las opciones de ajuste disponibles para los OEM, consulte Configuración de ART .
¿No hay dos copias de los archivos .odex en/data?
Es un poco más complicado... Después de escribir la nueva imagen del sistema, la nueva versión de dex2oat se ejecuta con los nuevos archivos .dex para generar los nuevos archivos .odex. Esto ocurre mientras el sistema antiguo todavía está ejecutándose, por lo que los archivos .odex antiguos y nuevos están en /data
al mismo tiempo.
El código en OtaDexoptService ( frameworks/base/+/main/services/core/java/com/android/server/pm/OtaDexoptService.java
) llama getAvailableSpace
antes de optimizar cada paquete para evitar el sobrellenado /data
. Tenga en cuenta que lo disponible aquí sigue siendo conservador: es la cantidad de espacio que queda antes de alcanzar el umbral de espacio bajo habitual del sistema (medido como porcentaje y recuento de bytes). Entonces, si /data
está lleno, no habrá dos copias de cada archivo .odex. El mismo código también tiene BULK_DELETE_THRESHOLD: si el dispositivo está tan cerca de llenar el espacio disponible (como se acaba de describir), los archivos .odex que pertenecen a las aplicaciones que no se utilizan se eliminan. Ese es otro caso sin dos copias de cada archivo .odex.
En el peor de los casos, cuando /data
está completamente lleno, la actualización espera hasta que el dispositivo se haya reiniciado en el nuevo sistema y ya no necesite los archivos .odex del sistema anterior. PackageManager maneja esto: ( frameworks/base/+/main/services/core/java/com/android/server/pm/PackageManagerService.java#7215
). Una vez que el nuevo sistema se haya iniciado correctamente, installd
( frameworks/native/+/main/cmds/installd/dexopt.cpp#2422
) puede eliminar los archivos .odex que utilizaba el sistema anterior, devolviendo el dispositivo al estado estable. donde solo hay una copia.
Entonces, si bien es posible que /data
contenga dos copias de todos los archivos .odex, (a) esto es temporal y (b) solo ocurre si de todos modos tenía suficiente espacio libre en /data
. Excepto durante una actualización, solo hay una copia. Y como parte de las características generales de robustez de ART, de todos modos nunca llenará /data
con archivos .odex (porque eso también sería un problema en un sistema que no sea A/B).
¿Toda esta escritura/copia no aumenta el desgaste del flash?
Sólo se reescribe una pequeña parte del flash: una actualización completa del sistema Pixel escribe alrededor de 2,3 GiB. (Las aplicaciones también se recompilan, pero eso también se aplica a las que no son A/B). Tradicionalmente, las OTA completas basadas en bloques escribían una cantidad similar de datos, por lo que las tasas de desgaste del flash deberían ser similares.
¿La actualización de dos particiones del sistema aumenta el tiempo de actualización de fábrica?
No. Pixel no aumentó el tamaño de la imagen del sistema (simplemente dividió el espacio en dos particiones).
¿Mantener los archivos .odex en B no hace que el reinicio después del restablecimiento de datos de fábrica sea lento?
Sí. Si realmente usó un dispositivo, tomó una OTA y realizó un restablecimiento de datos de fábrica, el primer reinicio será más lento de lo que sería de otro modo (1m40s frente a 40s en un Pixel XL) porque los archivos .odex se habrán perdido. B después de la primera OTA y, por lo tanto, no se puede copiar a /data
. Ésa es la compensación.
El restablecimiento de los datos de fábrica debería ser una operación poco común en comparación con el arranque normal, por lo que el tiempo necesario es menos importante. (Esto no afecta a los usuarios ni a los revisores que obtienen su dispositivo de fábrica, porque en ese caso la partición B está disponible). El uso del compilador JIT significa que no necesitamos volver a compilar todo , por lo que no es tan malo como usted. podría pensar. También es posible marcar aplicaciones que requieren compilación anticipada usando coreApp="true"
en el manifiesto: ( frameworks/base/+/main/packages/SystemUI/AndroidManifest.xml#23
). Actualmente, system_server
lo utiliza porque no está permitido JIT por razones de seguridad.
¿Mantener los archivos .odex en /data en lugar de /system no hace que el reinicio después de una OTA sea lento?
No. Como se explicó anteriormente, el nuevo dex2oat se ejecuta mientras la imagen anterior del sistema aún se está ejecutando para generar los archivos que necesitará el nuevo sistema. La actualización no se considera disponible hasta que se haya realizado ese trabajo.
¿Podemos (deberíamos) enviar un dispositivo A/B de 32 GiB? ¿16 GB? ¿8 GB?
32GiB funciona bien como se demostró en Pixel, y 320MiB de 16GiB significa una reducción del 2%. Del mismo modo, 320MiB de 8GiB suponen una reducción del 4%. Obviamente, A/B no sería la opción recomendada en dispositivos con 4GiB, ya que la sobrecarga de 320MiB es casi el 10% del espacio total disponible.
¿AVB2.0 requiere OTA A/B?
No. El arranque verificado de Android siempre ha requerido actualizaciones basadas en bloques, pero no necesariamente actualizaciones A/B.
¿Las OTA A/B requieren AVB2.0?
No.
¿Las OTA A/B rompen la protección de reversión de AVB2.0?
No. Hay cierta confusión aquí porque si un sistema A/B no arranca con la nueva imagen del sistema, (después de una cantidad de reintentos determinada por su gestor de arranque) volverá automáticamente a la imagen "anterior" del sistema. Sin embargo, el punto clave aquí es que "anterior" en el sentido A/B sigue siendo en realidad la imagen "actual" del sistema. Tan pronto como el dispositivo inicia con éxito una nueva imagen, se activa la protección de reversión y garantiza que no pueda regresar. Pero hasta que no haya iniciado con éxito la nueva imagen, la protección de reversión no la considera como la imagen actual del sistema.
Si estás instalando una actualización mientras el sistema está funcionando, ¿no es lento?
Con las actualizaciones que no son A/B, el objetivo es instalar la actualización lo más rápido posible porque el usuario está esperando y no puede usar su dispositivo mientras se aplica la actualización. Con las actualizaciones A/B, ocurre lo contrario; Debido a que el usuario todavía está usando su dispositivo, el objetivo es el menor impacto posible, por lo que la actualización es deliberadamente lenta. A través de la lógica en el cliente de actualización del sistema Java (que para Google es GmsCore, el paquete principal proporcionado por GMS), Android también intenta elegir un momento en el que los usuarios no estén usando sus dispositivos en absoluto. La plataforma admite pausar/reanudar la actualización, y el cliente puede usar eso para pausar la actualización si el usuario comienza a usar el dispositivo y reanudarla cuando el dispositivo esté inactivo nuevamente.
Hay dos fases al tomar una OTA, que se muestran claramente en la interfaz de usuario como Paso 1 de 2 y Paso 2 de 2 debajo de la barra de progreso. El paso 1 corresponde a escribir los bloques de datos, mientras que el paso 2 es precompilar los archivos .dex. Estas dos fases son bastante diferentes en términos de impacto en el rendimiento. La primera fase es la E/S simple. Esto requiere pocos recursos (RAM, CPU, E/S) porque simplemente copia bloques lentamente.
La segunda fase ejecuta dex2oat para precompilar la nueva imagen del sistema. Obviamente, esto tiene límites menos claros en sus requisitos porque compila aplicaciones reales. Y obviamente implica mucho más trabajo compilar una aplicación grande y compleja que una aplicación pequeña y simple; mientras que en la fase 1 no hay bloques de disco que sean más grandes o más complejos que otros.
El proceso es similar a cuando Google Play instala una actualización de la aplicación en segundo plano antes de mostrar la notificación de las 5 aplicaciones actualizadas , como se ha hecho durante años.
¿Qué pasa si un usuario realmente está esperando la actualización?
La implementación actual en GmsCore no distingue entre actualizaciones en segundo plano y actualizaciones iniciadas por el usuario, pero puede hacerlo en el futuro. En el caso de que el usuario solicite explícitamente que se instale la actualización o esté mirando la pantalla de progreso de la actualización, priorizaremos el trabajo de actualización asumiendo que está esperando activamente a que finalice.
¿Qué sucede si no se puede aplicar una actualización?
Con las actualizaciones que no son A/B, si una actualización no se aplicaba, el usuario generalmente se quedaba con un dispositivo inutilizable. La única excepción era si el error ocurría antes de que se iniciara una aplicación (por ejemplo, porque el paquete no se pudo verificar). Con las actualizaciones A/B, la falla al aplicar una actualización no afecta el sistema que se está ejecutando actualmente. La actualización simplemente se puede volver a intentar más tarde.
¿Qué sistemas en un chip (SoC) admiten A/B?
Al 15 de marzo de 2017, tenemos la siguiente información:
Android 7.x y anteriores | Android 8.x y posterior | |
Qualcomm | Dependiendo de las solicitudes del OEM | Todos los conjuntos de chips recibirán soporte |
MediaTek | Dependiendo de las solicitudes del OEM | Todos los conjuntos de chips recibirán soporte |
Para obtener detalles sobre los horarios, consulte con sus contactos de SoC. Para los SoC que no figuran en la lista anterior, comuníquese directamente con su SoC.