Regroupe l'état de travail en cours réalisé dans un même worktree sur plusieurs tickets/sprints (#85, #136, #145, #155-160, #162-164), mélangeant des tickets QA et inProgress. Ne constitue pas une feature terminée : commit de sauvegarde avant triage/split par ticket en branches feature/* dédiées. Exclut les dossiers d'environnement de build locaux et le heap dump parasite (.gitignore mis à jour). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
62 lines
4.0 KiB
Markdown
62 lines
4.0 KiB
Markdown
---
|
|
name: gametime-android-release-networking-and-apk-build
|
|
description: memory note gametime-android-release-networking-and-apk-build
|
|
metadata:
|
|
type: project
|
|
---
|
|
# GameTime — Réseau Android release, cleartext et build APK
|
|
|
|
Capitalise le bug de création de compte sur APK release (« Création impossible pour le moment. Réessaie plus tard ») et la procédure de build/distribution APK.
|
|
|
|
## Causes du bug (toutes nécessaires, stacking)
|
|
|
|
L'erreur UI générique `Création impossible pour le moment` (`lib/presentation/profile_screen.dart`, `_registerErrorMessage`) est retournée pour `RemoteAuthFailure.network` **ou** tout échec non `emailAlreadyUsed`. Trois causes indépendantes cumulées sur le release :
|
|
|
|
1. **Permission `INTERNET` absente du manifest release.** Elle n'était déclarée que dans `android/app/src/debug/AndroidManifest.xml` et `.../profile/...`. Le release (merge main+release, sans manifest release dédié) n'en héritait pas → aucun socket réseau possible → `http.ClientException` → `RemoteAuthFailure.network`.
|
|
- Fix définitif : `INTERNET` déclaré dans `android/app/src/main/AndroidManifest.xml` (racine `<manifest>`), hérité par tous les build types.
|
|
|
|
2. **Trafic cleartext bloqué.** Serveur de dev/LAN en `http://` (pas de TLS ; reverse proxy HTTPS externe). Sur Android 9+ (API 28+) le cleartext est bloqué par défaut.
|
|
- Fix : `android:usesCleartextTraffic="true"` sur `<application>` dans `src/main/AndroidManifest.xml`. Acceptable tant qu'il n'y a pas de TLS bout-en-bout ; à remplacer par une `network_security_config` ciblée quand la prod passe en HTTPS.
|
|
|
|
3. **Port serveur.** Le conteneur API publie le port interne 8080 sur le port hôte **8090** (`server/.env` : `API_BIND_ADDRESS=192.168.1.75`, `API_PORT=8090` ; `server/docker-compose.yaml` `${API_BIND_ADDRESS}:${API_PORT}:8080`). Donc l'URL joignable est `http://192.168.1.75:8090`, **pas** 8080.
|
|
|
|
## Contrat d'injection d'URL (ne pas coder en dur)
|
|
|
|
`HttpApiClient.defaultBaseUrl` (`lib/infrastructure/remote/http_api_client.dart`) reste `http://localhost:8080` par défaut (fallback de dev local). L'URL réelle est injectée au build via `--dart-define=GAMETIME_API_BASE_URL=...`. Ne pas hardcoder d'IP/port serveur dans le code (validé par Architect). Le défaut `localhost:8080` est volontairement non fonctionnel sur device physique distant.
|
|
|
|
## Build APK release (env Main)
|
|
|
|
Pré-requis machine projet : Flutter 3.44.6 (`/usr/bin/flutter`), Android SDK `/opt/android-sdk`, **JDK 21 obligatoire** (`/usr/lib/jvm/java-21-openjdk`) — le JDK système par défaut (java-26) casse Gradle.
|
|
|
|
```bash
|
|
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
|
|
export ANDROID_HOME=/opt/android-sdk
|
|
export PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH"
|
|
cd /home/anthony/Documents/Projects/GameTime
|
|
flutter build apk --release --dart-define=GAMETIME_API_BASE_URL=http://192.168.1.75:8090
|
|
```
|
|
|
|
Sortie : `build/app/outputs/flutter-apk/app-release.apk` (+ `.sha1`). Signé avec les clés debug (`android/app/build.gradle.kts` : `signingConfig = debug`) → installable sans keystore prod.
|
|
|
|
Note : les sandboxes agents (QA, codex runner) échouent à lancer Gradle (« Could not determine a usable wildcard IP for this machine ») ; le build release se fait depuis l'environnement Main uniquement.
|
|
|
|
## Vérification du manifest mergé d'un APK
|
|
|
|
```bash
|
|
AAPT=/opt/android-sdk/build-tools/34.0.0/aapt2
|
|
$AAPT dump permissions <apk> # doit lister android.permission.INTERNET
|
|
$AAPT dump xmltree <apk> --file AndroidManifest.xml | grep -iE 'INTERNET|usesCleartextTraffic'
|
|
```
|
|
|
|
Pour un release GameTime sain : `INTERNET` présent ET `usesCleartextTraffic=true`.
|
|
|
|
## Santé serveur (pre-flight)
|
|
|
|
```bash
|
|
curl http://192.168.1.75:8090/health # attendu {"status":"ok"}
|
|
curl -X POST http://192.168.1.75:8090/auth/register \
|
|
-H 'content-type: application/json' \
|
|
-d '{"email":"probe@example.com","password":"probe12345"}' # attendu HTTP 201
|
|
```
|
|
|
|
`docker ps` : `server-api-1` expose `192.168.1.75:8090->8080/tcp`, `server-postgres-1` healthy. |