Autocompléter du JavaScript avec Tern

Quel que soit le langage avec lequel on travaille, le besoin d'une bonne autocomplétion se fait vite sentir dès lors que l'on est amené à travailler sur des programmes de plus de quelques lignes. Le problème, c'est que tous les langages de programmation ne sont pas égaux face à l'autocomplétion : les langages fortement typés, tels que le Java ou le C# sont simples à traiter pour un moteur d'autocomplétion et disposent ainsi de très bons outils d'édition.

Pour les langages à typage faible, comme le JavaScript, ce n'est pas aussi simple : il n'est pas toujours possible de déterminer le type d'une variable ou le résultat d'une opération avec une simple analyse statique du code, ce qui rend la création d'outils d'édition avancés très compliquée pour ces langages.

Tern est un moteur d'analyse avancé de code JavaScript : il analyse en temps réel le code source en cours d'édition et détermine le type des différentes variables et les résultats des opérations afin de fournir une autocomplétion solide pour l'édition de programmes en JavaScript.

Tern est indépendant de tout éditeur de texte ce qui lui permet d'être intégré à de nombreux éditeurs via des plugins spécifiques. Il est par exemple disponible pour VIM, Emacs, Sublime Text, et plusieurs autres éditeurs.

Autocompletion de javascript avec Tern dans VIM

Installation de Tern

Étant donné que l'installation de Tern est dépendante de l'éditeur que vous utilisez, je ne vais pas détailler cette partie et je vous laisse vous référer à la documentation spécifique à chaque éditeur :

Amélioration de l'autocompletion d'un projet

Une fois le plugin Tern installé pour votre éditeur préféré, l'autocomplétion des sources JavaScript devrait être fonctionnelle. Cette autocomplétion peut être suffisante si vous écrivez des programmes JavaScript basiques qui tiennent en un seul fichier, sinon, il faut créer un fichier de configuration à la racine de votre projet pour indiquer à Tern quels sont les fichiers à analyser, et si vous travaillez dans des contextes ou avec des bibliothèques spécifiques (Node.js, RequireJS, Angular…).

Le fichier de configuration est au format JSON et doit être nommé .tern-project. Voici un exemple de configuration :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"ecmaVersion": 5,

"loadEagerly": [
"./src/**/*.js",
"./libs/*.js"
],

"libs": [
"browser",
"underscore"
],

"plugins": {
"angular": {},
"node": {}
}
}

ecmaVersion

La version du standard ECMAScript utilisé dans votre code (5 ou 6, défini par défaut à 6).

loadEagerly

