screen orientation and awake

This commit is contained in:
Paul Schneider 2026-11-05 10:44:19 +00:00
commit fa8038c676
Signed by: notazof
GPG key ID: AD4B9B545FBD7D12
25 changed files with 941 additions and 110 deletions

View file

@ -123,6 +123,10 @@ de fichier média temporaire ou de moteur WebRTC Android ajouté.
segments ni de lecture de capture par callbacks managés.
- La prévisualisation réutilise la surface EGL existante. Le retour
distant utilise la surface Android LibVLC déjà employée pour les Podcasts.
La rotation capteur/écran tient compte de celle déjà portée par la matrice
`SurfaceTexture` (miroir de la caméra avant compris) et suit les changements
portrait/paysage. Les dimensions
encodées restent fixes pendant l'appel, avec bandes noires si nécessaire.
- Le service de capture partagé affiche une notification d'appel avec
l'action « Raccrocher » ; cette action ne publie aucun Podcast.
Un Podcast et un appel ne peuvent pas posséder la capture simultanément.

View file

@ -53,6 +53,40 @@ Le rafraîchissement silencieux de session reste unique par processus.
Cette restauration couvre la recréation d'activité dans le même processus,
pas la destruction du processus par Android.
## Prévisualisation et orientation des Podcasts
« Prévisualiser la caméra » ouvre un aperçu local avant « Démarrer le
direct », sans exiger de titre. Cette phase ne crée aucune émission côté
serveur, n'enregistre aucun segment et n'ouvre pas le microphone. Le choix
de caméra est verrouillé pendant l'aperçu ; l'arrêter pour changer de caméra.
Le microphone sélectionné n'est ouvert qu'au démarrage du direct.
« Arrêter la prévisualisation », la sortie de page et la déconnexion libèrent
la caméra. Le passage au direct ferme d'abord l'aperçu, puis ouvre la capture
avec les périphériques sélectionnés : les images d'essai ne sont pas publiées.
Sous Android, un aperçu seul s'arrête aussi au passage en arrière-plan,
sans lancer de service de capture ni de notification de direct.
Les Podcasts en direct conservent leur service caméra/microphone existant.
Le chemin Android partage le rendu Camera2/EGL entre aperçu seul et encodage.
La rotation physique utilise l'orientation du capteur, la caméra avant/arrière
et la rotation de l'écran. Camera2 peut déjà inclure la rotation du capteur
dans la matrice `SurfaceTexture`, ainsi qu'un miroir pour la caméra avant :
seule la rotation restante est appliquée, dans le sens inverse si la matrice
contient un miroir, afin de ne pas tourner l'image deux fois.
Un changement de rotation d'écran recalcule ce rendu pendant la capture.
L'aperçu conserve les proportions ; les dimensions encodées restent celles
du démarrage du direct, avec des bandes noires si la nouvelle orientation
l'exige, pour ne pas modifier le format HLS/SRTP en cours d'émission.
Les tests partagés couvrent l'aperçu sans appel API, le passage au direct,
les arrêts et une sortie de page pendant l'ouverture de caméra. L'activité
Debug `CameraFrameRotationTestActivity` vérifie les quatre rotations avec
encodage, puis l'aperçu sans encodeur et ses changements de rotation.
Une validation physique caméra avant/arrière en portrait et paysage reste
nécessaire : les tests synthétiques ne vérifient pas le comportement du HAL
de chaque téléphone.
## Administration et profil personnel
L'accueil présente un seul accès **Administration**, visible et exécutable

View file

@ -156,6 +156,13 @@ adb shell am start -n fr.pschneider.postit/fr.pschneider.postit.CameraFrameRotat
adb shell run-as fr.pschneider.postit cat files/camera-rotation-test-result.txt
```
Pour un telephone ARM64, ajouter `-r android-arm64` au build et installer
l'APK de `bin/Debug/net10.0-android/android-arm64/`. Le projet transmet ce RID
aux targets natives LibVLC : l'APK doit contenir `libvlc.so` et
`libc++_shared.so`. Utiliser `adb -s <serial>` si plusieurs appareils sont
connectes. Laisser l'appareil deverrouille et les tests au premier plan ;
ne lancer le test suivant qu'apres `PASS` ou `FAIL`.
Attendre la fin du test : `RUNNING` doit devenir `PASS`. Il encode quatre
quadrants colores en MPEG-TS pour 0, 90, 180 et 270 degres, decode une image et
verifie les dimensions (640x480 ou 480x640) et les couleurs aux quatre positions.
@ -184,13 +191,36 @@ Le resultat inclut les angles capteur/ecran et la premiere matrice
SurfaceTexture recue. Les tests unitaires couvrent notamment la matrice
reelle `[0,-1,0,0,-1,0,0,0,0,0,1,0,1,1,0,1]` : pour un capteur a 90 degres
et un ecran a 0, elle porte deja la rotation et ne doit pas recevoir 90 degres
supplementaires. Le test synthetique seul ne detecte pas cette double rotation.
supplementaires. La camera avant mesuree
`[0,-1,0,0,1,0,0,0,0,0,1,0,0,1,0,1]` (capteur a 270 degres) contient en plus
un miroir : la rotation restante y est appliquee dans le sens inverse.
Le test synthetique seul ne detecte pas cette double rotation.
Verifier aussi manuellement les cameras avant/arriere en portrait et paysage,
le son, le direct et le replay, et la poursuite de l'emission en arriere-plan.
L'orientation est fixee au demarrage d'une emission ; tourner le telephone
pendant l'emission ne reconfigure pas le format encode.
### Anti-veille Android
`ScreenAwakeRequestsTests`, `PodcastPreferencesTests` et les regressions
d'apercu de `PodcastBroadcasterTests` couvrent les demandes independantes,
leur liberation, le changement d'option pendant la capture et sa persistance.
Le test natif Debug utilise une video MP4 H.264 locale synthetique, sans API,
camera ni microphone :
```bash
adb push /chemin/video-test.mp4 /data/local/tmp/postit-screen-awake-fixture.mp4
adb shell run-as fr.pschneider.postit cp /data/local/tmp/postit-screen-awake-fixture.mp4 files/screen-awake-fixture.mp4
adb shell am start -n fr.pschneider.postit/fr.pschneider.postit.ScreenAwakeTestActivity
adb shell run-as fr.pschneider.postit cat files/screen-awake-test-result.txt
```
Attendre `PASS` : lecture, pause/reprise, arret, fin, destruction de la surface,
demandes simultanees, arriere-plan et retour au premier plan sont verifies
sur le drapeau Android `KeepScreenOn`. Les changements de page et le retour
temporaire a l'accueil pendant ce test sont automatiques.
## Quand ne PAS écrire de test
Un test qui ne détecte rien n'est pas un test. Si l'invariant