Caméras dans des ROM personnalisées: comment les développeurs font fonctionner le matériel sans code source

Sans code source, comment les développeurs peuvent-ils faire fonctionner des composants matériels tels que des caméras dans des ROM personnalisées? La réponse est un BLOB, une cale et beaucoup de débogage.

Avec la sortie d'Android Oreo et de nombreux appareils tels que le Xiaomi Redmi Note 3, Google Nexus 5 et d'autres le reçoivent officieusement, il est probablement juste de se demander pourquoi les mêmes fonctionnalités (principalement l'appareil photo) ont tendance à être interrompues lorsque les développeurs portent une ROM basée sur le projet Android Open Source (AOSP). Vous avez probablement vu des fils de discussion de ROM sur le forum XDA avec une longue liste de fonctionnalités défectueuses en haut. « Qu'est-ce qui fonctionne » suivi d'une liste de fonctionnalités fonctionnelles, puis en dessous de l'emblématique « Qu'est-ce qui ne fonctionne pas? À vous de me dire!" sont deux refrains populaires sur nos forums qui sont pratiquement devenus des mèmes sur des sites comme Reddit et Twitter.

Pourquoi tant de fonctionnalités sont-elles interrompues chaque fois qu'un développeur tente de porter une ROM AOSP sur son appareil? La réponse de base est que, comme les fonctions changent selon les différentes versions d'Android, les anciens pilotes de périphériques conditionnés sous forme de BLOB ne fonctionneront pas avec les versions plus récentes d'Android, ni même uniquement avec l'AOSP d'origine. Pour surmonter ce problème, les développeurs utilisent ce qu’on appelle une « cale », mais le processus impliqué est délicat, prend beaucoup de temps et est parfois très difficile à déboguer.

Dans cet article, nous expliquerons le fonctionnement des cales, notamment en ce qui concerne le bon fonctionnement de la caméra sur les ROM basées sur AOSP. Nous utiliserons le OnePlus 3T comme exemple. Notez que la difficulté liée au fonctionnement de ces fonctionnalités est très spécifique à l’appareil.

OnePlus 3T exécutant OxygenOS. Bien que les téléphones OnePlus soient connus pour leur facilité de développement personnalisé, les développeurs effectuent beaucoup de travail en coulisses pour créer des ports stables d'AOSP.


Qu'est-ce qu'une cale ou un BLOB ?

Pour ne serait-ce que commencer à comprendre une partie de ce que font les développeurs, nous devons d’abord expliquer quelques choses. Bien que le système d’exploitation Android soit open source (on l’appelle Android Open Source Project pour une bonne raison), le logiciel (sans le noyau) fourni sur des milliers d’appareils Android ne l’est pas. Les développeurs n'ont pas accès au code source de Expérience Samsung, EMUI, OxygèneOS, ou l’une des autres versions tierces d’Android.

Désormais, les développeurs qui portent AOSP sur un appareil autre que Google ne se soucient probablement pas du code source de ces skins Android, car ils ne le seront pas. modifier et construire ces ROM. Ce serait vrai, sans une très grande raison: les pièces nécessaires au bon fonctionnement de l'appareil photo, principalement le caméra HAL (Couche d'abstraction matérielle), sont source également fermée.

Le problème d'avoir non seulement la caméra HAL mais aussi la ROM fermée est que les développeurs travaillant sur le portage d'AOSP sur leur appareil seront travailler à l'aveugle. La ROM OEM à source fermée est capable de s'interfacer très bien avec la caméra HAL car l'OEM a accès à la source HAL de la caméra. Le HAL de la caméra est ce qui permet à la ROM de « communiquer » avec le matériel de la caméra. Sans lui, la caméra ne fonctionnerait pas. Considérez la caméra HAL comme le volant et les pédales de la voiture. Le volant/pédales permettent de contrôler les composants internes du véhicule en fournissant une interface externe permettant au conducteur (la ROM) d'utiliser les composants internes.

Graphique montrant l'architecture de la caméra. Source: Google

À mesure que le matériel photo devient de plus en plus complexe (le avènement des doubles caméras, par exemple), avoir accès à la source HAL de la caméra rendrait le portage d'une ROM AOSP avec une caméra fonctionnelle beaucoup plus facile.