Permet de lister des fichiers à charger et à analyser dès que possible (l'utilisation de glob patterns est autorisée). Cette option n'est généralement pas nécessaire lorsque l'on utilise un plugin permettant le chargement de module (node, requirejs…).

libs

La section libs sert à charger des fichiers JSON contenant des définitions statiques qui permettent d'autocompléter une bibliothèque ou un environnement particulier.

Tern en fournit un certain nombre de base comme par exemple browser, jquery, underscore,... la liste complète peut être trouvée sur la page Github du projet.

Il est également possible de charger vos propres fichiers de définition en fournissant leurs chemins, relatifs à la racine de votre projet :

1
2
3
4
5
6
{
"libs": [
"./defs/mylib.json",
"./defs/foobar.json"
]
}

Si vous souhaitez écrire vos propres fichiers de définition, vous pouvez lire la documentation de Tern sur le sujet.

plugins

Pour les cas les plus complexes, où les définitions statiques sont insuffisantes (pour gérer des systèmes de module par exemple), il est possible de faire appel à des plugins.

Tern en embarque plusieurs en standard. Parmi les plus utiles on peut noter node (et les plugins qu'il charge automatiquement : commonjs et node_resolve), requirejs, es_modules, webpack et angular. La liste complète est disponible dans la section plugins de la documentation de Tern.

Note : Contrairement à la section libs, la section plugins n'est pas une liste mais un objet ; il est en effet possible de configurer certains plugins.

Comme pour les fichiers de définitions statiques, il est possible de charger des plugins tiers. D'après la documentation il est possible de charger un fichier JavaScript depuis le dossier du projet, mais en pratique cela ne fonctionne pas. Pour utiliser des plugins tiers, il faut se rendre dans le dossier où est installé le plugin Tern pour votre éditeur de texte et y installer le plugin Tern désiré (oui ça fait beaucoup de plugins en une seule phrase).

Par exemple, si je veux installer le plugin tern-abitbol pour mon éditeur VIM, ça donne :

1
2
cd ~/.vim/plugins/plugged/tern_for_vim/
npm install tern-abitbol

Et pour l'utiliser dans les projets où j'en ai besoin, il me suffit d'ajouter une ligne à mon fichier .tern-project :

1
2
3
4
5
{
"plugins": {
"abitbol": {},
}
}

Il existe de nombreux plugins pour de nombreuses bibliothèques et framework, une simple recherche sur NPM vous en donnera la liste.

Le mot de la fin

Je me sers de Tern depuis quelques mois maintenant, et bien que le résultat ne soit pas toujours parfait (JavaScript est vraiment un langage très compliqué à analyser), il s'en sort généralement bien.

Si vous êtes curieux de savoir comment ça marche à l'intérieur (comment Tern fait pour analyser le code et deviner les types), je vous invite à lire cet article écrit par l'auteur du logiciel, où il explique sa démarche et le fonctionnement général de Tern.

Configurer la souris SteelSeries Rival 100 sous Linux

Suite à mon article sur le reverse engineering de la SteelSeries Rival 100, j'ai développé un petit logiciel en ligne de commande nommé rivalcfg qui permet de configurer les différents paramètres de la souris (couleur, effet de lumière, sensibilité du capteur…). Le logiciel est développé en Python et devrait fonctionner sur la plupart des distributions Linux utilisant udev (Ubuntu, Debian, ArchLinux, Fedora…).

Pour les curieux, le code source est disponible sur Github : https://github.com/flozz/rivalcfg

EDIT 18/04/2016: Depuis la version 2.3.0 sortie aujourd'hui, rivalcfg supporte également la SteelSeries Rival originale et la SteelSeries Rival 300.
SteelSeries Rival 100 Linux CLI

Installation

Il n'y a pour l'instant pas de paquet disponible dans les différentes distributions Linux, il faut donc l'installer depuis le paquet Python. Pour ce faire, exécutez la commande suivante (en root) :

pip install rivalcfg

Voilà, rivalcfg est installé et prêt à être utilisé.

Utilisation

Une fois installé, il suffit de faire appel à la commande rivalcfg pour configurer la souris. Par exemple, pour que la souris s'allume par intermittence en rouge il faut entrer la commande suivante :

rivalcfg --color=red --light-effect=breath

Pour modifier les pré-réglages de sensibilité du capteur (que l'on peut alterner grâce au petit bouton sous la molette), on peut utiliser la commande suivante :

rivalcfg --sensitivity1=1000 --sensitivity2=2000

Pour remettre tous les paramètres à leur valeur par défaut, on peut utiliser l'option --reset :

rivalcfg --reset

Pour lister toutes les options disponibles, il suffit d'entrer la commande suivante :

rivalcfg --help

J'espère que ce petit logiciel vous sera utile. Si vous rencontrez des problèmes à l'utilisation ou si vous avez des suggestions pour l'améliorer, vous pouvez ouvrir un ticket sur Github. :)

SteelSeries Rival 100 : reverse engineering d'un périphérique USB

La semaine dernière je me suis acheté (un peu sur un coup de tête, je l'avoue) une nouvelle souris : la SteelSeries Rival 100. Cette souris propose de nombreuses options de personnalisation, telles que la couleur du rétro-éclairage, ou la configuration de la sensibilité du capteur… le seul hic, c'est que ces options ne sont accessibles que via un petit logiciel, le SteelSeries Engine 3, qui est disponible uniquement sous Windows et Mac OS X.

Étant donné que mon PC tourne exclusivement sous Ubuntu et que je n'ai pas la moindre envie de démarrer une machine sous Windows à chaque fois que je souhaite configurer ma souris, je me suis lancé dans le reverse engineering de la souris afin de pouvoir développer un petit utilitaire pour la configurer directement sous Linux.

SteelSeries Rival 100 reverse engineering

Pour réaliser le reverse engineering de la souris, je vais avoir besoin :

  • d'une machine virtuelle sous Windows,
  • de Wireshark,
  • et d'une deuxième souris (ou de tout autre périphérique de pointage comme un touchpad ou un trackpoint).

Je vais me servir de la machine virtuelle afin d'y faire tourner l'utilitaire de configuration, et pendant que je jouerai avec les réglages, je capturerai le trafic sur le bus USB à l'aide de Wireshark afin, je l'espère, de pouvoir déterminer le protocole utilisé entre le SteelSeries Engine 3 et la souris.

Récupération d'informations sur le périphérique USB

La première étape est de recueillir quelques informations sur la souris. La commande lsusb devrait fournir un certain nombre de renseignements utiles :

$ lsusb
...
Bus 001 Device 022: ID 1038:1702 SteelSeries ApS

Ici, on apprend :

  • que la souris est connectée au bus USB numéro 1,
  • que le système lui a attribué le numéro de périhpérique 22,
  • que l'identifiant du fabriquant (vendor id) est 1038,
  • que l'identifiant de ce modèle de souris (product id) est 1702.

Ça fait déjà pas mal d'informations, mais on devrait pouvoir en dénicher quelques-unes supplémentaires dans les journaux du noyau Linux :

$ dmesg
...
[23803.145407] usb 1-1: new full-speed USB device number 22 using xhci_hcd
[23803.382869] usb 1-1: New USB device found, idVendor=1038, idProduct=1702
[23803.382871] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[23803.382873] usb 1-1: Product: SteelSeries Rival 100 Gaming Mouse
[23803.382874] usb 1-1: Manufacturer: SteelSeries
[23803.385604] hid-generic 0003:1038:1702.000D: hiddev0,hidraw6: USB HID v1.11 Device [SteelSeries SteelSeries Rival 100 Gaming Mouse] on usb-0000:00:14.0-1/input0
[23803.387969] input: SteelSeries SteelSeries Rival 100 Gaming Mouse as /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.1/0003:1038:1702.000E/input/input22
[23803.388128] hid-generic 0003:1038:1702.000E: input,hidraw7: USB HID v1.11 Mouse [SteelSeries SteelSeries Rival 100 Gaming Mouse] on usb-0000:00:14.0-1/input1

On retrouve ici la plupart des informations vues précédemment, mais les lignes "hid-generic" nous informent que la souris fournit deux interfaces implémentant la classe HID (Human Interface Device), ce qui est une très bonne nouvelle.

Les interfaces qui implémentent cette classe sont très simples à contrôler, car le noyau Linux nous fournit pour chacune d'entre elles un fichier dans /dev afin de communiquer avec ces interfaces sans avoir à se soucier des détails du protocole.

Ces deux lignes nous renseignent également sur le fait que ces deux interfaces sont liées aux fichiers hidraw6 et hidraw7 (dans /dev), ce que l'on peut facilement vérifier :

$ ls /dev/hidraw*
/dev/hidraw0  /dev/hidraw2  /dev/hidraw4  /dev/hidraw6
/dev/hidraw1  /dev/hidraw3  /dev/hidraw5  /dev/hidraw7

Préparation de la machine virtuelle sous Windows

Maintenant que nous sommes en possession de toutes les informations utiles pour identifier le périphérique, il est temps de passer à la préparation de la machine virtuelle. Dans mon cas je vais utiliser VirtualBox avec une machine virtuelle sous Windows 8.1 qui traîne sur mon disque.

NOTE : Pour ceux qui ne possèdent pas de machine virtuelle sous Window, il est possible de s'en procurer une très facilement. Dans le cadre du projet Modern IE, Microsoft fournit gratuitement des machines virtuelles sous Windows, prêtes à l'emploi.

La préparation de la VM est très simple, il suffit :

  • de télécharger / installer / démarrer la machine virtuelle,
  • de télécharger la version du logiciel SteelSeries Engine 3 adaptée à la version de Windows installée sur la machine virtuelle,
  • et de l'installer sur le Windows virtualisé.

Une fois ceci fait, il ne reste plus qu'à vérifier que tout fonctionne :

  • on connecte la souris à la VM en utilisant l'icône en bas à droite de la fenêtre,
  • on lance SteelSeries Engine 3
  • et on s'assure qu'il reconnait bien la souris.

On peut même tester quelques réglages, normalement tout devrait être fonctionnel.

NOTE : c'est à ce moment-là que la seconde souris devient nécessaire. La Rival 100 n'est en effet plus utilisable dès lors qu'elle se retrouve connectée à la machine virtuelle.
Connexion de la souris à la VM Windows

Monitoring du bus USB à l'aide de Wireshark

Pour commencer il faut s'assurer que le module usbmon du noyau est bien chargé, c'est lui qui va permettre à Wireshark de récupérer les trames qui passent sur le bus USB. On peut vérifier que le module est chargé avec la commande suivante :

$ lsmod | grep usbmon

Si une ligne similaire à celle-ci apparait, c'est que le module est chargé :

usbmon                 28672  0

sinon, il faut le charger en utilisant la commande modprobe (en root) :

# modprobe usbmon

Une fois que le module usbmon est chargé, il ne reste plus qu'à lancer Wireshark (en root) :

# wireshark
NOTE : Il n'est pas recommandé de lancer Wireshark en root. Vous vous ferez d'ailleurs enguirlander lors du démarrage de celui-ci s'il détecte qu'il a été lancé en root… Ceci dit, je n'ai pas envie de régler ses permissions correctement pour l'instant, donc je vais le faire quand même.

Maintenant que Wireshark est lancé, on va pouvoir commencer à travailler.

Pour commencer, il faut sélectionner l'interface à espionner. Dans le cas présent il s'agit de "usbmonX", où "X" est le numéro du bus USB sur lequel la souris est connectée. Dans mon cas elle est connectée au bus numéro 1, je vais donc sélectionner l'interface "usbmon1".

Il ne reste plus qu'à lancer la capture en cliquant sur le bouton "Start" (oui celui avec une icône verte en forme d'aileron de requin…).

Wireshark : sélection de l'interface

Une fois la capture lancée, la fenêtre de Wireshark va très vite se remplir de plein de lignes : il s'agit de l'ensemble du trafic circulant sur le bus USB de la machine. Seule une infime partie de tout ce trafic nous intéresse, il va donc falloir filtrer un peu tout ça. Pour ce faire on va entrer le filtre suivant dans le champ "Filter" qui se trouve en haut de la fenêtre :

usb.device_address == XXX

"XXX" est le numéro qui a été attribué au périphérique (dans mon cas il s'agit du numéro 22).

Il devrait à présent y avoir beaucoup moins de lignes affichées (sauf si vous avez fait bouger la souris depuis le début de la capture, auquel cas vous aurez déjà plein de lignes).

Wireshark : filtré par usb.device_address

Analyse du protocole de la souris

Maintenant que tout est prêt, l'analyse va pouvoir débuter. Pour commencer on va jouer avec un réglage qui devrait être facile à interpréter : la couleur du rétro-éclairage de la souris.

Dans l'interface du SteelSeries Engine 3, sélectionnons une couleur dont le code hexadécimal soit facile à repérer, par exemple "#112233" ou "#AABBCC"… Dans mon cas je choisis "#FF4411" par ce que c'est un orange que j'aime bien (no comment)…

Une fois le réglage validé (en cliquant sur le bouton "Fermer" de la fenêtre), la souris change instantanément de couleur, et deux nouvelles lignes apparaissent dans Wireshask :

  • La première provient de notre machine ("host") et se dirige vers la première interface de la souris (22.0),
  • et la seconde provient de la souris et est destinée au PC.
NOTE : Normalement, dans la colonne Protocol du premier paquet, le protocole indiqué devrait être USBHID. Si ce n'est pas le cas, il faut déconnecter puis reconnecter la souris à la Machine virtuelle. Cela permettra à Wireshark de capturer les trames qui lui indiqueront qu'il a à faire à un périphérique de classe HID.

À priori celle qui devrait nous intéresser est la première, et en fouillant un peu dans les données de la trame, on finit par tomber sur la ligne suivante :

Data Fragment: 0500FF44110000000000000000000000...

On y retrouve très clairement la couleur que nous avions sélectionnée précédemment. Pour s'assurer qu'il ne s'agit pas là d'une coïncidence, il est possible de réessayer avec une autre couleur, par exemple "#00FFFF".

Cette fois encore, la souris change de couleur (elle vire au bleu) et deux nouvelles trames apparaissent dans Wireshark. Dans la première d'entre elles, on retrouve une fois de plus notre couleur :

Data Fragment: 050000FFFF0000000000000000000000...

À ce stade, on peut conclure qu'il existe une commande 0x0500 qui prend en paramètre les trois canaux (rouge, vert et bleu) de la couleur souhaitée.

À présent essayons de changer la couleur à la main. Vous vous souvenez des fichiers que nous avions trouvés dans /dev au tout début de nos investigations ? Et bah c'est maintenant qu'ils vont nous être utiles.

  • Pour commencer, il faut ouvrir un terminal root (si vous êtes sous Ubuntu, vous pouvez utiliser la commande "sudo su").
  • Ensuite il suffit d'écrire les octets souhaités directement dans le premier des deux fichiers trouvés précédemment (c'est à dire /dev/hidraw6 dans mon cas). Par exemple, essayons d'allumer la souris en rouge ("#FF0000") :
echo -en "\x05\x00\xFF\x00\x00" > /dev/hidraw6"
NOTE : Il est possible que dans certains cas il faille répéter la commande précédente deux fois pour que cela fonctionne car pour une raison que j'ignore, les octets peuvent ne pas être directement écrits dans le fichier (ils restent dans le buffer d'écriture en attendant d'être effectivement écrits).

Et là, la souris devrait s'allumer en rouge. Si ce n'est pas le cas, essayez d'écrire dans un autre fichier (voire dans /dev/hidraw0 dans certains cas…).

Il ne reste plus qu'à répéter les opérations pour chacun des réglages présents dans l'utilitaire de configuration de SteelSeries pour trouver toutes les commandes existantes.

Reverse engineering de la souris SteelSeries Rival 100

Liste des commandes

Ci-dessous, un tableau récapitulatif des commandes que j'ai été en mesure de découvrir :

Nom Commande Paramètres Descriptions
set_sensitivity 0x03 <preset> <value> Définit la sensibilité du capteur
set_polling_rate 0x04 0x00 <rate> Définit la fréquence d'interrogation
set_color 0x05 0x00 <red> <green> <blue> Change la couleur de la souris
set_light_effect 0x07 0x00 <effect> Définit les effets lumineux (pulsation…)
save 0x09 - Sauvegarde les paramètres dans la souris
set_btn6_action 0x0B <action> Définit l'action du bouton sous la molette
??? 0x16 ??? Envoyée à la connexion de la souris, action indéterminée

set_sensitivity

La souris est capable de contenir deux pré-réglages de sensibilité que l'on peut alterner via le bouton situé sous la molette de la souris.

0x03 <preset> <value>

Paramètres :

  • preset : Numéro du pré-réglage à modifier
    • 0x01 : pré-réglage numéro 1
    • 0x02 : pré-réglage numéro 2
  • value : Sensibilité du capteur parmi les valeurs suivantes :
    • 0x08 : 250 DPI
    • 0x07 : 500 DPI
    • 0x06 : 1000 DPI (valeur par défaut du pré-réglage numéro 1)
    • 0x05 : 1250 DPI
    • 0x04 : 1500 DPI
    • 0x03 : 1750 DPI
    • 0x02 : 2000 DPI (valeur par défaut du pré-réglage numéro 2)
    • 0x01 : 4000 DPI

set_polling_rate

Définit la fréquence à laquelle la position de la souris sera lue par l'ordinateur. Plus cette valeur est élevée, plus la précision sera grande. Cependant, une valeur élevée signifie également plus de trafic sur le bus USB et une plus grande utilisation du CPU.

0x04 0x00 <rate>

Paramètres :

  • 0x00 : le premier paramètre n'est pas utilisé sur ce modèle et doit être défini à 0x00
  • rate : le taux de rafraichissement parmi les valeurs suivantes :
    • 0x04 : 125 Hz (8 ms)
    • 0x03 : 250 Hz (4 ms)
    • 0x02 : 500 Hz (2 ms)
    • 0x01 : 1000 Hz (1 ms, valeur par défaut)

set_color

Définit la couleur du rétro-éclairage de la souris.

0x05 0x00 <red> <green> <blue>

Paramètres :

  • 0x00 : le premier paramètre n'est pas utilisé sur ce modèle et doit être défini à 0x00
  • red: valeur du canal rouge de la couleur RGB (compris entre 0x00 et 0xFF)
  • green: valeur du canal vert de la couleur RGB (compris entre 0x00 et 0xFF)
  • blue: valeur du canal bleu de la couleur RGB (compris entre 0x00 et 0xFF)

set_light_effect

Configure un effet de lumière.

0x07 0x00 <effect>

Paramètres :

  • 0x00 : le premier paramètre n'est pas utilisé sur ce modèle et doit être défini à 0x00
  • effect : l'effet à appliquer :
    • 0x01 : statique
    • 0x02 : pulsation lente
    • 0x03 : pulsation moyenne (appelée « respiration » dans le SteelSeries Engine 3)
    • 0x04 : pulsation rapide

save

Sauvegarde les réglages actuels dans la mémoire interne de la souris. Si cette commande n'est pas appelée après avoir modifié les paramètres de la souris, celle-ci retournera à sa précédente configuration la prochaine fois qu'elle sera reconnectée à la machine.

0x09

set_btn6_action

Définit l'action que le bouton numéro 6 (numéroté comme tel dans SteelSeries Engine 3) doit effectuer.

0x0B <action>

Paramètres :

  • action : action du bouton :
    • 0x00 : permet le basculement entre les pré-réglages de sensibilité du capteur (valeur par défaut)
    • 0x01 : rend le bouton accessible par le système d'exploitation (reconnu en tant que "bouton 10" par xev)

Conclusion

Au final, le reverse engineering de cette souris s'est avéré beaucoup plus simple que je ne l'aurais pensé. Et maintenant que je suis en possession de toutes les informations nécessaires, je devrais être en mesure de développer assez rapidement un petit utilitaire en ligne de commande pour configurer ma souris (je le placerais sur Github lorsque je l'aurai terminé).

EDIT 16/04/2016: J'ai écrit le petit utilitaire en python, et comme promis il est disponible sur Github : github.com/flozz/rivalcfg.
Si vous souhaitez étudier le code du logiciel, je vous recommande de jeter un coup d'œil à la version 1.0.1 qui est la plus simple à comprendre.

Mise en veille d'un PC portable sous Ubuntu 15.04 (systemd)

Depuis que je suis passé à Ubuntu 15.04, mon PC portable (un Thinkpad X1 Carbon Gen 3), ne se met plus systématiquement en veille lorsque je rabats l'écran. Cela se produit en fait lorsqu'un moniteur externe est connecté : le système bascule l'affichage sur le moniteur externe au lieu de se mettre en veille.

Il était auparavant possible de forcer la mise en veille via l'option GSettings "org.gnome.settings-daemon.plugins.power.lid-close-suspend-with-external-monitor", option également disponible via l'outil graphique gnome-tweak-tool, mais cette dernière n'a plus aucun effet depuis Ubuntu 15.04. Ceci est dû au passage à systemd. En effet, systemd gère lui-même les actions à mener en réaction à certains événements tels que la fermeture de l'écran du PC portable ou l'appuie sur le bouton d'alimentation. Il faut donc maintenant définir le comportement souhaité dans les fichiers de configuration de systemd (et plus précisément dans celui du module Logind).

gnome-tweak-tool Lid Close Option
NOTE : Bien que je parle dans cet article de la distribution Ubuntu, ce qui va suivre fonctionne pour toutes les distributions embarquant systemd (Debian 8, Archlinux, Fedora, openSUSE…).

Pour modifier les actions à entreprendre lorsque l'écran du pc portable est rabattu, il faut éditer (en root) le fichier "/etc/systemd/logind.conf" :

sudo vim /etc/systemd/logind.conf

Normalement, ce fichier devrait déjà contenir l'ensemble des options configurable, commentées et définies à leur valeur par défaut. Afin de toujours mettre en veille l'ordinateur lorsque l'écran est rabattu, même lorsqu'un moniteur externe est connecté, l'option qui nous intéresse est "HandleLidSwitchDocked", il faut la décommenter et la définir à "suspend" ce qui donne chez moi le résultat suivant :

[Login]
# ...
HandleLidSwitchDocked=suspend
# ...

D'autres valeurs peuvent être définies en fonction de vos préférences (par exemple "ignore", "hibernate", "poweroff"…). Pour plus d'informations vous trouverez la documentation de Logind par ici :

Enfin, pour appliquer les modifications sans avoir à redémarrer, vous pouvez exécuter les commandes suivantes (en root) :

sudo systemctl stop systemd-logind
sudo systemctl start systemd-logind

En espérant que cela puisse servir à quelqu'un. ;)

Installer CyanogenMod sur un HTC One (M8)

Je possède un smartphone HTC One (M8), et récemment, il m'a proposé d'effectuer une mise à jour OTA (Over The Air) pour passer d'Android 4.4 (Kitkat) à Android 5.0 (Lollipop). Ce genre de mises à jour, proposées par le constructeur ne pose normalement pas de souci : on appuie sur "OK", la mise à jour se fait, puis le téléphone redémarre sur le nouveau système. Je n'ai malheureusement pas eu cette chance. Au lieu de redémarrer sur le nouveau système, mon téléphone est resté bloqué sur un écran affichant un petit logo rouge-qui-n-annonce-rien-de-bon. De plus, plus aucune commande ne répondait, je ne pouvais même pas éteindre le téléphone (avant de trouver une combinaison de touche pas du tout intuitive grâce à @kyriog).

Un peu dépité et n'obtenant pas d"informations utiles du côté de HTC, je me suis dit qu'il était temps d'essayer autre chose. Je me suis donc lancé dans l'installation de CyanogenMod sur le téléphone, et c'est bien sûr de ça dont nous allons parler dans cet article.

CyanogenMod Cid
Attention : Déverrouiller et installer une ROM alternative sur votre téléphone est susceptible de vous faire perdre votre garantie. De plus, toutes les données présentes sur le téléphone seront supprimées. Si vous n'êtes pas sûr de ce que vous faites et que votre téléphone est encore sous garantie, il peut être préférable de contacter le service client HTC pour procéder à une réparation du terminal.
Note : Je vais réaliser l'intégralité des manipulations de cet article sous Ubuntu Linux. Vous pouvez tout à fait utiliser un autre système d'exploitation (autre distribution Linux, Windows, Mac OS X…) il vous faudra toutefois adapter certaines commandes en fonction de votre système.

Installer les outils nécessaires

Avant de commencer, il nous faut installer adb et fastboot sur notre ordinateur afin de pouvoir communiquer avec notre téléphone :

sudo apt-get install android-tools-adb android-tools-fastboot

Une fois ces outils installés, il faut configurer notre système d'exploitation afin qu'il nous autorise à communiquer avec le téléphone en USB. Pour ce faire, il nous faut créer le fichier "/etc/udev/rules.d/51-android.rules" et y insérer la ligne suivante :

SUBSYSTEM=="usb", ATTRS{idVendor}=="0bb4", MODE="0666"

Pour finir, il faut redémarrer udev :

sudo service udev restart

Voilà, nous sommes maintenant prêts à commencer !

Pour Windows, vous trouverez adb et fastboot sur le forum xda developers. Vous aurez également besoin d'installer HTC Sync Manager qui contient les pilotes USB du téléphone pour Windows.
Pour Mac OS X, vous trouverez adb et fastboot par ici : https://code.google.com/p/adb-fastboot-install/.

Accéder au menu de boot

La première étape de notre périple est de réussir à redémarrer le téléphone sur le bootmenu (il s'agit d'un menu caché accessible au démarrage du téléphone).

Éteindre le téléphone (1)

Dans mon cas, le téléphone est bloqué sur un écran affichant un logo rouge, aucune touche ne semble répondre. Pour le forcer à s'arrêter, il faut maintenir les boutons Power et Volume+ enfoncés pendant 10 secondes.

Remarque¹ : Si contrairement au mien votre téléphone n'est pas bloqué, vous pouvez l'éteindre normalement.
Remarque² : Dans mon cas, le téléphone redémarre immédiatement après avoir été éteint. Il faut donc enchaîner avec l'étape suivante dès que l'écran devient noir.

Redémarrer sur le menu de boot (2)

Pour accéder au bootmenu, une fois le téléphone éteint, il faut le rallumer en maintenant les boutons Power et Volume– enfoncés jusqu'à apparition du menu.

Menu de boot (3)

Maintenant que nous avons atteint le bootmenu, il ne nous reste plus qu'à relier le téléphone à l'ordinateur à l'aide d'un câble USB (le même qui sert à charger le téléphone).

Étapes pour accéder au menu de démarrage du HTC One (M8)

Déverrouiller le téléphone

Pour pouvoir installer une ROM non officielle sur le téléphone, il faut le déverrouiller. Par chance, HTC propose cette procédure sur son site dédié aux développeurs.

Afin de procéder au déverrouillage de l'appareil, il faut commencer par activer le mode fastboot. Pour ce faire,

  1. Mettez "FASTBOOT" en surbrillance en utilisant les boutons Volume+ et Volume– (normalement il devrait déjà être sélectionné).
  2. Appuyez sur le bouton Power pour valider.
  3. Si tout s'est bien passé, le titre du menu doit indiquer "FASTBOOT USB".
Étapes pour accéder au téléphone via fastboot

Maintenant nous allons vérifier que l'ordinateur reconnaît bien le téléphone. Pour cela, ouvrez un terminal puis entrez la commande suivante :

fastboot devices

Si la commande retourne une ligne semblable à celle-ci, vous êtes prêt à passer à la suite, sinon, vérifiez que votre téléphone est bien relié à votre ordinateur et que les permissions sont correctes (voir le passage sur udev dans la première partie de cet article) :

XXXXXXXXXXXX     fastboot

Afin de pouvoir suivre la procédure de déverrouillage sur le site de HTC Dev, il faut commencer par vous y inscrire :

Suivez en suite la procédure indiquée sur cette page :

Peu de temps après avoir suivi les instructions du site, vous devriez recevoir un e-mail contenant en pièce jointe le fichier nécessaire au déverrouillage du téléphone ("Unlock_code.bin"). Une fois cet e-mail reçu, suivez les instructions de la page suivante pour procéder au déverrouillage du téléphone :

Votre téléphone est à présent déverrouillé, nous allons enfin pouvoir entrer dans le vif du sujet.

Flasher l'image recovery

Nous allons à présent installer sur le téléphone un mini système (que l'on appelle recovery) qui va nous permettre de réaliser les diverses opérations nécessaires à l'installation de CyanogenMod (ou de tout autre système Android).

Pour commencer, il faut télécharger ClockworkMod, qui est le recovery que nous allons utiliser par la suite :

Ensuite, il faut démarrer le téléphone en mode fastboot (instructions dans la partie précédente).

Puis enfin, flashez ClockworkMod sur le téléphone à l'aide de la commande suivante (pensez bien à adapter le nom et le chemin du fichier que vous avez téléchargé) :

fastboot flash recovery clockworkmodrecovery.6051.m8.touch.img

Si tout s'est bien passé, la commande devrait retourner une sortie similaire au bout de quelques secondes :

target reported max download size of 1826418688 bytes
sending 'recovery' (13486 KB)...
OKAY [  1.492s]
writing 'recovery'...
OKAY [  0.513s]
finished. total time: 2.005s

Pour finir, nous allons redémarrer le téléphone en mode recovery afin de lancer ClockworkMod :

  • Sélectionnez "HBOOT" à l'aide des boutons Volume+ et Volume–,
  • et validez avec le bouton Power.
  • Puis sélectionnez "RECOVERY" (toujours à l'aide des boutons Volume+ et Volume–),
  • et validez avec… le bouton Power.

Si tout s'est bien passé, vous devriez avoir devant vous le menu de ClockworkMod.

ClockworkMod sur HTC One (M8)

Installer CyanogenMod

Maintenant que nous sommes sur le bootmenu, nous allons pouvoir procéder à l'installation de CyanogenMod.

Télécharger CyanogenMod

Pour commencer, il vous faut télécharger une version de CyanogenMod compatible avec notre téléphone. Prenez la dernière version stable disponible sur cette page :

Effacer toutes les données du téléphone

Ensuite, il faut effacer toutes les données présentes sur le téléphone. Normalement les données ont déjà été effacées lors de la procédure de déverrouillage, mais au cas où, voici là marche à suivre :

  • Sélectionnez l'option "wipe data/factory reset" à l'aide des boutons Volume+ et Volume– et validez en pressant le bouton Power.
  • Confirmez l'effacement en sélectionnant l'option "Yes - Wipe all user data".
Étapes pour effacer les données du téléphone

Envoi et installation de CyanogenMod sur le téléphone

Nous allons maintenant pouvoir installer CyanogenMod sur le téléphone.

Pour commencer, il faut s'assurer que la partition de donnée est bien montée (ça devrait normalement être le cas). Pour ce faire, rendez-vous dans le menu "mounts and storage", puis vérifiez la ligne qui mentionne "/data".

  • S'il est écrit "unmount /data" comme sur l'image ci-dessous, c'est que la partition est bien montée. Quittez le menu sans rien toucher en sélectionnant l'option "+++++Go Back+++++" tout en bas du menu.
  • S'il est écrit "mount /data", sélectionnez cette option afin de monter la partition de donnée puis quittez le menu en sélectionnant l'option "+++++Go Back+++++" tout en bas du menu.
Étapes pour monter la partition de donnée

Ensuite, nous allons envoyer sur le téléphone l'archive zip que nous avons téléchargée. Pour cela, ouvrez un terminal sur votre ordinateur puis entrez-y la commande suivante (en adaptant le nom et le chemin du fichier zip) :

adb push cm-11-20141112-SNAPSHOT-M12-m8.zip /sdcard/

L'opération prend quelques dizaines de secondes. Une fois terminée, le terminal devrait vous afficher une ligne similaire à celle-ci :

12231 KB/s (244823134 bytes in 19.546s)

Enfin, nous allons procéder à l'installation à proprement parler. Prenez votre téléphone, puis effectuez les manipulations suivantes :

  • Sélectionnez "install zip",
  • puis "choose zip from /sdcard",
  • le zip que vous avez envoyé devrait apparaître dans la liste, sélectionnez-le,
  • confirmez l'installation en sélectionnant l'option "Yes - install cm-11-20141112-SNAPSHOT-M12-m8.zip".

Une fois l'installation terminée, vous vous retrouvez de nouveau sur le menu de sélection du zip, et le journal en bas de l'écran devrait afficher "Install from sdcard complete.".

Étapes d'installation de CyanogenMod

Installer les Google App (facultatif)

Maintenant que notre système est installé, nous allons procéder à l'installation des applications Google sur le téléphone. Ceci n'est pas obligatoire, toutefois, si vous ne les installez pas, vous n'aurez pas accès au Play Store, à Google Map, à Youtube, etc.

L'installation des Google App se déroule de la même façon que l'installation de CyanogenMod.

Pour commencer, téléchargez la version des applications Google correspondant à la version de CyanogenMod que vous venez d'installer :

Note : si vous ne savez pas quelle version de CyanogenMod vous avez installé, regardez le nom du zip que vous aviez téléchargé à l'étape précédente. Le nom commence par la version de CyanogenMod (cm-11, cm-12…).

Ensuite, comme précédemment il faut envoyer le zip contenant les Google App sur le téléphone. Ressortez votre terminal et tapez-y la commande suivante (toujours en adaptant les noms de fichiers) :

adb push gapps-kk-20140606-signed.zip /sdcard/

puis, sur votre téléphone :

  • rendez-vous dans le menu "install zip",
  • sélectionnez "choose zip from /sdcard",
  • puis sélectionnez le zip que vous venez d'envoyer,
  • enfin confirmez l'installation en sélectionnant "Yes - install gapps-kk-20140606-signed.zip".

Une fois terminé, vous verrez encore une fois le message "Install from sdcard complete." en bas de votre écran.

Étapes d'installation des Google Apps

Reboot

Vous pouvez à présent redémarrer votre téléphone : retournez dans le menu principal grâce aux options "+++++Go Back+++++" en bas des menus, puis sélectionnez "reboot system now".

Votre téléphone va à présent redémarrer sous CynaogenMod (ça prend un peu de temps la première fois, c'est normal).

C'est reparti \o/

Voilà, votre téléphone fonctionne à nouveau, vous pouvez l'utiliser normalement.

Je vous invite également à lire les pages du wiki de CyanogenMod consacrées au HTC One (M8), et, pour les plus téméraires, à tester d'autres ROMs (les nightly de CyanogenMod 12 par exemple), d'autant que ClockworkMod vous permet de sauvegarder votre système afin de le restaurer rapidement si d'aventure vous tombiez sur une ROM qui ne fonctionnerait pas comme prévu.