Un téléphone intelligent sans service Google ou Apple

Maintenant que Windows Phone pour le grand public est mort – au moins à un horizon décidable – et que les projets ubuntu phone  et firefox os sont abandonnés, on se retrouve avec deux acteurs sur le marché des systèmes d’exploitation pour téléphone intelligent : Google avec Android et Apple avec iOS.

Apple développe des systèmes notoirement fermés, et rien que le fait qu’ils ont été les premiers promoteurs de ce système de spoliation des développeurs par le paiement de royalties sur la vente de logiciels sur la plateforme m’interdit d’utiliser leurs outils.

Google de son côté gagne de l’argent avec Android de deux manières : la même spoliation des développeurs par le paiement de royalties, bien que ce soit plus facile à contourner, et l’utilisation quasiment obligatoire de ses services sur les téléphones. Comme je l’ai déjà abordé, la gratuité de ces services n’est qu’apparente, Google se payant de la connaissance qu’il acquière de vous, tout comme Facebook, ce qui pose de très nombreux problèmes de libertés individuelles et publiques.

Alors en attendant des projets comme eelo ou le librem 5, qui ne seront là au mieux que dans 1 an, est-il possible d’avoir un téléphone intelligent utilisable sans être enfermé dans l’écosystème fermé de Apple ou livrer toutes ses données à Google ? Voici mon expérience.

Quel système d’exploitation ?

Comme les diverses alternatives aux deux gros ont été abandonnées ou ne sont pas encore à l’état de production, on se retrouve obligé de composer avec iOS ou Android. L’écosystème d’Apple est complètement fermé, et il n’y a aucun moyen de l’ouvrir ; à l’opposé, le code source d’Android est publié sous licence Apache à chaque sortie de version dans le projet AOSP (Android Open Source Project). On pourrait croire que cela implique qu’il soit facile d’installer sa propre version d’Android sur n’importe quel téléphone, mais la réalité est plus complexe : chaque constructeur de téléphone intelligent adapte Android à sa sauce pour coller à sa plateforme matérielle. D’une part, comme pour un PC, vous devez avoir les drivers de tous les composants, et ceux-ci ne sont pas toujours open source. Par ailleurs, plus un objet électronique a de contraintes fonctionnelles – taille, mobilité – plus il est difficile de respecter une architecture matérielle standard : les ordinateurs portables ont toujours posé des problèmes aux projets open source comme Linux, et les téléphones intelligents sont encore plus contraints. Enfin, les fabricants de téléphone sont pour la plupart des entreprises d’électronique grand public, et autant le monde du PC a toujours eu comme vertu cardinale la compatibilité – grosso modo, il n’y a eu que 5 architectures principales dans le monde du PC en 35 ans, IBM PC, XT, AT, ATX et BTX, cette dernière n’ayant pas encore totalement remplacé ATX – autant les fabricants d’électronique grand public sont habitués à faire leurs « petites bidouilles » sans trop se préoccuper de standards matériels ; pour avoir travaillé dans des projets où des PC discutaient avec des cartes électroniques, quand on est habitué aux API haut niveau bien standardisées, ça surprend.

De nombreuses équipes de développeurs bénévoles s’astreignent donc à la tâche ingrate d’extraire les drivers et les spécificités de chaque téléphone intelligent pour ensuite les combiner avec AOSP pour livrer un système plus ouvert que l’Android avec surcouche du fabricant. On pourra citer LineageOS, a priori le plus connu, OmniROM, AOKP. Chacun de ces projets publient ce qu’on appelle des ROM, pour Read Only Memory, ou mémoire morte en français, terme employé généralement pour le logiciel des cartouches de jeux vidéos dans les émulateurs et employé ici au sens de système d’exploitation complet, drivers compris, une ROM par modèle de téléphone et par version d’Android. Toutes les équipes ne sortent pas des ROM pour tous les modèles de téléphone ; certains accessoires ne fonctionnent pas dans les premières versions des ROM – par exemple, le lecteur d’empreinte digitale de mon téléphone ne fonctionne pas encore ; certains modèles de téléphone n’ont pas de ROM supportant suffisamment les accessoires du téléphone pour être exploitables.

Pour mon expérience, n’ayant pas encore de téléphone Android, j’ai pu me permettre d’en choisir un qui soit connu pour être facilement pris en charge par les ROM personnalisées. Après quelques recherches, j’ai jeté mon dévolu sur le OnePlus 5T ; OnePlus est une des marques proposant les ROM officielles surchargeant le moins Android, ils publient les drivers afin de faciliter le travail, ils n’annulent pas la garantie constructeur pour installation d’une ROM personnalisée, et même cerise sur le gâteau, ils disent que le service client peut vous aider à récupérer un téléphone inutilisable suite à un tripatouillage mal maîtrisé. Et ce qui ne gâche rien, les spécifications techniques sont de haute volée : 128Go de mémoire de stockage, 8Go de RAM, 8 coeurs à 2.45Ghz, écran AMOLED 6 pouces 1080P, deux capteurs photo arrière 16 et 20 Mégapixels, un capteur photo avant 16 Mégapixels, vidéo 4K, le tout pour à peu près la moitié du prix de chez Samsung ou Apple, encore moins en occasion récente. Le téléphone reçu, on met les mains dans la cambouis ; personnellement, j’ai choisi OmniROM car c’était au moment de mon installation la seule ROM en Android 8.1 pour le OnePlus 5T.

Installation du système d’exploitation

