Files
internet_use_control/android/tools/emu-proof.sh
Sam Rolfe e018c3bfa8 Phase 5.1: kids' Android client (Accessibility block overlay + tamper alert)
Add android/, a normal Gradle/Kotlin project with its own wrapper. It
blocks by interruption: an Accessibility Service watches the foreground
package and a full-screen overlay covers any listed app while the device
is locked (FR-16). No Device Owner, no factory reset, no managed profile.

The client subscribes to the retained restrict/<device>/config topic on
the 8883 TLS plane, keeps the last config on disk so a broker-less device
keeps its rules (FR-14), and reports tampering on its own status topic
(FR-17): a disabled service, a revoked overlay permission, or a
force-stop seen on the next start. The Control Service now parses the
tamper field and raises an Apprise alert, so it reaches Sam.

The block path and the tamper alert are proven on the headless pixel35
emulator on .27; see android/README.md and android/tools/emu-proof.sh.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-13 20:17:22 +11:00

77 lines
3.1 KiB
Bash

#!/usr/bin/env bash
# Emulator proof for the Phase 5.1 Android client. Runs on .27.
# bash emu-proof.sh <apk> <outdir>
set -uo pipefail
exec </dev/null
export ANDROID_HOME="$HOME/Android/Sdk"
export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator:$PATH"
PKG=au.audasmedia.webrestrict.kids
APK="${1:-/tmp/webrestrict-pre/android/app/build/outputs/apk/debug/app-debug.apk}"
OUT="${2:-/tmp/webrestrict}"
mkdir -p "$OUT"
# Headless test hygiene: a slow swiftshader emulator raises ANR dialogs, and an
# ANR dialog force-hides non-system overlay windows.
adb shell settings put global hide_error_dialogs 1
adb shell settings put global anr_show_background 0
adb shell svc power stayon true
adb shell input keyevent KEYCODE_WAKEUP
sleep 2
echo "== install =="
adb install -r "$APK" || exit 1
echo "== grant test permissions (adb, headless) =="
adb shell appops set $PKG SYSTEM_ALERT_WINDOW allow
adb shell appops set $PKG GET_USAGE_STATS allow
adb shell pm grant $PKG android.permission.POST_NOTIFICATIONS 2>/dev/null || true
# Toggle so the system binds the service even if it was already set.
adb shell settings put secure accessibility_enabled 0
adb shell settings delete secure enabled_accessibility_services 2>/dev/null || true
sleep 1
adb shell settings put secure enabled_accessibility_services $PKG/$PKG.BlockAccessibilityService
adb shell settings put secure accessibility_enabled 1
sleep 4
echo "a11y services: $(adb shell settings get secure enabled_accessibility_services)"
echo "a11y enabled: $(adb shell settings get secure accessibility_enabled)"
echo "overlay appop: $(adb shell appops get $PKG SYSTEM_ALERT_WINDOW)"
echo "== launch app once (seed config, start mqtt) =="
adb shell am start -n $PKG/.MainActivity
sleep 4
echo "== launch a blocked app: Settings =="
adb shell am force-stop com.android.settings
sleep 1
adb shell am start -a android.settings.SETTINGS
sleep 5
echo "== window state: overlay =="
adb shell dumpsys window windows | grep -i -A30 "u0 $PKG}:" | grep -E "Window #|ty=|isOnScreen|isVisible|mPolicyVisibility|shown=|mForceHide" | head -20
echo "current focus:"
adb shell dumpsys window | grep -E "mCurrentFocus" | head -2
echo "== screenshot: block overlay =="
adb exec-out screencap -p > "$OUT/block-overlay.png"
echo "wrote $OUT/block-overlay.png ($(stat -c%s "$OUT/block-overlay.png") bytes)"
echo "== logcat: service + overlay =="
adb logcat -d -s WebRestrictService WebRestrictOverlay WebRestrictConfig WebRestrictMqtt 2>/dev/null | tail -30
echo "== TAMPER: disable the Accessibility Service =="
adb shell settings put secure accessibility_enabled 0
adb shell settings delete secure enabled_accessibility_services 2>/dev/null || true
sleep 5
adb logcat -d -s WebRestrictTamper 2>/dev/null | tail -20 | tee "$OUT/tamper-logcat.txt"
echo "== tamper log file (persisted on device) =="
adb shell run-as $PKG cat files/tamper.log 2>/dev/null | tail -20 | tee "$OUT/tamper-file.txt" || true
echo "== screenshot: status screen after tamper =="
adb shell am start -n $PKG/.MainActivity
sleep 3
adb exec-out screencap -p > "$OUT/after-tamper.png"
echo "wrote $OUT/after-tamper.png ($(stat -c%s "$OUT/after-tamper.png") bytes)"
echo "== done =="