RebreakVpnService.onStartCommand crashed with SecurityException because Android 16's validateForegroundServiceType rejects the implicit 2-arg startForeground(). Now passes FOREGROUND_SERVICE_TYPE_SPECIAL_USE explicitly (Google's documented best practice) and guards the call so a failed foreground promotion stops the service cleanly instead of crashing the app. Verified vs reported Galaxy A54 / Android 16 signature (97% of crash events, 1-user crash loop). Bundles pending working-tree work across native/marketing/locales/mac + graphify-out rebuild. gitignore: google-services.json + /screenshots/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
97 lines
2.7 KiB
YAML
97 lines
2.7 KiB
YAML
# blocker/vpn-activate-verify.yaml
|
||
#
|
||
# Zweck: VERIFIZIERT den Android-16-FGS-Fix (systemExempted → specialUse).
|
||
# Loggt ein → Blocker → tippt WIRKLICH "VPN aktivieren" → Confirm-Sheet →
|
||
# System-VPN-Dialog "OK". Das löst RebreakVpnService.startForeground aus —
|
||
# genau die Stelle, die auf Android 16 mit systemExempted crashte.
|
||
#
|
||
# Verdikt kommt aus parallelem logcat (extern):
|
||
# FEHLER → "SecurityException: Starting FGS with type ..." (Fix kaputt)
|
||
# ERFOLG → kein FGS-SecurityException + "VPN established" / TUN aktiv
|
||
#
|
||
# Voraussetzung:
|
||
# - Android-16-Emulator (API 36.x) ODER echtes Gerät, App (Debug) installiert.
|
||
# - Test-Account auf Staging mit Schutz AUS (sonst kein "VPN aktivieren"-Button).
|
||
# - Env: E2E_TEST_USER, E2E_TEST_PASSWORD (via `infisical run -- maestro test ...`).
|
||
#
|
||
# Run:
|
||
# infisical run -- maestro test --env=E2E_LOCALE=de \
|
||
# apps/rebreak-native/.maestro/blocker/vpn-activate-verify.yaml
|
||
|
||
appId: org.rebreak.app
|
||
---
|
||
- launchApp:
|
||
clearState: true
|
||
- waitForAnimationToEnd:
|
||
timeout: 5000
|
||
|
||
# --- Login ---
|
||
- assertVisible:
|
||
text: "E-Mail"
|
||
- tapOn:
|
||
text: "E-Mail"
|
||
- inputText: ${E2E_TEST_USER}@rebreak.internal
|
||
- tapOn:
|
||
text: "Passwort"
|
||
- inputText: ${E2E_TEST_PASSWORD}
|
||
- tapOn:
|
||
text: "Anmelden"
|
||
- waitForAnimationToEnd:
|
||
timeout: 10000
|
||
- assertVisible:
|
||
text: "ReBreak"
|
||
|
||
# --- Blocker-Tab ---
|
||
- tapOn:
|
||
text: "Blocker"
|
||
- waitForAnimationToEnd:
|
||
timeout: 4000
|
||
- assertVisible:
|
||
text: "ReBreak-Schutz"
|
||
|
||
# Schutz ggf. erst antippen (Karte), damit der Setup-Flow erscheint.
|
||
- tapOn:
|
||
text: "Tippe um den Schutz zu aktivieren"
|
||
optional: true
|
||
- waitForAnimationToEnd:
|
||
timeout: 2000
|
||
|
||
# --- VPN aktivieren (DAS löst startForeground aus) ---
|
||
- tapOn:
|
||
text: "VPN aktivieren"
|
||
- waitForAnimationToEnd:
|
||
timeout: 2000
|
||
|
||
# Confirm-Sheet (Anti-Blind-Klick-Gate): Häkchen + Weiter. Optional, falls der
|
||
# Blocker-Screen anders gated als das Onboarding.
|
||
- tapOn:
|
||
text: "Ich hab’s verstanden"
|
||
optional: true
|
||
- tapOn:
|
||
text: "Weiter"
|
||
optional: true
|
||
- waitForAnimationToEnd:
|
||
timeout: 2000
|
||
|
||
# --- System-VPN-Consent-Dialog (außerhalb der App) ---
|
||
# Android zeigt "Verbindungsanfrage … VPN einrichten?". Button-Text variiert
|
||
# (OK / Zulassen / Allow) — wir versuchen mehrere.
|
||
- tapOn:
|
||
text: "OK"
|
||
optional: true
|
||
- tapOn:
|
||
text: "Zulassen"
|
||
optional: true
|
||
- tapOn:
|
||
text: "Allow"
|
||
optional: true
|
||
|
||
# startVpn() läuft jetzt: establish() → startForeground(specialUse). Kurz warten,
|
||
# damit der FGS-Aufruf im logcat landet.
|
||
- waitForAnimationToEnd:
|
||
timeout: 6000
|
||
|
||
# App lebt noch (kein Crash) → Blocker-Screen weiterhin sichtbar.
|
||
- assertVisible:
|
||
text: "ReBreak-Schutz"
|