Je ne vais pas rédiger un tutoriel d’installation complet, d’autres l’ont déjà fait bien mieux que je n’en serais capable. Un bon point de départ pour tout ce qui touche à l’installation et la maintenance des ROM est le site XDA developers qui a des forums par modèle, et des articles de présentation de très bonne qualité. Je vais juste résumer les différentes étapes pour donner une idée du niveau de complexité et de risque de l’opération :

  • sauvegarder toutes les données du téléphone avant de faire l’installation ; Android chiffre les données du téléphone, et l’installation du système d’exploitation doit tout effacer sinon une partie du stockage sera inaccessible. Moi, je n’avais pas le problème puisque le téléphone était vide
  • débloquer l’équivalent du BIOS – le bootloader ; pour cela, il faut télécharger les outils de développement Android, passer le téléphone en mode développeur, redémarrer le téléphone avec l’équivalent des options BIOS sous PC, le connecter en USB à son ordinateur, et lancer en ligne de commande des outils fournis avec les outils de développement Android. Par la suite, quand votre téléphone démarrera, il vous avertira que le processus de démarrage est débloqué et que c’est très dangereux !
  • installer TWRP qui est une application de démarrage contournant le système d’exploitation standard, un peu comme une clé USB ou un CD sur lequel on démarre avec un PC à la place du système d’exploitation installé. Android ne permet pas d’installer un système personnalisé depuis le système standard.
  • envoyer sur le téléphone la ROM choisie par transfert USB en dehors des partitions de données des applications
  • une fois TWRP installé, démarrer le téléphone avec, effacer les partitions de données – là, si vous n’avez pas sauvegardé, tant pis pour vous ! – redémarrez avec TWRP, et utilisez TWRP pour installer la ROM. C’est là où j’ai souffert, car au redémarrage juste après l’effacement, le système d’exploitation qui était toujours là reprenait la main et chiffrait à nouveau la partition de données. Il m’a fallu éteindre comme un bourrin le téléphone avant que le système ne prenne la main, pour forcer le redémarrage sur TWRP depuis les outils Android

Vous y êtes, au démarrage suivant, vous devez voir l’écran OmniROM.

Attention ! Quand vous installez une ROM personnalisée, en général, on vous dit d’installer d’une part la ROM, et d’autre part les « GApps » depuis le site OpenGApps. Si vous voulez être libéré de Google, n’installez surtout pas les GApps, qui contiennent tous les services Google, n’installez que la ROM que vous avez choisie.

Les habits neufs de votre téléphone

Je ne vous cacherai pas qu’à cet instant de l’expérience, votre téléphone va vous sembler un peu tout nu. Vous aurez les applications suivantes, fournies par OmniROM :

  • téléphone (si si, je vous jure, on peut téléphoner)
  • SMS / MMS
  • Chromium (version open source du navigateur web de Google)
  • Calculatrice
  • Agenda (mais sans compte Google on ne peut rien en faire…)
  • Paramètres
  • Appareil photo (de base de chez de base)
  • Contacts (marche en local, pas besoin de compte Google)
  • E-mail (vraiment pas top)
  • Egaliseur
  • Fichiers
  • Galerie (pour parcourir les photos et les vidéos)
  • OmniSwitch (pour changer d’application facilement, chouette outil)
  • Phonograph (lecteur audio, je ne l’ai pas essayé)
  • Search (qui lance Google !)

Et c’est tout. En particulier, vous n’aurez pas de magasin d’application. J’ai donc commencé par installer trois magasins d’application :

  • F-Droid qui ne contient que des applications open source (même si parfois elles s’appuient sur des services moyennement ouverts, auquel cas c’est indiqué clairement)
  • Aptoide
  • Uptodown

Avec ces deux derniers, vous aurez à peu près toutes les applications gratuites. Vous devrez autoriser toutes ces applications à installer des logiciels sur votre téléphone, c’est un peu casse-pieds mais ça ne se fait qu’une fois.

Une fois des magasins installés, vous pouvez partir à la chasse aux applications ; personnellement, j’ai installé :

  • Firefox avec recherche via Qwant
  • VLC (lecteur vidéo qui lit tout ce que vous pouvez imaginer, et plus encore)
  • un scanner de QR Code
  • AnySoft Keyboard pour remplacer le clavier de base que je ne trouve pas terrible
  • Authenticator pour sécuriser en deux facteurs (remplacement de Google Authenticator)
  • ConnectBot pour faire du SSH
  • Document Viewer pour lire les PDF et EPub
  • Mastalab pour accéder à Mastodon
  • Open Camera qui remplace avantageusement l’appareil photo d’OmniROM
  • PasswdSafe pour gérer les mots de passe (je synchronise mon fichier de mots de passe entre mes machines avec owncloud, voir ci-dessous)
  • SquareHome 2 comme écran d’accueil, pour retrouver l’interface de Windows Phone que j’aimais bien
  • Spotify
  • RD Client pour accéder en terminal server à des machines Windows
  • Ring pour des communications chiffrées de bout en bout en peer to peer, si vous voulez vous assurer que vos communications voix ne soient pas interceptées
  • Quelques autres sur lesquelles je vais revenir plus en détails

Google a longtemps misé sur la qualité de ses services pour les imposer auprès des utilisateurs, ce qui me semble être une façon de faire plutôt saine ; depuis quelque temps, ils ont ajouté une corde à leur arc, qui est que certaines fonctionnalités du téléphone, comme les notifications, ne marchent que si les GApps sont installés. Du coup, pas de notifications pour moi, et certaines applications refusent de s’installer ; la seule que j’ai rencontrée est celle de la chaîne météo, mais comme j’évite au maximum les applications mangeuses de données personnelles, j’en ai sans doute raté pas mal.

