APDE GSoC ’18: Integraciones de Android Mode 4.0

Cuando se ejecuta un sketch con el objetivo watch face, el sketch se construye y se envía al reloj. A continuación, la aplicación APDE wear companion carga automáticamente el sketch y lanza el selector de esfera del reloj:

Los sketches de RV se instalan igual que las aplicaciones normales. Son compatibles con la plataforma de RV de Google, que incluye los auriculares Cardboard y Daydream:

Si quieres poner tus manos en estas nuevas características, únete al canal de vista previa de APDE y sigue las instrucciones de la parte superior para unirte a la lista de probadores.

En el momento de escribir este artículo, la v0.5.0-pre2 está disponible e incluye fondos de pantalla y RV, pero no caras de reloj.

¿Cómo funciona todo esto?

La clave para soportar estos nuevos objetivos fue la actualización para utilizar el Modo Android 4.0 de Processing de escritorio, que añadió soporte para fondos de pantalla, caras de reloj y RV. Mi trabajo fue simplemente portar estas nuevas características a APDE, lo que no fue una tarea fácil.

Decidí desde el principio que quiero que cada boceto sea ejecutable para cada objetivo. Quiero que los usuarios puedan tomar cualquier sketch o ejemplo y trasplantarlo sin problemas de un entorno a otro, ya sea una aplicación, un fondo de pantalla, una esfera de reloj o una RV. De este modo, la flexibilidad y la capacidad de explorar todo el potencial de los sketches de Processing son máximas. La única excepción a esta regla es que los sketches de RV deben ser 3D (los sketches 2D simplemente no funcionan debido a la naturaleza de la RV).

Este enfoque difiere del del modo Android. Por ejemplo, en el escritorio, la RV se empaqueta como una biblioteca, por lo que sólo los bocetos que importan explícitamente la biblioteca de RV se pueden ejecutar para el objetivo de RV. En APDE, cada boceto 3D puede ser ejecutado para VR y las importaciones correctas se añaden automáticamente.

El sistema de construcción ahora utiliza un conjunto de plantillas para realizar un seguimiento de todos los archivos de construcción como las actividades, manifiestos y diseños. Este método es mucho mejor que la codificación que se hacía antes. Las plantillas se han tomado prácticamente al pie de la letra del modo Android, pero hay un par de cambios, como la compatibilidad con los auriculares Daydream VR.

Los fondos de pantalla en vivo y los bocetos VR se instalan igual que los bocetos de las aplicaciones normales, pero VR requiere las bibliotecas Google VR. Del mismo modo, las caras de reloj requieren la biblioteca de soporte para wearables, pero no se instalan de la misma manera porque deben instalarse en un reloj.

Watch Face Woes

Necesitaba instalar el sketch en el reloj.

Lo primero que intenté fue empujar el sketch al reloj e instalarlo allí. Resulta que la carga lateral de un APK en un reloj Wear OS (antes Android Wear) no es tan fácil como parece. En un teléfono Android, basta con activar la instalación desde fuentes desconocidas en los ajustes y ya está. En el wear, sin embargo, esta instalación está bloqueada por el sistema y no hay forma de evitarlo sin rootear el teléfono o el reloj o conectar el reloj a un ordenador. Ninguna de estas son opciones para un entorno de desarrollo móvil de nivel básico.

A continuación, traté de empaquetar la aplicación como una aplicación Wear 1.x e instalarla en el teléfono. Antes de Android Wear 2.0, todas las aplicaciones Wear se distribuían empaquetadas en aplicaciones de teléfono, incluso si esa aplicación de teléfono era sólo una carcasa vacía. Todo esto cambió en la versión 2.0 cuando las aplicaciones Wear pasaron a ser independientes. La esperanza era poder aprovechar el antiguo sistema para instalar la app del reloj a través del teléfono, pero no sirvió de nada. Todavía no sé si el antiguo método de instalación es compatible con los relojes más nuevos, pero no pude conseguir que funcionara una prueba de concepto.

Finalmente recurrí a un último método: la carga de clases, que es una especie de magia negra. La idea es que en lugar de instalar el sketch como una aplicación independiente, puedo cargar la clase del sketch en una aplicación que ya se está ejecutando en el reloj, eliminando la necesidad de instalar el sketch cada vez que se ejecuta. Este es un modelo fundamentalmente diferente de cómo funciona actualmente APDE. APDE construye un sketch y es una aplicación independiente que se instala. La pantalla de la aplicación acumula un montón de bocetos a medida que el usuario los ejecuta y permanecen cuando APDE se desinstala. El reloj es diferente. Ahora los sketches no se instalan, sólo se cargan. Sólo hay un sketch disponible como cara del reloj, y desaparece cuando se desinstala APDE.

