# 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 :

```powershell
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

```powershell
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

```powershell
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

```powershell
& '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`

```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

```powershell
$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
```

- `Dozing` ou `Asleep` → simple veille, réveiller
- `Awake` **et** écran noir → là seulement, suspecter le rendu graphique

Réveil et retour à l'accueil :

```powershell
& $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 :

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

Vérification :

```powershell
& $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.

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

## Le correctif

```powershell
& $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

- l'interface d'Android Studio affichait `Android SDK Location: D:\Android\Sdk`
- `Test-Path` sur ce chemin répondait `True` depuis une session Claude
- les deux chemins renvoyaient **exactement la même taille (4,12 Go)** — parce que le « vrai » est redirigé vers le virtualisé

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 :

```powershell
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

- `C:\Users\julie\AppData\Local\Android\Sdk` **lu depuis une session Claude**
- `D:\Android\Sdk` **lu par l'utilisateur dans sa propre console**

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` :

```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 :

```powershell
& '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 :

- ils contiennent une **image de la RAM** - avec 6 Go d'AVD, c'est **6 Go pour l'instantane seul** (9,06 Go de dossier AVD, dont 6 pour le seul `snapshots\\`)
- ils se cassent au moindre changement de version d'emulateur ou de configuration d'AVD
- ils vivent **dans** le dossier AVD : une corruption de l'AVD les emporte avec elle

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.

```powershell
& '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

```ini
hw.gpu.mode = host
```

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

```powershell
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 :

```powershell
& $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**.

```ini
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`

```powershell
& '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

```ini
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

- **4096 Mo** : le bon réglage pour cet usage (presse, lecture, quelques applications). Retenu.
- **3072 Mo** : encore faisable au vu des 2,2 Go de mémoire de travail constatés, mais ne laisse que ~800 Mo de cache — l'invité éviction­nerait plus souvent et s'appuierait sur son zram. À n'envisager que si l'hôte est vraiment à l'étroit.
- **6144 Mo** : surdimensionné. Ne rien attendre de plus qu'à 4 Go.

**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** :

```powershell
[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

```powershell
# 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 :

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

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

# Limites connues

- **Applications bancaires et de paiement** : Play Integrity échoue systématiquement sur émulateur
- **Vidéo protégée** (Netflix, Disney+, MyCanal) : pas de Widevine L1
- **Jeux avec anti-triche** : détection d'émulateur
- **Matériel absent** : NFC, appareil photo réel, SIM et téléphonie, empreinte digitale

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

- **Le pilote AMD de janvier 2022 n'est toujours pas réinstallé** (action en attente de la page 249). Les erreurs `UpdateLayeredWindowIndirect` du journal de l'émulateur en sont un symptôme de plus, même si elles n'ont pas empêché le fonctionnement.
- **Résolu.** Le *Virtual Device Manager* n'apparaissait pas dans *More Actions* : Android Studio tournait alors dans le conteneur MSIX, sur un SDK dont l'émulateur n'était pas correctement enregistré. Une fois Studio relancé **par l'utilisateur** et repointé sur `D:\Android\Sdk`, l'entrée est présente et l'AVD `Pixel_Tablet` y figure. Même cause racine que le reste — ce n'était pas une bizarrerie d'interface.
- **Le réglage *Cold boot* n'est pas encore persisté** dans `config.ini` — toujours `fastboot.forceFastBoot = yes` au 2026-08-31. Le démarrage à froid du jour a recalé l'horloge, mais la dérive reviendra à la prochaine reprise d'instantané après quelques jours d'arrêt. L'instantané `snapshots/default_boot` pèse par ailleurs **6,1 Go** sur le SSD système ; le supprimer force aussi un démarrage à froid et rend la place, sans toucher aux données de la tablette (`userdata-qemu.img`).

# Voir aussi

- Page **249** — stabilité du PC `julie`, écrans bleus, pilote AMD
- `Jux-scripts/PC-Health/bios_svm_a320m.md` — fiche BIOS pas à pas
- `CLAUDE.md`, section « Poste Windows `julie` » — piège MSIX, outillage du poste