Et les services tiers ?

Les applications que j’ai omises ont pour point commun de s’appuyer sur des services tiers, qu’il s’agit de remplacer par des services plus respectueux de la vie privée.

Cartographie

Exit Google Maps, que peut-on utiliser d’autre ? Une alternative ouverte existe, dont j’ai déjà parlé dans mon article de l’année dernière, OpenStreetMap. Plusieurs applications utilisent les données d’OpenStreetMap pour offrir des services de cartographie sous Android, j’ai personnellement choisi OsmAnd~ qui permet de télécharger les cartes en local sur le téléphone afin d’avoir des cartes hors ligne – 1.8Go pour la carte générale monde et la carte routière française. Je lui ai adjoint AddressToGPS qui fournit un proxy vers les services de géocodage de Google pour les adresses inconnues d’OpenStreetMap, afin que Google ne puisse pas journaliser vos appels. Non seulement OsmAnd~ vous libère du pistage de Google, mais en plus il vous apporte la fonctionnalité hors ligne ; OsmAnd~ est utilisable y compris sur les téléphones non libérés.

Courrier électronique

Pour mon courrier personnel, j’utilise depuis fin 1997 un compte Yahoo ! Mail. Evidemment, Yahoo ! n’étant pas une société philanthropique, et gérer un service de courrier électronique étant coûteux – en particulier pour s’opposer aux spams – Yahoo ! a forcément gagné de l’argent d’une façon ou d’une autre en me fournissant ce service. Or, seule la connaissance du contenu de mes communications,  le profil de moi que l’on peut en retirer pour me cibler, ne peuvent avoir une valeur ; c’est d’ailleurs explicite à l’article 15 de leurs CGU. On y découvre également que Yahoo ! peut transmettre vos données sur demande gouvernementale ; malgré les lois sécuritaires votées en France, nous ne sommes pas encore en Chine communiste, mais tant qu’à faire, je préférerais que mes conversations privées restent privées, sans compter que le FBI et la NSA surveillent les courriels Yahoo !.

Pour ce faire, il est possible de faire tourner son propre service de courrier électronique, mais d’une part, c’est coûteux en ressources systèmes, et d’autre part, ça prend un temps fou pour maintenir un bon fonctionnement du système. Sans compter que sécuriser ses courriels correctement est loin d’être simple.

Heureusement, des services existent qui fournissent des courriels sécurisés :

  • LavaMail : rendu célèbre par son utilisation par Edward Snowden, puis par sa fermeture abrupte à laquelle s’est résigné le fondateur de LavaMail quand le FBI lui a demandé de compromettre la sécurité de la plateforme, LavaMail a récemment ressuscité tel le Phénix, offrant 5Go de stockage pour 30$ par an
  • ProtonMail : développé au CERN, là où internet est né, et hébergé en Suisse qui actuellement a des lois sur l’hébergement de données semblables à celles que nous avions en France avant les lois Cazeneuve, c’est-à-dire très protectrices pour les données personnelles. Une offre gratuite de 500Mo de stockage est complétée par plusieurs offres payantes (4€ / mois pour 5Go et un domaine personnalisé, 6,25€ / mois pour 5Go et un domaine personnalisé partageable avec plusieurs utilisateurs)

Le prix peut sembler a priori élevé, mais il se justifie tout à fait :

  • d’après nos statistiques sur les domaines que nous gérons, 92 % des courriels reçus sont des spams. Et trier les spams des courriels légitimes, ça demande de grosses capacités de calcul
  • les courriels sont chiffrés de bout en bout (si tant est que le deuxième bout est sur le même service) ; le principe est le suivant : chaque utilisateur a une clé de chiffrage asymétrique, et chiffre les courriels reçus avec sa clé publique. Du coup, seul lui peut les relire avec sa clé privée. Or, le chiffrage asymétrique sur de gros volumes de données, comme un courriel à pièces jointes, est très coûteux en temps de calcul, raison pour laquelle on le limite habituellement à transmettre des secrets partagés de petite taille (quelques centaines d’octets)

Le prix résultant de ces contraintes est d’environ 50 % plus élevé que pour un service de courriel professionnel standard comme Exchange Online. Le prix du respect de la correspondance privée…

J’ai choisi ProtonMail en version payante pour bénéficier du domaine personnalisé. ProtonMail a un client web et des applications pour Android et iOS ; l’application Android a besoin des GApps pour les notifications, donc pas de notifications pour moi, mais à part ça tout marche très bien. Par ailleurs, vous pouvez maintenant sous Windows utiliser ProtonMail avec un client classique comme Thunderbird ou Outlook avec le ProtonMail Bridge ; c’est un logiciel qui fournit un service IMAP et SMTP local qui effectue les opérations de chiffrement et de déchiffrement nécessaires pour converser avec les serveurs de ProtonMail.

