Android 12s Fabricated Overlay API bringer rodløse temaer tilbage

Kan du huske, hvordan Android 8 gjorde det nemt at tematisere din enhed? Kan du huske, hvor sjovt det var? Nå, det er tilbage i Android 12, med et twist.

Den fulde stald Android 12 udgivelsen er lige rundt om hjørnet, og Google har endda postede kildekoden til sin AOSP-repo. Der er en meget nyt i Android 12, herunder en tilføjelse til ressourceoverlejringer kaldet Fabricated Overlays. Hvad var ment som en API til at hjælpe systemet med at administrere de dynamiske ændringer, der blev brugt i Materiale dig og monet kan blive til noget meget større – i hvert fald indtil Android 13 udkommer.

Baggrund

Mishaal Rahman opdagede denne nye API og gjorde mig opmærksom på den. Han havde brugt shell-kommandoen til at teste forskellige ressourceværdier i Android 12 uden at have til manuelt at kompilere overlejrings-APK'er, og han mente, at det kunne være en interessant app-idé til rootede enheder. Da han gjorde mig opmærksom på det, tog jeg meget på kildekoden til Android 12 og lagde mærke til noget, som jeg syntes var ret interessant. Jeg testede, hvad jeg fandt, og nu er vi her -- som det viser sig, kan Fabricated Overlay API bruges til at bringe rodløse temaer tilbage. Inden jeg kommer for langt ind i, hvad der sker her, vil jeg forklare, hvad Fabricated Overlays faktisk er.

Hvad er fremstillede overlejringer?

