Introduction
Dans le précédent article, nous avons décrit la mise en place d'un environnement de compilation afin de produire une image AOSP (Android Open Source Project) utilisable dans l'émulateur Android. Après un premier test d'utilisation, il est temps désormais de présenter ADB (Android Debug Bridge), un outil indispensable au développement Android en général, et système en particulier.
Avec ADB il est possible d'ouvrir des sessions sur les différentes cibles connectées, d'envoyer ou recevoir des fichiers, d'installer ou désinstaller des paquets Android .apk , de redémarrer la cible, et plus encore.
Qu'est-ce qu'ADB ?
ADB est un protocole défini par Google et disponible sur toutes les plate-formes Android. Il a le gros avantage d'unifier les modes d'accès à la plate-forme. ADB peut utiliser différents supports de communication (USB, Ethernet, …). Le bus USB est le plus fréquent mais ADB peut également fonctionner sur Ethernet dans le cas de cartes industrielles.
ADB utilise une architecture « client/serveur », le système est donc constitué de plusieurs éléments :
-
Un agent (démon) /sbin/adbd installé sur la cible dans l'image de démarrage initiale (INITRD) nommée ramdisk.img.
-
Un serveur utilisé sur le poste de développement. Ce serveur est chargé de gérer les connexions au différentes cibles Android. Il est démarré lors de la première connexion à une cible.
-
Un client correspondant à la commande adb.
L'ensemble des éléments est disponible dans l'arbre des sources AOSP. Si l'on ne compile pas AOSP, Les éléments 2 et 3 sont disponibles en binaire dans le SDK (ADT).
Première utilisation d'ADB
La commande adb est le point d'entrée privilégié du système. Outre l'accès à la cible, adb permet également de démarrer ou d'arrêter le serveur. Dans le cas de l'utilisation de l'environnement AOSP, nous rappelons que nous devons préalablement nous placer dans le répertoire de compilation et charger l'environnement par :
$ source build/envsetup.sh
$ lunch 1
La commande adb fait alors partie du chemin de recherche.
$ type adb
adb est /home/pierre/Android/work_google/out/host/linux-x86/bin/adb
Nous pouvons alors démarrer l'émulateur puis utiliser adb pour obtenir la liste des cibles disponibles.
$ emulator &
$ adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
emulator-5554 device
Nous remarquons que l'accès ADB fonctionne bien avant l'activation de l'interface graphique d'Android. En effet, le démon adbd est un des premiers service démarré par Android. Lors d'une première utilisation d'ADB sur un poste de développement, le serveur est automatiquement démarré et utilise le port 5037. Dans le cas présent, une seule cible est détectée mais en cas de cibles multiples, l'option -s nom_de_cible devra être utilisée à chaque commande pour préciser la cible.
Une première utilisation simple est l'ouverture d'une session « shell » sur la cible, ce qui nous permet – par exemple - d'obtenir le type de CPU puis la version du noyau.
$ adb shell
root@generic:/ # cat /proc/version
Linux version 3.4.0-gd853d22 (nnk@nnk.mtv.corp.google.com) (gcc version 4.6.x-google 20120106 (prerelease) (GCC) ) #1 PREEMPT Tue Jul 9 17:46:46 PDT 2013
root@generic:/ # cat /proc/cpuinfo
Processor : ARMv7 Processor rev 0 (v7l)
BogoMIPS : 594.73
Features : swp half thumb fastmult vfp edsp neon vfpv3 tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc08
CPU revision : 0
Hardware : Goldfish
Revision : 0000
Serial : 0000000000000000
On peut également exécuter directement une commande sur la cible par :
$ adb shell ls /system
app
bin
build.prop
etc
fonts
framework
lib
lost+found
media
tts
usr
xbin
Transfert de fichier
Le développement système nécessite souvent de transférer des fichiers depuis ou vers la cible. ADB simplifie largement le travail par rapport aux habituels SSH, HTTP et autres FTP utilisés sous GNU/Linux. Pour transférer un fichier vers la cible on pourra faire :
$ adb push /etc/issue /data
0 KB/s (26 bytes in 0.042s)
Puis vérifier par :
$ adb shell cat /data/issue
Ubuntu 12.04.4 LTS \n \l
Pour transférer un fichier de la cible vers le poste de développement, on fera :
$ adb pull /proc/cpuinfo
3 KB/s (277 bytes in 0.087s)
On vérifie par :
$ cat cpuinfo
Processor : ARMv7 Processor rev 0 (v7l)
BogoMIPS : 594.73
…
Il est important de noter que seul le répertoire /data est monté en lecture/écriture sur la cible. Ce répertoire est donc le seul utilisable pour cette opération.
$ adb push /etc/issue /system
failed to copy '/etc/issue' to '/system/issue': Read-only file system
Installation et suppression de paquet
ADB permet d'installer facilement un paquet .apk sur la cible par la commande :
$ adb install HelloJni.apk
2054 KB/s (184605 bytes in 0.087s)
pkg: /data/local/tmp/HelloJni.apk
Success
ADB se charge de transférer le fichier .apk puis de l'installer.
Une fois installé, le paquet apparaît sous le nom de sa classe, soit com.x.y. On peut rechercher le nom sur la cible en utilisant la commande pm (Package Manager) puis utiliser ce nom pour supprimer le paquet.
$ adb shell pm list packages | grep hello
package:com.example.hellojni
$ adb uninstall com.example.hellojni
Success
Connexion par Ethernet/IP
Le protocole Ethernet est souvent utilisé sur les systèmes industriels ou bien sur des PC tournant sous Android. La séquence suivante permet d'établir la connexion à la cible à partir de son adresse IP. Une fois la connexion établie il est possible d'ouvrir une session shell. L'exemple ci-dessous montre cela pour une machine de type x86.
$ adb connect 10.5.19.234
$ adb shell
root@x86:/ # uname -m
i686
Manipulation des traces Android
Android utilise un système de trace spécifique accessible par la commande logcat. Ce système est équivalent à syslog sous GNU/Linux. La commande suivante affiche les traces de la cible Android contenant la chaîne zygote dans le flux de traces. Zygote correspond à un service fondamental d'Android démarré à l'initialisation des services Java.
$ adb logcat | grep zygote
I/Zygote ( 294): Process: zygote socket opened
Liste des principales commandes
Le tableau ci-dessous donne la liste des principales commandes ADB.
start-server |
Démarre le serveur hôte |
kill-server |
Arrête le serveur hôte |
devices |
Affiche la liste des devices (cibles) |
connect |
Connexion à une cible par le port 5555 |
disconnect |
Déconnexion de la cible |
help |
Aide |
version |
Affichage du numéro de version |
shell [cmd] |
Démarrage d'une session « shell » sur la cible et exécution (optionnelle) de cmd |
push |
Copie un fichier vers la cible |
pull |
Copie un fichier depuis la cible |
install |
Installe une application (paquet .apk) |
uninstall |
Supprime une application (com.*) |
logcat |
Affiche les traces |
reboot |
Redémarrage de la cible |
forward |
Redirige un port (utilisé pour GDB et l'émulateur) |
Conclusion
Cet article nous a permis d'introduire l'outil ADB afin d'explorer un peu mieux l'image AOSP produite précédemment. Dans une prochaine publication nous verrons comment modifier l'image en compilant (entre autres) un noyau Linux adapté à l'émulateur.
Bibliographie