Il a également fallu modifier mon adresse partout où elle était utilisée, ce qui n’est pas une mince affaire, et j’ai également récupéré mon historique de courriels stocké chez Yahoo !. Pour ce faire, j’ai utilisé un outil en ligne de commandes nommé imapsync, qui lit vos courriels sur une source IMAP et le transfère vers une destination IMAP, en collaboration avec le ProtonMail bridge. Pour un historique depuis fin 1997, de l’ordre de 2Go de courriels, c’est trèèèèèèèèès long, mais ça fonctionne. La seule chose à savoir est que les dossiers personnalisés de ProtonMail sont stockés sous le nom Folders/[NomDossier], y compris quand on le crée sous le nom [NomDossier] ; du coup, on est obligé d’utiliser l’option –f1f2 pour forcer le nom du dossier de destination, car imapsync croit créer le dossier [NomDossier] et ne le retrouve pas ensuite. Par ailleurs, je n’ai pas réussi à utiliser des dossiers avec des espaces dans les noms, mais il suffit de les renommer avant le transfert.

Stockage distant

Il est très pratique de retrouver ses fichiers où que l’on se déplace, ainsi que de synchroniser automatiquement les photos et vidéos prises sur son téléphone vers un système de stockage « dans le cloud ». Malheureusement, par défaut, sous Android, tout part dans Google Drive, ou tout autre service équivalent, DropBox, OneDrive, etc. Depuis quelques années, j’utilise deux NAS Synology dans deux emplacements physiques distincts afin de conserver mes fichiers et ceux de ma famille, synchronisés entre eux. Synology offre un outil nommé « Synology Cloud Station » pour se créer son stockage en ligne personnel, mais il est peu configurable et synchronise par défaut tout le contenu des dossiers sur la machine locale, ce qui est gênant sur des dispositifs avec peu de mémoire comme un téléphone.

J’ai donc choisi d’installer owncloud sur un de mes NAS. Pour des raisons d’optimisation, je n’ai pas utilisé la méthode la plus simple, à savoir installer Apache et MySQL, j’ai préféré utiliser le serveur web et la base de données par défaut du Synology, soit nginx et postgresql. Une fois les difficultés d’installation dues à ce choix passées, l’outil est très agréable à utiliser, l’installation et la configuration des applications sur Android et Windows sont très simples, et l’envoi automatique des photos et vidéos vers les disques marche parfaitement. Et 2To de stockage personnel gratuit ! Enfin, sans abonnement, car si vous voulez vous assurer des sauvegardes correctes, le montage en synchronisation et l’achat de deux NAS revient à quelques centaines d’euros et quelques heures de jeu pour configurer le tout.

Autres migrations

Le transfert de documents est évidemment assez facile, quoique pour un utilisateur de Windows Phone, le fait que le câble USB n’ait qu’une fonctionnalité à la fois – transférer, déboguer ou recharger – est un peu étonnant. Pour les SMS et MMS, j’ai utilisé la fonctionnalité d’export en XML des SMS de Windows Phone, une transformation XSLT, puis l’outil d’import d’Android, puisque les formats XML ne sont pas les mêmes.

Conclusion

Pour quelqu’un qui n’avait jamais fait ça, mais qui sait se débrouiller avec un ordinateur, avec un téléphone réputé pour sa facilité de déblocage, monter un téléphone libéré et les services correspondants m’a pris environ 5 jours de travail, en comptant la synchronisation des deux NAS. Les coûts additionnels sont de quelques centaines d’euros pour les NAS, et 75€ par an pour les courriels – mais si vous pouvez vous limiter à conserver 500Mo de courriels, vous pouvez avoir un service de courriel sécurisé gratuit.

Vous ne devenez pas indétectable pour autant, puisque vous restez reconnu par votre carte SIM, que les IMSI catcher marchent toujours et que les trous de sécurité dans les algorithmes GSM sont toujours là, mais on ne peut pas faire beaucoup mieux sans avoir à monter un réseau mondial de communication personnel.

Enfin, on ne va pas se prendre pour Jean Moulin en 1943, mais à voir les dizaines de messages que j’ai reçus de Google pendant la procédure – littéralement : entre activer la localisation de 4 ou 5 manières différentes à chaque redémarrage, ne faites pas ci ou pas ça c’est dangereux, votre téléphone n’a pas toutes les applications Google envoyé deux ou trois fois sur toutes mes adresses de contact – le fait que Google a déréférencé sans explications ProtonMail pendant 9 mois, ou que ProtonMail a subi une attaque d’une ampleur peu commune qui fait penser à un Etat ou une entité de taille comparable, on se dit qu’avec ses petites bidouilles sur son téléphone, on insère un tout petit coin dans un modèle qui, bien que n’ayant même pas l’âge légal pour boire de l’alcool, a créé la structure d’un possible Etat de surveillance généralisé.

Analyser les erreurs

Comme tout ce qui n’est pas testé ne fonctionne pas, tout développeur a forcément des erreurs à corriger dans son code ; je laisse la démonstration de cette assertion au lecteur. D’après mon expérience, la capacité à bien utiliser les outils à sa disposition pour analyser les erreurs dans son programme est un des facteurs ayant le plus d’impact sur la rapidité des développeurs à livrer une application opérationnelle, d’autant plus pour les applications webs qui sont constituées de nombreuses couches de code interagissant les unes avec les autres. Sans prétendre à l’exhaustivité, cet article va vous donner les quelques pistes à explorer pour accélérer le processus d’analyse.

RTFL! (Read the Fucking Logs!)

De très nombreuses bibliothèques, frameworks et autres environnements d’exécution comme les navigateurs internet ou les machines virtuelles – et même les systèmes d’exploitation eux-mêmes – ont la politesse de créer des journaux dans lesquels on peut trouver des informations sur l’exécution des programmes. Rien n’est plus exaspérant pour un référent technique comme moi que de voir arriver un développeur coincé, de lui demander « que vois-tu dans les logs ? » et de s’entendre répondre « je ne sais pas, je n’ai pas regardé… ». Voici une liste de journaux utiles.