Cependant, les constructeurs OEM ne donnent pas accès à la source HAL de la caméra pour diverses raisons. Premièrement, s’ils ne disposent pas de tous les droits de propriété sur la caméra HAL (par exemple lorsqu’ils intègrent la propriété intellectuelle d’autres sociétés), ils ne peuvent pas distribuer la source. Deuxièmement, la diffusion de la source HAL de la caméra peut mettre en péril leur propre propriété intellectuelle. Enfin, les entreprises n'ont aucune obligation légale de fournir ce code source (contrairement au code source du noyau qu'elles fournissent). obligé de publier sous GPL), ils ne sont donc pas incités à le publier. Alors, sans accès à la source HAL de la caméra, comment les développeurs font-ils exactement pour que la caméra fonctionne sur les ROM AOSP? La réponse est un BLOB, une cale et beaucoup de débogage.

Un dispositif GOUTTE (Binary Large OBject) contient des binaires préemballés qui sont la forme compilée du logiciel. Dans ce cas, la source HAL de la caméra est compilée par l’OEM et expédiée sur les appareils sous forme de binaires. Lorsque les développeurs parlent de BLOB, ils font référence aux binaires livrés sur des appareils en direct et qu'ils sont capables d'extraire. Désormais, le sujet des « BLOBs de caméra » a OnePlus a longtemps tourmenté depuis de nombreux mois, mais la vérité est que les développeurs ont toujours eu accès aux BLOB des caméras. Le Le code source de la caméra HAL est le ticket d'or pour les développeurs ici, cependant, mais ce sera ne jamais être libéré en raison du risque juridique que cela entraînerait pour des entreprises comme OnePlus.

Ainsi, les développeurs cherchant à intégrer AOSP sur un appareil se retrouvent uniquement avec des BLOB de la caméra HAL pour lesquels ils n'ont pas accès au code source. Il est rare, voire jamais, qu'un développeur puisse associer son code ROM AOSP avec la caméra HAL BLOB et s'attendre à ce qu'il fonctionne. Ainsi, afin de combler le fossé entre les deux, les développeurs créent ce qu'on appelle un "cale.”

« Caler », c'est « coincer (quelque chose) ou remplir un espace ». C'est effectivement ce que fait un développeur lorsque écrire un shim: ils ajoutent du code pour permettre au BLOB de s'interfacer avec le code source AOSP sur lequel ils travaillent avec. Les cales sont utilisées pour faire fonctionner des BLOB de toutes sortes avec AOSP, mais généralement, c'est le BLOB de la caméra qui nécessite le plus de cales. Comme nous l'avons mentionné précédemment, le shimming est requis non seulement pour le portage de versions plus récentes d'Android sur un appareil (comme toutes ces ROM Android Oreo non officielles), mais également nécessaire lors du portage de l'AOSP de la même version d'Android sur celle-ci appareil.

Lecture recommandée: Du magasin à l'étagère: une capitulation détaillée des raisons pour lesquelles les appareils MSM8974 sont exclus de Nougat

Le OnePlus 2, par exemple, a reçu son dernière mise à jour majeure officielle du système d'exploitation sous la forme d’Android 6.0 Marshmallow. L'appareil, cependant, a en réalité ROM personnalisées entièrement fonctionnelles basées sur AOSP basé sur Android Nougat, et cela grâce au travail acharné des développeurs et de leurs cales. Nous allons détailler quelques exemples de cales, mais d’abord, nous devons parler du fonctionnement exact des cales.


Comment fonctionne le calage ?

Étant donné que les développeurs n’ont pas accès à la source HAL de la caméra ou à la ROM OEM (et uniquement aux binaires précompilés), ils ne peuvent pas savoir quelles fonctions attend la caméra HAL. Pour cette raison, il y a souvent une différence entre le nom de la fonction recherchée par la caméra HAL et le nom réel de la fonction dans le code AOSP avec lequel le développeur travaille.

