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>
78 lines
3.1 KiB
Bash
Executable File
78 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
#
|
||
# No-Login-Capture für die Marketing-Screenshots.
|
||
#
|
||
# Voraussetzung: Die App ist auf dem iOS-Simulator BEREITS eingeloggt
|
||
# (z. B. via Google-OAuth manuell). Dieses Script loggt NICHT ein, es navigiert
|
||
# nur und macht Screenshots. Braucht daher KEINE Test-Creds.
|
||
#
|
||
# Erzeugt 02–09 und kopiert sie nach apps/marketing/public/preview/.
|
||
#
|
||
# Aufruf:
|
||
# export PATH="$PATH:$HOME/.maestro/bin"
|
||
# bash apps/rebreak-native/.maestro/screens/capture-marketing-loggedin.sh
|
||
|
||
set -uo pipefail
|
||
|
||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)"
|
||
FLOW="$REPO_ROOT/apps/rebreak-native/.maestro/screens/marketing-tour-loggedin.yaml"
|
||
DEST="$REPO_ROOT/apps/marketing/public/preview"
|
||
export PATH="$PATH:$HOME/.maestro/bin"
|
||
|
||
if ! command -v maestro &>/dev/null; then
|
||
echo "FEHLER: Maestro nicht im PATH. → export PATH=\"\$PATH:\$HOME/.maestro/bin\""
|
||
exit 1
|
||
fi
|
||
|
||
# ─── Status-Bar (9:41, voll) auf gebootetem Simulator ───────────────────────
|
||
UDID=$(xcrun simctl list devices booted --json 2>/dev/null | python3 -c "
|
||
import json,sys
|
||
d=json.load(sys.stdin)
|
||
for r,ds in d.get('devices',{}).items():
|
||
for x in ds:
|
||
if x.get('state')=='Booted':
|
||
print(x['udid']); sys.exit()
|
||
" 2>/dev/null || true)
|
||
|
||
if [[ -n "$UDID" ]]; then
|
||
echo "Status-Bar auf Simulator $UDID setzen (9:41, voll)…"
|
||
xcrun simctl status_bar "$UDID" override \
|
||
--time "9:41" --wifiMode active --wifiBars 3 \
|
||
--cellularMode active --cellularBars 4 \
|
||
--batteryState charged --batteryLevel 100 2>/dev/null \
|
||
|| echo " Status-Bar-Override fehlgeschlagen (nicht kritisch)."
|
||
else
|
||
echo "Kein gebooteter Simulator gefunden — Status-Bar übersprungen."
|
||
fi
|
||
|
||
# ─── Flow laufen ────────────────────────────────────────────────────────────
|
||
# WICHTIG: aus REPO_ROOT starten — `takeScreenshot: screenshots/x` legt relativ
|
||
# zum Arbeitsverzeichnis ab, d.h. die PNGs landen in $REPO_ROOT/screenshots/.
|
||
echo ""
|
||
echo "Starte No-Login-Tour: $FLOW"
|
||
cd "$REPO_ROOT"
|
||
maestro test "$FLOW" || echo " (Maestro-Flow mit Fehlern beendet — vorhandene Screenshots werden trotzdem kopiert)"
|
||
|
||
# ─── Screenshots finden + kopieren ──────────────────────────────────────────
|
||
# Maestro speichert `takeScreenshot: screenshots/<name>` als $REPO_ROOT/screenshots/<name>.png
|
||
SRC="$REPO_ROOT/screenshots"
|
||
echo ""
|
||
echo "Quelle: $SRC"
|
||
mkdir -p "$DEST"
|
||
|
||
ok=0
|
||
for n in 02-blocker 03-blocked 04-sos-lyra 05-breathing 06-mail-schutz 07-community 07b-dm 08-streak 09-geraete; do
|
||
f=""
|
||
[[ -f "$SRC/$n.png" ]] && f="$SRC/$n.png"
|
||
[[ -z "$f" ]] && f=$(ls "$SRC"/*"$n"*.png 2>/dev/null | head -1 || true)
|
||
if [[ -n "$f" && -f "$f" ]]; then
|
||
cp "$f" "$DEST/$n.png" && echo " ✓ $n.png" && ok=$((ok+1))
|
||
else
|
||
echo " ✗ $n.png fehlt (Screen evtl. nicht erreicht)"
|
||
fi
|
||
done
|
||
|
||
[[ -n "$UDID" ]] && xcrun simctl status_bar "$UDID" clear 2>/dev/null || true
|
||
echo ""
|
||
echo "Fertig: $ok/8 Screenshots → $DEST"
|