Notre framework utilise log4net de l’Apache Software Foundation pour journaliser ses opérations ; par exemple, en mode ERROR, toutes les requêtes SQL provoquant une exception sont écrites dans le journal, et en mode DEBUG, toutes les requêtes y sont écrites. Si vous souhaitez ajouter une journalisation à vos programmes, je vous conseille log4net et ses équivalents sur d’autres plateformes, l’ancêtre log4j, log4php, etc. qui sont peu invasifs, performants, flexibles et possèdent de nombreuses méthodes d’écriture (fichier, journal d’évènement sous Windows, email, console, bases de données, trace ASP.NET, socket, etc.).

PHP peut afficher les erreurs dans la sortie HTML, ce qui est une très mauvaise idée pour des raisons de sécurité ; du coup, les administrateurs désactivent généralement complètement la journalisation des erreurs, alors qu’elles peuvent être très facilement envoyées vers un fichier précis ou vers les journaux système. Quand je débarque dans un code PHP inconnu, je commence généralement par activer la sortie des erreurs, et là c’est festival avant même d’avoir commencé à corriger les problèmes qu’on m’avait soumis !

Sous Windows, le journal d’événements est une mine d’or d’informations pour le débogage. Les services du système d’exploitation y écrivent toutes leurs erreurs, par exemple IIS ou le service de relais SMTP qui y met les messages d’erreur des serveurs SMTP distants. La machine virtuelle .NET y journalise les exceptions non interceptées avec la pile d’appels au moment de l’erreur. L’onglet « Sécurité » contient les erreurs d’authentification et, encore plus intéressant, les traces des audits d’accès aux ressources. Ce dernier outil, assez méconnu, est un don du ciel quand vous ne comprenez pas un problème d’accès à un fichier ; en effet, plus les problématiques de sécurité se font prégnantes, plus les systèmes d’exploitation ont tendance à faire exécuter les programmes par des profils à faibles autorisations, voire à ne pas charger totalement les profils – une spécialité de Windows. Si vous souhaitez comprendre pourquoi vous n’avez pas accès à tel ou tel fichier, vous devez effectuer les opérations suivantes :

  • cibler la ressource
  • activer l’audit sur la ressource (pour un fichier ou un répertoire, aller dans ses propriétés, onglet Sécurité, cliquer sur Avancé puis aller dans l’onglet Audit et activer les audits utiles)
  • activer l’audit sur la machine ; pour cela, aller dans Stratégie de sécurité locale dans les Outils d’administration, déplier Stratégies locales puis Stratégies d’audit, et activer les échecs et/ou les réussites sur la catégorie qui vous intéresse
  • réitérer la tentative d’accès
  • lire le journal Sécurité, dans lequel vous saurez quel utilisateur a tenté avec ou sans succès à la ressource, depuis quel programme, etc.
  • une fois les problèmes réglés, désactiver les audits pour éviter de graver le journal pour le plaisir

Les systèmes de gestion de bases de données relationnels peuvent, en fonction de leur configuration, écrire des traces des requêtes erronées – configuration par défaut de PostgreSQL – ou des requêtes coûteuses – configuration par défaut de MySQL. Ils supportent tous l’instruction EXPLAIN donnant le plan d’exécution, ont des outils de trace avancés, tiers ou natifs, capables de proposer des index pour accélérer les requêtes.

Les navigateurs internet modernes ont des outils pour les développeurs qui auraient fait baver le petit François à ses débuts de développeur web en 1997 : console avec toutes les erreurs, suivi de variables javascript, débogueur avec points d’arrêt et instruction d’entrée dans le débogueur (debugger), liste de règles CSS appliquées à un élément et possibilité de tester des modifications sur icelles, liste des ressources chargées avec source du chargement, temps d’attente du premier octet, temps de téléchargement, en-têtes HTTP en entrée et en sortie, remis en forme indentée des fichiers javascript compressés, manipulation du code HTML, simulation de résolutions tierces et d’interfaces utilisateur tactiles…

Les débogueurs modernes peuvent prendre la main sur un programme déjà lancé, sur la machine locale ou même sur une machine distante, en s’attachant à ce programme, en dehors de leur capacité bien connue de lancer un programme directement en mode débogage.

Et même quand vous n’avez pas accès à la machine, localement ou à distance, vous pouvez demander à l’utilisateur de faire un export mémoire exploitable par votre débogueur, par exemple avec procdump et Visual Studio pour Windows, natif ou .NET.

En bref, avant quoi que ce soit d’autre, RTFL!

Le mille-feuilles de l’informatique distribuée

Très longtemps, les programmes informatiques se sont exécutés sur une machine unique, sans collaboration avec d’autres ; au pire, on avait affaire à un serveur tout-puissant et un terminal d’affichage stupide.

Aujourd’hui, avec les développement des réseaux, le gros des applications d’entreprise et même grands public distribuent les tâches à plusieurs ordinateurs collaborant pour rendre le service attendu. C’est en particulier le cas du développement web, où vous avez au minimum un serveur manipulant des données de référence pour les rendre intelligibles et modifiables par un client exécutant l’interface utilisateur dans un navigateur web. Le cas général  comprend côté serveur des systèmes de stockage de données ayant leur propre langage, SQL ou non, un serveur web pour gérer les connexions réseau, une plateforme logicielle intégrée au serveur web pour tout lier, et côté client du code HTML et CSS définissant l’apparence des écrans et du code javascript pour gérer l’interaction avec l’utilisateur.

