Fără cod sursă, cum obțin dezvoltatorii componente hardware, cum ar fi camerele care lucrează în ROM-uri personalizate? Răspunsul este un BLOB, shim și multă depanare.
Odată cu lansarea Android Oreo și a multor dispozitive, cum ar fi Xiaomi Redmi Note 3, Google Nexus 5 și alții primind-o neoficial, probabil că este corect să ne întrebăm de ce aceleași caracteristici (mai ales camera) tind să fie rupte atunci când dezvoltatorii port un ROM bazat pe Android Open Source Project (AOSP). Probabil ați văzut fire de forum XDA cu ROM-uri cu o listă lungă de funcții sparte sus. „Ce funcționează”, urmat de o listă de funcții de lucru, apoi mai jos simbolul „Ce nu funcționează? Să-mi spuneți!" sunt două refrene populare pe forumurile noastre care au devenit practic un meme în locuri precum Reddit și Twitter.
De ce se întrerupe atât de multă funcționalitate ori de câte ori un dezvoltator încearcă să port un ROM AOSP pe dispozitivul său? Răspunsul de bază este că, deoarece funcțiile se modifică în diferite versiuni de Android, vechile drivere de dispozitiv împachetate ca BLOB nu vor funcționa cu versiuni mai noi de Android sau chiar doar cu AOSP stoc. Pentru a depăși acest lucru, dezvoltatorii folosesc ceea ce se numește „shim”, dar procesul implicat este dificil, necesită mult timp și uneori foarte dificil de depanat.
În acest articol, vom sublinia modul în care funcționează shim-urile, în special în ceea ce privește funcționarea corectă a camerei pe ROM-urile bazate pe AOSP. Vom folosi OnePlus 3T ca exemplu. Rețineți că dificultatea pe care o implică să funcționeze aceste funcții este foarte specifică dispozitivului.
OnePlus 3T rulează OxygenOS. Deși telefoanele OnePlus sunt cunoscute pentru ușurința de dezvoltare personalizată, există multă muncă pe care dezvoltatorii o fac în culise pentru a crea porturi stabile pentru AOSP.
Ce este un shim sau un BLOB?
Pentru a începe chiar să înțelegem o parte din ceea ce fac dezvoltatorii, mai întâi trebuie să explicăm câteva lucruri. Deși sistemul de operare Android este open source (se numește Android Open Source Project dintr-un motiv), software-ul (fără kernel) livrat pe mii de dispozitive Android nu este. Dezvoltatorii nu au acces la codul sursă al Samsung Experience, EMUI, OxygenOS, sau oricare dintre celelalte variante ale terțelor părți ale Android.
Acum, dezvoltatorii care portează stocul AOSP pe un dispozitiv non-Google probabil că nu le pasă de codul sursă al acestor skin-uri Android, deoarece acestea nu vor fi modificarea și construirea acestor ROM-uri. Asta ar fi adevărat, dacă nu pentru un motiv mare, mare: piesele necesare pentru ca camera să funcționeze corect, în principal cel camera HAL (Hardware Abstraction Layer), sunt de asemenea sursă închisă.
Problema cu a avea nu numai camera HAL, ci și sursa închisă ROM este că dezvoltatorii care lucrează la portarea AOSP pe dispozitivul lor vor fi orb de lucru. ROM-ul OEM cu sursă închisă este capabil să interfațeze cu camera HAL foarte bine, deoarece OEM are acces la sursa HAL a camerei. Camera HAL este cea care permite ROM-ului să „vorbească” cu hardware-ul camerei – fără ea, camera ar fi nefuncțională. Gândiți-vă la camera HAL ca la volanul și pedalele mașinii. Volanul/pedalele permit controlul componentelor interne ale vehiculului prin furnizarea unei interfețe externe pentru ca șoferul (ROM-ul) să utilizeze componentele interne.
Pe măsură ce hardware-ul camerei devine din ce în ce mai complex (the apariția camerelor duble, de exemplu), accesul la sursa HAL al camerei ar face ca portarea unui ROM AOSP cu o cameră funcțională să fie mult mai ușoară.
Cu toate acestea, OEM-urile nu oferă acces la sursa HAL a camerei din diverse motive. În primul rând, dacă nu dețin toate drepturile de proprietate asupra camerei HAL (cum ar fi atunci când încorporează proprietatea intelectuală de la alte companii), atunci nu pot distribui sursa. În al doilea rând, eliberarea sursei HAL a camerei poate pune în pericol propria lor proprietate intelectuală. În cele din urmă, companiile nu au obligația legală de a furniza acest cod sursă (spre deosebire de codul sursă al nucleului care sunt obligat să elibereze conform GPL), astfel încât nu au niciun stimulent să-l elibereze. Deci, fără acces la sursa HAL a camerei, cum fac dezvoltatorii să lucreze camera pe ROM-urile AOSP? Răspunsul este un BLOB, shim și o mulțime de depanare.
Un dispozitiv BLOB (Binary Large OBject) conține binare pre-ambalate care sunt forma compilată de software. În acest caz, sursa HAL a camerei este compilată de OEM și livrată pe dispozitive ca binare. Când dezvoltatorii vorbesc despre BLOB-uri, se referă la acele binare care sunt livrate pe dispozitive live pe care le pot extrage. Acum, subiectul „BLOB-urilor camerei” are de mult afectat OnePlus de multe luni, dar adevărul este că dezvoltatorii au avut întotdeauna acces la BLOB-urile camerei. The Codul sursă HAL al camerei este biletul de aur pentru dezvoltatorii de aici, totuși, dar asta va fi niciodată, niciodată eliberat din cauza pericolului legal în care ar pune companii precum OnePlus.
Astfel, dezvoltatorii care doresc să aducă AOSP pe un dispozitiv rămân doar cu BLOB-uri ale camerei HAL pentru care nu au acces la codul sursă. Rareori, dacă vreodată, un dezvoltator își poate asocia codul ROM AOSP cu camera HAL BLOB și se așteaptă ca acesta să funcționeze, așa că pentru a reduce decalajul dintre cele două, dezvoltatorii creează ceea ce se numește „shim.”
A „shim” înseamnă a „păna (ceva) sau a umple un spațiu”. Acest lucru este efectiv ceea ce face un dezvoltator atunci când scrierea unui shim - ei adaugă cod pentru a permite BLOB să interfațeze cu codul sursă AOSP pe care îl lucrează cu. Dispozitivele sunt folosite pentru a face ca BLOB-urile de toate tipurile să funcționeze cu AOSP, dar de obicei, BLOB-ul camerei este cel care necesită cel mai mult shimming. După cum am menționat anterior, shimming-ul este necesar nu numai pentru portarea versiunilor mai noi de Android pe un dispozitiv (cum ar fi toate acele ROM-uri Android Oreo neoficiale), dar necesare și la portarea AOSP a aceleiași versiuni Android pe acesta dispozitiv.
Lectură recomandată: De la magazin la raft: o capitulare aprofundată a motivului pentru care dispozitivele MSM8974 sunt excluse din Nougat
OnePlus 2, de exemplu, a primit-o ultima actualizare oficială majoră a sistemului de operare sub formă de Android 6.0 Marshmallow. Dispozitivul, însă, are de fapt ROM-uri personalizate bazate pe AOSP care funcționează complet bazat pe Android Nougat, și asta datorită muncii asidue a dezvoltatorilor și a lamelor lor. Vom detalia câteva exemple de lame, dar mai întâi trebuie să vorbim despre cum funcționează exact lamele.
Cum funcționează shimming-ul?
Deoarece dezvoltatorii nu au acces la sursa HAL al camerei sau la sursa ROM OEM (și doar la binarele precompilate), ei nu pot ști la ce funcții se așteaptă camera HAL. Din acest motiv, există adesea o nepotrivire între numele funcției pe care o caută camera HAL și numele real al funcției din codul AOSP cu care lucrează dezvoltatorul.
Pentru a rezolva această problemă, dezvoltatorul creează pur și simplu o nouă funcție care folosește același nume funcția la care se așteaptă camera HAL BLOB, dar această nouă funcție doar execută ceea ce își dorește dezvoltatorul acesta să. Această nouă funcție care acționează ca intermediar între BLOB și AOSP este shim-ul. Acest scenariu special în care BLOB nu reușește să găsească funcția pe care o caută este unul dintre cele mai comune în care este nevoie de o lamă.
Poate că lucrurile vor avea un pic mai logic cu un exemplu ipotetic care implică OnePlus 3T. Vom crea un exemplu folosind OxygenOS și camera OnePlus. Dacă folosim camere BLOB luate de la OxygenOS Nougat pentru OnePlus 3T pentru a construi un ROM Nougat bazat pe AOSP, este posibil să întâmpinăm probleme. Acest lucru se datorează faptului că BLOB-urile camerei (care au fost compilate inițial de OEM) vor putea face referire la toate funcțiile de care are nevoie în OxygenOS, dar deoarece ROM-ul AOSP compilat poate să nu aibă acele funcții sau să le fi compilat sub un alt nume (care duce la o nepotrivire între simbolurile funcției), va exista o eroare. Acest lucru poate fi rezolvat prin crearea unei noi funcții în ROM-ul AOSP cu numele pe care BLOB îl așteaptă - shim-ul nostru.
Simbolurile într-un context de programare sunt folosite pentru a se referi la anumite funcții din cod. Simbolurile sunt necesare deoarece poziția unei funcții se poate schimba atunci când codul este editat și astfel pentru a evita codificarea referințe la funcții, compilatorul creează un tabel de simboluri pe care alte funcții le pot folosi pentru a se referi întotdeauna la dreapta funcţie. Când schimbați numele unei funcții înainte de compilare, simbolul acesteia se schimbă și, deci practic orice modificări pe care OEM-ul îl face pe sursa HAL a camerei înainte de compilare va cere dezvoltatorilor să creeze un nou shim.
Explicația pe care am oferit-o până acum face să pară că a crea lamele este ușoară. Schimbarea câtorva nume de funcții aici și acolo nu sună prea greu, nu? Dacă ar fi atât de ușor. Realitatea shims-urilor implică mai mult decât doar redenumiri de funcții. Am vorbit cu dezvoltatorul recunoscut XDA Sultanxda, care a putut să ne ofere un exemplu al uneia dintre cele mai dificile lame la care a lucrat.
Shimming - Nu atât de ușor pe cât pare
Pentru cei care nu sunt familiarizați cu OnePlus 3T, camera frontală a fost mai degrabă spartă inițial ROM-uri personalizate bazate pe AOSP. Pentru început, încercarea de a face orice fotografie de peste 8MP ar avea drept rezultat prăbușindu-se. În încercarea sa de a rezolva această problemă, Sultanxda a făcut mai multe lamele pentru a permite camerei frontale OnePlus 3T să funcționeze corect.
Shim #1 - Schimbarea numelui pachetului camerei
Pentru a opri camera frontală să nu se prăbușească ori de câte ori utilizatorul a făcut o fotografie de peste 8MP, Sultanxda a forțat camera HAL să identifice toate camerele ca fiind camera OnePlus. Acest lucru se face deoarece OnePlus a decis să dedice o funcție de ajutor anumitor aplicații (isOnePlusCamera
, isFacebookCamera
, etc.) din anumite motive. Sultanxda a remediat acest lucru prin reglarea HAL a camerei, astfel încât să indice o nouă funcție care returnează întotdeauna „adevărat” ca și cum utilizatorul ar folosi camera OnePlus – chiar și atunci când nu o sunt.
Shim #2 - Dezactivează QuadraCfa
Pentru următoarea lui shim, a trebuit să dezactiveze QuadraCfa, care este probabil o tehnologie proprie Qualcomm legată de cameră. Spunem probabil pentru că nici eu, nici Sultanxda nu sunt exact ce este QuadraCfa, dar Sultanxda știe că a spart camera frontală ori de câte ori a fost activată.
El a observat că QuadraCfa s-ar activa cumva de la sine, dar nu era sigur de ce sau cum face acest lucru. Rezolvarea acestui lucru a necesitat o modificare destul de neconvențională din partea lui. Într-un shim convențional, funcția shim, atunci când este compilată, furnizează simbolul lipsă pe care BLOB-ul îl caută. În acest caz, BLOB avea deja simbolurile de care avea nevoie - cele care probabil reprezentau funcțiile care porneau QuadraCfa.
Astfel, trebuia să depășească simbolurile folosite de camera HAL și, în esență, să le facă „lipsă”, astfel încât a lui lamele ar furniza acele simboluri „lipsă”. Singura modalitate de a face asta este prin hex editând camera HAL în sine. Editarea hexadecimal este, practic, să caute printr-o grămadă de farfurii neorganizate sub formă de date binare pentru a găsi un ac în carul de fân - fie o funcție, fie un șir pe care doriți să îl editați.
Editarea hexagonală a unei funcții este substanțial mai dificilă decât editarea hexadecimală a unui șir, dar, din fericire, Sultanxda a reușit să evite să fie nevoită să editeze hexadecimal funcțiile din spatele QuadraCfa. editarea hex a numelor simbolurilor pentru a anula aceste simboluri.
Shim #3 - Remedierea accidentului cu lumină strălucitoare
În continuare, Sultanxda a identificat că fotografierea cu camera frontală în condiții de lumină puternică ar cauza blocarea camerei. Pentru a reproduce acest bug pe propriul dispozitiv, Sultanxda de fapt a activat funcția de lanternă a lui OnePlus One și a strălucit lumina în fața camerei frontale a lui OnePlus 3T pentru a se prăbuși și pentru a produce jurnalele utilizabile! Odată ce a descoperit ce funcție a cauzat accidentul, a creat o lamă pentru a forța dispozitivul să folosească modul de lumină scăzută tot timpul pentru camera frontală.
Shim #4 - Imagini cu camera frontală cu rezoluție scăzută
După ce a remediat blocarea luminii strălucitoare cu lama anterioară, Sultanxda a descoperit o altă eroare care a apărut de fapt ca rezultat direct al acelei lame: imagini cu rezoluție joasă a camerei frontale. În loc să faci fotografii la rezoluția cerută de utilizator (de ex. 16MP), fotografia rezultată va fi făcută la 4MP.
Rezolvarea acestui lucru a necesitat ca el să-și schimbe funcțiile handleSuperResolution
și isSuperResolution
pentru a reveni întotdeauna adevărat, dar NUMAI atunci când camera frontală este activă (pentru că altfel, camera s-ar bloca atunci când faceți fotografii de la senzorul din spate).
Lecția învățată - Shimming poate fi greu
Sultanxda admite că lamelele pe care a trebuit să le creeze pentru ca camera frontală OnePlus 3T să funcționeze nu reprezintă exemplul tău tipic de lame. Este destul de mândru de shim-ul său, având în vedere complexitatea sa și necesitatea rară de a edita hex BLOB-ul în sine. Dar acest exemplu arată cât de dificil poate fi să funcționeze hardware-ul camerei pe anumite dispozitive.
Fie ca aventurile voastre ale aparatului foto să fie mai puțin dureroase decât au fost ale mele. -Sultanxda
Jurnale, jurnale și mai multe jurnale. Fără o modalitate consistentă de a reproduce o blocare și fără jurnale, dezvoltatorii au puține speranțe de a găsi sursa problemei. Chiar dacă găsesc ceea ce cauzează problema, nu este întotdeauna o soluție simplă. Întregul proces de găsire și eliminare a acestor erori poate dura zile sau săptămâni și este motivul pentru care repararea camerei pe ROM-urile AOSP este una dintre sarcinile mai dificile.
Dacă dispozitivul dvs. are un ROM AOSP portat cu hardware complet funcțional, sperăm că puteți începe să apreciați lupta prin care ar fi putut trece acei dezvoltatori pentru a vă aduce pe acelea Caracteristici. Apreciază-i pentru munca lor, pentru că nu este ușor. Este multă muncă pe care marea majoritate a utilizatorilor nici nu o vor observa, deoarece dezvoltatorii talentați de pe forumurile noastre se ocupă de multele părți nevăzute ale Android.
Dorim să îi mulțumim în mod special lui Sultanxda pentru numeroasele contribuții pe care le-a sugerat în realizarea acestui articol.