Skip to content

Instantly share code, notes, and snippets.

@matbanik
Last active September 17, 2026 17:03
Show Gist options
  • Select an option

  • Save matbanik/7b2945ebefe21435df622752477976ad to your computer and use it in GitHub Desktop.

Select an option

Save matbanik/7b2945ebefe21435df622752477976ad to your computer and use it in GitHub Desktop.
NVIDIA Shield 2019 agent-safe fixes: layer map, Plex Indirect, cast, Projectivy, 24p proof, keep-list, Wi-Fi ceiling. Companion to matbanik.info/hobbies/systems/posts/nvidia-shield-7-minute-fixes/

NVIDIA Shield 2019 — agent-safe fix index

Playbook IDs: U (routing + safety) Companion post: Fix Your NVIDIA Shield in 7 Minutes: Slow Menus, Plex "Indirect," 24p Judder

Agent prompt (paste this first)

You are applying NVIDIA Shield 2019 client fixes from this gist cluster. Stop if adb devices does not show device (not unauthorized or offline). Stop if asked to paste house IPs, SSIDs, or adapter names as required values. Stop if asked to pm uninstall com.nvidia.ota, com.google.android.gms, or com.google.android.apps.mediashell. Substitute the reader's own IP, subnet, and adapter names. Contract: verify → apply → verify → revert. Record model, build, ABI, and app versions before changing anything.

Who this is for

2019 Shield TV or Shield TV Pro (product sif Tube, mdarcy Pro). Shield Experience 9.2.x, Android 11. You already own the box. You are not shopping for a replacement.

Safety rules (never skip)

  1. Disable, don't uninstall. Use pm disable-user --user 0 <pkg>. Recovery is pm enable --user 0 <pkg>.
  2. Never touch com.nvidia.ota (updates), com.google.android.gms (Play services), com.google.android.apps.mediashell (Cast).
  3. No Magisk, LineageOS, WAN port forwards, or factory reset as a first move.
  4. No house values. If a command has an IP, subnet, or adapter name, it is an example. Replace it with yours.
  5. ADB first. adb devices must say device. If it says unauthorized, accept the prompt on the TV. If it says offline, reconnect.

Pick your symptom

You see Open this gist
Picture looks soft, or Plex says Indirect / retries only on the Shield 10-plex-indirect-lan.md
Shield missing from Chrome's cast list; phone may still work 20-cast-wake-and-handshake.md
Projectivy installed, stock home keeps coming back 30-launcher-projectivy.md
Film pans stutter (24p judder) 40-framerate-proof.md
Menus lag; you want a safe keep-list 50-keep-list-appops.md
Wi-Fi only shows 802.11ac 60-wifi-ceiling.md

Prerequisites (once)

adb devices
# expect: <serial>    device

adb shell getprop ro.product.device
adb shell getprop ro.build.version.incremental
adb shell getprop ro.product.cpu.abi

Write those three values down. The 2019 Tube (sif) may report armeabi-v7a (32-bit). The 2019 Pro (mdarcy) is arm64-v8a. Sideloaded APKs must match.

Network ADB, if you use it, is port 5555. Wireless debugging must be allowed on the Shield first.

How an AI tool should run these

Open the matching gist in Cursor, Claude Code, or Codex CLI. Paste that gist's Agent prompt as the first message. The agent:

  1. Reads stop-conditions.
  2. Verifies current state (dumpsys, settings, dashboard).
  3. Changes one thing.
  4. Verifies the change.
  5. Leaves a revert command.

If a check fails, the agent stops and reports. It does not invent a next guess.