En cas de bogue, la couche dans laquelle il survient est rarement difficile à trouver, même si certaines erreurs réseau peuvent être un peu plus vicieuses – comme les validations de certificats SSL. Par contre, il peut s’avérer nettement plus compliqué de déterminer dans quelle couche la correction doit être effectuée : si la reptation jusqu’au client d’une donnée stockée dans une base relationnelle provoque une erreur dans le code javascript, par exemple une « ‘ » non échappée dans une chaîne de caractères, l’erreur se manifeste dans le code javascript exécuté sur le poste du client, alors que la correction à apporter doit l’être dans le code serveur le générant – et pas dans la base, dont les données doivent être agnostiques de la façon dont elles seront utilisées.

Il n’existe pas de règle s’appliquant à toutes les architectures distribuées pour débusquer ce genre d’erreurs, mais en être conscient est déjà un début de solution.

Utiliser les moteurs de recherche

Quand j’ai commencé à programmer, internet n’existait pas pour le grand public ; nous n’avions comme seules ressources que la documentation du langage – 700 pages sur papier bible pour Turbo Pascal 5.5 – et les articles de magazines et livres que nous pouvions trouver en français, autant dire pas grand chose.

Aujourd’hui, il est rare de tomber sur un problème dont personne n’a publié la solution sur internet, mais encore faut-il savoir comment chercher.

Première règle : chercher en anglais. On peut hurler à l’hégémonie anglo-saxonne autant que l’on voudra – j’écris en français volontairement pour créer du contenu francophone sur l’informatique – malgré ses 275 millions de locuteurs, notre langue est loin d’être la plus présente sur internet. Si votre message d’erreur est en français – ou dans n’importe quelle autre langue – traduisez-le du mieux que vous pouvez ; les systèmes de suggestion automatiques peuvent vous aider, et certains services existent pour certaines plateformes. Petit à petit, à force de parcourir les documentations et forums en anglais, vous acquerrez le vocabulaire ad hoc. En désespoir de cause, pour des plateformes traduisant les messages d’erreur en utilisant les paramètres régionaux comme .NET ou Java, vous pouvez forcer la langue d’exécution du programme pour obtenir le message d’erreur en anglais.

Deuxième règle : même si vous cherchez sur un site précis, n’utilisez pas la recherche intégrée du site, utilisez votre moteur de recherche préféré et sa fonctionnalité de limitation à un nom de domaine. Google ou Bing indexent mieux les sites que les sites eux-mêmes, et ils supportent la notation site:nomdedomaine.tld. De toutes façons, les meilleures ressources en dehors des documentations officielles, comme stackoverflow.com ou codeproject.com, sont par nécessité très bien construits pour les moteurs de recherche.

Troisième règle : si le message d’erreur ne donne pas de résultat, passer aux noms des fonctions employées assortis de mots clés correspondant à l’erreur et du langage de programmation ou la plateforme – .NET et Java par exemple ont tendance à avoir des noms d’objets assez semblables – et ça vous évite aussi les pages visant le grand public plutôt que les développeurs – les utilisateurs aussi voient des messages d’erreur. Les noms de méthode dans la pile d’appel peuvent aider à cibler plus précisément la recherche.

Enfin, si jamais vous résolvez un problème sans en passer par internet, ou après une longue recherche et un croisement de plusieurs ressources, rendez la solution disponible pour les copains !

Un bon framework

Avertissement : je suis l’architecte et l’auteur principal du framework de développement d’applications web et mobiles de Yoocan ; assez logiquement, les idées développées dans cet article correspondent aux principes architecturaux mis en oeuvre dans celui-ci.

Définition

En dehors des cas simples – en termes d’architecture – il est rare de démarrer le développement d’une application de zéro ; en général, on s’appuie sur une structure, un cadre prédéfini, qu’en informatique on nomme d’un mot anglais, framework, qui se traduit par cadre de travail. Des termes français comme « structure logicielle » ou « cadriciel » existent, mais sont peu usités. Un framework est un objet composite visant à simplifier et accélérer le travail de développement : il impose un plan d’architecture général appuyé sur un ensemble de patterns – ou patrons logiciels – et de bibliothèques standards.

L’utilisation d’un framework apporte de nombreux gains :

  • le partage de tâches communes et fastidieuses à développer à chaque nouvelle application : analyse des paramètres d’entrée, contrôles graphiques prêts à l’emploi, etc.
  • des garanties en termes de sécurité, en empêchant le développeur de faire des erreurs communes : injection SQL, cross-site scripting, buffer overflow, etc.
  • des garanties en termes de conformité de fonctionnalités standards vis-à-vis de règles métier, juridiques, techniques : respect des règles comptables, de lois physiques, etc.

La contrepartie réside dans le cadre imposé, et son degré de rigidité, ce qui limitera votre liberté d’agir ; j’y reviendrai.

Un framework peut être plus ou moins spécialisé :

  • le .NET framework ou la plateforme Java permettent de créer pratiquement tout type d’application, du petit utilitaire en ligne de commande au mastodonte distribué, à l’exception des logiciels très proches du métal comme les pilotes matériel
  • CodeIgniter ou Symfony, tous deux basés sur PHP, sont des frameworks adaptés au développement de tous types de site internet
  • DirectShow est un framework pour réaliser des applications Windows multimédias
  • WordPress peut être considéré comme un framework spécialisé dans un type de site internet, les blogs

