APDE GSoC ’18: Android Mode 4.0 Integraties

Wanneer je een sketch uitvoert met het watchface-doel, wordt de sketch gebouwd en naar het horloge gestuurd. Vervolgens laadt de APDE wear companion app automatisch de sketch en start de watch face chooser:

VR-schetches worden net als gewone apps geïnstalleerd. Ze ondersteunen het VR-platform van Google, waaronder Cardboard- en Daydream-headsets:

Als u deze nieuwe functies in handen wilt krijgen, wordt u verzocht lid te worden van het APDE Preview Channel en de instructies bovenaan te volgen om lid te worden van de testerlijst.

Op het moment van schrijven is v0.5.0-pre2 beschikbaar en bevat wallpapers en VR, maar geen watch faces.

Hoe werkt dit allemaal?

De sleutel tot het ondersteunen van deze nieuwe doelen was het upgraden om desktop Processing’s Android Mode 4.0 te gebruiken, die ondersteuning voor wallpapers, watch faces en VR heeft toegevoegd. Mijn werk bestond uit het overzetten van deze coole nieuwe functies naar APDE, wat op zich geen gemakkelijke taak was.

Ik heb al vroeg besloten dat ik wil dat elke sketch uitvoerbaar is voor elk doel. Ik wil dat gebruikers een schets of voorbeeld kunnen nemen en het naadloos van de ene omgeving naar de andere kunnen transplanteren, of het nu een app, wallpaper, watch face of VR is. Op deze manier is er maximale flexibiliteit en capaciteit voor het verkennen van het volledige potentieel van Processing schetsen. De enige uitzondering op deze regel is dat VR-schetsen 3D moeten zijn (2D-schetsen werken gewoon niet vanwege de aard van VR).

Deze aanpak verschilt van die van de Android-modus. Bijvoorbeeld, op de desktop, VR is verpakt als een bibliotheek, zodat alleen schetsen die expliciet importeren de VR-bibliotheek kan worden uitgevoerd voor de VR doel. In APDE kan elke 3D-schets voor VR worden uitgevoerd en de juiste import wordt automatisch toegevoegd.

Het bouwsysteem gebruikt nu een set sjablonen om alle bouwbestanden bij te houden, zoals de activiteiten, manifesten en lay-outs. Deze methode is veel beter dan de hard-coding die voorheen werd gedaan. De sjablonen zijn vrijwel woordelijk overgenomen van Android-modus, maar er zijn een paar wijzigingen, zoals ondersteuning voor Daydream VR-headsets.

Live wallpapers en VR-schetsen worden net als gewone apps-schetsen geïnstalleerd, maar VR vereist de Google VR-bibliotheken. Op dezelfde manier vereisen watch faces de wearable-ondersteuningsbibliotheek, maar ze installeren niet op dezelfde manier omdat ze op een horloge moeten worden geïnstalleerd.

Watch Face Woes

Ik moest de schets op het horloge installeren.

Het eerste wat ik probeerde, was de schets naar het horloge te duwen en het daar te installeren. Het blijkt dat het side-loaden van een APK op een Wear OS (voorheen Android Wear) horloge niet zo eenvoudig is als het lijkt. Op een Android-telefoon hoef je alleen maar installatie vanuit onbekende bronnen in te schakelen in de instellingen en je bent klaar. Op wear wordt deze installatie echter geblokkeerd door het systeem en is er geen manier om dit te omzeilen zonder de telefoon of het horloge te rooten of het horloge op een computer aan te sluiten. Dit zijn geen van alle opties voor een mobiele ontwikkelomgeving op instapniveau.

Volgende, ik probeerde de app te verpakken als een Wear 1.x-app en deze op de telefoon te installeren. Vóór Android Wear 2.0 werden alle Wear-apps gedistribueerd door ze te bundelen in telefoonapps, zelfs als die telefoonapp slechts een lege huls was. Dit veranderde allemaal in 2.0 toen Wear-apps standalone werden. De hoop was dat ik gebruik kon maken van het oude systeem om de horloge-app via de telefoon te installeren, maar dit mocht niet baten. Ik weet nog steeds niet of de oude installatie methode wordt ondersteund op nieuwere horloges, maar ik was niet in staat om een proof of concept aan het werk te krijgen.

Uiteindelijk nam ik mijn toevlucht tot een laatste-oplossing methode: klasse laden, dat is een soort van zwarte magie. Het idee is dat in plaats van het installeren van de schets als een onafhankelijke app, kan ik de schets klasse te laden in een app die al draait op het horloge, het verwijderen van de noodzaak om de schets te installeren elke keer dat het wordt uitgevoerd. Dit is een fundamenteel ander model dan hoe APDE momenteel werkt. APDE bouwt een sketch en het is een standalone app die wordt geïnstalleerd. Het scherm van de app verzamelt een heleboel schetsen naarmate de gebruiker ze uitvoert, en ze blijven bestaan wanneer APDE wordt verwijderd. Het horloge is anders. Schetsen worden niet geïnstalleerd, ze worden alleen geladen. Er is altijd maar één schets beschikbaar als watch face, en die verdwijnt als APDE wordt verwijderd.

