From af3e4a9b1396783806b3b1c73c80412807465f80 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Sun, 16 Aug 2026 21:23:39 +0200 Subject: [PATCH] Split update_android_hosts.sh; extract its blocklist as data 870 -> 146 across three libs, plus 247 lines of hosts entries moved from a heredoc into data/android_guardian_blocklist.hosts. A data file draws no linter, unlike extracting an embedded Python program. The installed blocklist is byte-identical: md5 7d3f2550 on both sides. The first attempt cut inside the `case` dispatcher and neither the entry nor a lib parsed. Redone with the case as a hard boundary - this script has no main(), so the case block and the argument parsing that feeds it stay in the entry. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY --- ...config-android-hosts-split-2026-08-16.json | 17 + ...config-android-hosts-split-2026-08-16.json | 39 + .../data/android_guardian_blocklist.hosts | 247 ++++++ .../single_use/utils/lib/android_commands.sh | 243 ++++++ .../single_use/utils/lib/android_device.sh | 210 +++++ .../single_use/utils/lib/android_module.sh | 49 ++ .../single_use/utils/update_android_hosts.sh | 738 +----------------- 7 files changed, 812 insertions(+), 731 deletions(-) create mode 100644 docs/superpowers/contracts/linux-config-android-hosts-split-2026-08-16.json create mode 100644 docs/superpowers/evidence/linux-config-android-hosts-split-2026-08-16.json create mode 100644 linux_configuration/scripts/single_use/utils/data/android_guardian_blocklist.hosts create mode 100755 linux_configuration/scripts/single_use/utils/lib/android_commands.sh create mode 100755 linux_configuration/scripts/single_use/utils/lib/android_device.sh create mode 100755 linux_configuration/scripts/single_use/utils/lib/android_module.sh diff --git a/docs/superpowers/contracts/linux-config-android-hosts-split-2026-08-16.json b/docs/superpowers/contracts/linux-config-android-hosts-split-2026-08-16.json new file mode 100644 index 00000000..65fc5f8b --- /dev/null +++ b/docs/superpowers/contracts/linux-config-android-hosts-split-2026-08-16.json @@ -0,0 +1,17 @@ +{ + "title": "Split update_android_hosts.sh under the 250-line cap", + "objective": "Bring the 870-line Android hosts installer under the cap, extracting its embedded blocklist as a data file rather than leaving 247 lines of hosts entries inside a heredoc.", + "acceptance_criteria": [ + "The entry script and all three new libs are at most 250 lines, and the extracted blocklist is data rather than shell.", + "The blocklist the module installs is byte-identical: the md5 of the original heredoc body must equal the md5 of the extracted file.", + "bash -n passes on the entry and every lib. The script dispatches through a `case` rather than a main(), so no seam may fall inside it.", + "The pre-commit shellcheck hook passes on every file, with no new suppression.", + "The entry declares SCRIPT_DIR exactly once, and it uses ${BASH_SOURCE[0]} because the libs resolve the data path through it." + ], + "out_of_scope": [ + "Executing the script; it pairs with a phone over adb and installs a Magisk module.", + "Changing any blocklist entry.", + "The other over-cap linux_configuration scripts." + ], + "verifier": "md5 comparison of the heredoc body against the extracted data file, bash -n on all four shell files, shellcheck -x on the entry and shellcheck on each lib, and check_file_length.sh." +} diff --git a/docs/superpowers/evidence/linux-config-android-hosts-split-2026-08-16.json b/docs/superpowers/evidence/linux-config-android-hosts-split-2026-08-16.json new file mode 100644 index 00000000..d44c6fa8 --- /dev/null +++ b/docs/superpowers/evidence/linux-config-android-hosts-split-2026-08-16.json @@ -0,0 +1,39 @@ +{ + "intent": "Split update_android_hosts.sh under the cap, extracting its 247-line blocklist as data rather than shell.", + "scope": [ + "linux_configuration/scripts/single_use/utils/update_android_hosts.sh (870 -> 146)", + "lib/android_device.sh, android_module.sh, android_commands.sh (new)", + "data/android_guardian_blocklist.hosts (new)", + "Non-goal: no script executed, no generated content changed" + ], + "changes": [ + "Three libs for device discovery, module building and the subcommands. The script dispatches through a `case` rather than a main(), so the case block and the argument parsing that feeds it stay in the entry.", + "build_module was 287 lines, almost all of it a single heredoc emitting 247 lines of hosts entries. That is data, so it moved to data/android_guardian_blocklist.hosts and the script now cats it. Unlike extracting an embedded Python program, a data file attracts no linter - it is the cheap version of the same move.", + "Two fixes the split exposed: the entry already declared SCRIPT_DIR (with $0, upgraded to ${BASH_SOURCE[0]} since the libs resolve the data path through it), and COMMAND was being assigned at the end of a lib but read by the entry's case - that argument-parsing tail moved back." + ], + "verification": [ + { + "command": "md5 of the original heredoc body vs the extracted data file", + "result": "pass", + "evidence": "7d3f2550bf24e30017e360c9f4f23b7f on both sides - the blocklist the module installs is byte-identical. For a script whose job is emitting a file, this is the check that matters." + }, + { + "command": "bash -n on the entry and each lib", + "result": "fail then pass", + "evidence": "The first attempt cut inside the `case` statement and both the entry and a lib failed to parse. Redone with the case boundary as a hard limit; all four parse now." + }, + { + "command": "shellcheck -x on the entry, shellcheck on each lib", + "result": "pass", + "evidence": "Zero findings across all four files, no suppression." + } + ], + "risks": [ + "Not executed: it pairs with a phone over adb and installs a Magisk module. The content hash covers what it writes; nothing covers the adb interaction.", + "The blocklist now lives two directories from the code that installs it, resolved through SCRIPT_DIR. If the script is ever copied elsewhere without data/, the module builds with an empty blocklist rather than failing loudly." + ], + "rollback": [ + "git revert the commit; the script returns to 870 lines with the blocklist inline.", + "After rollback, re-run bash -n and shellcheck on the restored script." + ] +} diff --git a/linux_configuration/scripts/single_use/utils/data/android_guardian_blocklist.hosts b/linux_configuration/scripts/single_use/utils/data/android_guardian_blocklist.hosts new file mode 100644 index 00000000..1b44a883 --- /dev/null +++ b/linux_configuration/scripts/single_use/utils/data/android_guardian_blocklist.hosts @@ -0,0 +1,247 @@ + +# ============================================ +# Custom blocking entries - Android Guardian +# ============================================ + +# YouTube +0.0.0.0 youtube.com +0.0.0.0 www.youtube.com +0.0.0.0 m.youtube.com +0.0.0.0 youtu.be +0.0.0.0 youtube-nocookie.com +0.0.0.0 www.youtube-nocookie.com +0.0.0.0 youtubei.googleapis.com +0.0.0.0 youtube.googleapis.com +0.0.0.0 yt3.ggpht.com +0.0.0.0 ytimg.com +0.0.0.0 i.ytimg.com +0.0.0.0 s.ytimg.com +0.0.0.0 i9.ytimg.com +0.0.0.0 googlevideo.com + +# Alternative YouTube Frontends (Invidious, Piped, etc.) +0.0.0.0 invidious.io +0.0.0.0 www.invidious.io +0.0.0.0 invidio.us +0.0.0.0 vid.puffyan.us +0.0.0.0 invidious.snopyta.org +0.0.0.0 yewtu.be +0.0.0.0 invidious.kavin.rocks +0.0.0.0 inv.riverside.rocks +0.0.0.0 invidious.namazso.eu +0.0.0.0 invidious.nerdvpn.de +0.0.0.0 invidious.projectsegfau.lt +0.0.0.0 invidious.slipfox.xyz +0.0.0.0 invidious.privacydev.net +0.0.0.0 invidious.perennialte.ch +0.0.0.0 invidious.protokoll-11.de +0.0.0.0 invidious.einfachzocken.eu +0.0.0.0 invidious.fdn.fr +0.0.0.0 inv.in.projectsegfau.lt +0.0.0.0 invidious.tiekoetter.com +0.0.0.0 invidious.lunar.icu +0.0.0.0 iv.ggtyler.dev +0.0.0.0 iv.melmac.space +0.0.0.0 piped.video +0.0.0.0 www.piped.video +0.0.0.0 piped.kavin.rocks +0.0.0.0 piped.mha.fi +0.0.0.0 piped.mint.lgbt +0.0.0.0 piped.projectsegfau.lt +0.0.0.0 piped.privacydev.net +0.0.0.0 piped.smnz.de +0.0.0.0 piped.adminforge.de +0.0.0.0 watch.whatever.social +0.0.0.0 piped.lunar.icu +0.0.0.0 viewtube.io +0.0.0.0 www.viewtube.io +0.0.0.0 freetube.io +0.0.0.0 www.freetube.io +0.0.0.0 tubo.media +0.0.0.0 www.tubo.media +0.0.0.0 materialious.nadeko.net +0.0.0.0 clipious.org +0.0.0.0 www.clipious.org +0.0.0.0 newpipe.net +0.0.0.0 www.newpipe.net +0.0.0.0 newpipe.schabi.org +0.0.0.0 grayjay.app +0.0.0.0 www.grayjay.app +0.0.0.0 libretube.dev +0.0.0.0 www.libretube.dev +0.0.0.0 hyperion.deishelon.com +0.0.0.0 inv.n8pjl.ca +0.0.0.0 inv.zzls.xyz +0.0.0.0 inv.tux.pizza +0.0.0.0 invidious.incogniweb.net +0.0.0.0 invidious.drgns.space +0.0.0.0 invidious.io.lol + +# Discord (media only - voice chat allowed) +0.0.0.0 cdn.discordapp.com +0.0.0.0 media.discordapp.net +0.0.0.0 images-ext-1.discordapp.net +0.0.0.0 images-ext-2.discordapp.net +0.0.0.0 tenor.com +0.0.0.0 giphy.com + +# Food Delivery Services +# Polish services +0.0.0.0 pyszne.pl +0.0.0.0 www.pyszne.pl +0.0.0.0 m.pyszne.pl +0.0.0.0 api.pyszne.pl +0.0.0.0 app.pyszne.pl +0.0.0.0 glovo.com +0.0.0.0 www.glovo.com +0.0.0.0 m.glovo.com +0.0.0.0 api.glovo.com +0.0.0.0 glovoapp.com +0.0.0.0 www.glovoapp.com +0.0.0.0 bolt.eu +:: bolt.eu +0.0.0.0 www.bolt.eu +:: www.bolt.eu +0.0.0.0 food.bolt.eu +:: food.bolt.eu +0.0.0.0 m.bolt.eu +:: m.bolt.eu +0.0.0.0 api.bolt.eu +:: api.bolt.eu +0.0.0.0 node.bolt.eu +:: node.bolt.eu +0.0.0.0 gw.bolt.eu +:: gw.bolt.eu +0.0.0.0 client-api.bolt.eu +:: client-api.bolt.eu +0.0.0.0 auth.bolt.eu +:: auth.bolt.eu +0.0.0.0 cdn.bolt.eu +:: cdn.bolt.eu +0.0.0.0 images.bolt.eu +:: images.bolt.eu +0.0.0.0 static.bolt.eu +:: static.bolt.eu +0.0.0.0 assets.bolt.eu +:: assets.bolt.eu +0.0.0.0 fleet.bolt.eu +:: fleet.bolt.eu +0.0.0.0 user.bolt.eu +:: user.bolt.eu +0.0.0.0 courier.bolt.eu +:: courier.bolt.eu +0.0.0.0 rider.bolt.eu +:: rider.bolt.eu +0.0.0.0 restaurant.bolt.eu +:: restaurant.bolt.eu +0.0.0.0 partner-food.bolt.eu +:: partner-food.bolt.eu +0.0.0.0 wolt.com +0.0.0.0 www.wolt.com +0.0.0.0 m.wolt.com +0.0.0.0 api.wolt.com +0.0.0.0 restaurant-api.wolt.com +0.0.0.0 consumer-api.wolt.com +0.0.0.0 woltwojta.pl +0.0.0.0 www.woltwojta.pl +0.0.0.0 jush.pl +0.0.0.0 www.jush.pl +0.0.0.0 m.jush.pl +0.0.0.0 api.jush.pl +0.0.0.0 delio.pl +0.0.0.0 www.delio.pl +0.0.0.0 m.delio.pl +0.0.0.0 api.delio.pl +0.0.0.0 delio.com +0.0.0.0 www.delio.com +0.0.0.0 delio.com.pl +0.0.0.0 www.delio.com.pl +0.0.0.0 api.delio.com.pl +0.0.0.0 lisek.app +0.0.0.0 www.lisek.app +0.0.0.0 api.lisek.app +0.0.0.0 stava.app +0.0.0.0 www.stava.app +0.0.0.0 api.stava.app +0.0.0.0 barbora.pl +0.0.0.0 www.barbora.pl +0.0.0.0 api.barbora.pl +0.0.0.0 frisco.pl +0.0.0.0 www.frisco.pl +0.0.0.0 api.frisco.pl +0.0.0.0 szama.pl +0.0.0.0 www.szama.pl +0.0.0.0 api.szama.pl +0.0.0.0 auchandirect.pl +0.0.0.0 www.auchandirect.pl +0.0.0.0 zakupy.biedronka.pl +0.0.0.0 ezakupy.tesco.pl +0.0.0.0 www.ezakupy.tesco.pl +# International services +0.0.0.0 ubereats.com +0.0.0.0 www.ubereats.com +0.0.0.0 m.ubereats.com +0.0.0.0 api.ubereats.com +0.0.0.0 uber.com +0.0.0.0 www.uber.com +0.0.0.0 m.uber.com +0.0.0.0 api.uber.com +0.0.0.0 login.uber.com +0.0.0.0 auth.uber.com +0.0.0.0 deliveroo.com +0.0.0.0 www.deliveroo.com +0.0.0.0 m.deliveroo.com +0.0.0.0 api.deliveroo.com +0.0.0.0 deliveroo.co.uk +0.0.0.0 www.deliveroo.co.uk +0.0.0.0 foodpanda.com +0.0.0.0 www.foodpanda.com +0.0.0.0 m.foodpanda.com +0.0.0.0 api.foodpanda.com +0.0.0.0 grubhub.com +0.0.0.0 www.grubhub.com +0.0.0.0 m.grubhub.com +0.0.0.0 api.grubhub.com +0.0.0.0 doordash.com +0.0.0.0 www.doordash.com +0.0.0.0 m.doordash.com +0.0.0.0 api.doordash.com +0.0.0.0 justeat.com +0.0.0.0 www.justeat.com +0.0.0.0 m.justeat.com +0.0.0.0 justeat.co.uk +0.0.0.0 www.justeat.co.uk +0.0.0.0 postmates.com +0.0.0.0 www.postmates.com +0.0.0.0 seamless.com +0.0.0.0 www.seamless.com +0.0.0.0 getir.com +0.0.0.0 www.getir.com +0.0.0.0 api.getir.com +0.0.0.0 flink.com +0.0.0.0 www.flink.com +0.0.0.0 gorillas.io +0.0.0.0 www.gorillas.io +0.0.0.0 gopuff.com +0.0.0.0 www.gopuff.com +0.0.0.0 instacart.com +0.0.0.0 www.instacart.com +0.0.0.0 takeaway.com +0.0.0.0 www.takeaway.com +0.0.0.0 api.takeaway.com + +# Fast Food +0.0.0.0 mcdonalds.com +0.0.0.0 www.mcdonalds.com +0.0.0.0 mcdonalds.pl +0.0.0.0 www.mcdonalds.pl +0.0.0.0 kfc.com +0.0.0.0 www.kfc.com +0.0.0.0 kfc.pl +0.0.0.0 www.kfc.pl +0.0.0.0 burgerking.com +0.0.0.0 www.burgerking.com +0.0.0.0 pizzahut.com +0.0.0.0 www.pizzahut.com +0.0.0.0 dominos.com +0.0.0.0 www.dominos.com diff --git a/linux_configuration/scripts/single_use/utils/lib/android_commands.sh b/linux_configuration/scripts/single_use/utils/lib/android_commands.sh new file mode 100755 index 00000000..a1d73ab2 --- /dev/null +++ b/linux_configuration/scripts/single_use/utils/lib/android_commands.sh @@ -0,0 +1,243 @@ +#!/bin/bash +# The install, status, disable and app-blocking subcommands. +# +# Sourced by update_android_hosts.sh; split out to keep it under the 250-line cap. +# Sourced rather than run, so it inherits the caller's strict mode. + +# Install/update the guardian module +cmd_install() { + ensure_device_ready + + local module_zip + module_zip=$(build_module) + + log "Pushing module to device..." + adb push "$module_zip" /sdcard/android_guardian.zip || die "Failed to push module" + + log "Installing module..." + adb shell "su -c 'mkdir -p $MODULE_DEST'" || die "Failed to create module directory" + adb shell "su -c 'cd $MODULE_DEST && unzip -o /sdcard/android_guardian.zip'" || die "Failed to extract module" + adb shell "su -c 'chmod 755 $MODULE_DEST/*.sh'" + adb shell "su -c 'rm /sdcard/android_guardian.zip'" + + # Set up guardian data directory + log "Setting up guardian data..." + adb shell "su -c 'mkdir -p $GUARDIAN_DATA_DIR'" + adb shell "su -c 'echo ENABLED > $GUARDIAN_DATA_DIR/control'" + + # Copy blocked apps list + adb push "$GUARDIAN_MODULE_DIR/blocked_apps.txt" /sdcard/blocked_apps.txt || die "Failed to push blocked apps list" + adb shell "su -c 'cp /sdcard/blocked_apps.txt $GUARDIAN_DATA_DIR/blocked_apps.txt'" + adb shell "su -c 'rm /sdcard/blocked_apps.txt'" + + # Create hosts backup for tamper protection + adb shell "su -c 'cp $MODULE_DEST/system/etc/hosts $GUARDIAN_DATA_DIR/hosts.backup'" + + # Immediately uninstall any currently installed blocked apps + log "Checking for blocked apps to remove..." + uninstall_blocked_apps + + echo "" + echo "==========================================" + echo " ✓ Android Guardian installed!" + echo "==========================================" + echo "" + echo "Features enabled:" + echo " • Hosts-based ad/tracker blocking" + echo " • App installation blocking" + echo " • Tamper protection" + echo "" + echo "⚠️ This can ONLY be controlled via ADB:" + echo " Disable: $0 disable" + echo " Enable: $0 enable" + echo " Status: $0 status" + echo "" + echo "Reboot your device to activate the module." + echo "" +} + +# Uninstall currently installed blocked apps +uninstall_blocked_apps() { + local blocked_apps + blocked_apps=$(grep -v '^#' "$GUARDIAN_MODULE_DIR/blocked_apps.txt" | grep -v '^$' || true) + + for package in $blocked_apps; do + if adb shell "pm list packages" 2>/dev/null | grep -q "package:$package"; then + log "Uninstalling blocked app: $package" + adb shell "pm uninstall $package" 2>/dev/null || true + fi + done +} + +# Show status +cmd_status() { + ensure_device_ready + + echo "" + echo "=== Android Guardian Status ===" + echo "" + + # Check if module is installed + if adb shell "su -c 'test -d $MODULE_DEST'" 2>/dev/null; then + echo "Module: INSTALLED" + else + echo "Module: NOT INSTALLED" + return + fi + + # Check control status + local status + status=$(adb shell "su -c 'cat $GUARDIAN_DATA_DIR/control 2>/dev/null || echo UNKNOWN'" | tr -d '\r') + echo "Status: $status" + + # Check if module is "disabled" in Magisk UI (should be auto-fixed by watchdog) + local magisk_disabled + if adb shell "su -c 'test -f $MODULE_DEST/disable'" 2>/dev/null; then + magisk_disabled="YES (watchdog should fix this)" + else + magisk_disabled="No" + fi + echo "Magisk UI disabled: $magisk_disabled" + + # Check if watchdog is running + local watchdog_running + watchdog_running=$(adb shell "su -c 'pgrep -f watchdog.sh 2>/dev/null | wc -l'" | tr -d '\r') + if [ "$watchdog_running" -gt 0 ] 2>/dev/null; then + echo "Watchdog: RUNNING ($watchdog_running processes)" + else + echo "Watchdog: NOT RUNNING (reboot phone to start)" + fi + + # Check hosts file + local hosts_entries + hosts_entries=$(adb shell "su -c 'grep -c \"^0.0.0.0\" /system/etc/hosts 2>/dev/null || echo 0'" | tr -d '\r') + echo "Blocked domains: $hosts_entries" + + # Check blocked apps count + local blocked_count + blocked_count=$(adb shell "su -c 'grep -v \"^#\" $GUARDIAN_DATA_DIR/blocked_apps.txt 2>/dev/null | grep -v \"^$\" | wc -l || echo 0'" | tr -d '\r') + echo "Blocked app rules: $blocked_count packages" + + echo "" + echo "Protection: Module cannot be disabled from Magisk UI" + echo " Only controllable via: $0 disable/enable" + echo "" +} + +# Disable guardian +cmd_disable() { + ensure_device_ready + + log "Disabling Android Guardian..." + adb shell "su -c 'echo DISABLED > $GUARDIAN_DATA_DIR/control'" || die "Failed to disable guardian" + + echo "" + echo "✓ Guardian DISABLED" + echo " Hosts blocking still active until reboot" + echo " App blocking service paused" + echo "" + echo "To re-enable: $0 enable" + echo "" +} + +# Enable guardian +cmd_enable() { + ensure_device_ready + + log "Enabling Android Guardian..." + adb shell "su -c 'echo ENABLED > $GUARDIAN_DATA_DIR/control'" || die "Failed to enable guardian" + + echo "" + echo "✓ Guardian ENABLED" + echo "" +} + +# Uninstall module +cmd_uninstall() { + ensure_device_ready + + # Check if disabled first + local status + status=$(adb shell "su -c 'cat $GUARDIAN_DATA_DIR/control 2>/dev/null || echo ENABLED'" | tr -d '\r') + + if [[ $status != "DISABLED" ]]; then + echo "" + echo "⚠️ Guardian must be disabled before uninstalling!" + echo " Run: $0 disable" + echo " Then: $0 uninstall" + echo "" + exit 1 + fi + + log "Removing Android Guardian..." + adb shell "su -c 'rm -rf $MODULE_DEST'" + adb shell "su -c 'rm -rf $GUARDIAN_DATA_DIR'" + + echo "" + echo "✓ Guardian uninstalled" + echo " Reboot to remove hosts blocking" + echo "" +} + +# Show logs +cmd_logs() { + ensure_device_ready + + echo "=== Guardian Logs ===" + adb shell "su -c 'cat $GUARDIAN_DATA_DIR/guardian.log 2>/dev/null || echo \"No logs yet\"'" +} + +# Block an app +cmd_block_app() { + local package="${1:-}" + + if [[ -z $package ]]; then + echo "Usage: $0 block-app " + echo "Example: $0 block-app com.ubercab.eats" + exit 1 + fi + + ensure_device_ready + + log "Adding $package to block list..." + adb shell "su -c 'echo \"$package\" >> $GUARDIAN_DATA_DIR/blocked_apps.txt'" + + # Also add to local file + echo "$package" >>"$GUARDIAN_MODULE_DIR/blocked_apps.txt" + + # Try to uninstall if currently installed + if adb shell "pm list packages" 2>/dev/null | grep -q "package:$package"; then + log "Uninstalling $package..." + adb shell "pm uninstall $package" 2>/dev/null || true + fi + + echo "✓ $package added to block list" +} + +# Unblock an app +cmd_unblock_app() { + local package="${1:-}" + + if [[ -z $package ]]; then + echo "Usage: $0 unblock-app " + exit 1 + fi + + ensure_device_ready + + log "Removing $package from block list..." + adb shell "su -c 'grep -v \"^$package\$\" $GUARDIAN_DATA_DIR/blocked_apps.txt > $GUARDIAN_DATA_DIR/blocked_apps.tmp && mv $GUARDIAN_DATA_DIR/blocked_apps.tmp $GUARDIAN_DATA_DIR/blocked_apps.txt'" + + # Also remove from local file + grep -v "^$package$" "$GUARDIAN_MODULE_DIR/blocked_apps.txt" >"$GUARDIAN_MODULE_DIR/blocked_apps.tmp" && mv "$GUARDIAN_MODULE_DIR/blocked_apps.tmp" "$GUARDIAN_MODULE_DIR/blocked_apps.txt" + + echo "✓ $package removed from block list" +} + +# List blocked apps +cmd_list_blocked() { + ensure_device_ready + + echo "=== Blocked Apps ===" + adb shell "su -c 'cat $GUARDIAN_DATA_DIR/blocked_apps.txt 2>/dev/null'" | grep -v "^#" | grep -v "^$" || echo "No blocked apps" +} diff --git a/linux_configuration/scripts/single_use/utils/lib/android_device.sh b/linux_configuration/scripts/single_use/utils/lib/android_device.sh new file mode 100755 index 00000000..278362b3 --- /dev/null +++ b/linux_configuration/scripts/single_use/utils/lib/android_device.sh @@ -0,0 +1,210 @@ +#!/bin/bash +# Device discovery, pairing and connection. +# +# Sourced by update_android_hosts.sh; split out to keep it under the 250-line cap. +# Sourced rather than run, so it inherits the caller's strict mode. + +# Discover Android devices on the network using mDNS +discover_android_device() { + local found_address="" + + # Ensure avahi-browse is available + if ! command -v avahi-browse &>/dev/null; then + if command -v pacman &>/dev/null; then + echo "Installing avahi for device discovery..." >&2 + sudo pacman -S --noconfirm avahi nss-mdns &>/dev/null || true + sudo systemctl enable --now avahi-daemon &>/dev/null || true + elif command -v apt-get &>/dev/null; then + sudo apt-get install -y avahi-utils &>/dev/null || true + fi + fi + + if command -v avahi-browse &>/dev/null; then + echo "Scanning for Android devices (5 seconds)..." >&2 + + # Android wireless debugging advertises as _adb-tls-connect._tcp + local discovery_result + discovery_result=$(timeout 5 avahi-browse -rpt _adb-tls-connect._tcp 2>/dev/null | grep "^=" | head -1) + + if [[ -n $discovery_result ]]; then + # Parse: =;eth0;IPv4;adb-...;_adb-tls-connect._tcp;local;hostname.local;192.168.x.x;port;... + local ip port + ip=$(echo "$discovery_result" | cut -d';' -f8) + port=$(echo "$discovery_result" | cut -d';' -f9) + + if [[ -n $ip && -n $port ]]; then + found_address="$ip:$port" + echo "✓ Found device: $found_address" >&2 + fi + fi + fi + + # Fallback: try adb's mdns discovery + if [[ -z $found_address ]]; then + echo "Trying adb mdns discovery..." >&2 + + # adb can discover devices via mdns + local mdns_result + mdns_result=$(timeout 5 adb mdns services 2>/dev/null | grep -E "adb-tls-connect|_adb\._tcp" | head -1) + + if [[ -n $mdns_result ]]; then + # Try to extract IP:port from the result + local service_name + service_name=$(echo "$mdns_result" | awk '{print $1}') + if [[ -n $service_name ]]; then + # Try connecting via service name + echo "Found service: $service_name" >&2 + fi + fi + fi + + # Return found address (or empty) + echo "$found_address" +} + +# Pair with device over WiFi (Android 11+) +cmd_pair() { + ensure_adb_installed + + echo "" + echo "=== Wireless ADB Pairing (Android 11+) ===" + echo "" + echo "On your phone:" + echo " 1. Go to Settings > Developer Options > Wireless debugging" + echo " 2. Enable Wireless debugging" + echo " 3. Tap 'Pair device with pairing code'" + echo " 4. Note the IP:port and pairing code shown" + echo "" + + read -rp "Enter pairing IP:port (e.g., 192.168.1.100:37123): " pair_address + read -rp "Enter pairing code: " pair_code + + if [[ -z $pair_address || -z $pair_code ]]; then + die "Pairing address and code are required" + fi + + log "Pairing with device at $pair_address..." + if adb pair "$pair_address" "$pair_code"; then + echo "" + echo "✓ Pairing successful!" + echo "" + echo "Now get the connection address:" + echo " On phone: Wireless debugging screen shows IP:port under 'IP address & Port'" + echo " (This is DIFFERENT from the pairing port)" + echo "" + read -rp "Enter connection IP:port (e.g., 192.168.1.100:41567): " connect_address + + if [[ -n $connect_address ]]; then + # Save for future connections + mkdir -p "$(dirname "$WIRELESS_CONFIG")" + echo "$connect_address" >"$WIRELESS_CONFIG" + log "Saved connection address for future use" + + # Connect now + cmd_connect + fi + else + die "Pairing failed. Make sure the code is correct and you're on the same network." + fi +} + +# Connect to already-paired device +cmd_connect() { + ensure_adb_installed + + local connect_address="" + + # Check for saved address + if [[ -f $WIRELESS_CONFIG ]]; then + connect_address=$(cat "$WIRELESS_CONFIG") + log "Using saved address: $connect_address" + fi + + # Try auto-discovery if no saved address + if [[ -z $connect_address ]]; then + echo "" + log "Searching for Android devices on network..." + connect_address=$(discover_android_device) + fi + + # Manual fallback + if [[ -z $connect_address ]]; then + echo "" + echo "Auto-discovery failed. Enter address manually." + echo "On phone: Settings > Developer Options > Wireless debugging" + echo "Look for IP address & Port (NOT the pairing port)" + echo "" + read -rp "Enter connection IP:port (e.g., 192.168.1.100:41567): " connect_address + + if [[ -z $connect_address ]]; then + die "Connection address is required" + fi + fi + + # Save for future + mkdir -p "$(dirname "$WIRELESS_CONFIG")" + echo "$connect_address" >"$WIRELESS_CONFIG" + + log "Connecting to $connect_address..." + if adb connect "$connect_address" | grep -q "connected"; then + echo "" + echo "✓ Connected to device wirelessly!" + echo "" + + # Verify connection + if adb devices | grep -q "$connect_address"; then + echo "Device ready. You can now run other commands." + fi + else + echo "" + echo "Connection failed. Possible issues:" + echo " - Wireless debugging not enabled on phone" + echo " - Phone and PC not on same WiFi network" + echo " - Port changed (check Wireless debugging screen)" + echo " - May need to pair first: $0 pair" + echo "" + # Clear saved config since it failed + rm -f "$WIRELESS_CONFIG" + exit 1 + fi +} + +# Disconnect wireless ADB +cmd_disconnect() { + ensure_adb_installed + + log "Disconnecting all wireless devices..." + adb disconnect + echo "✓ Disconnected" +} + +# Check device connection and root +ensure_device_ready() { + ensure_adb_installed + + # Check if any device is connected + if ! adb devices | grep -qE "device$|:.*device$"; then + echo "" + echo "No device connected!" + echo "" + echo "Options:" + echo " 1. Connect USB cable with debugging enabled" + echo " 2. Use wireless: $0 pair (first time) or $0 connect" + echo "" + + # Check if we have a saved wireless config + if [[ -f $WIRELESS_CONFIG ]]; then + read -rp "Try connecting to saved wireless device? [Y/n]: " try_wireless + if [[ ${try_wireless,,} != "n" ]]; then + cmd_connect + else + exit 1 + fi + else + exit 1 + fi + fi + + check_adb_device + check_adb_root +} diff --git a/linux_configuration/scripts/single_use/utils/lib/android_module.sh b/linux_configuration/scripts/single_use/utils/lib/android_module.sh new file mode 100755 index 00000000..217f24b3 --- /dev/null +++ b/linux_configuration/scripts/single_use/utils/lib/android_module.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# Building the Magisk hosts module. +# +# Sourced by update_android_hosts.sh; split out to keep it under the 250-line cap. +# Sourced rather than run, so it inherits the caller's strict mode. + +# Build the module zip +build_module() { + local tmp_dir="$WORK_DIR/guardian_module" + local module_zip="$WORK_DIR/android_guardian.zip" + + echo "[BUILD] Building Android Guardian module..." >&2 + + rm -rf "$tmp_dir" + mkdir -p "$tmp_dir/system/etc" + + # Copy module files + cp "$GUARDIAN_MODULE_DIR/module.prop" "$tmp_dir/" + cp "$GUARDIAN_MODULE_DIR/service.sh" "$tmp_dir/" + cp "$GUARDIAN_MODULE_DIR/post-fs-data.sh" "$tmp_dir/" + cp "$GUARDIAN_MODULE_DIR/uninstall.sh" "$tmp_dir/" + + # Build hosts file + local hosts_file="$tmp_dir/system/etc/hosts" + if [[ -f /etc/hosts.stevenblack ]]; then + echo "[BUILD] Using StevenBlack hosts cache..." >&2 + cp /etc/hosts.stevenblack "$hosts_file" + elif [[ -f /etc/hosts ]]; then + echo "[BUILD] Using /etc/hosts..." >&2 + cp /etc/hosts "$hosts_file" + else + die "No hosts file found" + fi + + # Append custom blocking entries + # The blocklist is a data file, not a heredoc: 248 lines of hosts + # entries that belong under data/ where they can be diffed and edited + # without touching shell. + cat "$SCRIPT_DIR/data/android_guardian_blocklist.hosts" >>"$hosts_file" + + local total_entries + total_entries=$(grep -c "^0\.0\.0\.0 " "$hosts_file" || echo 0) + echo "[BUILD] Hosts file contains $total_entries blocked domains" >&2 + + # Create zip + (cd "$tmp_dir" && zip -r "$module_zip" . -x "*.DS_Store") >/dev/null + + echo "$module_zip" +} diff --git a/linux_configuration/scripts/single_use/utils/update_android_hosts.sh b/linux_configuration/scripts/single_use/utils/update_android_hosts.sh index 42ff34dd..a9e856a6 100755 --- a/linux_configuration/scripts/single_use/utils/update_android_hosts.sh +++ b/linux_configuration/scripts/single_use/utils/update_android_hosts.sh @@ -4,7 +4,7 @@ set -euo pipefail # Source common library -SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" +SCRIPT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" # shellcheck source=../../lib/common.sh source "$SCRIPT_DIR/../../lib/common.sh" # shellcheck source=../../lib/android.sh @@ -83,737 +83,13 @@ EOF # Wireless ADB connection file WIRELESS_CONFIG="$HOME/.config/android_guardian_wireless" -# Discover Android devices on the network using mDNS -discover_android_device() { - local found_address="" +# shellcheck source=lib/android_device.sh +source "$SCRIPT_DIR/lib/android_device.sh" +# shellcheck source=lib/android_module.sh +source "$SCRIPT_DIR/lib/android_module.sh" +# shellcheck source=lib/android_commands.sh +source "$SCRIPT_DIR/lib/android_commands.sh" - # Ensure avahi-browse is available - if ! command -v avahi-browse &>/dev/null; then - if command -v pacman &>/dev/null; then - echo "Installing avahi for device discovery..." >&2 - sudo pacman -S --noconfirm avahi nss-mdns &>/dev/null || true - sudo systemctl enable --now avahi-daemon &>/dev/null || true - elif command -v apt-get &>/dev/null; then - sudo apt-get install -y avahi-utils &>/dev/null || true - fi - fi - - if command -v avahi-browse &>/dev/null; then - echo "Scanning for Android devices (5 seconds)..." >&2 - - # Android wireless debugging advertises as _adb-tls-connect._tcp - local discovery_result - discovery_result=$(timeout 5 avahi-browse -rpt _adb-tls-connect._tcp 2>/dev/null | grep "^=" | head -1) - - if [[ -n $discovery_result ]]; then - # Parse: =;eth0;IPv4;adb-...;_adb-tls-connect._tcp;local;hostname.local;192.168.x.x;port;... - local ip port - ip=$(echo "$discovery_result" | cut -d';' -f8) - port=$(echo "$discovery_result" | cut -d';' -f9) - - if [[ -n $ip && -n $port ]]; then - found_address="$ip:$port" - echo "✓ Found device: $found_address" >&2 - fi - fi - fi - - # Fallback: try adb's mdns discovery - if [[ -z $found_address ]]; then - echo "Trying adb mdns discovery..." >&2 - - # adb can discover devices via mdns - local mdns_result - mdns_result=$(timeout 5 adb mdns services 2>/dev/null | grep -E "adb-tls-connect|_adb\._tcp" | head -1) - - if [[ -n $mdns_result ]]; then - # Try to extract IP:port from the result - local service_name - service_name=$(echo "$mdns_result" | awk '{print $1}') - if [[ -n $service_name ]]; then - # Try connecting via service name - echo "Found service: $service_name" >&2 - fi - fi - fi - - # Return found address (or empty) - echo "$found_address" -} - -# Pair with device over WiFi (Android 11+) -cmd_pair() { - ensure_adb_installed - - echo "" - echo "=== Wireless ADB Pairing (Android 11+) ===" - echo "" - echo "On your phone:" - echo " 1. Go to Settings > Developer Options > Wireless debugging" - echo " 2. Enable Wireless debugging" - echo " 3. Tap 'Pair device with pairing code'" - echo " 4. Note the IP:port and pairing code shown" - echo "" - - read -rp "Enter pairing IP:port (e.g., 192.168.1.100:37123): " pair_address - read -rp "Enter pairing code: " pair_code - - if [[ -z $pair_address || -z $pair_code ]]; then - die "Pairing address and code are required" - fi - - log "Pairing with device at $pair_address..." - if adb pair "$pair_address" "$pair_code"; then - echo "" - echo "✓ Pairing successful!" - echo "" - echo "Now get the connection address:" - echo " On phone: Wireless debugging screen shows IP:port under 'IP address & Port'" - echo " (This is DIFFERENT from the pairing port)" - echo "" - read -rp "Enter connection IP:port (e.g., 192.168.1.100:41567): " connect_address - - if [[ -n $connect_address ]]; then - # Save for future connections - mkdir -p "$(dirname "$WIRELESS_CONFIG")" - echo "$connect_address" >"$WIRELESS_CONFIG" - log "Saved connection address for future use" - - # Connect now - cmd_connect - fi - else - die "Pairing failed. Make sure the code is correct and you're on the same network." - fi -} - -# Connect to already-paired device -cmd_connect() { - ensure_adb_installed - - local connect_address="" - - # Check for saved address - if [[ -f $WIRELESS_CONFIG ]]; then - connect_address=$(cat "$WIRELESS_CONFIG") - log "Using saved address: $connect_address" - fi - - # Try auto-discovery if no saved address - if [[ -z $connect_address ]]; then - echo "" - log "Searching for Android devices on network..." - connect_address=$(discover_android_device) - fi - - # Manual fallback - if [[ -z $connect_address ]]; then - echo "" - echo "Auto-discovery failed. Enter address manually." - echo "On phone: Settings > Developer Options > Wireless debugging" - echo "Look for IP address & Port (NOT the pairing port)" - echo "" - read -rp "Enter connection IP:port (e.g., 192.168.1.100:41567): " connect_address - - if [[ -z $connect_address ]]; then - die "Connection address is required" - fi - fi - - # Save for future - mkdir -p "$(dirname "$WIRELESS_CONFIG")" - echo "$connect_address" >"$WIRELESS_CONFIG" - - log "Connecting to $connect_address..." - if adb connect "$connect_address" | grep -q "connected"; then - echo "" - echo "✓ Connected to device wirelessly!" - echo "" - - # Verify connection - if adb devices | grep -q "$connect_address"; then - echo "Device ready. You can now run other commands." - fi - else - echo "" - echo "Connection failed. Possible issues:" - echo " - Wireless debugging not enabled on phone" - echo " - Phone and PC not on same WiFi network" - echo " - Port changed (check Wireless debugging screen)" - echo " - May need to pair first: $0 pair" - echo "" - # Clear saved config since it failed - rm -f "$WIRELESS_CONFIG" - exit 1 - fi -} - -# Disconnect wireless ADB -cmd_disconnect() { - ensure_adb_installed - - log "Disconnecting all wireless devices..." - adb disconnect - echo "✓ Disconnected" -} - -# Check device connection and root -ensure_device_ready() { - ensure_adb_installed - - # Check if any device is connected - if ! adb devices | grep -qE "device$|:.*device$"; then - echo "" - echo "No device connected!" - echo "" - echo "Options:" - echo " 1. Connect USB cable with debugging enabled" - echo " 2. Use wireless: $0 pair (first time) or $0 connect" - echo "" - - # Check if we have a saved wireless config - if [[ -f $WIRELESS_CONFIG ]]; then - read -rp "Try connecting to saved wireless device? [Y/n]: " try_wireless - if [[ ${try_wireless,,} != "n" ]]; then - cmd_connect - else - exit 1 - fi - else - exit 1 - fi - fi - - check_adb_device - check_adb_root -} - -# Build the module zip -build_module() { - local tmp_dir="$WORK_DIR/guardian_module" - local module_zip="$WORK_DIR/android_guardian.zip" - - echo "[BUILD] Building Android Guardian module..." >&2 - - rm -rf "$tmp_dir" - mkdir -p "$tmp_dir/system/etc" - - # Copy module files - cp "$GUARDIAN_MODULE_DIR/module.prop" "$tmp_dir/" - cp "$GUARDIAN_MODULE_DIR/service.sh" "$tmp_dir/" - cp "$GUARDIAN_MODULE_DIR/post-fs-data.sh" "$tmp_dir/" - cp "$GUARDIAN_MODULE_DIR/uninstall.sh" "$tmp_dir/" - - # Build hosts file - local hosts_file="$tmp_dir/system/etc/hosts" - if [[ -f /etc/hosts.stevenblack ]]; then - echo "[BUILD] Using StevenBlack hosts cache..." >&2 - cp /etc/hosts.stevenblack "$hosts_file" - elif [[ -f /etc/hosts ]]; then - echo "[BUILD] Using /etc/hosts..." >&2 - cp /etc/hosts "$hosts_file" - else - die "No hosts file found" - fi - - # Append custom blocking entries - cat >>"$hosts_file" <<'CUSTOM_EOF' - -# ============================================ -# Custom blocking entries - Android Guardian -# ============================================ - -# YouTube -0.0.0.0 youtube.com -0.0.0.0 www.youtube.com -0.0.0.0 m.youtube.com -0.0.0.0 youtu.be -0.0.0.0 youtube-nocookie.com -0.0.0.0 www.youtube-nocookie.com -0.0.0.0 youtubei.googleapis.com -0.0.0.0 youtube.googleapis.com -0.0.0.0 yt3.ggpht.com -0.0.0.0 ytimg.com -0.0.0.0 i.ytimg.com -0.0.0.0 s.ytimg.com -0.0.0.0 i9.ytimg.com -0.0.0.0 googlevideo.com - -# Alternative YouTube Frontends (Invidious, Piped, etc.) -0.0.0.0 invidious.io -0.0.0.0 www.invidious.io -0.0.0.0 invidio.us -0.0.0.0 vid.puffyan.us -0.0.0.0 invidious.snopyta.org -0.0.0.0 yewtu.be -0.0.0.0 invidious.kavin.rocks -0.0.0.0 inv.riverside.rocks -0.0.0.0 invidious.namazso.eu -0.0.0.0 invidious.nerdvpn.de -0.0.0.0 invidious.projectsegfau.lt -0.0.0.0 invidious.slipfox.xyz -0.0.0.0 invidious.privacydev.net -0.0.0.0 invidious.perennialte.ch -0.0.0.0 invidious.protokoll-11.de -0.0.0.0 invidious.einfachzocken.eu -0.0.0.0 invidious.fdn.fr -0.0.0.0 inv.in.projectsegfau.lt -0.0.0.0 invidious.tiekoetter.com -0.0.0.0 invidious.lunar.icu -0.0.0.0 iv.ggtyler.dev -0.0.0.0 iv.melmac.space -0.0.0.0 piped.video -0.0.0.0 www.piped.video -0.0.0.0 piped.kavin.rocks -0.0.0.0 piped.mha.fi -0.0.0.0 piped.mint.lgbt -0.0.0.0 piped.projectsegfau.lt -0.0.0.0 piped.privacydev.net -0.0.0.0 piped.smnz.de -0.0.0.0 piped.adminforge.de -0.0.0.0 watch.whatever.social -0.0.0.0 piped.lunar.icu -0.0.0.0 viewtube.io -0.0.0.0 www.viewtube.io -0.0.0.0 freetube.io -0.0.0.0 www.freetube.io -0.0.0.0 tubo.media -0.0.0.0 www.tubo.media -0.0.0.0 materialious.nadeko.net -0.0.0.0 clipious.org -0.0.0.0 www.clipious.org -0.0.0.0 newpipe.net -0.0.0.0 www.newpipe.net -0.0.0.0 newpipe.schabi.org -0.0.0.0 grayjay.app -0.0.0.0 www.grayjay.app -0.0.0.0 libretube.dev -0.0.0.0 www.libretube.dev -0.0.0.0 hyperion.deishelon.com -0.0.0.0 inv.n8pjl.ca -0.0.0.0 inv.zzls.xyz -0.0.0.0 inv.tux.pizza -0.0.0.0 invidious.incogniweb.net -0.0.0.0 invidious.drgns.space -0.0.0.0 invidious.io.lol - -# Discord (media only - voice chat allowed) -0.0.0.0 cdn.discordapp.com -0.0.0.0 media.discordapp.net -0.0.0.0 images-ext-1.discordapp.net -0.0.0.0 images-ext-2.discordapp.net -0.0.0.0 tenor.com -0.0.0.0 giphy.com - -# Food Delivery Services -# Polish services -0.0.0.0 pyszne.pl -0.0.0.0 www.pyszne.pl -0.0.0.0 m.pyszne.pl -0.0.0.0 api.pyszne.pl -0.0.0.0 app.pyszne.pl -0.0.0.0 glovo.com -0.0.0.0 www.glovo.com -0.0.0.0 m.glovo.com -0.0.0.0 api.glovo.com -0.0.0.0 glovoapp.com -0.0.0.0 www.glovoapp.com -0.0.0.0 bolt.eu -:: bolt.eu -0.0.0.0 www.bolt.eu -:: www.bolt.eu -0.0.0.0 food.bolt.eu -:: food.bolt.eu -0.0.0.0 m.bolt.eu -:: m.bolt.eu -0.0.0.0 api.bolt.eu -:: api.bolt.eu -0.0.0.0 node.bolt.eu -:: node.bolt.eu -0.0.0.0 gw.bolt.eu -:: gw.bolt.eu -0.0.0.0 client-api.bolt.eu -:: client-api.bolt.eu -0.0.0.0 auth.bolt.eu -:: auth.bolt.eu -0.0.0.0 cdn.bolt.eu -:: cdn.bolt.eu -0.0.0.0 images.bolt.eu -:: images.bolt.eu -0.0.0.0 static.bolt.eu -:: static.bolt.eu -0.0.0.0 assets.bolt.eu -:: assets.bolt.eu -0.0.0.0 fleet.bolt.eu -:: fleet.bolt.eu -0.0.0.0 user.bolt.eu -:: user.bolt.eu -0.0.0.0 courier.bolt.eu -:: courier.bolt.eu -0.0.0.0 rider.bolt.eu -:: rider.bolt.eu -0.0.0.0 restaurant.bolt.eu -:: restaurant.bolt.eu -0.0.0.0 partner-food.bolt.eu -:: partner-food.bolt.eu -0.0.0.0 wolt.com -0.0.0.0 www.wolt.com -0.0.0.0 m.wolt.com -0.0.0.0 api.wolt.com -0.0.0.0 restaurant-api.wolt.com -0.0.0.0 consumer-api.wolt.com -0.0.0.0 woltwojta.pl -0.0.0.0 www.woltwojta.pl -0.0.0.0 jush.pl -0.0.0.0 www.jush.pl -0.0.0.0 m.jush.pl -0.0.0.0 api.jush.pl -0.0.0.0 delio.pl -0.0.0.0 www.delio.pl -0.0.0.0 m.delio.pl -0.0.0.0 api.delio.pl -0.0.0.0 delio.com -0.0.0.0 www.delio.com -0.0.0.0 delio.com.pl -0.0.0.0 www.delio.com.pl -0.0.0.0 api.delio.com.pl -0.0.0.0 lisek.app -0.0.0.0 www.lisek.app -0.0.0.0 api.lisek.app -0.0.0.0 stava.app -0.0.0.0 www.stava.app -0.0.0.0 api.stava.app -0.0.0.0 barbora.pl -0.0.0.0 www.barbora.pl -0.0.0.0 api.barbora.pl -0.0.0.0 frisco.pl -0.0.0.0 www.frisco.pl -0.0.0.0 api.frisco.pl -0.0.0.0 szama.pl -0.0.0.0 www.szama.pl -0.0.0.0 api.szama.pl -0.0.0.0 auchandirect.pl -0.0.0.0 www.auchandirect.pl -0.0.0.0 zakupy.biedronka.pl -0.0.0.0 ezakupy.tesco.pl -0.0.0.0 www.ezakupy.tesco.pl -# International services -0.0.0.0 ubereats.com -0.0.0.0 www.ubereats.com -0.0.0.0 m.ubereats.com -0.0.0.0 api.ubereats.com -0.0.0.0 uber.com -0.0.0.0 www.uber.com -0.0.0.0 m.uber.com -0.0.0.0 api.uber.com -0.0.0.0 login.uber.com -0.0.0.0 auth.uber.com -0.0.0.0 deliveroo.com -0.0.0.0 www.deliveroo.com -0.0.0.0 m.deliveroo.com -0.0.0.0 api.deliveroo.com -0.0.0.0 deliveroo.co.uk -0.0.0.0 www.deliveroo.co.uk -0.0.0.0 foodpanda.com -0.0.0.0 www.foodpanda.com -0.0.0.0 m.foodpanda.com -0.0.0.0 api.foodpanda.com -0.0.0.0 grubhub.com -0.0.0.0 www.grubhub.com -0.0.0.0 m.grubhub.com -0.0.0.0 api.grubhub.com -0.0.0.0 doordash.com -0.0.0.0 www.doordash.com -0.0.0.0 m.doordash.com -0.0.0.0 api.doordash.com -0.0.0.0 justeat.com -0.0.0.0 www.justeat.com -0.0.0.0 m.justeat.com -0.0.0.0 justeat.co.uk -0.0.0.0 www.justeat.co.uk -0.0.0.0 postmates.com -0.0.0.0 www.postmates.com -0.0.0.0 seamless.com -0.0.0.0 www.seamless.com -0.0.0.0 getir.com -0.0.0.0 www.getir.com -0.0.0.0 api.getir.com -0.0.0.0 flink.com -0.0.0.0 www.flink.com -0.0.0.0 gorillas.io -0.0.0.0 www.gorillas.io -0.0.0.0 gopuff.com -0.0.0.0 www.gopuff.com -0.0.0.0 instacart.com -0.0.0.0 www.instacart.com -0.0.0.0 takeaway.com -0.0.0.0 www.takeaway.com -0.0.0.0 api.takeaway.com - -# Fast Food -0.0.0.0 mcdonalds.com -0.0.0.0 www.mcdonalds.com -0.0.0.0 mcdonalds.pl -0.0.0.0 www.mcdonalds.pl -0.0.0.0 kfc.com -0.0.0.0 www.kfc.com -0.0.0.0 kfc.pl -0.0.0.0 www.kfc.pl -0.0.0.0 burgerking.com -0.0.0.0 www.burgerking.com -0.0.0.0 pizzahut.com -0.0.0.0 www.pizzahut.com -0.0.0.0 dominos.com -0.0.0.0 www.dominos.com -CUSTOM_EOF - - local total_entries - total_entries=$(grep -c "^0\.0\.0\.0 " "$hosts_file" || echo 0) - echo "[BUILD] Hosts file contains $total_entries blocked domains" >&2 - - # Create zip - (cd "$tmp_dir" && zip -r "$module_zip" . -x "*.DS_Store") >/dev/null - - echo "$module_zip" -} - -# Install/update the guardian module -cmd_install() { - ensure_device_ready - - local module_zip - module_zip=$(build_module) - - log "Pushing module to device..." - adb push "$module_zip" /sdcard/android_guardian.zip || die "Failed to push module" - - log "Installing module..." - adb shell "su -c 'mkdir -p $MODULE_DEST'" || die "Failed to create module directory" - adb shell "su -c 'cd $MODULE_DEST && unzip -o /sdcard/android_guardian.zip'" || die "Failed to extract module" - adb shell "su -c 'chmod 755 $MODULE_DEST/*.sh'" - adb shell "su -c 'rm /sdcard/android_guardian.zip'" - - # Set up guardian data directory - log "Setting up guardian data..." - adb shell "su -c 'mkdir -p $GUARDIAN_DATA_DIR'" - adb shell "su -c 'echo ENABLED > $GUARDIAN_DATA_DIR/control'" - - # Copy blocked apps list - adb push "$GUARDIAN_MODULE_DIR/blocked_apps.txt" /sdcard/blocked_apps.txt || die "Failed to push blocked apps list" - adb shell "su -c 'cp /sdcard/blocked_apps.txt $GUARDIAN_DATA_DIR/blocked_apps.txt'" - adb shell "su -c 'rm /sdcard/blocked_apps.txt'" - - # Create hosts backup for tamper protection - adb shell "su -c 'cp $MODULE_DEST/system/etc/hosts $GUARDIAN_DATA_DIR/hosts.backup'" - - # Immediately uninstall any currently installed blocked apps - log "Checking for blocked apps to remove..." - uninstall_blocked_apps - - echo "" - echo "==========================================" - echo " ✓ Android Guardian installed!" - echo "==========================================" - echo "" - echo "Features enabled:" - echo " • Hosts-based ad/tracker blocking" - echo " • App installation blocking" - echo " • Tamper protection" - echo "" - echo "⚠️ This can ONLY be controlled via ADB:" - echo " Disable: $0 disable" - echo " Enable: $0 enable" - echo " Status: $0 status" - echo "" - echo "Reboot your device to activate the module." - echo "" -} - -# Uninstall currently installed blocked apps -uninstall_blocked_apps() { - local blocked_apps - blocked_apps=$(grep -v '^#' "$GUARDIAN_MODULE_DIR/blocked_apps.txt" | grep -v '^$' || true) - - for package in $blocked_apps; do - if adb shell "pm list packages" 2>/dev/null | grep -q "package:$package"; then - log "Uninstalling blocked app: $package" - adb shell "pm uninstall $package" 2>/dev/null || true - fi - done -} - -# Show status -cmd_status() { - ensure_device_ready - - echo "" - echo "=== Android Guardian Status ===" - echo "" - - # Check if module is installed - if adb shell "su -c 'test -d $MODULE_DEST'" 2>/dev/null; then - echo "Module: INSTALLED" - else - echo "Module: NOT INSTALLED" - return - fi - - # Check control status - local status - status=$(adb shell "su -c 'cat $GUARDIAN_DATA_DIR/control 2>/dev/null || echo UNKNOWN'" | tr -d '\r') - echo "Status: $status" - - # Check if module is "disabled" in Magisk UI (should be auto-fixed by watchdog) - local magisk_disabled - if adb shell "su -c 'test -f $MODULE_DEST/disable'" 2>/dev/null; then - magisk_disabled="YES (watchdog should fix this)" - else - magisk_disabled="No" - fi - echo "Magisk UI disabled: $magisk_disabled" - - # Check if watchdog is running - local watchdog_running - watchdog_running=$(adb shell "su -c 'pgrep -f watchdog.sh 2>/dev/null | wc -l'" | tr -d '\r') - if [ "$watchdog_running" -gt 0 ] 2>/dev/null; then - echo "Watchdog: RUNNING ($watchdog_running processes)" - else - echo "Watchdog: NOT RUNNING (reboot phone to start)" - fi - - # Check hosts file - local hosts_entries - hosts_entries=$(adb shell "su -c 'grep -c \"^0.0.0.0\" /system/etc/hosts 2>/dev/null || echo 0'" | tr -d '\r') - echo "Blocked domains: $hosts_entries" - - # Check blocked apps count - local blocked_count - blocked_count=$(adb shell "su -c 'grep -v \"^#\" $GUARDIAN_DATA_DIR/blocked_apps.txt 2>/dev/null | grep -v \"^$\" | wc -l || echo 0'" | tr -d '\r') - echo "Blocked app rules: $blocked_count packages" - - echo "" - echo "Protection: Module cannot be disabled from Magisk UI" - echo " Only controllable via: $0 disable/enable" - echo "" -} - -# Disable guardian -cmd_disable() { - ensure_device_ready - - log "Disabling Android Guardian..." - adb shell "su -c 'echo DISABLED > $GUARDIAN_DATA_DIR/control'" || die "Failed to disable guardian" - - echo "" - echo "✓ Guardian DISABLED" - echo " Hosts blocking still active until reboot" - echo " App blocking service paused" - echo "" - echo "To re-enable: $0 enable" - echo "" -} - -# Enable guardian -cmd_enable() { - ensure_device_ready - - log "Enabling Android Guardian..." - adb shell "su -c 'echo ENABLED > $GUARDIAN_DATA_DIR/control'" || die "Failed to enable guardian" - - echo "" - echo "✓ Guardian ENABLED" - echo "" -} - -# Uninstall module -cmd_uninstall() { - ensure_device_ready - - # Check if disabled first - local status - status=$(adb shell "su -c 'cat $GUARDIAN_DATA_DIR/control 2>/dev/null || echo ENABLED'" | tr -d '\r') - - if [[ $status != "DISABLED" ]]; then - echo "" - echo "⚠️ Guardian must be disabled before uninstalling!" - echo " Run: $0 disable" - echo " Then: $0 uninstall" - echo "" - exit 1 - fi - - log "Removing Android Guardian..." - adb shell "su -c 'rm -rf $MODULE_DEST'" - adb shell "su -c 'rm -rf $GUARDIAN_DATA_DIR'" - - echo "" - echo "✓ Guardian uninstalled" - echo " Reboot to remove hosts blocking" - echo "" -} - -# Show logs -cmd_logs() { - ensure_device_ready - - echo "=== Guardian Logs ===" - adb shell "su -c 'cat $GUARDIAN_DATA_DIR/guardian.log 2>/dev/null || echo \"No logs yet\"'" -} - -# Block an app -cmd_block_app() { - local package="${1:-}" - - if [[ -z $package ]]; then - echo "Usage: $0 block-app " - echo "Example: $0 block-app com.ubercab.eats" - exit 1 - fi - - ensure_device_ready - - log "Adding $package to block list..." - adb shell "su -c 'echo \"$package\" >> $GUARDIAN_DATA_DIR/blocked_apps.txt'" - - # Also add to local file - echo "$package" >>"$GUARDIAN_MODULE_DIR/blocked_apps.txt" - - # Try to uninstall if currently installed - if adb shell "pm list packages" 2>/dev/null | grep -q "package:$package"; then - log "Uninstalling $package..." - adb shell "pm uninstall $package" 2>/dev/null || true - fi - - echo "✓ $package added to block list" -} - -# Unblock an app -cmd_unblock_app() { - local package="${1:-}" - - if [[ -z $package ]]; then - echo "Usage: $0 unblock-app " - exit 1 - fi - - ensure_device_ready - - log "Removing $package from block list..." - adb shell "su -c 'grep -v \"^$package\$\" $GUARDIAN_DATA_DIR/blocked_apps.txt > $GUARDIAN_DATA_DIR/blocked_apps.tmp && mv $GUARDIAN_DATA_DIR/blocked_apps.tmp $GUARDIAN_DATA_DIR/blocked_apps.txt'" - - # Also remove from local file - grep -v "^$package$" "$GUARDIAN_MODULE_DIR/blocked_apps.txt" >"$GUARDIAN_MODULE_DIR/blocked_apps.tmp" && mv "$GUARDIAN_MODULE_DIR/blocked_apps.tmp" "$GUARDIAN_MODULE_DIR/blocked_apps.txt" - - echo "✓ $package removed from block list" -} - -# List blocked apps -cmd_list_blocked() { - ensure_device_ready - - echo "=== Blocked Apps ===" - adb shell "su -c 'cat $GUARDIAN_DATA_DIR/blocked_apps.txt 2>/dev/null'" | grep -v "^#" | grep -v "^$" || echo "No blocked apps" -} # Main # Initialize Android script (handles sudo, sets WORK_DIR)