APDE GSoC ’18: Integrazioni Android Mode 4.0

Quando si esegue uno sketch con il target watch face, lo sketch viene costruito e inviato all’orologio. Poi l’app APDE wear companion carica automaticamente lo sketch e lancia il watch face chooser:

Gli sketch VR sono installati proprio come le app normali. Supportano la piattaforma VR di Google, che include gli auricolari Cardboard e Daydream:

Se vuoi mettere le mani su queste nuove funzionalità, unisciti al canale di anteprima APDE e segui le istruzioni in alto per unirti alla lista dei tester.

Al momento della scrittura, v0.5.0-pre2 è disponibile e include sfondi e VR, ma non le watch faces.

Come funziona tutto questo?

La chiave per supportare questi nuovi obiettivi è stata l’aggiornamento per utilizzare l’Android Mode 4.0 di Desktop Processing, che ha aggiunto il supporto per sfondi, watch faces e VR. Il mio lavoro è stato solo il porting di queste nuove caratteristiche su APDE, che non è stato di per sé un compito facile.

Ho deciso presto che voglio che ogni schizzo sia eseguibile per ogni obiettivo. Voglio che gli utenti siano in grado di prendere qualsiasi schizzo o esempio e trapiantarlo senza soluzione di continuità da un ambiente all’altro, sia esso un’app, uno sfondo, un watch face o un VR. In questo modo c’è la massima flessibilità e capacità di esplorare il pieno potenziale degli sketch di Processing. L’unica eccezione a questa regola è che gli sketch VR devono essere 3D (gli sketch 2D semplicemente non funzionano a causa della natura della VR).

Questo approccio differisce da quello della modalità Android. Per esempio, sul desktop, VR è impacchettato come una libreria, quindi solo gli sketch che importano esplicitamente la libreria VR possono essere eseguiti per il target VR. In APDE, ogni schizzo 3D può essere eseguito per VR e le importazioni corrette vengono aggiunte automaticamente.

Il sistema di compilazione ora utilizza un set di modelli per tenere traccia di tutti i file di compilazione come le attività, i manifesti e i layout. Questo metodo è molto preferibile all’hard-coding che veniva fatto prima. I modelli sono presi praticamente alla lettera dalla modalità Android, ma ci sono un paio di cambiamenti, come il supporto per gli auricolari Daydream VR.

Sfondi vivi e schizzi VR sono installati proprio come gli schizzi delle app regolari, ma VR richiede le librerie Google VR. Allo stesso modo, i watch face richiedono la libreria di supporto per gli indossabili, ma non si installano allo stesso modo perché devono essere installati su un orologio.

Watch Face Woes

Ho avuto bisogno di installare lo sketch sull’orologio.

La prima cosa che ho provato è stata spingere lo sketch sull’orologio e installarlo lì. Si scopre che il caricamento laterale di un APK su un orologio Wear OS (ex Android Wear) non è così facile come può sembrare. Su un telefono Android, basta abilitare l’installazione da fonti sconosciute nelle impostazioni e sei a posto. Su wear, invece, questa installazione è bloccata dal sistema e non c’è modo di aggirarla senza fare il rooting del telefono o dell’orologio o collegando l’orologio a un computer. Nessuna di queste sono opzioni per un ambiente di sviluppo mobile entry-level.

Poi ho provato a confezionare l’app come app Wear 1.x e a installarla sul telefono. Prima di Android Wear 2.0, tutte le app Wear erano distribuite in bundle con le app del telefono, anche se l’app del telefono era solo un guscio vuoto. Tutto questo è cambiato nella 2.0, quando le app per l’usura sono diventate autonome. La speranza era che potessi sfruttare il vecchio sistema per installare l’app dell’orologio attraverso il telefono, ma questo non è servito a nulla. Non so ancora se il vecchio metodo di installazione sia supportato o meno sugli orologi più recenti, ma non sono riuscito a far funzionare una prova di concetto.

Finalmente ho fatto ricorso a un metodo di ultima spiaggia: il caricamento delle classi, che è una sorta di magia nera. L’idea è che invece di installare lo sketch come app indipendente, posso caricare la classe dello sketch in un’app che è già in esecuzione sull’orologio, eliminando la necessità di installare lo sketch ogni volta che viene eseguito. Questo è un modello fondamentalmente diverso da come funziona attualmente APDE. APDE costruisce uno sketch ed è un’app indipendente che viene installata. Lo schermo dell’app accumula un mucchio di schizzi man mano che l’utente li esegue e questi rimangono in giro quando APDE viene disinstallato. L’orologio è diverso. Ora gli schizzi non sono installati, sono solo caricati. C’è sempre e solo uno schizzo disponibile come volto dell’orologio, e scompare quando APDE viene disinstallato.