Resulta que este enfoque funciona. El usuario instala una app puente en su reloj desde la Play Store (aún no disponible) llamada «APDE Wear Companion». Cuando APDE construye un sketch, lo envía al wear companion. El wear companion desempaqueta el boceto y pide al usuario que seleccione una esfera de reloj integrada en el wear companion. A continuación, la esfera del reloj carga el boceto y lo muestra. Esto es sorprendentemente perfecto.

Hubo un par de desafíos.

Cuando el boceto se bloquea, se está ejecutando en el wear companion, por lo que toda la aplicación wear companion se bloquea también. Actualmente estoy tratando de contener el daño, pero a veces el compañero de desgaste se rompe y necesita ser reiniciado porque el boceto se estrelló demasiadas veces. APDE también no puede ver los rastros de la pila de estrellarse caras del reloj en el momento porque el proceso muere antes de la pila de seguimiento puede ser enviado. (Sin embargo, las declaraciones de impresión funcionan.)

No hay sólo una watch face; en realidad hay dos. Processing tiene dos clases base para las watch faces: una para el renderizador por defecto (JAVA2D) y otra para los renderizadores basados en OpenGL (P2D y P3D). Por tanto, hay dos watch faces, una para cada renderizador. Cuando el wear companion desempaqueta un sketch, comprueba qué renderizador está utilizando. Entonces la esfera del reloj correspondiente se hace visible y la otra se oculta. Este es otro tipo de magia negra porque el usuario no debería notarlo, pero parece que funciona bastante bien.

Acabo de mentir. En realidad hay cuatro caras de reloj. Resulta que cuando se carga una nueva esfera de reloj, si la nueva es la misma que la anterior (y todos los bocetos usan las mismas dos esferas de reloj), entonces el sistema hace un «cortocircuito» (ese es el término técnico para ello) y no vuelve a cargar la esfera de reloj. Esto está muy bien para las esferas de reloj normales, pero la esfera de reloj APDE necesita recargarse para obtener el nuevo boceto. La solución es sucia, pero eficaz: basta con tener dos esferas de reloj para cada renderizador (cuatro en total) y alternar entre ellas cuando se cargan nuevos bocetos para que la esfera de reloj se vea obligada a recargarse.

A pesar de todas estas dificultades, me alegra decir que las esferas de reloj parecen funcionar bastante bien, al menos en los dos conjuntos de dispositivos en los que las he probado. Los otros objetivos, más probable de ser utilizado – fondos de pantalla y VR – fueron significativamente más fácil de implementar.

Mirando hacia el futuro

La próxima característica importante prevista para este verano es un modo de «vista previa». Actualmente, los bocetos de APDE deben instalarse cada vez que se ejecutan. Esta disposición no es ideal porque el instalador duplica el tiempo entre que se pulsa «ejecutar» y se ve el boceto en algunos teléfonos. Además, como se ha descrito anteriormente, todos los bocetos pueden saturar la pantalla de las aplicaciones. No tener que instalar los sketches es probablemente la característica más solicitada de APDE.

Originalmente tenía dos soluciones propuestas para este problema. Primero, utilizar Processing.js para convertir el sketch a JavaScript y ejecutarlo en una WebView. Segundo, aprovechar Instant Apps para ejecutar un sketch sin instalarlo. Ambas soluciones son todavía imperfectas. Processing.js está desactualizado y no soporta ninguna API nativa de Android, como el acelerómetro. Instant Apps es una idea inestable en el mejor de los casos porque ni siquiera sé si será posible falsificar el depurador para alojar los sketches localmente y ejecutarlos, o si esto sería más rápido que simplemente instalarlos.

Afortunadamente, romper la tuerca de la cara del reloj me ha dado un nuevo enfoque. APDE no necesita convertir un sketch a JavaScript o construir una aplicación instantánea. Sólo necesita tomar el sketch existente y cargarlo con clases en lugar de instalarlo.

Con este enfoque, APDE sólo necesita construir los recursos con AAPT, compilar las clases con ECJ, y dex las clases. En mi teléfono, todo este proceso tarda menos de dos segundos (aunque muchos teléfonos son considerablemente más lentos), lo que supone una gran mejora respecto a tener que construir el APK e instalarlo.

Mirando aún más hacia el futuro, este verano tengo previsto implementar la compilación incremental, es decir, que el compilador se ejecute en segundo plano para mostrar los errores en tiempo real. Con este sistema en marcha, es probable que el sketch se compile incluso antes de que el usuario pulse el botón de ejecutar, lo que significa que lo único que queda es dexar. En otras palabras, los cargadores de clases podrían reducir el proceso de compilación a menos de un segundo, dependiendo del hardware del teléfono, por supuesto.

¡Hay mucha emoción por venir este verano!

Fin

Si quieres explorar los cambios que he hecho con más detalle, echa un vistazo a la rama android-mode-4 en GitHub. He dejado mensajes de confirmación detallados (la mayor parte del tiempo) y todo el código está allí.

¡Manténgase en sintonía para el modo de vista previa!