Lab scope (so you don't over-generalize)

Measured September 2026 on two 2019 Shields, Shield Experience 9.2.4. Sleep still answering Cast, set-home-activity as a no-op, and Plex Custom URLs not publishing without Remote Access are scoped findings for that build. Re-verify after any Shield OTA.

Plex on Shield: Indirect, Relay, and retries

Playbook IDs: E10a (Relay / LAN Networks), E10b (retries on Shield only) Linked from: post H2 Plex says "Indirect" or needs retries on your own network

Agent prompt (paste this first)

You are applying the Plex LAN/retry fix on a 2019 NVIDIA Shield. Stop if the Shield client and the Plex server are not on the same subnet. Before editing anything, read and record: Secure connections, LAN Networks, Relay, and the Shield's Allow insecure connections. Do not rely on Custom server access URLs while Remote Access is unmapped. Do not add WAN port forwards. Substitute the reader's subnet. Verify → apply → verify → revert.

Human, five lines

  1. Phone and laptop play fine, Shield does not → the server is up; the path is wrong.
  2. Fault 1 = picture is soft, Shield shows an Indirect playback warning, or the dashboard says Indirect / relayed / client 127.0.0.1.
  3. Fault 2 = library or playback needs two or three tries, Shield only.
  4. Fix Fault 1 on the server (LAN Networks + Relay). Fix Fault 2 on the Shield (insecure on same network).
  5. Custom URLs may save and never publish if Remote Access is not mapped. That is not your first move.

Stop conditions

  • Client and server on different subnets / VLANs → stop. This gist does not do mDNS across VLANs.
  • LAN Networks field missing → Plex Pass network preference; stop and say so.
  • Asked to forward TCP 32400 on the router → stop (out of scope).
  • Asked to set Allow insecure connections to Always → stop. Use On same network as server only.

Verify (before any change)

A. Same-subnet check

On a PC on the LAN:

# Shield can reach the server (replace both IPs)
adb -s <shield-serial> shell ping -c 4 <server-ip>
adb -s <shield-serial> shell toybox nc -zvw 2 <server-ip> 32400

You should see replies and port 32400 open. If not, stop: this is not a Plex-settings problem.

B. Indirect check while the Shield plays

Play a movie on the Shield. An Indirect playback warning on the Shield player is already Fault 1. On a computer you can also open Plex Web → Activity → Dashboard → expand the playing card. Direct URL after you click your server in Settings (hex in the address bar between /server/ and the next /):

https://app.plex.tv/desktop/#!/settings/server/YOUR_SERVER_ID/status/server-dashboard
You see Fault
Shield Indirect playback warning, or dashboard Indirect / relayed / location=wan / client 127.0.0.1 Fault 1
Already local + Direct Play, but the Shield needed 2–3 retries to get here Fault 2
Phone also Indirect Server/network, not Shield-only; still do Fault 1, then stop

Relay is Plex sending the movie out to the internet and back. It is capped (~1–2 Mbps depending on plan). That is why the picture goes soft. Docs: Relay, Network settings.

C. Read the three server fields (do not edit yet)

Plex Web → Settings → [server] → Network → Show Advanced, or:

https://app.plex.tv/desktop/#!/settings/server/YOUR_SERVER_ID/settings/network

On the PC that runs Plex Media Server you can start at http://127.0.0.1:32400/web.

Write down:

  • Secure connections
  • LAN Networks (blank or a CIDR)
  • Enable Relay (on/off)
  • Treat WAN IP as LAN Bandwidth (on/off)
  • Remote Access status (mapped port vs not mapped / publicPort=0)

D. Read the Shield client field

On the Shield: Plex → Settings → Advanced → Allow insecure connections

Write down the current value: Never / On same network as server / Always.


Apply — Fault 1 (soft / Indirect)

One change at a time. Save after each.

  1. LAN Networks: enter your subnet in CIDR, for example 192.168.1.0/24. Blank means only the server's own subnet counts as local. A relayed client presents as 127.0.0.1, which is not in that subnet.
  2. Uncheck Enable Relay unless you actually watch away from home today.
  3. Turn on Treat WAN IP as LAN Bandwidth.

Do not start with Custom server access URLs. In the lab they saved and never published because Remote Access was unmapped (not yet mapped, publicPort=0 in the server log). Plex docs say Custom URLs inherit the Remote Access port. If Remote Access is unmapped, skip Custom URLs.

Verify — Fault 1

Force-stop Plex on the Shield, play again, expand the dashboard card.

You should now see local, not relayed, Direct Play (or video copy) for a compatible file.

Still Indirect? Stop. Next suspects live outside this gist (DNS rebinding on some routers is real, but it was ruled out in the lab where *.plex.direct resolved correctly). Do not add a router recipe here.

Ceiling check

Click the movie's ⋯ → Get Info. The file is the file. A 1482×620 source will not become 1080p. If video still says Transcode, picture-style (image-format) subtitles can force a video re-encode — change subtitle burn-in, then re-check the video decision.


Apply — Fault 2 (retries on Shield only)

  1. On the Shield: Plex → Settings → Advanced → Allow insecure connections → On same network as server.
  2. Settings → Apps → Plex → Force stop. Reopen Plex. Play a movie.

Verify — Fault 2

Cold-start the Shield (or Force stop Plex). Library and playback should start on the first try. Dashboard still local + Direct Play.

This setting was the whole difference between two lab Shields on the same server.


Revert

On the server: re-enable Relay if you need it; clear LAN Networks; restore Treat WAN IP as LAN to whatever you wrote down.

On the Shield: Allow insecure connections → Never.

# Plex background restriction was a false lead. If you (or a previous gist) set it:
adb -s <serial> shell cmd appops set com.plexapp.android RUN_ANY_IN_BACKGROUND default
adb -s <serial> shell cmd appops get com.plexapp.android RUN_ANY_IN_BACKGROUND
# expect: RUN_ANY_IN_BACKGROUND: default

What was ruled out (do not chase these first)

Router DNS rebinding, Windows firewall, Plex GDM UDP ports, a down VPN adapter, server load, and "the Shield IP is missing from the PMS log" (Plex does not log client IPs at default verbosity — a working phone is also absent). RUN_ANY_IN_BACKGROUND ignore on Plex did not cause or fix retries and was reverted.

Agent stop / report

If Fault 1 and Fault 2 are both already correct (local Direct Play, first-try load) → stop and say so. Do not keep editing.

Cast: sleep, ports, handshake, and Windows multicast

Playbook IDs: E2, E6, E7 (receiver), E3 (Windows sender) Linked from: post fork line 5 and closing

Agent prompt (paste this first)

You are applying the Cast fix. Stop if dumpsys power cannot print mWakefulness. Never infer sleep from a timer. A TCP connect to 8008 or 8009 is not a completed CastV2 session. Chrome's picker is a human check — do not claim the picker works from a script. Do not name a specific virtual adapter as a required value. Discover local adapters; change only a demonstrated offender; restore saved metrics. Do not paste house IPs or Cast display names. Verify → apply → verify → revert.

Human, five lines

  1. If your phone can cast to the Shield, the Shield is fine. The problem is the PC.
  2. Sleep does not kill Cast on Shield Experience 9.2.4. A confirmed-asleep Shield still answered the ports and completed a Cast session, which woke the TV.
  3. An open TCP port is not a Cast session. Session = TLS to :8009, CONNECT, PING/PONG, GET_STATUS, LAUNCH, media load.
  4. On Windows, virtual adapters (Hyper-V, VPN, leftover Wi-Fi) can steal multicast. Inventory them. Don't guess a metric number.
  5. Google's sample MP4 bucket now returns 403. Use a short clip on your LAN if you test media load.

Stop conditions

  • mWakefulness cannot be read → stop (ADB not useful).
  • Asked to "just disable IGMP snooping" or "uninstall Google Cast updates" as the first fix → those are untested community steps; do not lead with them.
  • Asked to keep the Shield awake forever → stop (OLED burn-in; also makes the sleep question moot).

Branch A — Is the Shield even the problem?

Cast from your phone to the Shield.

  • Phone works → Shield receiver is fine. Go to Branch C (PC / Windows).
  • Phone fails too → Branch B (receiver).

Branch B — Receiver (the Shield)

B1. Prove sleep with power state, not a clock

The two 2019 models can have different sleep timeouts (lab: Pro 20 min, Tube 5 min). Waiting N minutes mislabels one of them.

adb -s <serial> shell input keyevent KEYCODE_SLEEP
# wait ~45s
adb -s <serial> shell "dumpsys power | grep -E 'mWakefulness=|mHolding'"
adb -s <serial> shell "dumpsys display | grep -o 'state O[NF]*'"

You should see mWakefulness=Asleep and display OFF. If you still see Awake, wait or press sleep again. Do not continue until the state is confirmed.

B2. Ports while confirmed asleep

Replace <shield-ip> with the reader's Shield IP (discover it; do not invent one):

# from a PC on the same LAN
curl -sS "http://<shield-ip>:8008/setup/eureka_info"

TCP 8008, 8009, and 8443 should still be open. eureka_info should still return 200 and a name. Ping may get slower while asleep (Wi-Fi power save). That is normal.

Scoped lab result (9.2.4): asleep Shield still answered ICMP + those three ports and still served eureka_info.

B3. Port open ≠ session

A TCP connect to :8009 only proves something is listening. CastV2 is TLS on 8009, then CONNECT, heartbeat PING/PONG, GET_STATUS, LAUNCH Default Media Receiver (CC1AD845), then media QUEUE_LOAD. Open-port-only "fixes" contradict that standard.

If you run a session test:

  • Do not use commondatastorage.googleapis.com/gtv-videos-bucket — it 403s.
  • Serve a 10-second clip from a computer on the same LAN.
  • Pass = TLS up, PONG, LAUNCH, MEDIA_STATUS reaches PLAYING and holds, STOP is clean.
  • After a session started while asleep, mWakefulness should become Awake and the display ON. Casting wakes the Shield.

B4. Chrome picker (human only)

Open Chrome on a phone or a PC that already works. Confirm the Shield name appears and a cast plays. Scripts cannot see that native picker. Report PASS/FAIL from a human.


Branch C — Sender (Windows PC)

Google's checklist already covers VPN and firewall. The extra piece: which interface multicast actually leaves from.

C1. Inventory (verify, don't guess)

In an elevated PowerShell:

Get-NetIPInterface -AddressFamily IPv4 |
  Where-Object { $_.ConnectionState -eq 'Connected' -or $_.InterfaceAlias -match 'Wi-Fi|vEthernet|VPN|VMware|Hyper-V|WSL|Docker|VirtualBox' } |
  Select-Object ifIndex, InterfaceAlias, ConnectionState, InterfaceMetric |
  Sort-Object InterfaceMetric

Write down: alias, Connected vs Disconnected, InterfaceMetric.

Look for: Hyper-V vEthernet (...), VPN adapters, phantom Wi-Fi (Disconnected but still in the metric race), VMware/WSL/Docker.

C2. Observe, then change only the offender

Raising one obvious virtual adapter's metric can be not enough. Disconnected leftover adapters can still outrank the real Wi-Fi. The lab: Hyper-V 15→100 was insufficient; phantom Wi-Fi + VPN still won.

Do not publish "set metric N" as a universal cure.

For each leftover virtual / disconnected adapter that outranks the real LAN:

  1. Record its current InterfaceMetric.
  2. Raise it above the real Wi-Fi metric (example: real Wi-Fi 30, leftovers 100+).
  3. Recheck Chrome's picker.
# EXAMPLE — replace the alias with one from YOUR inventory
Set-NetIPInterface -InterfaceAlias '<alias-from-inventory>' -InterfaceMetric 100

Optional: set the real LAN profile to Private if it is Public (Cast discovery likes a private profile). Use the profile name from Get-NetConnectionProfile, not a copied SSID.

C3. Verify sender

  • Chrome picker shows the Shield without binding tricks.
  • Phone still works (you didn't break the receiver).

If Chrome still fails after leftovers are outranked, stop. Next layer is router multicast / VLAN reflection — saturated, not in this gist.


Revert

# restore each metric you changed, using the numbers you wrote down
Set-NetIPInterface -InterfaceAlias '<alias>' -InterfaceMetric <original>

Re-enable any adapter you disabled. Do not leave the Shield forced awake.

Untested community steps (do not lead with these)

Uninstalling Google Cast updates, clearing Cast data, disabling IGMP snooping. Incomplete in public threads. Mention only after Branches B and C fail, and label them untested here.

Projectivy: safe HOME swap on Shield 2019

Playbook IDs: E8, E9 Linked from: post slow-menus teaser and closing

Agent prompt (paste this first)

You are applying the launcher swap. Stop unless a second HOME is installed and visibly running. Check ro.product.cpu.abi first: 2019 Tube (sif) may be 32-bit armeabi-v7a; 2019 Pro (mdarcy) is arm64-v8a. cmd package set-home-activity reporting Success is not proof. Confirm resolver priority. Expect stock HOME priority 2 vs Projectivy 0. Disable stock only with pm disable-user after Projectivy is on screen. Never uninstall the stock launcher or OTA. cmd role does not exist on Shield Android 11. Verify → apply → verify → revert. After any Shield OTA, re-check HOME.

Human, five lines

  1. Install Projectivy from Play Store (not a random APK). Open it. You must see it on the TV.
  2. set-home-activity can print Success and change nothing while stock is enabled.
  3. Stock launcher wins because its HOME priority is 2; Projectivy is 0; FallbackHome is −1000.
  4. Disable stock with pm disable-user only after step 1. Keep OTA enabled.
  5. A system update can turn stock back on. Re-run the disable. Recovery is one pm enable.

Stop conditions

  • Projectivy not installed, or installed but not on screen → stop.
  • Asked to pm uninstall com.google.android.tvlauncher or com.nvidia.ota → stop.
  • Tube (sif) and a 64-bit-only sideload → stop; use Play Store or a matching ABI.
  • Network ADB not confirmed working → stop (you need a way back if HOME breaks).

Verify (before any disable)

adb -s <serial> shell getprop ro.product.device
adb -s <serial> shell getprop ro.product.cpu.abi
adb -s <serial> shell getprop ro.product.cpu.abilist
adb devices   # must be: device
Device Typical ABI
2019 Tube sif armeabi-v7a (32-bit userspace)
2019 Pro mdarcy arm64-v8a
adb -s <serial> shell cmd package resolve-activity -c android.intent.category.HOME -a android.intent.action.MAIN

Write down the name= line. Stock is com.google.android.tvlauncher.MainActivity.

Confirm a second HOME exists and is running:

adb -s <serial> shell pm path com.spocky.projengmenu
adb -s <serial> shell dumpsys window | grep mCurrentFocus

You should see Projectivy's MainActivity (or its current home activity) in focus. If you don't, open it on the TV and stop until you do.

Install via Play Store intent (normal install, not sideload):

adb -s <serial> shell am start -a android.intent.action.VIEW -d 'market://details?id=com.spocky.projengmenu'

Someone still has to tap Install on the TV if Play Store asks.

The Success/no-op (so you don't trust it)

adb -s <serial> shell cmd package set-home-activity com.spocky.projengmenu/.ui.home.MainActivity
# often prints: Success
adb -s <serial> shell cmd package resolve-activity -c android.intent.category.HOME -a android.intent.action.MAIN
# often STILL: com.google.android.tvlauncher.MainActivity

On Shield Android 11, HOME follows intent-filter priority, not that command:

HOME activity Priority (lab, 9.2.4)
com.google.android.tvlauncher/.MainActivity 2
com.spocky.projengmenu/.ui.home.MainActivity 0
com.android.tv.settings/.system.FallbackHome −1000

cmd role returns Unknown command on this OS. Don't look for it.


Apply

Only after Projectivy is installed, onboarded, and on screen:

adb -s <serial> shell pm disable-user --user 0 com.google.android.tvlauncher

Expect: Package com.google.android.tvlauncher new state: disabled-user

Onboarding notes (match a conservative setup): allow storage and TV listings if asked; skip notification access; skip anonymous crash reporting. Projectivy's "Launcher wallpaper = Reddit" pulls images from the internet — set wallpaper to None if you don't want that. Commit the dropdown with the center button; Back cancels.

Verify

adb -s <serial> shell cmd package resolve-activity -c android.intent.category.HOME -a android.intent.action.MAIN
# expect: com.spocky.projengmenu ... MainActivity

Press Home. You should land on Projectivy. Reboot. HOME should still be Projectivy; stock should still be disabled-user.

Also confirm Cast still answers (ports or a phone-cast). A launcher swap must not break mediashell.

adb -s <serial> shell pm list packages -d | grep nvidia.ota
adb -s <serial> shell pm list packages -e | grep -E 'nvidia.ota|gms|mediashell'

OTA, GMS, mediashell must remain enabled.

Revert

adb -s <serial> shell pm enable --user 0 com.google.android.tvlauncher

Then reboot. Pick HOME from the on-screen picker if Android asks.

After a Shield OTA

Stock can come back because it still outranks Projectivy. Re-run the pm disable-user command. Re-verify resolver. This is expected, not a failed install.

24p judder: prove the refresh-rate switch

Playbook ID: E5 Linked from: post H2 24p judder and closing

Agent prompt (paste this first)

You are applying the frame-rate fix. Capture mActiveModeId before playback. Claim a switch only if that mode id changes during 24p. NVIDIA Match frame rate (beta) must not be used with Plex or Kodi. There is no settings key for this feature — do not grep for one and call the job done. Dolby Vision / new-Plex-interface stutter is a different branch; stop if the mode already switched and judder remains. Verify → apply → verify → revert.

Human, five lines

  1. Only do this if film pans actually stutter. Most people never notice.
  2. Plex: Settings → Advanced → Refresh Rate Switching → On. It can be OFF with nobody noticing.
  3. Do not also use NVIDIA's Quick Settings beta with Plex or Kodi. KB 4908.
  4. Other apps: add the beta to Quick Settings, start the video, press Settings, select it. Short black screen is normal.
  5. Prove it with dumpsys display, not a menu screenshot. Idle is often 59.94 Hz; 24p should become 23.976 or 24.

Stop conditions

  • Cannot capture mActiveModeId → stop.
  • Asked to turn on both the NVIDIA beta and Plex switching → stop. NVIDIA says not to.
  • Mode already 23.976/24 and pans still stutter → stop (TV motion processing or Dolby Vision; not this toggle).
  • No 23.976/24 modes in dumpsys display → the TV path can't switch; stop and say so.

Verify (before changing toggles)

NVIDIA's 2019 path is not Display & Sound → Advanced → Match content frame rate. It is Quick Settings. No ADB key exists:

adb -s <serial> shell "settings list system | grep -iE 'frame|refresh|match'"
adb -s <serial> shell "settings list secure | grep -iE 'frame|refresh|match'"
adb -s <serial> shell "settings list global | grep -iE 'frame|refresh|match'"

Empty is expected. A grep cannot prove the feature is on.

List modes and the idle mode:

adb -s <serial> shell "dumpsys display | grep -E 'mActiveModeId|width=|fps='"

Idle is often a 59.94 Hz mode. You should also see 23.976 and/or 24.000 modes advertised. Record the idle mActiveModeId.

Plex on-screen (person at the TV): Plex → Settings → Advanced

Setting What to write down
Refresh Rate Switching ON or OFF
Resolution Switching ON or OFF (companion; do not prescribe a change unless you measured it)

Lab: living-room Shield had Refresh Rate Switching OFF, so Plex could never match.

Apply

Plex / Kodi

Turn Refresh Rate Switching On in the app. Do not touch NVIDIA's beta for these apps.

Kodi has its own equivalent. Use that, not the NVIDIA action.

Other apps (Netflix, YouTube, …)

  1. Settings → Device Preferences → System → Customize Quick Settings
  2. Add Match frame rate (beta)
  3. Start the video so it is visible
  4. Press the Settings button on the 2019 remote (or NVIDIA mobile app)
  5. Select Match frame rate (beta)

Brief blanking is normal. It reverts when playback stops.

Verify (the only proof)

While 24p content is playing:

adb -s <serial> shell "dumpsys display | grep mActiveModeId"

The id must differ from the idle capture. On lab TVs that meant moving off a 59.94 mode onto a 23.976 or 24.000 mode. Your TV's info panel showing 23.976/24 is also acceptable proof.

If the id did not change: the toggle didn't take, the file isn't 24p, or the HDMI chain refused the mode. Stop and report those three. Don't stack more toggles.

If the id did change and pans still stutter: TV motion interpolation / a Dolby Vision-specific case. Out of this gist. Do not claim the checkbox fixes that.

Revert

Plex: Refresh Rate Switching → Off.

Other apps: stop using the Quick Settings action (it already reverts when playback stops). You can remove it from Customize Quick Settings.

Sources

Slow menus: keep-list, disable-user, what not to do

Playbook ID: E4 Linked from: post H2 Slow menus and closing

Agent prompt (paste this first)

You are applying the keep-list. Ask what the user actually watches before disabling anything. Use pm disable-user --user 0 only, never pm uninstall. Never disable or uninstall com.nvidia.ota, com.google.android.gms, or com.google.android.apps.mediashell. Usage stats on Shield can be useless (lastTimeUsed epoch) — do not trust them. Plex RUN_ANY_IN_BACKGROUND ignore was a false lead and must not be applied. If a freezer override exists, delete it; do not write a new one. One package at a time. Verify → apply → verify → revert.

Human, five lines

  1. Write down what you watch. Everything else is a candidate.
  2. Disable one unused app. Time the home screen. No change → enable it again.
  3. Disable, don't uninstall. Public lists that uninstall OTA exist; people report breakage.
  4. Two copies of the same app (two SmartTubes) → keep one.
  5. Restricting Plex's background work did nothing useful in the lab. Skip it.

Stop conditions

  • Asked to run a mass uninstall/debloat script (Florisse, Level1Techs, GitHub command dumps) → stop. Quote the three protected packages.
  • Asked to set cached_apps_freezer to enabled → stop. Removing an override is fine; writing one is not in this gist.
  • Can't tell menus-lag from playback failure → send them back to the post's fork.

Verify (before any disable)

adb -s <serial> shell getprop ro.product.device
adb -s <serial> shell getprop ro.build.version.incremental
adb -s <serial> shell pm list packages -e

Protected — must stay enabled:

adb -s <serial> shell pm list packages -e | grep -E 'com.nvidia.ota|com.google.android.gms|com.google.android.apps.mediashell'

All three must appear. If any is missing, stop and recover that package before doing anything else.

Don't trust usage stats

adb -s <serial> shell dumpsys usagestats | grep -E 'lastTimeUsed|appLaunchCount' | head

Lab: every media app showed appLaunchCount=0 and lastTimeUsed="1969-12-31 ...". Ask the human. Do not pick favourites from this dump.

Duplicate apps

adb -s <serial> shell pm list packages -e | grep -iE 'smarttube|teamsmart|liskovsoft'

If two SmartTube-family packages are enabled, keep one (the one they actually open). Example disable of the extra:

adb -s <serial> shell pm disable-user --user 0 com.teamsmart.videomanager.tv

Your extra package name may differ. Identify it first.

Freezer override

adb -s <serial> shell settings get global cached_apps_freezer

null = no override (fine). A value like enabled is a manual override, not proof of OEM default. Removing it:

adb -s <serial> shell settings delete global cached_apps_freezer

Do not write settings put global cached_apps_freezer ....


Apply

  1. Human names the keep apps (what they watch).
  2. Pick one enabled package that is not on the keep list and not protected.
  3. Prefer the on-TV path: Settings → Apps → See all apps → [app] → Disable.
  4. If there is no Disable button:
adb -s <serial> shell pm disable-user --user 0 <package>
# expect: new state: disabled-user
  1. Press Home. Count how long the UI takes. Same? Re-enable that one package and try a different candidate. One change at a time.

Do not set:

# FALSE LEAD — do not run this on Plex
cmd appops set com.plexapp.android RUN_ANY_IN_BACKGROUND ignore

It did not fix lag or retries. It was reverted to default on both lab boxes.

Verify

  • Home is not slower than before.
  • Keep apps still open (Plex, YouTube, whatever they named). Allow ~20 s for a cold start before calling a launch failed.
  • Protected three still enabled.
  • Sleep timeout unchanged (settings get secure sleep_timeout must not be -1).

Revert

adb -s <serial> shell pm enable --user 0 <package>
adb -s <serial> shell cmd appops set com.plexapp.android RUN_ANY_IN_BACKGROUND default

If you disabled the wrong SmartTube, enable it and disable the other after the human confirms which one they use.

Negative examples (for the agent, not to copy)

Public lists that pm uninstall com.nvidia.ota (and sometimes GMS): florisse.nl/shield-debloat, Level1Techs de-Google thread, various GitHub commands.txt. Use them only as what not to run.

2019 Shield Wi-Fi: ac is the ceiling

Playbook ID: E11 Linked from: post closing (one sentence)

Agent prompt (paste this first)

You are reading the Wi-Fi ceiling, not applying a "fix." Stop if asked to treat Ethernet as a required value. Stop if asked to enable Wi-Fi 6 / ax on the Shield — the 2019 radio cannot do it. An ac association is expected. Ethernet is a lever when throughput is actually the problem, never a house-specific instruction. Informational gist: verify → explain → stop. No revert unless you changed a router setting the human asked for.

Human, five lines

  1. 2019 Shield TV and Shield TV Pro are 802.11ac 2×2 MIMO (Wi-Fi 5).
  2. Your router can be Wi-Fi 6/6E/7. The Shield still speaks ac. That is not a misconfig.
  3. Comparing the Shield's link rate to a modern PC radio is not a fair test.
  4. If streams actually drop, the lever is 5 GHz signal / channel width, or a cable.
  5. There is no setting that turns this radio into ax.

Stop conditions

  • Asked to "upgrade the Shield to Wi-Fi 6" in software → stop.
  • Asked to name a specific SSID, DFS channel plan, or USB Ethernet dongle as required → stop (Tube dropped USB; both 2019 models still have Gigabit Ethernet).
  • Throughput is fine and they only noticed the ac label → stop after the spec sentence. Don't "tune" a non-problem.

Verify

NVIDIA spec: Shield TV Pro — Dual-Band Wi-Fi 5 (802.11ac 2×2) and Ethernet.

On the Shield:

adb -s <serial> shell dumpsys wifi | grep -iE 'Wi-Fi|WifiInfo|frequency|ssid' | head

Expect an ac / 802.11ac association on 2.4 or 5 GHz. That is the hardware doing its job.

adb -s <serial> shell getprop ro.product.device
# sif = 2019 Tube, mdarcy = 2019 Pro — same Wi-Fi generation

Apply

None, unless they have a real throughput problem (buffering on high-bitrate local files while Ethernet would not).

Then, in order:

  1. Confirm it is Wi-Fi, not Plex Relay (see 10-plex-indirect-lan.md). Soft picture from Relay looks like a "slow Wi-Fi" complaint.
  2. Ethernet — if a cable can reach the box. Not required. Tube has Ethernet; it does not have USB for a dongle workaround.
  3. 5 GHz signal quality (placement, not a new standard).

Do not prescribe DFS pinning or iperf recipes unless the human asked for a measurement plan.

Revert

n/a for the informational path.

If you changed a router channel at their request, restore the previous channel from the note you took before the change.

Sources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment