260826-Secure Virtual Machine et Emulateur Android

Mise en place d'un émulateur Android sur le poste julie pour faire tourner des applications de presse (The Guardian, Le Monde) et d'autres APK. Séance du 2026-08-26.

Trois obstacles se sont enchaînés, chacun avec un diagnostic trompeur : la virtualisation matérielle absente, un pilote d'accélération dont l'installation échoue en silence, et un faux écran noir. Cette page retient surtout les pièges, parce que chacun a coûté plusieurs allers-retours.

Contexte et matériel

Élément Valeur
Poste julie — MSI A320M-A PRO (MS-7C51), BIOS E7C51AMS.140 du 12/08/2020
CPU AMD Ryzen 5 2600X, 6 cœurs / 12 threads
RAM 16 Go
GPU Radeon RX 6500 XT, pilote du 18/01/2022 (voir page 249)
Écran dalle 4K 3840x2160, bureau logique 2560x1440 (mise à l'échelle 150 %)
OS Windows 10 19045, firmware UEFI, démarrage rapide actif

1. Activer la virtualisation (SVM)

Le symptôme

systeminfo répondait Virtualisation activée dans le microprogramme : Non, alors que le CPU est parfaitement capable de SVM. Sans virtualisation, aucun émulateur Android ne fonctionne — BlueStacks, LDPlayer, MEmu, Nox, Genymotion et l'AVD d'Android Studio sont tous des machines virtuelles x86. Changer d'émulateur ne contourne pas le problème.

Vérification préalable qu'aucune cause logicielle n'était en jeu :

Get-CimInstance Win32_ComputerSystem | Select-Object HypervisorPresent          # False
(Get-CimInstance -Namespace root\Microsoft\Windows\DeviceGuard `
  -ClassName Win32_DeviceGuard).VirtualizationBasedSecurityStatus               # 0

Aucun hyperviseur actif, pas de VBS : ni Hyper-V ni l'isolation du noyau ne confisquaient la virtualisation. La cause était donc bien dans le firmware.

Le chemin dans le BIOS

Ce poste a l'ancienne interface MSI Click BIOS à onglets horizontaux, pas la version récente à tuiles. Donc ni EZ Mode, ni touche F7, ni OC Explore Mode à chercher — toutes indications que l'on trouve partout en ligne et qui ne s'appliquent pas ici.

Touche d'entrée dans le BIOS sur cette machine : F11. Plus fiable, le démarrage rapide étant actif : Paramètres → Mise à jour et sécurité → Récupération → Démarrage avancé → Redémarrer maintenant → Dépannage → Options avancées → Changer les paramètres du microprogramme UEFI.

Chemin réel du réglage :

Overclocking → (section Other Setting, tout en bas) → Caractéristique du CPU → SVM Mode

Caractéristique du CPU est la traduction française de CPU Features.

Piège n°1 — deux sous-menus qui se ressemblent

La section Other Setting du menu Overclocking contient trois entrées :

CPU Specifications        -> INFORMATIONS, lecture seule
MÉMOIRE-Z                 -> informations RAM
Caractéristique du CPU    -> LES RÉGLAGES

CPU Specifications → CPU Technology Support affiche une fiche technique :

Secure Virtual Machine        YES

Ce « YES » ne signifie pas que SVM est activé — seulement que le processeur en est capable. C'est une page de consultation.

Règle pour distinguer d'un coup d'œil : dans ce BIOS, un réglage modifiable est toujours entre crochets (A-XMP [Désactivé], NX Mode [Activé], SVM Mode [Activé]). Une valeur en texte nu (YES, N/A, 3.60GHz) est informative.

Piège n°2 — la vraie cause : il faut couper le secteur

Contenu réel de Overclocking\Caractéristique du CPU :

Simultaneous Multi-Threading   [AUTO]
Global C-state Control         [AUTO]
Opcache Control                [AUTO]
IOMMU                          [AUTO]
Spread Spectrum                [AUTO]
Relaxed EDC throttling         [AUTO]
AMD Cool'n'Quiet               [Activé]
NX Mode                        [Activé]
SVM Mode                       [Activé]   <-- déjà correct
Power Supply Idle Control      [AUTO]

Le réglage était déjà bon, et Windows répondait pourtant Non.

Ce qui a débloqué : le débranchement de la prise pendant 10 secondes. Après quoi :

Virtualisation activée dans le microprogramme : Oui
VirtualizationFirmwareEnabled                 : True

Sur cette carte, un SVM Mode correctement réglé peut rester invisible du système tant qu'il n'y a pas eu de vraie coupure secteur. Un redémarrage, et même un arrêt Windows normal, ne suffisent pas — le démarrage rapide maintient un état résiduel. Débrancher d'abord, diagnostiquer ensuite.

Ne pas toucher aux autres lignes, en particulier laisser IOMMU et Simultaneous Multi-Threading sur [AUTO].

Fiche pas-à-pas réutilisable : Jux-scripts/PC-Health/bios_svm_a320m.md.

2. Android Studio

winget install -e --id Google.AndroidStudio --accept-package-agreements --accept-source-agreements

Version installée : 2026.1.3.7, 3,29 Go dans C:\Program Files\Android\Android Studio.

Installation en mode Custom pour accéder aux composants. Composants retenus :

Composant Version Rôle
Android Emulator 37.1.11 l'émulateur
Android SDK Platform-Tools 37.0.1 adb
Android SDK Command-line Tools 23.0.0 avdmanager, diagnostics
Android Emulator hypervisor driver 2.2.0 accélération AMD — voir section suivante

Symptôme si le pilote manque : l'assistant marque Android Virtual Device comme indisponible, et n'installe ni l'émulateur ni les platform-tools. Ce n'est pas un échec du BIOS — il manque juste la couche d'accélération.

Note : sdkmanager est déprécié et son remplaçant android est encore incomplet (android sdk list ne liste que l'installé). Passer par l'interface pour tout ce qui touche aux images système.

3. Le pilote AEHD — installation manuelle

Pourquoi ce pilote

Sur un CPU AMD sous Windows, l'émulateur a besoin de l'un des deux mécanismes suivants :

Mécanisme Prérequis Retenu ?
AEHD (Android Emulator Hypervisor Driver) SVM activé, Hyper-V absent Oui — correspond à la configuration du poste
WHPX Hyper-V + Windows Hypervisor Platform installés Non — alourdirait le système

Piège n°3 — le SDK Manager échoue et efface ses traces

Sortie observée :

Installing Android Emulator hypervisor driver (installer) in ...\extras\google\Android_Emulator_Hypervisor_Driver
"Install Android Emulator hypervisor driver (installer) v.2.2.0" complete.
Failed to update status to COMPLETE
"Install Android Emulator hypervisor driver (installer) v.2.2.0" failed.

Le paquet se télécharge et s'extrait, puis l'étape d'installation du pilote échoue faute d'élévation, et le gestionnaire annule l'extraction : extras\google se retrouve vide. Il ne reste donc rien à réparer sur place — il faut repartir du paquet d'origine.

La réparation

New-Item -ItemType Directory -Force 'D:\temp_aehd' | Out-Null
Invoke-WebRequest -Uri 'https://dl.google.com/android/repository/aehd-windows_v2.2.zip' `
                  -OutFile 'D:\temp_aehd\aehd.zip'
Expand-Archive 'D:\temp_aehd\aehd.zip' -DestinationPath 'D:\temp_aehd\x' -Force
Start-Process -FilePath 'cmd.exe' -Verb RunAs -Wait -ArgumentList `
  '/c','"cd /d D:\temp_aehd\x && silent_install.bat > D:\temp_aehd\out.txt 2>&1"'

Piège MSIX — utiliser D: et non le dossier temporaire habituel. Claude Code tourne dans un conteneur MSIX : ce qu'il écrit sous %LOCALAPPDATA% atterrit en réalité dans …\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Local\. Un installeur lancé en élevé sort du conteneur et ne verrait pas ces fichiers. Même famille de piège que le home Syncthing (voir la section « Poste Windows julie » du CLAUDE.md).

Contenu du paquet : aehd.Sys (403 Ko), aehd.cat, aehd.Inf, silent_install.bat. Le script installe via RUNDLL32 SETUPAPI.DLL,InstallHinfSection puis lance le service. Désinstallation : silent_install.bat -u.

Résultat :

SERVICE_NAME: aehd
        TYPE  : 1  KERNEL_DRIVER
        STATE : 4  RUNNING

Vérification

& 'D:\Android\Sdk\emulator\emulator.exe' -accel-check

Attendu : AEHD (version 2.2) is installed and usable. et code de retour 0.

4. L'AVD

Choix retenus

Profil Pixel Tablet en paysage : l'écran du PC est large, et Guardian comme Le Monde ont de vraies mises en page tablette (multi-colonnes). Un profil téléphone donnerait une colonne étroite au milieu d'un grand écran.

Ce qui déclenche la mise en page tablette, c'est la largeur en dp, pas en pixels : 1600 / (320/160) = 800 dp, au-delà du seuil de 600 dp.

Si aucun profil tablette ne porte l'icône Play Store, ne pas se rabattre sur un téléphone : prendre un profil téléphone avec Play Store, puis régler dans Edit une résolution de 1920x1200 en 240 dpi (soit 800 dp). On garde le Play Store et la mise en page large.

Image système

system-images\android-35\google_apis_playstore_tablet\x86_64
Android 15, API 35

La variante « Google Play » est indispensable pour installer les applications depuis le Store. C'est une build de production : adb root y est impossible, mais adb install fonctionne normalement.

Traduction ARM confirmée — point décisif pour les APK récupérés ailleurs :

ro.product.cpu.abilist = x86_64,arm64-v8a

Les images x86_64 en API 30 et plus traduisent l'ARM 64 bits à la volée. Sans cela, un APK ARM échoue sur INSTALL_FAILED_NO_MATCHING_ABIS.

Piège n°4 — les réglages avancés ne s'appliquent pas à la création

Valeurs demandées dans l'assistant, valeurs réellement écrites :

Réglage Demandé Obtenu Corrigé en
hw.ramSize 4096 2048 6144
vm.heapSize — 192 512
disk.dataPartition.size 16 Go 10 Go 10 Go (suffisant)
hw.cpu.ncore 4 4 4

Plus simple que de rechercher le Device Manager dans l'interface : éditer directement, émulateur arrêté (il réécrit son fichier en quittant).

C:\Users\julie\.android\avd\Pixel_Tablet.avd\config.ini

hw.ramSize=6144
vm.heapSize=512
hw.cpu.ncore=4
disk.dataPartition.size=10G
hw.gpu.mode=auto

vm.heapSize est le réglage sous-estimé : c'est le plafond mémoire par application, distinct de la RAM totale. À 192 Mo, une application de presse chargeant beaucoup d'images se fait tuer sans message. C'était le vrai goulet d'étranglement, davantage que les 2 Go de RAM.

Sauvegarde : config.ini.bak-260826. Vérification côté invité : MemTotal: 6072156 kB — l'écart avec 6144 Mo est la part réservée par le noyau, c'est normal.

Augmenter le stockage après coup impose un effacement des données. C'est le seul réglage à ne pas rater à la création.

5. Piège n°5 — le faux écran noir

Le symptôme

Après quelques minutes, écran entièrement noir. La capture prise depuis l'intérieur d'Android était noire elle aussi — ce qui semblait exclure un simple problème de fenêtre Windows et accusait la pile graphique, d'autant que le journal de l'émulateur contenait :

UpdateLayeredWindowIndirect failed ... (Un périphérique attaché au système ne fonctionne pas correctement)

avec un pilote AMD de janvier 2022 comme suspect tout désigné.

La vraie cause

mWakefulness=Dozing

L'écran s'était simplement mis en veille, comme sur une vraie tablette. Et le volet de notifications était resté déployé par-dessus (mCurrentFocus=NotificationShade), ce qui gardait l'affichage noir même après réveil.

Aucune erreur graphique dans logcat. Le pilote AMD était hors de cause.

Méthode de diagnostic, dans cet ordre

$adb = 'D:\Android\Sdk\platform-tools\adb.exe'
& $adb devices                                              # le système répond-il ?
& $adb shell getprop sys.boot_completed                     # 1 = démarrage fini
& $adb shell dumpsys power   | Select-String mWakefulness   # Dozing / Asleep / Awake
& $adb shell dumpsys window  | Select-String mCurrentFocus  # quelle fenêtre au premier plan

Réveil et retour à l'accueil :

& $adb shell input keyevent 224        # KEYCODE_WAKEUP
& $adb shell cmd statusbar collapse    # referme le volet de notifications
& $adb shell input keyevent 3          # HOME

BACK et HOME ne referment PAS le volet de notifications quand il reste bloqué ouvert après un réveil. Seul cmd statusbar collapse y parvient. Symptôme : mWakefulness=Awake mais mCurrentFocus=NotificationShade et une capture toujours à ~19 Ko.

Le piège de stay_on_while_plugged_in

Ce réglage n'agit que si l'appareil se déclare en charge. Après un -wipe-data, la batterie virtuelle repart sur AC powered: false — et l'écran se remet donc en veille malgré stay_on = 7. Il faut forcer l'alimentation secteur :

& $adb shell dumpsys battery set ac 1
& $adb shell dumpsys battery set status 2

Vérification :

& $adb shell dumpsys battery | Select-String 'AC powered|status'

Attendu : AC powered: true et status: 2. À refaire après chaque effacement des données, en même temps que les deux settings put.

Indice utile : le poids de la capture d'écran. 23 Ko = écran noir, ~3 Mo = interface réellement dessinée.

& $adb shell screencap -p /sdcard/s.png; & $adb pull /sdcard/s.png D:\s.png

Le correctif

& $adb shell settings put global stay_on_while_plugged_in 7
& $adb shell settings put system screen_off_timeout 1800000

stay_on_while_plugged_in = 7 couvre secteur + USB + sans-fil. L'émulateur se déclarant toujours « en charge », l'écran ne s'éteint plus jamais. Le réglage persiste au redémarrage (il vit sur la partition de données).

6. Piège n°6 — le plus coûteux : ne jamais lancer un installeur depuis Claude Code

Android Studio a été lancé par Claude Code via Start-Process. Un processus enfant hérite du conteneur MSIX du parent. Android Studio a donc tourné dans le conteneur, et tout ce qu'il a écrit sous %LOCALAPPDATA%\Android\Sdk est parti dans :

C:\Users\julie\AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Local\Android\Sdk

Pourquoi c'est indétectable de l'intérieur

Le symptôme n'apparaît qu'en dehors de Claude : un double-clic sur le raccourci du bureau donnait

Windows ne trouve pas 'D:\Android\Sdk\emulator\emulator.exe'

Le même piège sur les raccourcis

Un .lnk créé par WScript.Shell depuis le conteneur résout et fige la cible en chemin virtualisé :

Target : C:\Users\julie\AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Local\Android\Sdk\emulator\emulator.exe

Le raccourci ne fait alors rien du tout, sans message. Les arguments, eux, sont stockés littéralement — d'où un contournement possible : viser cmd.exe (dans System32, non virtualisé) et passer le vrai chemin en argument.

Correctif retenu

Le SDK a été sorti sur D:\Android\Sdk, hors de toute virtualisation :

robocopy 'C:\Users\julie\AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Local\Android\Sdk' `
         'D:\Android\Sdk' /E /MT:8

Puis : skin.path corrigé dans config.ini, raccourci repointé sur D:\Android\Sdk\emulator\emulator.exe. L'émulateur retrouve seul sa racine SDK à partir de son propre emplacement (Found systemPath D:\Android\Sdk\system-images\...). Le dossier .android (les AVD) n'était pas concerné : il vit à la racine du profil, hors LocalAppData.

Preuve directe de la redirection de %APPDATA% (2026-08-26) : après que l'utilisateur a repointé le SDK, le fichier %APPDATA%\Google\AndroidStudio2026.1.3\options\android.sdk.path.xml affichait

Deux contenus différents pour un chemin identique. La redirection ne concerne donc pas que %LOCALAPPDATA% : %APPDATA% (Roaming) l'est aussi. Conséquence pratique : depuis une session Claude, on ne peut pas relire un réglage écrit par une application lancée hors conteneur — la vérification revient à l'utilisateur.

Règles à retenir

  1. Ne jamais faire lancer un installeur ou un IDE par Claude Code. L'utilisateur le lance lui-même depuis le menu Démarrer.
  2. Ne jamais installer sous %LOCALAPPDATA% sur ce poste — préférer D:.
  3. Un .lnk créé depuis Claude vers une cible sous %LOCALAPPDATA% est cassé par construction.
  4. Pour vérifier : comparer le chemin réel et …\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Local\…. Deux tailles identiques = c'est le même dossier redirigé.

Même famille que le piège du home Syncthing (D:\SyncthingHome) documenté dans CLAUDE.md.

7. Piège n°7 — le multi-écrans casse l'AVD

Une configuration d'écrans multiples essayée depuis l'interface a rendu la tablette inutilisable. Elle laisse des lignes dans config.ini :

hw.display1.width = 2160
hw.display1.height = 3840
hw.display1.density = 640
hw.display1.flag = 1739

Un Wipe Data seul ne les enlève pas — elles vivent dans config.ini, pas dans les données invité. Remise en état, émulateur arrêté :

  1. supprimer toutes les lignes hw.displayN.* de config.ini
  2. redémarrer avec -wipe-data -no-snapshot-load
  3. réappliquer les réglages invités — stay_on_while_plugged_in et screen_off_timeout sont effacés par le wipe

Vérification du retour à un seul écran :

& 'D:\Android\Sdk\platform-tools\adb.exe' shell dumpsys SurfaceFlinger --display-id

Une seule ligne attendue.

8. Point de restauration de la tablette

Une fois la tablette configuree - langue francaise, compte Google connecte, Play Store fonctionnel - cet etat vaut la peine d'etre fige. Le reconstituer a la main prend une bonne demi-heure.

Ce qu'il ne faut PAS utiliser : l'instantane interne

L'emulateur sait enregistrer des instantanes (snapshots\\), mais ils sont a ecarter comme sauvegarde :

Ce sont des caches de demarrage rapide, pas des sauvegardes.

La bonne methode : copie froide du dossier AVD

Emulateur arrete - copier un qcow2 en cours d'ecriture donne une image incoherente.

& 'D:\Android\Sdk\platform-tools\adb.exe' -s emulator-5554 emu kill
Get-Process emulator,qemu-system-x86_64 -ErrorAction SilentlyContinue | Stop-Process -Force

$d = "D:\Android\Backups\Pixel_Tablet_$(Get-Date -Format 'yyMMdd')"
robocopy 'C:\Users\julie\.android\avd\Pixel_Tablet.avd' "$d\Pixel_Tablet.avd" /E /XD snapshots tmpAdbCmds /R:1 /W:1
Copy-Item 'C:\Users\julie\.android\avd\Pixel_Tablet.ini' "$d\Pixel_Tablet.ini" -Force
compact /c /s /i /f /exe:LZX "$d\*"

/XD snapshots tmpAdbCmds retire l'instantane : 9,06 Go -> 4,06 Go. Apres restauration, le premier demarrage sera simplement a froid.

Sur la compression

La compression NTFS LZX est transparente - rien a decompresser a la restauration. Mais le gain est faible : 4,06 Go -> 3,26 Go, soit 1,2 pour 1 seulement. Les donnees de userdata sont deja denses.

Ne pas chercher mieux avec une archive 7z : on gagnerait peut-etre 1 Go, au prix d'une etape de decompression au moment ou l'on est presse. Compter ~3,3 Go par point de restauration et faire le menage dans les anciens.

Repartition du volume

Fichier Taille
userdata-qemu.img.qcow2 2 430 Mo
sdcard.img 512 Mo
cache.img.qcow2 + cache.img 137 Mo
snapshots\\ ~6 Go - exclu

Restaurer

  1. arreter l'emulateur et verifier qu'aucun processus ne subsiste
  2. renommer l'AVD abime plutot que le supprimer (Pixel_Tablet.avd.casse-AAMMJJ)
  3. robocopy de la sauvegarde vers C:\Users\julie\.android\avd\Pixel_Tablet.avd, plus le .ini
  4. redemarrer avec -no-snapshot-load
  5. ecran noir eventuel = veille, voir la section 5

Ce que la sauvegarde ne contient PAS

Si le PC lui-meme est reinstalle, il faut d'abord remettre en place, dans cet ordre :

  1. SVM dans le BIOS - avec la coupure secteur (section 1)
  2. le pilote AEHD - sans lui l'emulateur ne demarre pas (section 3)
  3. le SDK sur D:\Android\Sdk - jamais sous %LOCALAPPDATA% (section 6)

Emplacement

D:\Android\Backups\Pixel_Tablet_260826\
    Pixel_Tablet.avd\
    Pixel_Tablet.ini
    RESTAURATION.md      <- procedure complete, sur place

Piege annexe

Une redirection > D:\dossier\fichier.log dans un cmd /c echoue silencieusement si le dossier n'existe pas - et l'emulateur n'est alors jamais lance. Symptome : aucun processus, journal de 0 octet. Verifier l'existence du dossier de log avant de conclure a une panne de l'emulateur.

9. Piège n°8 — l'horloge de la tablette dérive et casse les applications

Symptôme trompeur : une application (ici Le Monde) semble privée d'Internet alors que la tablette navigue normalement. Le pare-feu Portmaster affiche au même moment une notification Blocked Bypass Attempt by Netsimd qui n'est pas la cause et détourne tout le diagnostic. Son conseil — « désactiver Secure DNS dans Netsimd » — est de surcroît inapplicable : netsimd.exe est le démon réseau de l'émulateur, il n'a aucun réglage de DNS sécurisé.

Le vrai défaut

L'AVD reprend un instantané (Quick boot) : au réveil, l'horloge invitée repart de l'heure figée au moment de la sauvegarde et ne se recale pas sur celle du PC. Écart mesuré le 2026-08-31 : 4 jours et 18 heures de retard.

Les serveurs rejettent alors toute requête signée. La preuve tient en une ligne d'adb logcat :

[LOGGER] error sending logs to kinesis - Signature expired:
20260826T234130Z is now earlier than 20260831T182829Z

AWS SigV4 tolère 5 minutes d'écart, pas 5 jours. Tout ce qui repose sur une signature ou une expiration de jeton tombe : connexion, abonnement, contenus.

⚠ auto_time = 1 ne protège pas. Le réglage « heure automatique » était bien actif et n'a rien rattrapé — il ne couvre pas la reprise d'instantané. Le vérifier ne sert à rien.

Correctif

Device Manager → arrêter la tablette → menu ⋮ → Cold Boot.

⚠ L'option n'apparaît pas tant que la tablette tourne : le menu propose Stop à la place. C'est ce qui fait qu'on ne la trouve pas. Le libellé a par ailleurs perdu son « Now » dans les versions récentes.

Durablement, pour que la dérive ne revienne pas : Edit → Show Advanced Settings → Boot option → Cold boot. Équivalent dans %USERPROFILE%\.android\avd\Pixel_Tablet.avd\config.ini :

fastboot.forceColdBoot = yes
fastboot.forceFastBoot = no

⚠ Android Studio n'écrit config.ini qu'à sa fermeture. Après un changement dans l'interface, relire le fichier avant de conclure que le réglage est pris.

⚠ adb shell date -s ne marche pas : l'image google_apis_playstore n'est pas rootable. Le démarrage à froid est la seule voie.

⚠ Ce chemin n'est PAS redirigé par le conteneur MSIX. C:\Users\julie\.android\ n'est ni %LOCALAPPDATA% ni %APPDATA% — vérifié le 2026-08-31, aucun jumeau sous …\Packages\Claude_pzs8sxrjxfjjc\LocalCache\. Une écriture y est donc réelle, contrairement au piège n°6.

Vérification

Comparer les époques, pas l'affichage : la tablette est en GMT, le PC en heure de Paris.

adb shell date +%s ; date +%s

Attendu : quelques secondes d'écart au plus. Après recalage le 2026-08-31 — écart 1 seconde, Signature expired disparu, application fonctionnelle.

Méthode de diagnostic, dans cet ordre

1. Écarter le pare-feu d'abord. Sa notification est bruyante et fausse la piste. Mesurer la connectivité réelle depuis l'invité :

adb shell ping -c 2 8.8.8.8
adb shell curl -s -o /dev/null -w '%{http_code}' http://connectivitycheck.gstatic.com/generate_204

HTTP 204 est la réponse qu'Android attend pour se déclarer connecté. Si elle arrive, Portmaster est hors de cause.

2. Comparer les horloges. Contrôle le moins cher et le plus rentable — il aurait fait gagner toute la séance.

3. Lire le journal de l'application, pas seulement celui du pare-feu :

adb logcat -d --pid $(adb shell pidof com.lemonde.androidapp)

C'est là, et nulle part ailleurs, que se trouvait Signature expired.

⚠ monkey affiche not connected dans ses statistiques réseau même quand tout va bien : c'est sa comptabilité interne, pas l'état de ConnectivityManager. Se fier à dumpsys connectivity, qui doit montrer IS_VALIDATED.

⚠ Un logcat peut être périmé sans le dire : le tampon affichait encore des lignes datées du 26/08 alors qu'on était le 31/08 — conséquence directe de la dérive. Vider (adb logcat -c) et relancer l'application avant de conclure.

⚠ Le TLS n'était PAS cassé malgré 5 jours d'écart : curl depuis l'invité rendait 200/301/404. Une horloge en retard ne casse que les certificats émis après elle. Ne pas s'arrêter à ce test pour disculper l'horloge.

Ce que Portmaster bloquait réellement

Un seul blocage légitime à lever : cmp.lemonde.fr, la plateforme de consentement du Monde, classée traceur par la liste TRAC. Bloquée, l'application reste sur son écran de consentement — ce qui ressemble à une panne de réseau. Règle posée dans Outgoing Rules → Allow.

⚠ Deux profils netsimd.exe coexistent dans Portmaster, séquelle du piège n°6 : l'ancien sous …\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Local\Android\Sdk\ (mort depuis le 26/08) et le vrai sur D:\Android\Sdk\emulator\. Portmaster identifie les applications par chemin de binaire : une règle posée sur le mauvais profil ne fait rien, sans le moindre message.

⚠ Ne pas taper le + dans le champ de la règle — le menu Allow le pose lui-même, et + + cmp.lemonde.fr échoue sur la regex de validation. Même piège que les Incoming Rules (CLAUDE.md, section « Portmaster »). À noter : Outgoing Rules est de niveau user, donc visible en mode Simple, contrairement aux Incoming Rules.

Le reste est voulu : ws.batch.com, tracking.purchasely.io, logs13.xiti.com, firebase-settings.crashlytics.com sont des traceurs. ws.batch.com reboucle indéfiniment — 4 224 requêtes en une journée, toutes les 2 à 6 secondes — c'est bruyant dans le journal et sans effet sur l'application. Ne pas l'autoriser pour faire taire le journal.

Portmaster laisse passer NTP (time.google.com accepté) : il n'est pour rien dans la dérive d'horloge.

9. Piège n°8 — « auto » choisit le rendu LOGICIEL (lavapipe)

2026-09-02. Retours d'usage : tablette peu réactive, vidéo saccadée, son défaillant, « bord blanc inutile », écran trop petit. Tout venait d'une seule cause.

Le diagnostic décisif : comparer les DEUX fichiers

config.ini porte ce qu'on a demandé. hardware-qemu.ini porte ce que l'émulateur a réellement retenu au dernier lancement. C'est ce second fichier qu'il faut lire.

config.ini         hw.gpu.mode = auto
hardware-qemu.ini  hw.gpu.mode = lavapipe     <-- rasteriseur Vulkan LOGICIEL

lavapipe, c'est le processeur qui dessine tout. Le GPU ne fait rien. À 2560x1600, cela représente 4,1 millions de pixels par image à la charge du CPU — d'où la lenteur, les saccades vidéo, et le son qui décroche (l'audio est sous-alimenté quand le CPU sature).

Chaîne d'échecs visible dans le journal de l'émulateur :

Failed to load [...\qemu\windows-x86_64\lib64\vulkan\vulkan-1.dll]
[Vulkan Loader] Registry lookup failed to get layer manifest files
Critical: Failed to load opengl32sw
Warning: Software OpenGL failed. Falling back to system OpenGL.

Le chemin Vulkan échoue, et auto se rabat silencieusement sur le logiciel. Aucun message d'erreur visible dans l'interface.

Correctif

hw.gpu.mode = host

Vérification après relance — c'est le seul test qui compte :

Get-Content 'C:\Users\julie\.android\avd\Pixel_Tablet.avd\hardware-qemu.ini' | Select-String 'gpu.mode'

Doit répondre host. Si host donne des artefacts, essayer angle_indirect (OpenGL traduit en Direct3D 11) : un peu plus lent, nettement plus robuste sur pilote ancien.

Suite (2026-09-03). Le pilote a été mis à jour en Adrenalin 26.8.1 (voir page 295). Vulkan n'est toujours pas enregistré pour autant : HKLM\SOFTWARE\Khronos\Vulkan\Drivers reste absente, l'installation Driver Only n'ayant pas recréé l'ICD supprimée par le Factory Reset. Conserver hw.gpu.mode = host — repasser en auto ferait retomber en lavapipe.

Cause racine : le pilote AMD de janvier 2022 (voir page 249), qui expose mal Vulkan. host contourne le problème, il ne le corrige pas. Résultat après correction : vidéo fluide et tablette nettement plus réactive, confirmé par l'utilisateur.

Le faux « cadre blanc » et l'écran trop petit : même cause

Le bord clair n'était pas le skin de la tablette — hardware-qemu.ini ne contenait aucune ligne skin ni showDeviceFrame, l'émulateur ne l'appliquait déjà plus.

C'était du remplissage de fenêtre : l'AVD faisait 2560x1600 pour un bureau logique de 2560x1440. Impossible à afficher en entier, donc image réduite pour tenir, et le fond clair de l'émulateur comble le reste.

Règle : la définition de l'AVD doit tenir dans le bureau, sinon l'image est réduite en permanence et entourée de remplissage.

Correctif appliqué — 1920x1200 en densité 240 :

Avant Après
Définition 2560x1600 1920x1200
Densité 320 240
Largeur en dp 800 800 (inchangée)
Pixels à calculer 4,1 Mpx 2,3 Mpx (-44 %)

Les 800 dp sont conservés : les mises en page tablette sont identiques. Mais l'image tient dans l'écran sans réduction, la fenêtre peut être agrandie à la main, et le GPU travaille moins. Résultat confirmé : bord blanc disparu, écran nettement plus grand.

Retirer aussi skin.name et skin.path de config.ini (showDeviceFrame = no seul les rend inopérants, mais autant être net).

Le son

Mesurer avant de conclure :

& $adb shell cmd media_session volume --stream 3 --get

Le volume invité était déjà à 13/15 — il a été passé à 15.

Résolu, et la cause n'était pas l'audio. Les ratés de son étaient un symptôme de la saturation processeur : quand le CPU dessinait 4,1 Mpx par image en lavapipe, le flux audio n'était plus alimenté à temps et décrochait. Une fois le rendu basculé sur host et la définition ramenée à 1920x1200, le son est redevenu correct sans aucun réglage audio supplémentaire. Ne pas partir sur le mélangeur de volume Windows ni sur le périphérique de sortie tant que le rendu graphique n'est pas vérifié — c'est une fausse piste coûteuse.

Note : la commande media n'existe pas sur cette image, il faut cmd media_session.

Horloge : démarrage à froid obligatoire

La tablette affichait lundi 31 août alors que le PC était au mercredi 2 septembre. Cause déjà documentée sur ce poste : en Quick boot, l'horloge repart de l'heure figée dans l'instantané et ne se recale jamais.

fastboot.forceColdBoot = yes
fastboot.forceFastBoot = no

Après correction : Wed Sep 2 21:18 GMT côté tablette pour 23:18 côté PC — le même instant, l'écart n'étant que le fuseau. Le démarrage passe de ~20 s à 2-3 min : compromis accepté, une horloge fausse ayant déjà fait rejeter des requêtes signées et accuser Portmaster à tort.

Le fuseau se règle à la main dans la tablette (Paramètres → Système → Date et heure) : setprop persist.sys.timezone est refusé sur une image Google Play, qui est une build de production.

Deux conséquences du démarrage à froid

  1. La tablette arrive verrouillée. mCurrentFocus=NotificationShade désigne alors l'écran de verrouillage, pas le volet de notifications. Déverrouiller par un glissement : adb shell input swipe 960 1000 960 200 200.
  2. dumpsys battery set ac 1 ne persiste pas — c'est une valeur d'exécution. À chaque lancement la tablette repart sur batterie, donc stay_on_while_plugged_in ne s'applique pas. Seul screen_off_timeout (30 min) protège alors de la veille.

10. Dimensionner la mémoire — mesurer, ne pas deviner

2026-09-02. qemu-system-x86_64 consommait 7 Go sur les 16 de la machine. L'AVD avait été réglé à 6 Go « pour être tranquille ».

La bonne mesure : MemAvailable, pas MemFree

& 'D:\Android\Sdk\platform-tools\adb.exe' shell cat /proc/meminfo

Relevé à 6 Go :

MemTotal:        6 071 Mo
MemFree:         1 038 Mo
MemAvailable:    3 834 Mo     <-- 63 % reellement disponible
Cached:          3 429 Mo
SwapTotal / SwapFree : 4 554 / 4 111 Mo   -> 442 Mo utilises, aucune pression

MemFree est trompeur : Linux remplit toujours la mémoire inoccupée de cache disque, donc MemFree reste bas quoi qu'il arrive. C'est MemAvailable qui dit ce que le système peut réellement rendre — ici 63 %, plus 3,4 Go de cache purement opportuniste. Android n'utilisait qu'environ 2,2 Go de mémoire de travail.

Second indice : la partition d'échange de l'invité n'était sollicitée qu'à 442 Mo sur 4 554. Aucune contrainte mémoire.

Résultat après passage à 4 Go

hw.ramSize = 4096
6 Go 4 Go
Guest MemTotal 6 071 Mo 4 013 Mo
Guest MemAvailable 3 834 Mo (63 %) 2 596 Mo (65 %)
qemu working set 6 964 Mo 3 479 Mo
Hôte libre 3,1 Go 6,9 Go

La mémoire de qemu est divisée par deux et Android conserve exactement la même marge relative. 3,8 Go rendus à l'hôte sans contrepartie mesurable.

Repères

Ne pas toucher à vm.heapSize en même temps : c'est un plafond par application, pas une réservation. Le laisser à 512 Mo, c'est ce qui évite qu'une application de presse chargeant beaucoup d'images se fasse tuer sans message (voir section 4).

Méthode réutilisable

  1. laisser tourner la tablette en usage normal quelques minutes
  2. lire MemAvailable et l'état du swap invité
  3. si MemAvailable dépasse ~50 % et que le swap est quasi inutilisé, il y a de la marge à reprendre
  4. réduire par paliers de 1 Go, émulateur arrêté, et remesurer
  5. penser à recopier config.ini dans le point de restauration après chaque changement

11. Apres un deplacement du SDK : « Could not automatically detect an ADB binary »

2026-09-06. Boite de dialogue au demarrage de l'emulateur, apres la sortie du SDK vers D:\\Android\\Sdk (section 6).

L'emulateur ne cherche pas adb seulement a cote de lui : il consulte d'abord ANDROID_HOME, ANDROID_SDK_ROOT et le PATH, qui pointaient implicitement sur l'ancien emplacement disparu.

adb present       D:\Android\Sdk\platform-tools\adb.exe   OK
ANDROID_HOME      non defini
ANDROID_SDK_ROOT  non defini
platform-tools    absent du PATH

Ce n'est pas anodin : les fonctions de l'emulateur qui reposent sur adb tombent — installation d'un APK par glisser-deposer sur la fenetre, bouton de capture d'ecran des Extended Controls, envoi de fichiers. Les scripts qui appellent adb par un chemin absolu, eux, ne sont pas concernes.

Correctif — a taper par l'utilisateur dans sa propre console, non elevee :

[Environment]::SetEnvironmentVariable('ANDROID_HOME','D:\Android\Sdk','User')
[Environment]::SetEnvironmentVariable('ANDROID_SDK_ROOT','D:\Android\Sdk','User')
[Environment]::SetEnvironmentVariable('PATH',
  [Environment]::GetEnvironmentVariable('PATH','User') + ';D:\Android\Sdk\platform-tools', 'User')

Fermer puis rouvrir l'emulateur : les variables ne sont lues qu'au demarrage du processus. Benefice annexe, adb devient utilisable sans chemin dans n'importe quelle console.

Repli si l'on ne veut rien toucher au systeme : ... (Extended Controls) -> Settings -> onglet General -> decocher Use detected ADB location et indiquer le chemin. Reglage propre a l'emulateur, sans effet ailleurs.

Precision sur la redirection MSIX : le registre se lit, mais ne s'ecrit pas

Constate a cette occasion : les valeurs ecrites par l'utilisateur dans HKCU\\Environment sont immediatement visibles depuis une session Claude Code, contrairement aux fichiers sous %LOCALAPPDATA% et %APPDATA% (section 6).

C'est le comportement classique de MSIX pour le registre : lecture directe, ecriture redirigee.

Consequence pratique : une variable d'environnement utilisateur peut etre verifiee depuis Claude Code — ce qui n'est pas le cas d'un fichier de configuration. En revanche, presumer qu'une ecriture depuis Claude serait visible a l'exterieur reste faux. La regle « c'est l'utilisateur qui ecrit » ne change pas ; seule la verification devient possible.

Aide-mémoire

Chemins

Android Studio   C:\Program Files\Android\Android Studio
SDK              D:\Android\Sdk   (sorti du conteneur MSIX, voir section 6)
adb              ...\Sdk\platform-tools\adb.exe
emulator         ...\Sdk\emulator\emulator.exe
AVD              C:\Users\julie\.android\avd\Pixel_Tablet.avd
Raccourci        C:\Users\julie\Desktop\Tablette Android.lnk

Commandes

# Démarrer (le raccourci du bureau fait la même chose)
& '...\Sdk\emulator\emulator.exe' -avd Pixel_Tablet

# Démarrage propre, si un boot se passe mal
& '...\Sdk\emulator\emulator.exe' -avd Pixel_Tablet -no-snapshot-load

# Lister les AVD / arrêter proprement
& '...\Sdk\emulator\emulator.exe' -list-avds
& '...\adb.exe' -s emulator-5554 emu kill

# Installer un APK (ou glisser-déposer le fichier sur la fenêtre)
& '...\adb.exe' install monapp.apk
& '...\adb.exe' install-multiple base.apk split_config.arm64_v8a.apk split_config.xxhdpi.apk

Les dépôts type APKMirror servent souvent des .xapk / .apkm : ce sont des archives ZIP de plusieurs APK. adb install échoue dessus, il faut les décompresser et utiliser install-multiple.

Premier démarrage : 2 à 3 minutes, sans aucune fenêtre visible pendant une bonne partie du temps. Ne pas conclure trop vite que le raccourci ne marche pas — vérifier le processus :

Get-Process emulator,qemu-system-x86_64 -ErrorAction SilentlyContinue

Les démarrages suivants réutilisent l'instantané, environ 20 secondes.

Limites connues

Presse, lecture, productivité et utilitaires : sans problème.

Voies écartées

Option Raison
Émulateur sur le VPS juxjux La virtualisation imbriquée y est pourtant active (/dev/kvm, kvm_intel.nested=Y) — mais 2,7 Gio de RAM disponibles seulement, swap déjà à moitié plein, aucun GPU, et usage interactif à travers le réseau. Redroid exigerait en plus un changement de noyau : le noyau cloud n'a pas CONFIG_ANDROID_BINDER_IPC
BlueStacks / LDPlayer / MEmu / Nox Mêmes prérequis de virtualisation, plus publicité et télémétrie
Genymotion Dépend de VirtualBox, déjà impliqué dans le dossier écrans bleus (page 249)
Waydroid sur l'Ubuntu 25.10 Reste une bonne solution de repli : conteneur LXC, aucun besoin de VT-x/AMD-V. Aurait été retenu si SVM était resté inaccessible
scrcpy + tablette existante Écarté ici, mais pertinent : recopie l'écran d'une Lenovo Tab K11 ou d'une SM-T720 sur le PC, sans virtualisation ni émulateur

Points restés ouverts

Voir aussi


Revision #12
Created 2026-08-26 18:30:32 UTC by Julien
Updated 2026-09-06 17:27:08 UTC by Julien