# Environnement de développement — EVABRPUploader. # # Commité volontairement : il décrit comment construire le projet, pas la machine de # quelqu'un. Les chemins passent par {{env.HOME}} / JAVA_HOME, jamais en dur. # Pour une surcharge locale (chemin de keystore, SDK ailleurs), créer un mise.local.toml # — celui-là reste ignoré par git. # # mise install installe le JDK # mise run bootstrap installe le SDK Android si absent # mise run test tests unitaires # mise tasks liste tout # # Pourquoi épingler le JDK : le JDK par défaut de la machine (26) n'est pas supporté # par AGP et fait échouer le build avec une erreur de version de classe peu parlante. [tools] java = "17" [env] ANDROID_HOME = "{{env.HOME}}/Android/Sdk" ANDROID_SDK_ROOT = "{{env.HOME}}/Android/Sdk" _.path = [ "{{env.HOME}}/Android/Sdk/platform-tools", "{{env.HOME}}/Android/Sdk/cmdline-tools/latest/bin", ] # Version du SDK requise par app/build.gradle (compileSdk = 36). COMPILE_SDK = "36" BUILD_TOOLS = "36.0.0" # Secrets de SIGNATURE D'APK — sans rapport avec la clé d'API ABRP, qui se saisit dans # l'application. À définir hors du dépôt : décommenter dans un mise.local.toml (ignoré # par git) et pointer vers un keystore local, JAMAIS vers un fichier du dépôt. # SIGNING_KEYSTORE = "{{env.HOME}}/.keystores/signing.keystore" # SIGNING_STORE_PASSWORD = "…" # SIGNING_KEY_ALIAS = "platform" # SIGNING_KEY_PASSWORD = "…" # Gradle doit tourner sur le JDK que mise vient d'installer. Sans -Dorg.gradle.java.home, # Gradle peut réutiliser un daemon lancé par un autre JDK — typiquement celui embarqué par # l'extension Java de VS Code, un JRE 21 sans jlink : le build échoue alors sur # JdkImageTransform, avec un message qui n'a rien à voir avec le code. # JAVA_HOME est posé par [tools] ci-dessus : $JAVA_HOME est résolu par le shell au moment # de l'exécution, donc ceci reste portable d'une machine à l'autre. # ── Émulateur ──────────────────────────────────────────────────────────────────── # # ATTENTION sur la fidélité : le véhicule tourne en AAOS 9 (API 28). Google ne publie # AUCUNE image système Automotive en dessous d'API 33 — vérifié avec sdkmanager --list. # Il n'existe donc pas d'émulateur qui reproduise à la fois l'OS et l'API voiture du MG4. # D'où deux profils, chacun fidèle sur un axe : # # emulator-car API 33 Automotive — a bien un CarPropertyManager, mauvaise version # d'OS. Pour tester le cycle de vie du service et le chemin voiture. # Les propriétés VENDEUR SAIC (0x216xxxxx : SOC, autonomie) n'existent # pas dans l'émulateur : ces lectures échoueront, c'est normal. # emulator-screen API 28 tablette — bonne version d'OS et bon écran (1920x720 @ 160dpi, # 12,8" HD comme le MG4), mais AUCUN service voiture. # Pour l'UI, les layouts et la densité. # # Rien de tout cela ne remplace un essai sur le véhicule. # Densité cible du projet : 160 dpi. # Écran 12,8" 1920x720. Firmware de référence : SWI68-29958-1300R69. EMU_CAR_AVD = "evabrp-car" EMU_CAR_IMAGE = "system-images;android-33;android-automotive;x86_64" EMU_SCREEN_AVD = "evabrp-screen" EMU_SCREEN_IMAGE = "system-images;android-28;google_apis;x86_64" EMU_WIDTH = "1920" EMU_HEIGHT = "720" EMU_DENSITY = "160" [tasks.bootstrap] description = "Installe le SDK Android (platform + build-tools) s'il manque" run = """ set -e if [ -d "$ANDROID_HOME/platforms/android-$COMPILE_SDK" ]; then echo "SDK $COMPILE_SDK déjà présent → rien à faire" exit 0 fi mkdir -p "$ANDROID_HOME" if [ ! -x "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" ]; then echo "Téléchargement des commandline-tools…" tmp=$(mktemp -d) curl -sSL -o "$tmp/tools.zip" \ https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip unzip -q "$tmp/tools.zip" -d "$tmp" mkdir -p "$ANDROID_HOME/cmdline-tools" mv "$tmp/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest" rm -rf "$tmp" fi yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --sdk_root="$ANDROID_HOME" --licenses > /dev/null "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --sdk_root="$ANDROID_HOME" \ "platform-tools" "platforms;android-$COMPILE_SDK" "build-tools;$BUILD_TOOLS" echo "sdk.dir=$ANDROID_HOME" > local.properties echo "SDK installé, local.properties écrit" """ [tasks.build] description = "Compile l'APK debug" run = './gradlew -Dorg.gradle.java.home=$JAVA_HOME assembleStableDebug' [tasks.test] description = "Tests unitaires JVM" run = './gradlew -Dorg.gradle.java.home=$JAVA_HOME testStableDebugUnitTest testUnstableDebugUnitTest' [tasks.lint] description = "Analyse lint Android" run = './gradlew -Dorg.gradle.java.home=$JAVA_HOME lintStableDebug lintUnstableDebug' [tasks.permissions] description = "Contrôle de dérive des permissions (le même que la CI)" run = "bash .github/security/check-permissions.sh" [tasks.check] description = "Ce que la CI exécute : permissions + lint + tests" depends = ["permissions", "lint", "test"] [tasks.install] description = "Installe l'APK debug sur le véhicule connecté en ADB" run = './gradlew -Dorg.gradle.java.home=$JAVA_HOME installStableDebug' [tasks.logs] description = "Suit les logs de l'app sur le véhicule" run = "adb logcat -s AbrpUploadService:V CarPropertyAdapter:V VhalProbe:V SecurePrefs:V OtaUpdater:V UpdateHook:V" [tasks.release] description = "APK release des deux canaux (stable sans OTA, unstable avec OTA)" run = './gradlew -Dorg.gradle.java.home=$JAVA_HOME assembleStableRelease assembleUnstableRelease' [tasks.clean] run = './gradlew -Dorg.gradle.java.home=$JAVA_HOME clean' [tasks.emulator-setup] description = "Installe l'émulateur + les images système et crée les deux AVD" run = ''' set -e SDK="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" AVDM="$ANDROID_HOME/cmdline-tools/latest/bin/avdmanager" if [ ! -e /dev/kvm ]; then echo "ERREUR : /dev/kvm absent — pas d'accélération matérielle, l'émulateur sera inutilisable." >&2 echo "Sous WSL2 : activer la virtualisation imbriquée côté Windows." >&2 exit 1 fi if ! id -nG | tr ' ' '\n' | grep -qx kvm; then echo "ATTENTION : utilisateur absent du groupe kvm. Corriger avec :" >&2 echo " sudo usermod -aG kvm $USER # puis se reconnecter" >&2 fi yes | "$SDK" --sdk_root="$ANDROID_HOME" --licenses > /dev/null "$SDK" --sdk_root="$ANDROID_HOME" "emulator" "platform-tools" "$EMU_CAR_IMAGE" "$EMU_SCREEN_IMAGE" create_avd() { name="$1"; image="$2"; device="$3" if "$AVDM" list avd 2>/dev/null | grep -q "Name: $name"; then echo "AVD $name déjà présent" else echo no | "$AVDM" create avd -n "$name" -k "$image" -d "$device" --force fi cfg="$HOME/.android/avd/$name.avd/config.ini" # Écran du MG4. Sans ça l'AVD garde la densité du profil générique et les layouts # ne ressemblent pas à ce que voit le conducteur. sed -i '/^hw.lcd/d;/^disk.dataPartition.size/d' "$cfg" { echo "hw.lcd.width=$EMU_WIDTH" echo "hw.lcd.height=$EMU_HEIGHT" echo "hw.lcd.density=$EMU_DENSITY" echo "disk.dataPartition.size=4G" } >> "$cfg" echo "AVD $name configuré en ${EMU_WIDTH}x${EMU_HEIGHT} @ ${EMU_DENSITY}dpi" } create_avd "$EMU_CAR_AVD" "$EMU_CAR_IMAGE" "automotive_1024p_landscape" create_avd "$EMU_SCREEN_AVD" "$EMU_SCREEN_IMAGE" "pixel_c" ''' # swiftshader_indirect, pas « host » : WSL2 n'expose aucun GPU réel (uniquement Mesa # llvmpipe). Avec -gpu host l'émulateur meurt au démarrage sur « Your GPU cannot be used # for hardware rendering », avant qu'aucune fenêtre n'apparaisse — d'où l'icône de tray # sans émulateur visible. Le rendu logiciel est plus lent, mais il démarre. [tasks.emulator-car] description = "Lance l'émulateur Automotive (API 33 — a un CarPropertyManager)" run = ''' set -e "$ANDROID_HOME/emulator/emulator" -avd "$EMU_CAR_AVD" \ -gpu swiftshader_indirect -no-snapshot-save -no-boot-anim & "$ANDROID_HOME/platform-tools/adb" wait-for-device echo "Émulateur voiture prêt." ''' [tasks.emulator-screen] description = "Lance l'émulateur écran MG4 (API 28, 1920x720 @ 160dpi — pas de service voiture)" run = ''' set -e "$ANDROID_HOME/emulator/emulator" -avd "$EMU_SCREEN_AVD" \ -gpu swiftshader_indirect -no-snapshot-save -no-boot-anim & "$ANDROID_HOME/platform-tools/adb" wait-for-device echo "Émulateur écran prêt." ''' [tasks.emulator-stop] description = "Arrête l'émulateur en cours" run = '"$ANDROID_HOME/platform-tools/adb" emu kill || true' [tasks.run] description = "Compile, installe et lance l'APK sur l'émulateur ou le véhicule connecté" depends = ["build"] run = ''' set -e ADB="$ANDROID_HOME/platform-tools/adb" if [ -z "$($ADB devices | sed '1d' | grep -w device || true)" ]; then echo "Aucun appareil connecté. Lancer d'abord 'mise run emulator-car' ou 'mise run emulator-screen'," >&2 echo "ou brancher le véhicule en ADB." >&2 exit 1 fi APK=$(ls -t app/build/outputs/apk/stable/debug/*.apk | head -1) echo "Installation de $APK" $ADB install -r -g "$APK" $ADB shell am start -n "com.stinnesbeck.nilsmg4/com.evsuite.abrp.MainActivity" echo "Lancé. Logs : mise run logs" '''