Pour résoudre ce problème, le développeur crée simplement une nouvelle fonction qui utilise le même nom que le fonction attendue par la caméra HAL BLOB, mais cette nouvelle fonction exécute simplement ce que le développeur veut à. Cette nouvelle fonction qui fait office d’intermédiaire entre le BLOB et l’AOSP est le shim. Ce scénario particulier dans lequel le BLOB ne parvient pas à trouver la fonction qu'il recherche est l'un des cas les plus courants où une cale est nécessaire.

Schéma de peinture MS très simple montrant où une cale est nécessaire.

Peut-être que les choses auront un peu plus de sens avec un exemple hypothétique impliquant le OnePlus 3T. Nous allons créer un exemple utilisant OxygenOS et la caméra OnePlus. Si nous utilisons des BLOB de caméra extraits d'OxygenOS Nougat pour le OnePlus 3T afin de créer une ROM Nougat basée sur AOSP, nous pourrions rencontrer des problèmes. En effet, les BLOB de la caméra (qui ont été initialement compilés par l'OEM) pourront référencer toutes les fonctions dont ils ont besoin dans OxygenOS, mais puisque le La ROM AOSP compilée peut ne pas avoir ces fonctions ou les avoir compilées sous un nom différent (entraînant ainsi une inadéquation entre les symboles de fonction), il y aura un erreur. Cela peut être résolu en créant une nouvelle fonction dans la ROM AOSP avec le nom attendu par le BLOB: notre cale.

Les symboles dans un contexte de programmation sont utilisés pour faire référence à des fonctions spécifiques dans le code. Les symboles sont nécessaires car la position d'une fonction peut changer lorsque le code est édité, et donc afin d'éviter le codage en dur références aux fonctions, le compilateur crée une table de symboles que d'autres fonctions peuvent utiliser pour toujours faire référence à la bonne fonction. Lorsque vous changez le nom d'une fonction avant la compilation, son symbole change également, donc pratiquement tout changement que l'OEM apporte à la source HAL de la caméra avant la compilation obligera les développeurs à créer un nouveau cale.

Affichage d'une table de symboles avec Hopper. Source: Priorité

L’explication que nous avons proposée jusqu’à présent donne l’impression que créer des cales est facile. Changer quelques noms de fonctions ici et là ne semble pas trop difficile, n'est-ce pas? Si seulement c'était aussi simple. La réalité des cales implique bien plus que de simples renommages de fonctions. Nous avons parlé avec Sultanxda, développeur reconnu par XDA, qui a pu nous fournir un exemple de l'une des cales les plus difficiles sur lesquelles il a travaillé.


Calage – Pas aussi simple qu’il y paraît

Pour ceux qui ne connaissent pas le OnePlus 3T, la caméra frontale était plutôt cassée au départ. ROM personnalisées basées sur AOSP. Pour commencer, tenter de prendre une photo de plus de 8MP entraînerait s'écraser. Dans sa tentative de résoudre ce problème, Sultanxda a fait plusieurs cales pour permettre à la caméra frontale OnePlus 3T de fonctionner correctement.

Cale n°1 - Modification du nom du package de la caméra

Afin d'empêcher la caméra frontale de planter chaque fois que l'utilisateur prend une photo supérieure à 8MP, Sultanxda a forcé la caméra HAL à identifier toutes les caméras comme étant la caméra OnePlus. Ceci est dû au fait que OnePlus a décidé de dédier une fonction d'assistance à certaines applications (isOnePlusCamera, isFacebookCamera, etc.) pour une raison quelconque. Sultanxda a résolu ce problème en calant la caméra HAL afin qu'elle pointe vers une nouvelle fonction qui renvoie toujours « vrai » comme si l'utilisateur utilisait la caméra OnePlus, même s'il ne l'utilisait pas.

Cale n°2 - Désactiver QuadraCfa

Pour sa prochaine cale, il a dû désactiver QuadraCfa, qui est vraisemblablement une technologie propriétaire Qualcomm relative à la caméra. Nous disons probablement parce que ni moi ni Sultanxda ne sommes exactement sûrs de ce qu'est QuadraCfa, mais Sultanxda sait qu'il a cassé la caméra frontale chaque fois qu'elle était activée.