Fabricated Overlays er en ny funktion introduceret i Android 12. De ligner de klassiske Runtime Resource Overlays (RRO'er), som Android har haft i et par år nu. Både RRO'er og Fabricated Overlays kan tilsidesætte forskellige ressourcer til forskellige applikationer. Du kan ændre en boolean fra falsk til sand (eller omvendt), indstille hvor stor du vil have statuslinjen til at være, og så videre.

Fremstillede overlejringer har dog nogle bemærkelsesværdige forskelle fra RRO'er. For det første behøver du ikke generere en overlejrings-APK og derefter installere den. I stedet fortæller du bare Android, hvilke værdier du vil ændre for hvilken applikation, og den sørger for at registrere dine ændringer som et overlay, du så kan aktivere.

De er også lidt mere begrænsede end RRO'er. Før Android 11 kunne RRO'er tilsidesætte stort set enhver ressource: booleans, heltal, dimensioner, attributter, layouts og endda rådatafiler. Android 11 foretog nogle ændringer i, hvordan RRO'er fungerer, hvilket gjorde overordnede layouts ikke rigtig gennemførlige længere, selvom det gjorde RRO'er mere stabile generelt.

Fabricerede overlejringer kan på den anden side kun tilsidesætte værdier, der kan repræsenteres som heltal. Det inkluderer heltal (duh), dimensioner, booleaner og farver. Du kan ikke bruge dem til at tilsidesætte rådataressourcer, layouts, strenge eller arrays - i hvert fald ikke let. Dette er lidt en vilkårlig begrænsning i API'en: det accepterer kun heltalsværdier og ressourcekategorier som defineret af TypedValue-klassen. TypedValue gør support strenge og de andre ressourcetyper, men kun for at referere til deres ressource, ikke holde deres faktiske data.

Disse begrænsninger er dog ikke for store til det tilsigtede formål med Fabricated Overlays: Materiale dig og pengeeffekter. Fabricerede overlejringer gør det nemt for systemet at generere og anvende farve- og dimensionsoverlejringer på farten, uden at skulle genstarte eller vente på, at en APK-fil bliver kompileret.

Normalt ville dette bare være endnu en pæn API for folk med rodfæstede enheder at drage fordel af. Medmindre der er et smuthul skabt af producenten (som det Synergy udnytter på Samsung-enheder), kan overlejringer kun installeres af tredjeparter med root-adgang. Det er dog den bedste del - Google glemte at lappe et hul i Android 12.

Fremstillede overlæg uden rod

Android 8 introducerede den nye Overlay Manager Service (eller OMS) API, og folk opdagede ret hurtigt, at overlejrings-APK'er kunne installeres som normale apps og derefter aktiveres ved hjælp af ADB. Desværre lappede Google dette i Android 9, og siden da er det kun overlejringer, der er signeret med den samme nøgle som systemet, der kan installeres dynamisk.

Som det viser sig, har Android 12s Fabricated Overlays et smuthul, der minder om det, der findes i Android 8: de behøver ikke root-adgang eller tilladelser på signaturniveau. De skal bare have noget, der kører som shell-brugeren (dvs. ADB) for at registrere dem.

Det er ret tydeligt, at Google havde til hensigt, at Fabricated Overlays kun skulle være tilgængelige for root- og systembrugerne. Der er en ADB-kommandoimplementering til at oprette dem, og den kører ikke, hvis den udførende bruger ikke er root. Smuthullet er, at kontrollen kun er i kommandoen, ikke den faktiske API, hvilket betyder, at vi kan drage fordel af det med lidt arbejde.

ADB On-Device

I lang tid har Android haft en trådløs ADB-funktion. Dette lader en computer (eller noget med en ADB binær og netværksadgang) oprette forbindelse til en enhed trådløst. Det er for det meste beregnet til Android-enheder, der ikke har brugertilgængelige USB-forbindelser, f.eks smarture og tv. Desuden havde du før Android 11 brug for en kablet ADB-forbindelse for at aktivere trådløs tilstand.

Android 11 er det, der officielt bragte trådløs ADB til telefoner og tablets. Det er lidt mere kompliceret end den klassiske trådløse ADB, med parring og autentificeringskoder, men den kan aktiveres af brugeren helt på enheden, så længe enheden er tilsluttet WiFi. Det betyder, at det er muligt at oprette forbindelse til din enhed via ADB fra din enhed, og alt hvad du behøver er en WiFi forbindelse.

Brug af forhøjede API'er i en app

Der er mange grunde til, at du måske vil bruge begrænsede API'er i din app. Normalt er det fordi de giver nogle specielle funktioner, du har brug for. Så længe den API, du har brug for, har en shell-kommandoimplementering, er det ret nemt at bruge det fra en app. Alt du skal gøre er at oprette en shell-proces som root (eller ADB), køre den rigtige kommando og parse resultatet, hvis nogen.

Hvad hvis API'en ikke har en shell-implementering, eller shell-implementeringen mangler noget, du har brug for? Hvis du er på en rootet enhed, kan du bruge noget som f.eks libRootJava. libRootJava lader dig interagere med Android framework API'erne, som om din app kører som root-brugeren. Dette er både mere praktisk og meget hurtigere end at køre shell-kommandoer, da det hele er på samme sprog, og du behøver ikke bekymre dig om at parse strenge manuelt. Det har nogle begrænsninger, men for det meste fungerer det godt.

libRootJava API er ret fleksibelt. Du kan tilpasse den til at køre som shell-bruger i stedet for root. Heldigvis behøver du ikke, for nogen har allerede lavet det, og det hedder Shizuku. Shizuku er næsten som en kombination af Magisk Manager og libRootJava.

Shizuku Manager-appen guider dig gennem opsætning af en proces, der kører som den shell-bruger, som Shizuku kan få adgang til. Shizuku API-biblioteket kan implementeres i apps for at give dem adgang til system-API'er, som om de var shell-brugeren. Det er en meget mere centraliseret proces end libRootJava, da Shizuku kun skal konfigureres én gang, før hver app, der implementerer Shizuku API-biblioteket, kan bruge den. Hvis du er interesseret i, hvordan Shizuku fungerer, og hvordan du kan integrere det i din app, Det har jeg en guide til her.

Shizuku og Fabricated Overlays

Nu kan du sikkert se, hvor det går hen. Vi kan bruge en tjeneste som Shizuku til at få adgang til Fabricated Overlays API som shell-bruger, og vi kan bruge Android 11s trådløse ADB-funktion til at få adgang på shellniveau, alt sammen på enheden. Da root-brugerbegrænsningen kun er til stede i Fabricated Overlays shell-kommandoen og ikke den faktiske API, er det nok at køre som shell-brugeren til at bruge det direkte.

Implementering: Bibliotek og Sample App

Hvad med implementeringsdetaljerne? Nå, det har jeg også dækket dig til.

Som forberedelse hertil lavede jeg både en bibliotek og en fuldt funktionel prøveapp ved at bruge det bibliotek.

Selve biblioteket er mest for nemheds skyld. Det omslutter nogle af de skjulte system-API'er og giver dig et par praktiske metoder til at håndtere Shizuku-tilladelser. Den er også fleksibel, så du kan levere din egen instans af IOverlayManager API, hvis du har en anden måde at hente den på.

Eksempel-appen viser, hvordan du kan gå om at implementere biblioteket ved hjælp af Shizuku. Det er også en fuldt funktionel og nyttig app. Hovedsiden viser aktuelt registrerede fremstillede overlejringer, der blev oprettet gennem den, grupperet efter målapp. Du kan også aktivere, deaktivere og slette dem derfra.

Hvis du trykker på knappen "Tilføj overlejring" nederst, kommer du til en liste over alle apps, der kan overlejres. Søg eller rul for at finde den, du har brug for, og tryk på den. Derefter kan du trykke på knappen "Tilføj" nederst på skærmen for at se listen over ressourcer, der kan tilsidesættes i den pågældende app. Vælg en ressource, indstil dens værdi, og gentag for så mange værdier, som du vil ændre. Tryk på knappen "Gem", indtast et navn, bekræft, og du vil blive bragt tilbage til hovedskærmen, der nu viser den nye overlejring, klar til at blive aktiveret.

Her er nogle skærmbilleder fra appen, takket være Mishaal Rahman.

Som en sidebemærkning har jeg også en generel overlay manager-app kaldet... Overlay Manager. Selve den prækompilerede app er kun tilgængelig på min Patreon, men kildekoden er frit tilgængelig til alle, der ønsker at kompilere eller ændre det.

Konklusion

Den nye Fabricated Overlays API i Android 12 er ret god, mest fordi den ikke har brug for root. Det er måske ikke så sofistikeret som en fuld-on RRO APK, men det giver dig meget mere fleksibilitet uden root-adgang.

Tjek Fabricate Overlay-appen på GitHub

Hvis du har en enhed, der kører Android 12, og du vil prøve dette, så tjek GitHub-lageret, der er linket ovenfor. Udgivelsessektionen vil have en APK, der skal downloades og bruges. Biblioteket skal være nemt at inkludere i din egen applikation ved hjælp af JitPack.

Selvfølgelig skal du ikke forvente, at denne funktion bliver ved i lang tid. Google kan virkelig ikke lide tredjeparts overlejringer, så dette vil næsten helt sikkert blive rettet, når Android 13 frigives. I mellemtiden kan du dog nyde det, mens det varer!