nixos/services/tv-detox.nix

153 lines
5.8 KiB
Nix
Raw Normal View History

# services/tv-detox.nix — keep the Philips TV's bloat turned off.
#
# Oct 2026: the living-room Philips 58PUS7304 (Android TV 12) was cleaned up
# over adb: bloat turned off with `pm disable-user` (never uninstalled), and
# the tv-detox home screen (github.com/Ansub/tv-detox) replaced Google's
# launcher. Philips firmware switches some of those apps back on at every
# cold boot (the UK Freeview Play apps and DTS Play-Fi), and nothing on an
# unrooted TV can switch them off again by itself.
#
# This timer connects over adb every 2 minutes and turns off anything on
# `keepOff` that has come back. TV off / in standby / unreachable -> no-op.
#
# One-time setup: on the first run the TV shows "Allow USB debugging?" for this
# server's own key (kept in /var/lib/tv-detox). Tick "Always allow".
#
# To deliberately turn an app back on, remove it from `keepOff` first,
# otherwise this switches it off again within 2 minutes.
{ config, lib, pkgs, ... }:
let
# Reserved for the TV in ../devices.toml.
tv = "10.0.0.40:5555";
keepOff = [
# Pre-installed Philips / partner apps
"org.droidtv.nettvapp1814" # ARTE
"org.droidtv.nettvapp20004410" # Couchplay Games
"org.droidtv.nettvapp4546" # MEGOGO
"org.droidtv.nettvapp4655" # Deezer
"org.droidtv.nettvapp4771" # Divan.TV
"org.droidtv.nettvapp4932" # Free Games by PlayWorks
"org.droidtv.nettvapp5326" # Toon Goggles
"org.droidtv.nettvapp5512" # Fishing TV
"org.droidtv.nettvapp5527" # Flix Premiere
"com.zeasn.whalelive" # WhaleLive
"com.mgmedia.androidApp" # CHILI
"tv.wuaki.apptv" # Rakuten TV
"com.singa.client" # Singa
"com.ted.android.tv" # TED
"com.blacknut.client" # Blacknut
"com.boosteroidtv.streaming" # Boosteroid
"org.droidtv.android.fitness" # Fitness Buddy
"tv.pluto.android" # Pluto TV
# Philips / Google background extras
"org.droidtv.demome" # Demo me
"org.droidtv.sticker" # Sticker (store demo)
"org.droidtv.eum" # How to… (manual)
"org.droidtv.nettvrecommender" # Top Picks
"org.droidtv.recommendation" # Recommendation
"org.droidtv.usagelogger" # Usage logger
"org.droidtv.tv.frameworklogger" # Framework logger
"org.droidtv.nettv.market" # Philips App Gallery
"com.google.android.tvrecommendations" # Google TV recommendations
"com.google.android.play.games" # Google Play Games
"com.google.android.feedback" # Google Feedback
"com.android.printspooler" # Print spooler
"com.google.android.marvin.talkback" # TalkBack
"com.google.android.backdrop" # Ambient mode / Backdrop
# Not used
"com.google.android.youtube.tvmusic" # YouTube Music
"tv.twitch.android.app" # Twitch (official)
"com.google.android.videos" # Google TV / Play Movies
"com.google.android.apps.mediashell" # Chromecast built-in
"com.google.android.katniss" # Google Assistant / voice search
"org.droidtv.amazonalexa" # Amazon Alexa
"org.droidtv.alhuewizard" # Hue setup wizard
"org.droidtv.ambihuecommon" # Ambilight + Hue
"org.droidtv.ambiair" # Ambilight + air
"org.droidtv.contentexplorer" # Media (USB player)
"org.droidtv.dlna" # DLNA
"com.phorus.playfi.tv" # DTS Play-Fi
"com.phorus.playfi.softap" # DTS Play-Fi hotspot
# Freeview Play (re-enabled by Philips at every boot)
"org.droidtv.freeviewplayers" # Freeview Play hub
"uk.co.freeview.bbc" # BBC iPlayer
"uk.co.freeview.bbc_sounds" # BBC Sounds
"uk.co.freeview.itv" # ITVX
"uk.co.freeview.ch4_vod" # Channel 4
"uk.co.freeview.ch5" # Channel 5
"uk.co.freeview.stv" # STV
"uk.co.freeview.uktv" # UKTV Play
"uk.co.freeview.amc_catchup" # AMC
"uk.co.freeview.amc_horror" # AMC Horror
"uk.co.freeview.sony_kids_vod" # Sony Kids
"uk.co.freeview.explore" # Freeview Explore
"uk.co.freeview.onnow" # Freeview On Now
"uk.co.freeview.mdsclient" # Freeview Play bridge
"uk.co.freeview.tifbridge" # Freeview Play TV-input bridge
"uk.co.freeview.fvpconfigauth" # Freeview Play config/auth
# Replaced by the tv-detox home screen (com.ansub.tvhome)
"com.google.android.tvlauncher" # Google Android TV home screen
];
enforce = pkgs.writeShellScript "tv-detox" ''
set -uo pipefail
tv=${tv}
adb connect "$tv" >/dev/null 2>&1 || true
state=$(adb -s "$tv" get-state 2>&1 || true)
case "$state" in
device) ;;
*unauthorized*)
echo "tv-detox: TV is asking \"Allow USB debugging?\" for this server; tick Always allow"
exit 0 ;;
*) exit 0 ;; # off, in standby or unreachable
esac
enabled=$(adb -s "$tv" shell pm list packages -e </dev/null | tr -d '\r' | sed 's/^package://')
for p in ${lib.escapeShellArgs keepOff}; do
grep -qxF "$p" <<<"$enabled" || continue
if adb -s "$tv" shell pm disable-user --user 0 "$p" </dev/null | grep -q disabled-user; then
echo "tv-detox: $p was back on, turned it off"
else
echo "tv-detox: failed to turn off $p"
fi
done
adb kill-server >/dev/null 2>&1 || true
'';
in
{
config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") {
systemd.services.tv-detox = {
description = "Keep the Philips TV's bloat apps turned off";
path = with pkgs; [ android-tools coreutils gnugrep gnused ];
environment = {
# adb keeps its key in $HOME/.android. Own server port so it never
# shares an adb server (and key) with an interactive session.
HOME = "/var/lib/tv-detox";
ANDROID_ADB_SERVER_PORT = "5038";
};
serviceConfig = {
Type = "oneshot";
ExecStart = enforce;
DynamicUser = true;
StateDirectory = "tv-detox";
TimeoutStartSec = "90s";
};
};
systemd.timers.tv-detox = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = "2min";
OnUnitActiveSec = "2min";
};
};
};
}