# Set up a TV with تلفزيونك: the prompt for your AI agent **On the TV first:** Settings → System → About → press OK on **Build** 7 times → back → Developer options → turn on **USB debugging** (and **Network debugging** if it is listed). Keep the TV on. **Then** open an AI agent that runs commands **on a computer on the same Wi-Fi** as the TV (for example Claude Code installed on it; a chat in the browser or a cloud session can't reach your TV), and paste everything below the line. On Windows, everything it needs installs from PowerShell in three lines (then close PowerShell, open a new one, type `claude` and log in): ``` winget install -e --id Git.Git --source winget winget install -e --id Python.Python.3.12 --source winget irm https://claude.ai/install.ps1 | iex ``` A deep folder breaks Windows paths («Filename too long»): clone into a short one such as `C:\UrTV` (below), and once run `git config --global core.longpaths true`. If `winget` fails with a certificate error on its store source (`0x8a15005e`, «server certificate had a validation error»), the lines above already use `--source winget`: use it on every `winget` command. Or in the Claude desktop app: the **Code** tab, with a **local** folder on this computer (not a cloud environment). --- Set up my Android TV / Google TV with **تلفزيونك** from https://github.com/tshi-dev/UrTV: a faster TV (bloat off, safely), an Arabic home screen, and the screensaver «شاشة تلفزيونك». Talk to me in Arabic (or my language); keep commands in English. ## Start here: three short messages, word for word, before you touch the TV Everything that needs me comes first; after that you work alone. Your first three messages are fixed: send them in this order, each on its own, word for word, and wait for my answer after each. Never skip one (not even the first: you can't see my approval settings, so never assume they are already right), never merge them, never assume my answers, and never skip or work around anything that asks me (an approval on this computer, «Allow USB debugging?» on the TV). Cloning the repo and reading this file before message 1 is fine; nothing else. **Message 1, approvals.** If you are Codex: > قبل نبدأ: من القائمة اللي تحت خانة الكتابة، اختر «Approve for me» للموافقات، عشان ما أوقف أسألك عن كل أمر. > وقلّي «تم». Any other agent: the same in your words: ask me to allow running commands and network access in this folder for the whole task, and to say «تم». **Message 2, the city:** > وش مدينتك؟ > (لمواقيت الصلاة والطقس. مثال: الرياض، جدة، الرس) **Message 3, the clubs and the defaults:** > وتتابع مباريات أي أندية؟ اكتب أسماءها، أو «لا شي». > > والباقي بخليه على الافتراضي، وتقدر تطلب تغيير أي شي منه الحين أو بعدين: > • جنب الساعة: «آية وحديث اليوم» (أو: مواقيت الصلاة، المسلسلات، الطقس، المباريات، لا شي) > • المفضلة: أول ٦ تطبيقات من واجهتك الحالية، بنفس الترتيب > • بركّب TV Bro (متصفح للتلفزيون) و SmartTube (يوتيوب بدون إعلانات)، مجانيين من GitHub > • ما فيه بطاقة في الواجهة الرئيسية، ووقت شاشة التوقف يبقى مثل ما هو، وما أعطّل إضافات TCL الاختيارية After my answer to message 3, start steps 0 and 1 at once, in the same turn: don't end your turn to wait for me again. The only other thing I do is press Allow on the TV, and step 1 tells me when, without stopping. Those defaults, unless I change them: - the card beside the clock: verse and hadith; - the favourites row: the first 6 apps of my current home screen (you note them in step 1), in that order; an icon you couldn't name is left out; - TV Bro and SmartTube installed (`optimize/run.sh` does it; if I don't want them: `SKIP_EXTRAS=1 optimize/run.sh`); - no card on the home screen; the TV's own screensaver delay is kept; - nothing from `optimize/lists/tcl-optional.txt` is disabled (`optimize/lists/mine.txt` stays empty); - if I pick the episodes card: all genres and languages. My city is checked later against `android/app/src/main/java/sa/urtv/screensaver/Cities.java`: Saudi Arabia and the main cities of Bahrain, Kuwait, Qatar, the UAE, Oman, Egypt, Jordan, Syria, Lebanon, Palestine, Morocco, Algeria and Tunisia are in it, each with its country's time zone and its prayer calculation, so a city by name (`city الدوحة`, `city القاهرة`) just works. If it isn't there, step 4 sets it with its coordinates and time zone (`city `) without asking me again; the zone of a place in those countries picks that country's calculation (`Asia/Kuwait`, `Asia/Qatar`, `Asia/Dubai`, `Asia/Bahrain`, `Asia/Muscat`, `Africa/Cairo`, `Asia/Amman`, `Asia/Damascus`, `Asia/Beirut`, `Asia/Hebron` or `Asia/Gaza`, `Africa/Casablanca`, `Africa/Algiers`, `Africa/Tunis`), so give the right one. If I ask for the Shia Ja'fari times: `optimize/saver.sh prayermethod jafari`. ## 0. Can you reach my TV? (check this first, 1 minute) I am on a computer on the same Wi-Fi as the TV, and your commands most likely run on it. A clone or download that fails at first, or a network error before the check below, is your own sandbox not allowed yet (see «Permissions first»): ask, then try again. Never decide you can't reach the TV from that; only the check below decides. ADB needs a direct connection, from the terminal where your commands run, to the TV on my Wi-Fi. Many agents run their commands somewhere else: a cloud container, a sandbox, or a Linux virtual machine on this computer (a "connected folder" or `device_bash`-style tool works that way). From there the TV can never be reached, however often you retry, so find out before anything else. **Permissions first.** Some agents run commands in a sandbox that blocks the network or starting programs until I allow it (Codex on Windows does). The signs are errors like `getaddrinfo() thread failed to start`, `Bash/E_ACCESSDENIED` or `Operation not permitted`. They mean "not allowed yet", not "can't reach the TV": message 1 is how I allow them (network access and running git, bash and python in this folder, for the whole task); if one still appears, send me message 1 again, then go on. On Windows, run every script in Git Bash (they find a working Python themselves, past the Microsoft Store shortcut); if `bash` isn't found, use its full path: `"C:\Program Files\Git\bin\bash.exe" -lc "cd && optimize/find-tv.sh --check"`. Run the commands here exactly as written and add no quotes, `;` or `|` of your own: PowerShell runs those itself before Git Bash sees them (that is why every check has its own script). **Codex: the network from the first try.** Its sandbox blocks the internet and the home network, so a command that needs them fails there first and wastes minutes (a `git clone` that sits with no progress, then a retry). Run `git clone`, `git pull` and every Git Bash command **outside the sandbox from the first try**: request escalated permissions straight away, with the justification below. If a request gets no answer within a minute, or is refused twice, don't wait or look for another way: tell me in one line which command needs approval and why, and ask me to approve it myself (or to allow it for the rest of the task). **Codex on Windows:** its sandbox can never start Git Bash (`0xC0000022`, `NtCreateDirectoryObject`: a known Codex bug, openai/codex#54449). So run every Git Bash command **outside the sandbox**: request escalated permissions for it, with this justification: "Git Bash cannot start inside the Codex Windows sandbox (openai/codex#54449); this runs the UrTV setup script the user asked for, in this folder, to reach their TV on their Wi-Fi." With «Approve for me» the reviewer decides; when it offers to allow `bash.exe` from now on, take it. I don't need Full access for this. A refusal that never reached a reviewer (`you cannot ask for escalated permissions`, `rejected by policy`, `sandbox_approval is false`) means approvals are not on «Approve for me»: Codex then rejects every escalation by itself (openai/codex#32563). Send me message 1 again, wait for «تم», then run the same command. If a reviewer turns it down, ask once more with the same justification and the exact command; if it is turned down again, stop and tell me exactly what was refused. Don't port the scripts to PowerShell or look for another way: they need Git Bash. **Missing Git or Python is yours to fix, not mine.** If Git Bash isn't there, or a script says `!! No working Python 3 here`, ask me once, then install it yourself and carry on: `winget install -e --id Git.Git --source winget --accept-source-agreements --accept-package-agreements` or `winget install -e --id Python.Python.3.12 --source winget --accept-source-agreements --accept-package-agreements`. Then run the same command again: the scripts find the new Python without a new terminal. Don't stop and hand me the install. On a Mac with only the system Python 3.9 and no Homebrew, `uv python install 3.12` needs no admin password (get uv with `curl -LsSf https://astral.sh/uv/install.sh | sh`); the scripts find uv's Python by themselves. ``` git config --global core.longpaths true # Windows only, once (a deep folder breaks git: «Filename too long») git clone --depth 1 https://github.com/tshi-dev/UrTV # only the latest version: much faster. On Windows into a short folder: git clone --depth 1 https://github.com/tshi-dev/UrTV C:/UrTV (a deep one breaks Python and git: «Filename too long») cd UrTV # on Windows: cd C:/UrTV git pull # always the latest (a command of its own, not joined with the others) optimize/find-tv.sh --check # Windows: always through Git Bash (below), never plain `python` ``` - `OK: this terminal can reach the home network` → go on with step 1. - `!! This terminal cannot reach the home network` → **stop**. Tell me, in plain words, that you can't reach the TV from where your commands run, and that I need an agent running on this computer itself (for example Claude Code installed on it, or the Claude desktop app's Code tab on a local folder; on Windows first, in PowerShell: `winget install -e --id Git.Git --source winget`, `winget install -e --id Python.Python.3.12 --source winget`, `irm https://claude.ai/install.ps1 | iex`, then a new PowerShell window and `claude`). A chat that only links to my computer's folders or screen does not run commands on it, so it does not count. Give me the one line to paste there: «Set up my TV with https://github.com/tshi-dev/UrTV: clone it and follow `docs/SETUP-PROMPT.md` step by step. You are on a computer on the same Wi-Fi as the TV.» Don't look for workarounds. **Android 11 or newer, and port 5555 does not answer: pair with «Wireless debugging».** Some Android 11+ TVs (a Skyworth on Android 14 closed 5555 after every restart) offer ADB only through Developer options → «Wireless debugging». If `optimize/find-tv.sh` ends with `No TV with ADB open` and the TV is Android 11 or newer (or it says the TV answers as «Wireless debugging»), offer it to me once, in Arabic, and wait for my answer: > التلفزيون ما فتح المنفذ العادي (5555). نستخدم «التصحيح اللاسلكي»: في التلفزيون افتح الإعدادات ← النظام ← خيارات > المطوّر ← «Wireless debugging» وشغّله، بعدين اضغط «Pair device with pairing code». بيطلع لك رمز من ٦ أرقام وتحته > عنوان مثل 192.168.x.x:xxxxx. اكتبهم لي هنا، وخلّ النافذة مفتوحة. Then `optimize/find-tv.sh pair ` (alone, `pair` explains it and shows the pairing port if the TV announces it). It pairs, finds the connection port by itself, connects and remembers the TV in `~/.urtv` (never in a report or a share); then `--probe` as in step 1. It needs the platform's `adb` program: if it says it is missing, install it as its message says (`winget install -e --id Google.PlatformTools --source winget`, `brew install android-platform-tools`, `sudo apt install adb`) and run the same command again. After a restart the port changes: `tv.py` and `find-tv.sh` look it up again by themselves; only if that fails, ask me for the «IP address & Port» on the main Wireless debugging screen (not the pairing window) and run `optimize/find-tv.sh connect `. No code and no IP goes in `report.md` or the share. Signs you are in such a place, if you want to know why: your address is not 192.168.x, 10.x or 172.16–31.x; the network interfaces are only `lo` and `tap0`; `echo > /dev/tcp//80` says `Network is unreachable`; or every address "answers" (a proxy). If `git clone` stops halfway (on Windows it can leave an empty folder, «No commits yet»), or an old UrTV folder is there without a working `.git`, delete that folder and clone again with `--depth 1`. ## Rules (protective layer: these win over everything else here) - Use only the scripts in `optimize/`. They are made for slow, dropping ADB over Wi-Fi: they retry by themselves and remember progress. **If a command fails, run the same command again.** Don't write your own adb loops, probes or test scripts to find out why: the `!!` line and the table below say what to do. - One command at a time: never run two scripts against the TV at once, or in the background while you run another. - If the TV had a system update since the setup (Home back on the TV's own screen, apps it had off back on): `optimize/run.sh again` redoes every step; the apps' settings stay. - Long commands (`run.sh`, `measure.sh`, `--reboot`) can be silent for 5 minutes. Give them a long timeout (40 minutes for `run.sh`). If your tool kills one anyway, nothing is lost: run the same command again, it continues. - Never send `reboot` as a shell command. Restart only with `optimize/venv/bin/python -I optimize/tv.py --reboot`. - Never disable anything in `optimize/lists/keep.txt` (AirPlay, Chromecast, mirroring, voice, remote, inputs, tuner, firmware updates, Play Store, Google services), and never edit `keep.txt` to get past a refusal. Never disable the TV's own home screen or setup app yourself; only `optimize/install.sh launcher` does that, behind a 5-minute safety switch. - Never switch Play Protect or the package verifier off yourself (`settings put global package_verifier_enable 0`, or `verifier_verify_adb_installs`): one agent did, for the whole TV. `optimize/install.sh` is the only thing that touches `verifier_verify_adb_installs`, for one install, and puts it back. - Never uninstall system apps, never `pm clear`, never factory-reset, never touch accounts, Wi-Fi, network or developer settings (turning ADB off locks us out). Never delete `optimize/run/` or `optimize/backup-*.txt`: they are how we undo. Everything is reversible: `optimize/reset.sh` puts the TV back as it came. - Anything I ask for about the screensaver, the home screen or the TV (now or any time later): look it up in `docs/SETTINGS.md` and use its command. Never edit the apps' code, build or install your own APK, or turn the automatic update off to make something; if it isn't in `docs/SETTINGS.md`, tell me it isn't in تلفزيونك yet and pass my words on in the share message (step 8). - **A problem goes to the developer's form, never to GitHub.** When something doesn't work, or I say «بلّغ المطوّر عن مشكلة» (now or any time later, from this computer or another one): look into it first with this prompt's tools, then `optimize/share.sh --preview --problem --agent "" --owner "" ""`, show me the whole text, ask «أرسله؟», and only if I say yes `optimize/share.sh --send`. Never open a GitHub issue, discussion, comment or pull request for me, never use `gh` or the GitHub website on my behalf: the developer reads the form, and a GitHub post is public and can carry my details. If the TV doesn't answer, send it anyway: the report says so. - Ask me before anything not in this prompt. If something fails twice, and the table's fix didn't help, stop, show me the output and propose a fix. - Never tell me something worked without its proof: the script's own success line, or a screenshot you looked at. ## When something goes wrong (expected, and what to do) Lines starting with `!!` are the scripts telling you to stop and act. These are the ones we have seen: | You see | It means | Do | |---|---|---| | `getaddrinfo() thread failed to start`, `Bash/E_ACCESSDENIED`, `Operation not permitted` | your sandbox hasn't been allowed network or programs yet | ask me to allow them for this folder (see step 0), then the same command | | `0xC0000022` or `NtCreateDirectoryObject` starting Git Bash (Codex) | Codex's sandbox can't start Git Bash | run it outside the sandbox (step 0, «Codex on Windows») | | `you cannot ask for escalated permissions`, `rejected by policy` (Codex) | Codex's approvals are not on «Approve for me» | message 1 again, wait for «تم», then the same command | | `ModuleNotFoundError: No module named 'adb_shell'`, or `!! The Python packages aren't in optimize/venv` | `optimize/setup.sh` didn't finish (often pip had no network) | `optimize/setup.sh` again until it ends with «✓ Python ADB client»; its `!!` line says what is wrong. Then the same command; don't stop for this | | `!! This folder's path is too long for Windows`, `Filename too long`, or `DLL load failed … too long` | the UrTV folder sits too deep for Windows | clone it again into a short folder: `git clone -c core.longpaths=true https://github.com/tshi-dev/UrTV C:/UrTV`, and carry on there (or once, `git config --global core.longpaths true`, then clone again; a short folder like `C:/UrTV` is still best) | | `!! No working Python 3 here`, or `python` opens the Microsoft Store | Python not installed, or only Windows' Store shortcut | ask me once, install it yourself (`winget install -e --id Python.Python.3.12 --source winget --accept-source-agreements --accept-package-agreements`), then the same command again in Git Bash | | `INSTALL_FAILED_VERIFICATION_FAILURE: Install not allowed` (seen on Android 12–14 for the home app, which targets an older SDK than Play Protect likes) | Play Protect checks apps installed over ADB and refused it | tell me, in Arabic, to watch the TV and press «تثبيت على أي حال» (Install anyway) if Play Protect shows a message (`install.sh` prints these words). `install.sh` switches `verifier_verify_adb_installs` to 0 for that install only, retries once and puts the old value back (it says so in one line); if it still fails, the line shows the TV's own message and the same words. **Never** turn the verifier off for the whole TV | | `Could not download …` on Windows with `CRYPT_E_NO_REVOCATION_CHECK` / `revocation` | Windows' curl (Schannel) can't reach the certificate revocation server | nothing: `install.sh` retries 3 times and, on that error, once more with `--ssl-revoke-best-effort`; if it keeps failing, check the internet/proxy and run the same command again | | `CERTIFICATE_VERIFY_FAILED` (macOS) | python.org's Python has no CA certificates | `optimize/setup.sh` again: it installs certifi into `optimize/venv` and every script uses it; if the line stays, delete `optimize/venv` first | | `symbol _ERR_get_error_all`, or a cryptography `DLL`/`dlopen` error (macOS) | an old system Python (3.9) was used, and the cryptography wheel won't load on it | `brew install python@3.12`, or with no admin password and no Homebrew `uv python install 3.12` (install uv first: `curl -LsSf https://astral.sh/uv/install.sh \| sh`), delete `optimize/venv`, then `optimize/setup.sh`: uv's Python is found by itself | | `!! Python 3.14 is too new` | no wheels for it yet, so pip would build them | `brew install python@3.12` (Windows: the `winget` line above), delete `optimize/venv`, then `optimize/setup.sh` | | `(connection problem: …; retrying in 5s)` | Wi-Fi ADB dropped for a moment | nothing, it retries by itself | | `resuming upload at 40%` | an earlier upload was cut off | nothing, it continues and checks the file | | no output for several minutes | a restart, or the 3-minute settle before measuring | wait; don't interrupt | | the first connection hangs for up to 2 minutes | the TV is showing «Allow USB debugging?» | ask me to press Allow and tick «Always allow» | | `--probe` silent for 5 minutes and the TV shows no «Allow USB debugging?» | the first connection to a TCL sometimes just hangs | stop it and run the same command again: the second time it connects at once | | `--probe` times out and the TV shows no «Allow USB debugging?» after a new clone of the repo | the ADB key the TV trusted stayed in the older folder's `optimize/adbkey`; a new clone makes a new key and the TV never saw it | the key now lives outside any clone, in `~/.urtv` (Windows: `%USERPROFILE%\.urtv`), and `tv.py` moves an older `optimize/adbkey` there by itself. If the older folder is not the one you are in, copy its `optimize/adbkey/adbkey` and `adbkey.pub` into `~/.urtv`, then the same command. Never print or paste that path: it holds my user name. The saved TV (`tv-id.json`) is there too | | `reset.sh`: `mv: cannot move 'optimize/run' … Permission denied` (Windows) | something holds a file open inside `optimize/run` (a log you write there, an editor, an image viewer) | close it, never write your own logs into `optimize/run`; the same command again (the apps are already removed, it carries on) | | `!! The import failed (…). The TV was put back as it was` (`saver.sh import --yes`) | the TV refused one of the values, or did not show it when read back; everything was put back | nothing changed: read the reason in the line, fix the file (or update the apps: `optimize/install.sh`), then the same command | | `!! The import failed (…) and the TV could NOT be put back completely` | the TV refused the put-back too (it went off, or its apps are older) | `optimize/saver.sh import optimize/run/settings-before-import.json --yes` (the path is in the line), and if that fails too, `optimize/saver.sh show` and set the rest with the commands in `docs/SETTINGS.md` | | `!! This terminal cannot reach the home network` | your commands run in a cloud, sandbox or virtual machine | stop, tell me (step 0) | | the TV forgot its Wi-Fi after the first restart (two TCL sets did) | some firmware drops its saved network on a restart | **before the first restart** (step 3 starts with one) ask me to have the Wi-Fi password at hand. If the TV comes back with no network: tell me to open Settings → Network & Internet, pick the network and type the password, and say «تم»; then `optimize/find-tv.sh` (the address may change) and the same command. Never touch the Wi-Fi settings yourself | | a «choose a home app» list, or a «who is watching» profile picker, shows on the TV during the home switch (a Sony with two profiles, a Nokia) | the TV asks which home to use, or which profile to open | look at the screen (`optimize/shot.sh home`) and ask me to press OK on «تلفزيونك» then «دائماً» (Always) in the list; on a profile picker my usual profile, then Home. Then the same command if it stopped | | `Home switch skipped: this TV refuses to turn its own home screen off` (`This command is illegal`, a Nokia Streaming Box 8000) | that TV's firmware does not let `pm disable-user` touch its launcher | nothing is broken: the stock home is back and the rest of the setup goes on. Say so to me in Arabic (the TV keeps its own home screen; the screensaver works); `report.md` has the line «Home switch: skipped»; don't try `SKIP_LAUNCHER` or other ways. **In your final message** tell me where things are now: the screensaver settings open from the app «تلفزيونك» in the TV's own apps row (it has a launcher entry); the «تلاوة وأذان» screens (Quran, radio) are reached only from our home's pill, so they are not reachable while the TV keeps its own home (our home app has no launcher entry on purpose) | | `Don't know your TV's IP` | `find-tv.sh` was not run or found nothing | `optimize/find-tv.sh`, or ask me for the IP (TV: Settings → Network → the Wi-Fi) and save it: `echo > optimize/.tv_host` | | `No TV with ADB open` | debugging off, TV asleep, or the computer is on another (guest) Wi-Fi | ask me to check all three, then `optimize/find-tv.sh` again (it scans the whole network, the router's known devices and mDNS, and knocks twice, slowly the second time); on Android 11+ with 5555 still closed: pair (step 0, «Wireless debugging») | | `No TV with ADB open on port 5555` and «Wireless debugging» in the next line, or `ADB open` never appears after a restart of a TV that worked before | Android 11+ TVs may close 5555 after every restart (seen on a Skyworth, Android 14) | `optimize/find-tv.sh pair` (step 0); a TV that was paired once is reconnected by `optimize/find-tv.sh` itself | | `!! Wireless debugging needs the platform's own adb program` | pairing and the Wireless-debugging connection go through `adb`, which isn't installed (the Python client has no pairing) | install it as the line says (`winget install -e --id Google.PlatformTools --source winget`, `brew install android-platform-tools`, `sudo apt install adb`), a new Git Bash window on Windows, then the same command | | `!! Pairing failed: the code is wrong or it has expired` / `the pairing dialog must be open` | the 6 digits changed (they do whenever the dialog is closed and opened), or the IP:port is not the one in the dialog | ask me to read the dialog again, then `optimize/find-tv.sh pair ` | | `the TV's Wireless-debugging port does not answer and was not found on the Wi-Fi` | the port changed after a restart and the router doesn't pass mDNS (multicast) | ask me for «IP address & Port» on the main Wireless debugging screen, then `optimize/find-tv.sh connect ` | | `!! This is not the TV the setup started on` | two devices answer on this Wi-Fi (a box and the TV), or the address now belongs to another one; the script stopped **before changing anything** | ask me which one is my TV; `optimize/find-tv.sh` and pick it (or `echo > optimize/.tv_host`), then the same command. The same TV on a new address is fine. Only if I say it really is a new TV: `optimize/venv/bin/python -I optimize/tv.py --new-tv`, then `optimize/run.sh` (it starts from the first step); or work from a fresh clone of the repo | | `!! TV not answering after 6 tries` (10 for an upload or install) | TV went to standby, lost Wi-Fi (weak signal: seen on a TCL G10, Android 12), or got a new IP. The tries wait 5, 10, 15, 20, 30 s | ask me to wake the TV, and if the signal is weak to move the router or the TV closer or use a cable; run `optimize/find-tv.sh` if the IP may have changed; then the same command (an upload resumes where it stopped; so do the extras: TV Bro and SmartTube already on the TV are not sent again) | | `!! TV did not come back within 5 minutes` | slow restart, or it stayed in standby | ask me to turn it on, then `optimize/venv/bin/python -I optimize/tv.py --wait`, then the same command | | `!! upload keeps failing` or `md5 mismatch` | bad Wi-Fi, or the TV's storage is full (the line says how much space is left) | the same command once; if again, show me that line | | `!! … is not a folder on the TV`, or a TV path like `C:/Program Files/Git/data/…` | an old copy: Git Bash rewrote the TV's path before Python saw it (now undone by `tv.py`) | `git pull`, then the same command | | `UnicodeEncodeError` or `charmap` (Windows) | an old copy: Arabic text in Windows' own code page | `git pull`, then the same command | | `Refusing: these are in …keep.txt` | a protected package got into `mine.txt` | take that line out of `mine.txt`, run again | | `!! … has a package rated Unsafe` | `mine.txt` has a package the TV may need | take it out of `mine.txt`, run again | | `(unknown model: no optional list. …)` from the community step | our lists are TCL's and no community list fits this brand and model (or the device code is shared by several sizes: a guess is never applied) | nothing: the setup goes on without an optional list. Say in step 7 that nothing was disabled beyond the common Google extras | | `Unknown package` or `not installed` while disabling | that package is not on this model | nothing, normal | | `!! … is already installed, signed with another key` (`install.sh`) | an app with our name but another signature is on the TV (a copy built by hand, or from another source); ours can't replace it, and removing it deletes its settings, tasks and own adhan (Android can't keep them across signatures). Nothing was removed | **stop and ask me**, in Arabic (the line has the words): remove it and install the official one (it then updates itself)? Only after my yes: `pm uninstall `, then the same command. If I say no, leave it and go on without that app. Never build or install your own APK | | `!! Install of … failed` | usually storage, or a very old Android | stop and show me | | `!! The TV stopped answering while … was installing` (install.sh), or `!! … was skipped: the TV stopped answering while it installed` (SmartTube, TV Bro) | some sets take minutes to install a big APK and drop ADB meanwhile; the install may even have finished | for an extra: nothing, the setup goes on (add it later with `optimize/install.sh extras`; one that finished is found). For the screensaver or the home: wake the TV, wait a minute, then the same command (a finished install is not repeated) | | `!! Install of urtv-screensaver.apk failed: cmd: Can't find service: package` | the TV's package service is not up yet (just after a restart, or the TV is still booting) | wait a minute and run the same command again; if it persists, `optimize/venv/bin/python -I optimize/tv.py --reboot`, then the same command | | `!! The TV did not come back within 6 minutes` (install.sh, during the home switch) | ADB dropped during the switch and the TV did not answer for 6 minutes (off, standby, or the Wi-Fi went) | ask me to check the TV is on and on Wi-Fi (`optimize/find-tv.sh` if the address may have changed); the safety switch restores the stock home by itself; then the same command | | `!! The screensaver is installed but NOT switched on` | the TV's WebView is older than 80, so the page would not run; the TV keeps its own screensaver | tell me in Arabic to update «Android System WebView» (`optimize/precheck.sh webview-store`), then `optimize/install.sh saver` again. Don't select the screensaver by hand | | `!! Could not read which TV this is` (tv.py) | the TV gave no serial, make or model (still waking, or a busy shell); nothing was changed | wait a minute, then the same command; never skip the check | | `!! The TV stopped answering while it ran this command … NOT sent again` | a command that must not run twice (a task added or deleted, a photo deleted by number, a key press) lost its reply; it may or may not have happened | look first (`optimize/saver.sh tasks list`, `optimize/photos.sh list`, or a screenshot), run it again only if it did not happen | | `!! Could not download …` (install.sh) | no such build at that tag, or no internet on this computer | check `APK_TAG` (unset = the latest) and the releases page https://github.com/tshi-dev/UrTV/releases, and that the computer is online; then the same command | | `!! GitHub rate limit, try later` (install.sh extras) | GitHub allows only a few anonymous requests an hour | wait a few minutes, then `optimize/run.sh` again (it redoes the extras step) | | `Done, with problems:` and `optimize/run.sh` exits 1 | every step ran, but `report.md` has `!!` lines (printed under it) | read them, fix what each says (this table), then `optimize/run.sh` again: only the report step is redone | | `ADB dropped during the switch; the TV is back, trying the switch again` | Wi-Fi ADB dropped while the home was being switched; the script waited for the TV (up to 6 minutes) and is doing the switch a second time, the safety switch armed again | nothing, wait; only if it ends in `!!` follow that line | | `!! The safety switch put the stock home back` | ADB was slower than the 5-minute switch | nothing is broken: the same command again | | `This TV ends background jobs when the ADB session closes, so there is no safety switch on the TV itself…` (install.sh, during the home switch) | seen on a TCL with Android 14: a job started over ADB (nohup or setsid) is ended the moment the ADB session closes, so the 5-minute safety switch cannot stay alive on the TV. `install.sh` checks for its heartbeat, says this in a plain line (not a `!!`) and goes on: the switch is checked and undone from this computer at once if Home does not open ours, and the journal (`optimize/run/home-switch.json`, which records `safety_switch: unavailable`) restores the stock home on the next run if this computer stopped in the middle | nothing to do; the report says «Home switch: no safety switch on the TV itself». Keep the computer and the TV on until `Launcher is home`. If the run is cut off, run `optimize/install.sh launcher` or `optimize/restore-home.sh` again. Do not start `deadman.sh` yourself. When Home is already ours, `install.sh` prints «Home is already the new launcher: nothing to switch» and starts no safety switch at all | | `An earlier home switch was cut off (the TV or this computer restarted)… putting the home back from optimize/run/home-switch.json` | `install.sh` and `run.sh` write a journal of the switch (`optimize/run/home-switch.json`: the stock home, the setup wizard and who held Home before) and read it first on the next run. A restart kills the safety switch on the TV, so with the journal still «switching», Home not ours and no marker on the TV, they put the stock home back from it. Ours being home, or the switch having confirmed itself, is left alone | nothing: wait, the switch is done again if it is a step of this run. If it then says `!! Could not restore the home from the journal`: the TV did not answer; when it is on and on Wi-Fi run `optimize/restore-home.sh` | | «استرجاع الشاشة الرئيسية» (the person wants the stock home back, or Home is wrong after a switch) | the home app has no button for it (with no home there is nothing to press): it is a command and it needs ADB | `optimize/restore-home.sh`: puts the stock home, the setup wizard and the previous HOME holder back from the journal (and the stock home's helpers); with no journal it does what `optimize/restore.sh` does. The TV must be on and on Wi-Fi. It only ever turns the wizard on, never off | | `!! window_animation_scale: this TV did not take the value (asked for 0.5, it says …)` (or `transition_animation_scale`, `animator_duration_scale`, `cached_apps_freezer`, `max_cached_processes`, and the Play Store's `standby_bucket`, `appop_RUN_IN_BACKGROUND`, `appop_RUN_ANY_IN_BACKGROUND`) | `optimize/tweaks.sh` reads every setting back after setting it; this firmware keeps its own value | nothing is broken and the setup goes on; mention it in the report. Do not set it again by hand. `optimize/tweaks.sh status` shows what each setting was (`optimize/run/tweaks-journal.txt`) and is now; `optimize/tweaks.sh restore` puts back exactly the recorded values (a value that was not set is deleted) | | `!! window_animation_scale: could not read what this TV has, so it is left as it is` (or another setting) | a read of the setting failed or came back empty, so `tweaks.sh` neither records it as «not set» nor changes it (a wrong «not set» would make restore delete the TV's real value) | nothing is broken; the same command later reads it again (the journal says `unknown` until then). Do not set it by hand | | `!! standby_bucket: the TV's own value was not recorded` (or `appop_…`) | this firmware did not say what the Play Store's standby bucket or background appop was before `tweaks.sh apply`, so `restore` puts `active` / `allow` back (forced: Android may move the bucket again); a bucket Android exempted (the Play Store is exempt from standby) is never changed | nothing is broken; mention it in the report | | `!! screensaver_components: this TV did not take our screensaver` | the firmware keeps its own screensaver whatever is written (seen on some operator TVs) | tell me in Arabic to choose «شاشة تلفزيونك» in the TV's own settings (الإعدادات ← تفضيلات الجهاز ← شاشة التوقف); the screensaver app is installed | | `!! enabled_accessibility_services: this TV did not take the sleep service` (`dock.sh sleep-setup`) | the TV refused the accessibility entry | the sleep timer still counts down but its end will not turn the screen off; say so. `optimize/reset.sh` takes only our entry out of the list | | `!! This device is not an Android TV` (`run.sh: stopped at precheck`) | no `android.software.leanback`: a phone, a tablet or a box that is not Android TV | nothing was changed; give me the Arabic message in the line, and stop | | `!! WebView: system WebView is 66` (or any number below 80) | the screensaver page needs WebView/Chrome 80+ (its CSS: clamp, gap, inset) and would not run | tell me in Arabic to update «Android System WebView» from the Play Store (`optimize/precheck.sh webview-store` opens its page); then `optimize/precheck.sh` again. The setup and the report go on (our screensaver is installed but the TV's own stays selected until the WebView is new enough), the line stays until it is fixed | | `The setup wizard of this TV owns its saved Wi-Fi network: left on` or `The setup wizard answers Home and owns the saved Wi-Fi network: it is left on` | disabling `com.google.android.tungsten.setupwraith` can delete the Wi-Fi network saved during the first-run wizard (two TCL sets lost their password; CleanYourTV documents it). `install.sh` turns the wizard off only when it really answers Home and the network is not its own; otherwise it switches the home with the wizard left on | nothing to do. Never turn the wizard off yourself, never delete a saved network or its files, and never override this: if Home then does not open the new launcher (`!! Home did not open`), the TV keeps its stock home; say so. `optimize/restore.sh` and the safety switch always turn the wizard back on | | `!! Auto-start (TCL): not allowed for sa.urtv.home(ignore)` | TCL firmware starts apps at boot only if they hold its auto-start op; ours need it (adhan alarms after a restart, the sleep service) | `optimize/autostart.sh` again; the report shows `Auto-start (TCL): … allow` after the restart. Not a TCL: «Auto-start: not a TCL», nothing to do | | `!! Home did not open the new launcher` | slow ADB, or firmware that pins its own home (a Fire TV often refuses another home, and so can a TV whose setup wizard owns the Wi-Fi) | the stock home is already back. `optimize/run.sh` once more; if again, `SKIP_LAUNCHER=1 optimize/run.sh` and tell me the TV keeps its own home. Never force it (turning the wizard off, deleting networks, editing the guard). In your final message say what the previous row says about where the screensaver settings and «تلاوة وأذان» are | | the TV has no home at all (black screen, Home does nothing) | our home app is gone while the stock home is off | `optimize/restore.sh` (no list: only the home screen), then `optimize/install.sh launcher`; more in `docs/OPTIMIZE.md`, «Home screen problems» | | `!! The stock home is not on screen` (reset) | the stock home was slow to start | ask me to press Home, then `optimize/reset.sh` again | | `!! still off` (keep.sh) | a protected feature would not turn back on | **stop**, show me; don't continue | | `left off by the TV itself` (keep.sh) | a protected package was already off before UrTV and the TV won't turn it on (TCL ships Alexa off outside its regions) | nothing to do: go on | | `start-saver.sh --preview` prints `dream` on some runs and `preview` on others on the same TV | the real screensaver starts sometimes, the app's preview the other times; both draw the same page | nothing to fix, either shot is good | | the TV's own screensaver screenshot is black | Android hides it from screenshots | expected; ours can be shot | | our screensaver shot has no weather or matches yet | data still loading | `optimize/saver.sh update`, wait a minute, shoot again | | `find-team` finds nothing | a spelling our list doesn't have, or a club outside the app's leagues | once with the English name; or `optimize/saver.sh find-team --list ` (e.g. `Saudi`, `Premier`) and pick it from there | | `screensaver: preview` (shot.sh), or «not measured» for a screensaver | this Android won't start the screensaver from ADB (some Android 14 sets) | expected: the shot is our app's preview of the same page; don't look for other ways to start it | | `optimize/run.sh status` has no «protected features» step | an old copy of this repo | `git pull`, then `optimize/run.sh` | Anything else, or anything twice: stop, show me the output and what you think it is. ## 1. Connect and look (5 minutes) ``` optimize/setup.sh optimize/find-tv.sh # accept "Allow USB debugging?" on the TV, tick "Always allow" optimize/venv/bin/python -I optimize/tv.py --probe # first tell me to watch the TV (below) optimize/precheck.sh # is it an Android TV, is its WebView 80 or newer (run.sh does it as its first step too) optimize/shot.sh home my-apps ``` Right before `--probe`, tell me, word for word, and **don't end your turn or wait for my reply**: run `--probe` straight after it. It waits by itself (silent, up to 2 minutes) until I press Allow; that is the wait, not a fault. If it times out, tell me again and run it once more. > الحين بتطلع لك على التلفزيون رسالة «Allow USB debugging?»: اضغط Allow وعلّم «Always allow». بعدها تقدر > تتركني، أكمّل لحالي حوالي ٤٠ دقيقة. - `optimize/precheck.sh` decides first whether to go on. **Exit 3, «not an Android TV»**: stop, change nothing, and give me its Arabic message as it is (Samsung Tizen and LG webOS TVs can't run these apps; a phone or tablet is not a TV). **Fire TV** (Amazon): tell me in Arabic it may work only partly and the home switch may be refused; go on. **`!! WebView: system WebView is NN`** (below 80; the screensaver page's CSS (clamp, gap, inset) needs 80, and on 66 it never ran): tell me its Arabic text, and offer to open the page myself (`optimize/precheck.sh webview-store` opens «Android System WebView» in the TV's Play Store; I press Update; then `optimize/precheck.sh` again). The setup can go on meanwhile, and `report.md` keeps the `!!` line until the WebView is new enough. Never try to change the page for an old WebView. - Tell me the model and Android version. - Read the row for this TV model in `docs/TVS.md` before going on: it says what was seen on that model (ADB port, what to watch out for). - Look at `optimize/run/shots/my-apps-small.png` (the 960 px copy; the full-size `my-apps.png` is often too large to attach) and write down the first **6 apps** of my apps / favourites row, left to right, by name: they become the favourites of the new home screen in step 4. - Only then, if this TV was set up with these tools before (also an older version of it), run `optimize/reset.sh` so we start like new. ## 2. Before you run it: how to undo Before you start step 3, tell me in plain Arabic how to undo everything, so I know it is safe: one command, `optimize/reset.sh`, run from this folder (say the folder's full path), puts the TV back as it came (the disabled apps back on, the TV's own home screen and screensaver back, our two apps removed, TV Bro and SmartTube removed if the setup installed them, the speed tweaks back to the values the TV had before, from `optimize/run/tweaks-journal.txt` (written by the first `tweaks.sh apply`) or `optimize/run/backup.txt`, else Android's defaults; a value the TV did not have set is deleted); my photos, accounts and other apps are not touched. Any agent on this computer can run it for me later. Also tell me, in Arabic, before the first restart: «التلفزيون بيعيد التشغيل مرتين. بعض تلفزيونات TCL نسيت الواي فاي بعد أول إعادة تشغيل، فجهّز كلمة سر الواي فاي. لو رجع التلفزيون بدون إنترنت: الإعدادات ← الشبكة والإنترنت، اختر شبكتك واكتب كلمة السر، وقلّي «تم».» (Table: «the TV forgot its Wi-Fi».) ## 3. Run it (20–30 minutes, the TV restarts twice) ``` optimize/run.sh ``` It saves the TV's state, measures memory and the TV's own screensaver, disables telemetry/ads/demos and my picks, applies the speed and memory tweaks, installs the screensaver and the home screen (behind the safety switch) and TV Bro and SmartTube (from their own GitHub releases, the build for this TV's processor), measures again and writes `optimize/run/report.md`. Before the optional picks, on a TV whose model our own lists do not know (a Sony, Hisense, Haier, Xiaomi…), `optimize/community.sh` applies the tested list for exactly that model from CleanYourTV (MIT, `optimize/lists/community/`) if there is one: never a list for another model, never anything in `keep.txt`, a launcher or a setup wizard; `report.md` shows them («Community list: …») and `optimize/keep.sh off` names them. If it stops for any reason: `optimize/run.sh` again (it continues), and `optimize/run.sh status` shows where it is. If the home-screen step says Home did not switch, leave the TV alone for 5 minutes (the stock home comes back by itself) and tell me. Some TCL firmware keeps its own home: then `SKIP_LAUNCHER=1 optimize/run.sh`. ## 4. Apply my choices (5 minutes; no remote needed) Every setting, and what to say when I ask for something else: `docs/SETTINGS.md`. ``` optimize/saver.sh cities # find my city (Saudi Arabia, the Gulf, Egypt, the Levant, North Africa), then: optimize/saver.sh city , even for Riyadh (until a city is set the screensaver shows a «change your city» note) (not listed: city