Si scopre che questo approccio funziona. L’utente installa un’app ponte sul suo orologio dal Play Store (non ancora disponibile) chiamata “APDE Wear Companion”. Quando APDE costruisce uno schizzo, lo invia al wear companion. Il wear companion decomprime lo schizzo e chiede all’utente di selezionare un watch face integrato nel wear companion. Poi quella faccia dell’orologio carica lo schizzo e lo visualizza. Questo è sorprendentemente senza soluzione di continuità.

Ci sono state un paio di sfide.

Quando lo schizzo va in crash, è in esecuzione nel wear companion, quindi anche l’intera app wear companion va in crash. Attualmente sto cercando di contenere i danni, ma a volte il wear companion si rompe e deve essere riavviato perché lo sketch è andato in crash troppe volte. APDE inoltre non può vedere le tracce dello stack delle watch face che si bloccano al momento perché il processo muore prima che la traccia dello stack possa essere inviata. (Le istruzioni di stampa però funzionano.)

Non c’è solo una watch face; in realtà ce ne sono due. Processing ha due classi base per le watch face: una per il renderer di default (JAVA2D) e una per i renderer basati su OpenGL (P2D e P3D). Quindi ci sono due watch face, uno per ogni renderer. Quando il wear companion scompatta uno schizzo, controlla quale renderer sta usando. Poi la watch face corrispondente viene resa visibile e l’altra viene nascosta. Questo è un altro tipo di magia nera perché l’utente non dovrebbe nemmeno notarlo, ma sembra funzionare abbastanza bene.

Ho appena mentito. In realtà ci sono quattro watch face. Si scopre che quando si carica un nuovo quadrante, se quello nuovo è uguale a quello vecchio (e tutti gli schizzi usano gli stessi due quadranti), allora il sistema va in “corto circuito” (questo è il termine tecnico) e non ricarica il quadrante. Questo va bene per i quadranti normali, ma il quadrante APDE deve essere ricaricato per ottenere il nuovo schizzo. La soluzione è sporca, ma efficace: basta avere due watch face per ogni renderer (quattro in totale) e alternarli quando si caricano nuovi schizzi in modo che il watch face sia costretto a ricaricare.

Nonostante tutte queste difficoltà, sono felice di dire che i watch face sembrano funzionare abbastanza bene, almeno sui due set di dispositivi su cui li ho testati. Gli altri obiettivi più probabili da utilizzare – sfondi e VR – sono stati significativamente più facili da implementare.

Guardando avanti

La prossima grande caratteristica prevista per questa estate è una modalità “anteprima”. Attualmente, gli schizzi APDE devono essere installati ogni volta che vengono eseguiti. Questa disposizione non è ideale perché l’installatore raddoppia il tempo tra il premere “run” e vedere lo schizzo su alcuni telefoni. Inoltre, come descritto sopra, tutti gli schizzi possono ingombrare la schermata delle applicazioni. Non dover installare gli sketch è probabilmente la caratteristica più richiesta di APDE.

In origine avevo due proposte di soluzione a questo problema. Primo, usare Processing.js per convertire lo sketch in JavaScript ed eseguirlo in una WebView. Secondo, sfruttare Instant Apps per eseguire uno sketch senza installarlo. Entrambe queste soluzioni sono ancora imperfette. Processing.js non è aggiornato e non supporta nessuna API nativa di Android, come l’accelerometro. Instant Apps è un’idea traballante nel migliore dei casi, perché non so nemmeno se sarà possibile spoofare il debugger per ospitare gli sketch localmente ed eseguirli, o se questo sarebbe più veloce della semplice installazione.

Grazie al cielo, la rottura del dado del watch face mi ha dato un nuovo approccio. APDE non ha bisogno di convertire uno sketch in JavaScript o costruire un’app istantanea. Ha solo bisogno di prendere lo sketch esistente e caricarlo in classi invece di installarlo.

Con questo approccio, APDE ha solo bisogno di costruire le risorse con AAPT, compilare le classi con ECJ, e dex le classi. Sul mio telefono, l’intero processo richiede meno di due secondi (anche se molti telefoni sono considerevolmente più lenti), che è un enorme miglioramento rispetto al dover costruire l’APK e installarlo.

Guardando ancora più avanti, ho intenzione di implementare la compilazione incrementale quest’estate, cioè avere il compilatore in esecuzione in background per visualizzare gli errori in tempo reale. Con questo sistema in atto, lo sketch sarà probabilmente compilato anche prima che l’utente prema il pulsante di esecuzione, il che significa che tutto ciò che rimane è il dexing. In altre parole, i caricatori di classi potrebbero plausibilmente ridurre il processo di compilazione a meno di un secondo, a seconda dell’hardware del telefono, naturalmente.

C’è ancora molta eccitazione per questa estate!

Fin

Se volete esplorare i cambiamenti che ho fatto in modo più dettagliato, controllate il ramo android-mode-4 su GitHub. Ho lasciato messaggi di commit dettagliati (la maggior parte delle volte) e tutto il codice è lì.

Stai sintonizzato per la modalità anteprima!