Le point commun entre tous ces outils est leur capacité à vous emmener de l’α à l’ω du développement de votre application, ce qui différencie les frameworks des bibliothèques ou des patrons logiciels.

L’art du cadrage

Le terme anglais framework a un grand défaut et une grande qualité. D’un côté, il décrit assez mal l’idée d’accompagner les développeurs dans le développement et l’aide apportée, mais de l’autre, il appuie sur un point qui me semble central pour le choix : la notion de cadre, qui induit certaines rigidités.

Les frameworks imposent très souvent des bibliothèques précises pour certaines fonctionnalités génériques (accès aux sources de données, journalisation, etc.) quand vous voudriez utiliser votre pilote de base de données ou votre outil de journalisation préféré.

Il est également assez habituel de démarrer son application avec un jeu de fonctionnalités limité et de choisir un framework très ajusté pour développer au plus vite ; lorsque vient le moment de faire évoluer le logiciel, il arrive très souvent que le framework ne permette pas de développer les nouvelles fonctions, voire pire, qu’il ne puisse pas cohabiter avec des outils tiers. Par exemple, il n’est pas très facile d’intégrer ensemble un blog WordPress et un forum phpBB. Dans un genre plus technique, Facebook avait commencé son développement en PHP, et s’est vite trouvé confronté à de grosses problématiques de performance ; en effet, quand le nombre d’utilisateurs augmente, PHP propose principalement deux façons de distribuer la charge : la mise en cache HTML, impossible de par la nature de Facebook, ou l’augmentation du nombre de serveurs, ce qui aurait induit des coûts délirants. Après avoir hésité à tout redévelopper, Facebook s’en est remis à optimiser la plateforme elle-même, en précompilant les pages PHP avec un outil développé en interne.

Le choix d’un framework est donc un exercice subtil où il s’agit d’équilibrer les gains apportés en rapidité de développement et en fonctionnalités « out of the box » et les limitations de l’outil en termes de configurabilité, d’ouverture et de possibilité d’intervertir ou d’ajouter des composants.

Principaux critères de choix

Pour bien choisir son framework, le plus important est évidemment son adéquation avec le type d’application que vous souhaitez construire ; vous n’utiliserez pas un framework internet PHP pour construire une application Windows classique. En prenant en compte la problématique du cadre décrite ci-dessus, cela peut s’avérer moins trivial qu’il n’y parait ; si vous démarrez un blog, vous vous pencherez très probablement sur WordPress, mais si le but de votre blog est de vendre votre production artisanale, et que la partie blog n’est qu’une manière d’améliorer votre visibilité par le grand public dans votre domaine, que faire ?

Tous les frameworks ont un cœur de fonctionnalités qui a présidé à sa création, déterminé ses choix techniques et fonctionnels fondamentaux ; quand un outil assez ajusté – comme WordPress pour les blogs par exemple – cherche à sortir de ce noyau pour faire un peu du tout – du forum, de l’e-commerce, etc. – c’est souvent une mauvaise idée et il fera presque toujours plus mal ses fonctions annexes qu’un outil spécifique. Je conseille d’éviter le proverbial « qui trop embrasse, mal étreint », et si vous vous appuyez sur un framework spécifique, de limiter son usage à ce qu’il sait nativement très bien faire.

Un autre atout d’un framework souvent cité est sa « communauté », c’est-à-dire l’ensemble de ses développeurs et de ses utilisateurs actifs, et plus précisément, ceux volontaires pour apporter de l’aide technique. Il est vrai qu’une communauté nombreuse est un gage, à un instant t, d’obtenir des réponses rapides à ses questions techniques ; cependant, contrairement à une idée répandue, il n’est pas une assurance de pérennité de l’outil. En effet, on constate généralement que lorsque les développeurs en chef disparaissent, pratiquement quelle que soit la taille de la communauté, les outils tombent dans l’oubli ou sont modifiés de fond en comble par une nouvelle équipe, quand vous avez la chance qu’elle se crée.

Car oui, comme tout en ce bas monde, il arrive que les frameworks meurent. Bien entendu, rien ne vous empêche de continuer à les utiliser, enfin, tant que les plateformes sous-jacentes peuvent les faire tourner, qu’il n’y a pas besoin d’ajouter de fonctionnalités ou de boucher des trous de sécurité, qu’on trouve d’autres orphelins de la communauté pour vous aider… Ce qui m’amène à un autre critère très important pour le choix et qui est assez peu souvent évoqué : s’appuyer sur des standards de l’industrie. Entre un framework avec son propre système de template, son propre langage d’accès aux données, son propre format d’export de données, et un autre qui s’appuie sur le SQL, normalisé par l’ANSI, XSLT, normalisé par le w3c, XML, normalisé par le w3c, on pressent naturellement qu’on trouvera plus facilement de l’aide en dehors de la communauté pour le deuxième que pour le premier.

Enfin, pour revenir sur la rigidité du cadre, avant de s’enfermer dans un choix, il est vital de bien étudier les possibilités que vous laissent le framework d’étendre le cadre ou d’en sortir :

  • l’utilisation de l’inversion de contrôle est généralement un gage de la possibilité de réimplémenter à sa sauce certaines parties du framework
  • dans le cas d’un outil fortement spécialisé, il faut étudier dans quelle mesure il peut s’intégrer dans un écosystème tiers (authentification, autorisation, suivi statistique, charte graphique, etc.), donc de vivre dans un framework plus générique que lui
  • à l’inverse, un outil générique doit être capable d’accueillir en son sein des produits plus spécialisés

Conclusion