Il a observé que QuadraCfa se permettrait d’une manière ou d’une autre, mais il ne savait pas vraiment pourquoi ni comment il le faisait. Résoudre ce problème a nécessité une modification plutôt non conventionnelle de sa part. Dans un shim conventionnel, la fonction shim, une fois compilée, fournit le symbole manquant recherché par le BLOB. Dans ce cas, le BLOB possédait déjà les symboles dont il avait besoin, ceux qui représentaient vraisemblablement les fonctions qui démarraient QuadraCfa.

Bénissez l'éditeur hexadécimal. Le programme utilisé par Sultanxda.

Ainsi, il devait remplacer les symboles utilisés par la caméra HAL et, essentiellement, les rendre « manquants » son des cales fourniraient ces symboles « manquants ». La seule façon de le faire est via édition hexadécimale de la caméra HAL elle-même. L'édition hexadécimale consiste essentiellement à examiner un tas de charabia non organisé sous forme de données binaires afin de trouver une aiguille dans la botte de foin, soit une fonction, soit une chaîne que vous souhaitez modifier.

L'édition hexadécimale d'une fonction est nettement plus difficile que l'édition hexadécimale d'une chaîne, mais heureusement, Sultanxda a pu éviter d'avoir à éditer hexadécimalement les fonctions derrière QuadraCfa en remplaçant édition hexadécimale des noms de symboles pour annuler ces symboles.

Cale n°3 – Correction d'un crash de lumière vive

Ensuite, Sultanxda a identifié que prendre une photo avec la caméra frontale dans des conditions d'éclairage intense entraînerait le crash de la caméra. Afin de reproduire ce bug sur son propre appareil, Sultanxda a en fait a activé la fonction lampe de poche de son OnePlus One et a allumé la lumière devant la caméra frontale du OnePlus 3T afin de le faire planter et produire des logs utilisables! Une fois qu'il a découvert quelle fonction était à l'origine du crash, il a créé une cale pour forcer l'appareil à utiliser en permanence le mode faible luminosité pour la caméra frontale.

Cale n°4 – Images de la caméra frontale basse résolution

Après avoir corrigé le crash de lumière vive avec la cale précédente, Sultanxda a découvert un autre bug qui résultait en fait directement de cette cale: des images de caméra frontale basse résolution. Plutôt que de prendre des photos à la résolution demandée par l'utilisateur (par ex. 16MP), la photo résultante serait prise à 4MP.

Pour résoudre ce problème, il lui fallait caler les fonctions handleSuperResolution et isSuperResolution pour toujours renvoyer vrai, mais UNIQUEMENT lorsque la caméra frontale est active (car sinon, la caméra planterait lors de la prise de photos à partir du capteur arrière).


Leçon apprise - Le calage peut être difficile

Sultanxda admet que les cales qu'il a dû créer pour faire fonctionner la caméra frontale OnePlus 3T ne représentent pas votre exemple typique de cale. Il est plutôt fier de sa cale étant donné sa complexité et la rare nécessité de modifier le BLOB lui-même. Mais cet exemple montre à quel point il peut être difficile de faire fonctionner le matériel de la caméra sur certains appareils.

Que vos aventures avec les cales d'appareil photo soient moins douloureuses que les miennes. -Sultanxda

Journaux, journaux et encore journaux. Sans moyen cohérent de reproduire un crash et sans journaux, les développeurs ont peu d'espoir de trouver la source du problème. Même s’ils trouvent la cause du problème, la solution n’est pas toujours simple. L'ensemble du processus de recherche et d'élimination de ces bogues peut prendre des jours, voire des semaines, et c'est la raison pour laquelle réparer la caméra sur les ROM AOSP est l'une des tâches les plus difficiles.

Si votre appareil dispose d'une ROM AOSP portée avec un matériel entièrement fonctionnel, nous espérons que vous pourrez commencer à apprécier la lutte que ces développeurs ont pu mener pour vous proposer ces caractéristiques. Appréciez-les pour leur travail, car ce n’est pas facile. C'est beaucoup de travail que la grande majorité des utilisateurs ne remarqueront même pas, car les développeurs talentueux de nos forums s'occupent des nombreuses parties invisibles d'Android.

Nous tenons à remercier tout particulièrement Sultanxda pour les nombreuses contributions qu'il a suggérées dans la rédaction de cet article.