mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 19:07:04 +01:00
The enforcer failed in both directions: nothing blocked at home, and everything blocked at the office. The comparison was never inverted -- `metres <= threshold` was always right. Three separate causes: Only ACCESS_COARSE_LOCATION was declared. Android 12+ fuzzes coarse to a ~1-2 km grid against a 150 m fence, so a fix taken at home routinely landed outside it, read as AWAY, and restored every app the geofence exists to hide. FINE is now declared and self-granted by the device owner, along with coarse and background, re-asserted every pass so a reinstall cannot silently drop it. There were three states but two behaviours. LOCATION_UNKNOWN applies the identical sweep to AT_HOME -- correct fail-closed design, indistinguishable from outside. And nothing ever requested a fix: the pass read whatever another app happened to cache, so at the office with no navigation running the cache was empty. Passes now acquire a fix inside a location-typed foreground service, bounded at 20 s, and treat anything older than 30 min as no fix. That window is deliberately longer than the 15-minute cadence; a shorter one marks the newest cache stale on every pass of an idle phone and blocks everything. None of it was diagnosable. `adb logcat -d -s FocusOwner:V` came back empty while dumpsys showed 82 alarms had fired, and `run-as` is refused on the release build device owner requires. So the pass now writes a ring-buffered JSONL record read back in-app: reason, distance vs the fence, fix age/provider/accuracy, curfew state, and every hidden app with the rule that hid it. Coordinates are never recorded -- a distance is enough to debug a geofence, and this is a home address. Also fixed along the way: - Hysteresis keyed off `isEnforcing`, which is true under AWAY too because YouTube stays hidden, so the threshold was permanently radius+hysteresis. It now keys off whether the previous pass was inside the fence. - The scheduler's curfew-boundary alarms were documented but never scheduled; both callers invoked `scheduleNext()` bare, so 05:00 could land 15 min late. - Installing over the app cancelled its pending alarms, so `adb install -r` silently stopped enforcement until someone opened the app. MY_PACKAGE_REPLACED now re-arms it, verified on device without launching the app. - A wrong-typed log record threw instead of being skipped, and the exception escaped far enough to leave the page stuck busy -- which disables the release-device-owner button, the one control that must work when everything else has gone wrong. - `lib/enforcement.dart` was a second decision layer with no always-blocked concept, cited by KDoc as pinned by a `PolicyParityTest` that never existed. It would have made the new screen report YouTube visible while it is hidden. Deleted; the UI renders the Kotlin record rather than re-deciding. - Anchoring home accepted a stale or unknown-precision fix. A wrong home offsets the fence everywhere and forever, which is what produced a 766 m reading while standing at home. Policy: Play Store is allowed by day (not during curfew) so infakt can be installed and updated; the sweep is default-deny for third-party packages, so anything installed from Play is hidden on the next at-home pass. Tachiyomi's per-source extension apks are covered by a new prefix allowlist rather than an exact list that goes stale whenever an extension is installed. `export.py` stopped subtracting the allowlist from `blockable_system_packages`. Sweepable is not hideable: that list decides which system packages are eligible for a decision, and `isAllowed` is what protects them. Removing an allowed system package from the sweep freezes it in its last state -- it would have stranded Play hidden permanently the moment it was allowlisted. Verified on the Pixel 6a: FINE granted POLICY_FIXED, `applied AT_HOME` with a 0 m distance from a +/-11 m GPS fix, YouTube/Chrome/Firefox absent from `pm list packages -e`, Play Store, infakt, RunnerUp and all five Tachiyomi packages present. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HjxL9kdAzZmGqQA5tMNrZ8
153 lines
3.9 KiB
JSON
153 lines
3.9 KiB
JSON
{
|
|
"allowed_packages": [
|
|
"com.android.vending",
|
|
"com.celzero.bravedns",
|
|
"com.facebook.orca",
|
|
"com.google.android.apps.maps",
|
|
"com.google.android.apps.nexuslauncher",
|
|
"com.google.android.calendar",
|
|
"com.google.android.deskclock",
|
|
"com.ichi2.anki",
|
|
"com.kuhy.diet_guard_app",
|
|
"com.kuhy.focus_owner",
|
|
"com.kuhy.home_inventory",
|
|
"com.kuhy.untools",
|
|
"com.kuhy.wake_alarm_sync",
|
|
"com.kuhy.workout_app",
|
|
"com.kunzisoft.keepass.libre",
|
|
"com.metrolist.music",
|
|
"com.revolut.revolut",
|
|
"com.sosauce.cutecalc",
|
|
"com.zaneschepke.wireguardautotunnel",
|
|
"dev.kuhy.todo",
|
|
"eu.kanade.tachiyomi.sy",
|
|
"org.fossify.contacts",
|
|
"org.fossify.messages",
|
|
"org.fossify.phone",
|
|
"org.runnerup",
|
|
"org.runnerup.free",
|
|
"pl.infakt.infakt",
|
|
"pl.mbank",
|
|
"pl.nask.mobywatel"
|
|
],
|
|
"allowed_prefixes": [
|
|
"eu.kanade.tachiyomi"
|
|
],
|
|
"always_blocked_packages": [
|
|
"com.android.chrome",
|
|
"com.google.android.apps.youtube.music",
|
|
"com.google.android.youtube"
|
|
],
|
|
"always_on_vpn_package": "com.celzero.bravedns",
|
|
"blockable_system_packages": [
|
|
"com.android.chrome",
|
|
"com.android.vending",
|
|
"com.google.android.apps.youtube.music",
|
|
"com.google.android.videos",
|
|
"com.google.android.youtube"
|
|
],
|
|
"browser_packages": [
|
|
"com.android.chrome",
|
|
"org.mozilla.fenix"
|
|
],
|
|
"curfew": {
|
|
"end": "05:00",
|
|
"start": "23:00"
|
|
},
|
|
"home": {
|
|
"hysteresis_m": 30.0,
|
|
"latitude": null,
|
|
"longitude": null,
|
|
"radius_m": 150.0
|
|
},
|
|
"launcher_package": "com.google.android.apps.nexuslauncher",
|
|
"never_disable_prefixes": [
|
|
"android",
|
|
"com.android.bluetooth",
|
|
"com.android.camera",
|
|
"com.android.camera2",
|
|
"com.android.captiveportallogin",
|
|
"com.android.certinstaller",
|
|
"com.android.contacts",
|
|
"com.android.dialer",
|
|
"com.android.documentsui",
|
|
"com.android.emergency",
|
|
"com.android.externalstorage",
|
|
"com.android.inputmethod",
|
|
"com.android.keychain",
|
|
"com.android.launcher",
|
|
"com.android.launcher3",
|
|
"com.android.location",
|
|
"com.android.messaging",
|
|
"com.android.mms",
|
|
"com.android.networkstack",
|
|
"com.android.nfc",
|
|
"com.android.permissioncontroller",
|
|
"com.android.phone",
|
|
"com.android.providers",
|
|
"com.android.se",
|
|
"com.android.settings",
|
|
"com.android.shell",
|
|
"com.android.systemui",
|
|
"com.android.vpndialogs",
|
|
"com.android.wifi",
|
|
"com.celzero.bravedns",
|
|
"com.google.android.apps.messaging",
|
|
"com.google.android.contacts",
|
|
"com.google.android.deskclock",
|
|
"com.google.android.dialer",
|
|
"com.google.android.ext.services",
|
|
"com.google.android.ext.shared",
|
|
"com.google.android.gms",
|
|
"com.google.android.gsf",
|
|
"com.google.android.inputmethod.latin",
|
|
"com.google.android.permissioncontroller",
|
|
"com.google.android.setupwizard",
|
|
"com.google.android.trichromelibrary",
|
|
"com.google.android.webview",
|
|
"com.mediatek",
|
|
"com.qualcomm",
|
|
"pl.infakt.infakt"
|
|
],
|
|
"night_allowed_packages": [
|
|
"com.celzero.bravedns",
|
|
"com.google.android.apps.nexuslauncher",
|
|
"com.google.android.deskclock",
|
|
"com.kuhy.focus_owner",
|
|
"com.kuhy.wake_alarm_sync",
|
|
"com.kunzisoft.keepass.libre",
|
|
"com.revolut.revolut",
|
|
"org.fossify.contacts",
|
|
"org.fossify.messages",
|
|
"org.fossify.phone",
|
|
"org.runnerup",
|
|
"org.runnerup.free",
|
|
"pl.infakt.infakt",
|
|
"pl.mbank",
|
|
"pl.nask.mobywatel"
|
|
],
|
|
"night_allowed_prefixes": [
|
|
"eu.kanade.tachiyomi"
|
|
],
|
|
"private_dns_host": "",
|
|
"schema_version": 1,
|
|
"vpn_lockdown": true,
|
|
"workout_unblock_domains": [
|
|
"googlevideo.com",
|
|
"i.ytimg.com",
|
|
"i9.ytimg.com",
|
|
"m.youtube.com",
|
|
"s.ytimg.com",
|
|
"www.youtube-nocookie.com",
|
|
"www.youtube.com",
|
|
"youtu.be",
|
|
"youtube-nocookie.com",
|
|
"youtube.com",
|
|
"youtube.googleapis.com",
|
|
"youtubei.googleapis.com",
|
|
"yt3.ggpht.com",
|
|
"yt3.googleusercontent.com",
|
|
"ytimg.com"
|
|
]
|
|
}
|