Le choix d’un framework est très loin d’être anodin et peut revenir vous hanter pour des années, oscillant entre Charybde – la réécriture complète – et Scylla – maintenir un outil obsolète ou en étendre un mal adapté. De plus, il est très souvent sujet à des guerres de religion dont les informaticiens sont friands – microkernel contre kernel monolithique, Linux contre Microsoft, .NET contre Java, etc., quand ce ne sont pas des béotiens sur les questions techniques qui en imposent un pour des raisons n’ayant rien à voir avec la technologie. Si vous retenez de cet article qu’il faut bien évaluer le cadre imposé, et vous méfier des frameworks vous proposant une énième solution quand des standards techniques internationaux existent, il aura atteint son but.

Des outils et des hommes

Ma première rencontre avec un outil automatisé d’aide au développement logiciel remonte à ma troisième année d’école d’ingénieur en option ingénierie du logiciel. L’outil en question, dont j’ai oublié le nom, évaluait la qualité du code par le calcul d’un lot de métriques et leur comparaison avec des seuils prédéfinis. Parmi ces métriques se trouvaient le nombre de lignes de code par fonction, le nombre de lignes de commentaires par ligne de code et la présence de commentaires en cartouche d’une méthode, le nombre d’utilisations d’une fonction ou méthode, etc. Une fonction trop longue – de mémoire, plus d’une centaine de lignes, une fonction non commentée – aussi triviale soit-elle, ou une fonction trop utilisée, déclenchaient des torrents d’insultes de la part de l’outil qui se montrait assez à cheval sur ses principes. Appliqué sans discernement, comme dans les travaux pratiques de ce cours, ce genre d’approche kafkaïenne amène à des sommets de la littérature informatique tels que :

/* Sets the threshold (no shit, it really does) */
public void setThreshold(int threshold) {
  this.threshold = threshold;
}

voire à des abominations du genre :

public void thisMethodIsReallyTooLong() {
  /* does lots of interesting things, and then, when the metric is about to be exceeded... */
  thisMethodIsReallyTooLongPart2();
}

public void thisMethodIsReallyTooLongPart2() {
  /* Now, where were we? */
}

Non seulement la règle a dégradé la lisibilité du code, mais qui pis en fonction de la bonne volonté du compilateur, elle peut même avoir réduit les performances. J’ai appliqué les règles comme on me le demandait et je suis passé à autre chose.

Une fois en situation d’organiser la réalisation de projets pour mes clients, la question des outils s’est posée à nouveau. Editeur de texte, IDE, contrôle de source, générateurs de code, tests unitaires automatisés, intégration continue, déploiement, les outils sont nombreux, résolvent des problèmes très variés et ont des avocats véhéments prompts à l’anathème. En tant que décideur, quels critères appliquer dans ses choix ?

Fidèle à mes principes, je ne m’engage dans la mise en place d’un outil que si il répond à un problème identifié ; je ne pense pas qu’il existe un seul développeur professionnel qui n’ait été confronté à des régressions – « mais je l’avais corrigé ce bug, qui a écrasé mon code ? » – ou à la gestion de versions de ses développements : un système de contrôle de source s’impose donc à tous. A l’inverse, une équipe sortant une version publique tous les ans au plus a-t-elle besoin d’un système d’intégration continue, avec le coût de mis en oeuvre inhérent à ce type d’outil complexe ? Rien n’est moins sûr. Tester voire déployer systématiquement tous les derniers outils à la mode en évaluant mal leur pertinence dans le contexte local est un indicateur certain du mauvais décideur.

Par ailleurs, un outil n’est rien s’il n’est pas pris en main par l’équipe. Naturellement, le décideur aura tendance à se méfier des membres de l’équipe qui auront soutenu vocalement d’autres outils que celui de son choix. Le « fanboy »  d’un outil concurrent induit effectivement un risque, mais il est une quantité connue : il sera mécontent que sa préférence ait été mise de côté, mais ayant compris ce que pouvait apporter ce type d’outil, il sera probablement à même d’utiliser correctement le choix du décideur – à moins d’être une tête de cochon n’ayant pas très bien intégré les notions d’équipe et de compromis, auquel cas il serait sans doute mieux tout seul, mais c’est une autre histoire.

La passivité est bien plus pernicieuse, car elle est la marque soit d’un désintérêt total pour la question, soit d’une incompréhension des enjeux, et au pire d’une incapacité à intégrer correctement l’outil dans sa pratique quotidienne.

On l’a vu, appliquer à la serpe des métriques amène à des aberrations ; l’usage correct est donc d’utiliser les seuils comme des avertissements à traiter manuellement avec discernement. Mais encore faut-il comprendre l’avertissement, ne pas simplement le désactiver pour avoir la paix, et le traiter correctement – par exemple analyser une fonction longue pour déterminer si elle n’est pas découpable en unités signifiantes plus petites, mais ne pas la charcuter pour le plaisir. Utiliser des branches pour matérialiser des lignes de développement séparées – la version 1.0 en cours de maintenance, la version 1.1 contenant des évolutions mineures et la version 2.0 qui refond l’architecture du logiciel – est une très bonne chose, encore faut-il les créer à bon escient et savoir effectuer les merge en bout de ligne.

Par conséquent, de même qu’un outil résolvant un problème ne se posant pas est contre-productif, un outil que l’équipe n’est pas assez mature ou organisée pour utiliser correctement est plus dangereux que l’absence d’outil.

Pour paraphraser Jean Bodin, il n’est d’outil que d’homme.