Het blijkt dat deze aanpak werkt. De gebruiker installeert een bridge app op zijn horloge uit de Play Store (nog niet beschikbaar) genaamd de “APDE Wear Companion”. Wanneer APDE een schets bouwt, stuurt het die naar de wear companion. De wear companion pakt de schets uit en vraagt de gebruiker een wijzerplaat te kiezen die in de wear companion is ingebouwd. Dan laadt die wijzerplaat de schets en geeft hem weer. Dit is verrassend naadloos.

Er waren een paar uitdagingen.

Wanneer de schets crasht, wordt het uitgevoerd in de wear companion, zodat de hele wear companion app crasht, ook. Ik probeer momenteel de schade te beperken, maar soms breekt de wear companion en moet opnieuw worden opgestart omdat de schets te vaak is gecrasht. APDE kan op dit moment ook de stack traces van crashende watch faces niet zien, omdat het proces sterft voordat de stack trace kan worden verzonden. (Print statements werken wel.)

Er is niet slechts één watch face; er zijn er eigenlijk twee. Processing heeft twee basis klassen voor watch faces: een voor de standaard renderer (JAVA2D) en een voor OpenGL-gebaseerde renderers (P2D en P3D). Er zijn dus twee watch faces, één voor elke renderer. Wanneer de wear companion een sketch uitpakt, controleert het welke renderer het gebruikt. Dan wordt de corresponderende wijzerplaat zichtbaar gemaakt en de andere verborgen. Dit is weer een soort zwarte magie omdat de gebruiker het niet eens zou mogen merken, maar het schijnt redelijk goed te werken.

Ik heb net gelogen. Er zijn eigenlijk vier wijzerplaten. Het blijkt dat wanneer je een nieuwe wijzerplaat laadt, als de nieuwe dezelfde is als de oude (en alle sketches gebruiken dezelfde twee wijzerplaten), dan maakt het systeem “kortsluiting” (dat is de technische term ervoor) en laadt de wijzerplaat niet opnieuw. Dit is prima voor gewone wijzerplaten, maar de APDE wijzerplaat moet opnieuw geladen worden om de nieuwe schets te krijgen. De oplossing is vies, maar effectief: heb gewoon twee watch faces voor elke renderer (vier in totaal) en wissel ze af bij het laden van nieuwe schetsen, zodat de watch face gedwongen wordt te herladen.

Ondanks al deze moeilijkheden, ben ik blij te kunnen zeggen dat watch faces redelijk goed lijken te werken, tenminste op de twee sets apparaten waarop ik ze getest heb. De andere, meer waarschijnlijk te gebruiken doelen – wallpapers en VR – waren aanzienlijk gemakkelijker te implementeren.

Vooruitkijken

De volgende belangrijke functie die voor deze zomer is gepland, is een “preview”-modus. Momenteel moeten APDE-schetsen iedere keer dat ze worden uitgevoerd, worden geïnstalleerd. Dit is niet ideaal, omdat de installateur de tijd tussen het drukken op “uitvoeren” en het zien van de schets op sommige telefoons verdubbelt. Ook kunnen, zoals hierboven beschreven, alle schetsen het scherm van de apps onoverzichtelijk maken. Het niet hoeven installeren van sketches is waarschijnlijk de meest gevraagde functie van APDE.

Ik had oorspronkelijk twee voorgestelde oplossingen voor dit probleem. Ten eerste, gebruik Processing.js om de schets om te zetten in JavaScript en voer het uit in een WebView. Ten tweede, gebruik maken van Instant Apps om een schets uit te voeren zonder deze te installeren. Beide oplossingen zijn nog niet perfect. Processing.js is verouderd en ondersteunt geen native Android API’s, zoals de versnellingsmeter. Instant Apps is op zijn best een wankel idee, omdat ik niet eens weet of het mogelijk zal zijn om de debugger te spoofen om de sketches lokaal te hosten en ze uit te voeren, of dat dit sneller zou zijn dan ze gewoon te installeren.

Het kraken van de watch face noot heeft me gelukkig een nieuwe aanpak gegeven. APDE hoeft een schets niet om te zetten in JavaScript of een instant app te bouwen. Het hoeft alleen maar de bestaande sketch te nemen en de classes te laden in plaats van te installeren.

Met deze aanpak hoeft APDE alleen maar de resources te bouwen met AAPT, de classes te compileren met ECJ, en de classes te dexen. Op mijn telefoon duurt dit hele proces minder dan twee seconden (hoewel veel telefoons aanzienlijk langzamer zijn), wat een enorme verbetering is ten opzichte van het bouwen van de APK en het installeren ervan.

Nog verder vooruitkijkend ben ik van plan om deze zomer incrementele compilatie te implementeren, d.w.z. de compiler op de achtergrond te laten draaien om de fouten in real-time weer te geven. Met dit systeem zal de sketch waarschijnlijk al gecompileerd zijn voordat de gebruiker op de run-knop drukt, wat betekent dat alles wat overblijft het dexen is. Met andere woorden, class loaders zouden het bouwproces kunnen reduceren tot minder dan een seconde, afhankelijk van de telefoon hardware natuurlijk.

Er is nog veel opwinding te komen deze zomer!

Fin

Als je de veranderingen die ik heb gemaakt in meer detail wilt bekijken, bekijk dan de android-mode-4 branch op GitHub. Ik heb gedetailleerde commit berichten achtergelaten (de meeste van de tijd) en alle code is daar.

Blijf op de hoogte van de preview mode!