diff --git a/script/todo/todo.py b/script/todo/todo.py index c52eb40..48f4394 100755 --- a/script/todo/todo.py +++ b/script/todo/todo.py @@ -5781,6 +5781,13 @@ class TODO: f"'cd {el_dir} && ./script/manifest/update_manifest_local_mobile.sh; " "test -f mobile/erplibre_home_mobile/install-android.sh' && " f'mstep "{t("prerequisites of the upstream installer")}" ' + # libpulse0 : l'émulateur a DEUX binaires qemu, et seul le + # « headless » se passe de PulseAudio. Celui qui ouvre une FENÊTRE — + # le cas d'un « ssh -X » — lie libpulse.so.0, absente des images + # cloud, et s'arrête sur « cannot open shared object file » même + # avec « -no-audio ». Mesuré : c'est la SEULE bibliothèque qui + # manque, tout le reste des dépendances Qt voyage dans le bundle. + # # openjdk-21 EN PLUS du 17 que pose l'installateur amont : mesuré, # Gradle s'arrête sur « Cannot find a Java installation matching # {languageVersion=21} » — les modules de Capacitor 8 réclament 21. @@ -5788,7 +5795,7 @@ class TODO: # unzip et xauth, eux, manquent des images cloud. "'sudo DEBIAN_FRONTEND=noninteractive apt-get " "-o DPkg::Lock::Timeout=600 install -y unzip wget xauth " - "openjdk-21-jdk' && " + "libpulse0 openjdk-21-jdk' && " # L'installateur amont n'est PAS idempotent : au second passage il # s'arrête sur « mv: cannot overwrite latest/cmdline-tools ». Mesuré. # On ne le rejoue donc que s'il reste quelque chose à poser — un @@ -5932,10 +5939,16 @@ class TODO: # La commande à copier, avec l'adresse déjà remplie : un émulateur # dont on ignore comment l'ouvrir ne sert à personne. "ip=$(hostname -I 2>/dev/null | awk '{print $1}'); " + # Chemins ABSOLUS, et c'est le point : « ssh hôte 'commande' » + # ne lit NI ~/.profile NI ~/.bashrc — Ubuntu place même un + # « return » en tête du second pour les shells non interactifs. + # Le PATH que l'installateur y écrit ne s'applique donc jamais + # à ces commandes, et « emulator » y répond « command not + # found ». Vécu, sur la ligne que ce message affichait lui-même. f'echo " {t("open it from your workstation:")} ' - 'ssh -X erplibre@$ip \\"emulator -avd erplibre -no-audio\\""; ' + 'ssh -X erplibre@$ip \\"$HOME/android/emulator/emulator -avd erplibre -no-audio\\""; ' f'echo " {t("then install the APK:")} ' - 'ssh erplibre@$ip \\"adb install -r ' + 'ssh erplibre@$ip \\"$HOME/android/platform-tools/adb install -r ' f"{el_dir}/mobile/erplibre_home_mobile/android/app/build" '/outputs/apk/debug/app-debug.apk\\""' ) diff --git a/test/test_qemu_desktop_tools.py b/test/test_qemu_desktop_tools.py index ec65625..e2db8e6 100644 --- a/test/test_qemu_desktop_tools.py +++ b/test/test_qemu_desktop_tools.py @@ -413,6 +413,21 @@ class TestAndroidEmulator(unittest.TestCase): self.assertIn("ssh -X erplibre@$ip", self.cmd) self.assertIn("adb install -r", self.cmd) + def test_the_printed_commands_use_absolute_paths(self): + """« ssh hôte 'commande' » ne lit ni ~/.profile ni ~/.bashrc — Ubuntu y + met même un « return » pour les shells non interactifs. Une commande + affichée qui compte sur le PATH répond « command not found ». Vécu.""" + self.assertIn("$HOME/android/emulator/emulator", self.cmd) + self.assertIn("$HOME/android/platform-tools/adb", self.cmd) + self.assertNotIn('"emulator -avd', self.cmd) + self.assertNotIn('"adb install', self.cmd) + + def test_the_windowed_emulator_gets_its_audio_library(self): + """Deux binaires qemu : seul le « headless » se passe de PulseAudio. + Celui qui ouvre une fenêtre lie libpulse.so.0, absente des images + cloud, et échoue même avec « -no-audio ».""" + self.assertIn("libpulse0", self.cmd) + def test_one_prologue_and_one_sdk_for_both_options(self): """Deux prologues, et le second tronquerait le journal du premier.""" both = self.todo._qemu_after_remote_cmd(("mobile", "avd"))