Skip to content
urtubaPublic

About

Give spare Android TV remote keys a new job. No root, no accessibility service, no input lag.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

tvkeys

Give spare keys on your Android TV remote a new job. No root. No accessibility service. No input lag. About 3 MB of RAM.

Why

Key mapper apps like Button Mapper use an accessibility service. That service sees every key press first, so it can add lag. It can use more than 100 MB of RAM, and memory cleaners on some TVs stop it.

tvkeys reads the remote at the Linux input level. It runs a small daemon as the adb shell user, so it needs no root. It does not sit between the remote and Android, so other keys keep their speed.

What it can and cannot do

tvkeys listens to key presses. It does not intercept them. Android still gets every key and does its own thing with it.

So tvkeys is good for keys that do nothing on your TV:

  • app keys that died after you disabled the stock launcher, for example to use Projectivy
  • vendor keys for apps or features you removed
  • keys your remote has but your TV never used

It cannot change what a working key does. If you map a key that already opens something, both things open. Volume, Home and Back stay as they are.

How it works

There are two parts in one APK.

  1. tvkeys run is the daemon, written in Go. It reads /dev/input/event* and runs an action for each mapped key.
  2. The TV Keys app starts the daemon after every boot. An app cannot read /dev/input, but the adb shell user can. So the app connects to the TV's own adb daemon on 127.0.0.1:5555. It copies the daemon to /data/local/tmp/tvkeys/ and starts it as the shell user.

The app does this at boot, after an update, when you open it, and every 15 minutes. It does nothing when the daemon already runs.

Requirements

  • Android TV or Google TV with Android 11 or newer.
  • Network adb that listens on port 5555 and stays on after a reboot. Many TVs do this when you turn on USB debugging. TVs that only offer "Wireless debugging" with pairing codes do not work yet.
  • A computer with adb for the one-time setup.

Tested on: TCL 50P735 with the RC902V remote. If you try another TV, please open an issue and tell us how it went.

Setup

  1. On the TV, turn on Developer options and USB debugging. Find the TV's IP address in the network settings.
  2. Download tvkeys.apk from the Releases page. On your computer:
    adb connect <tv-ip>:5555
    adb install tvkeys.apk
    
  3. TCL TVs only. TCL blocks new apps from starting at boot:
    adb shell appops set io.github.urtuba.tvkeys APP_AUTO_START allow
    
  4. Open TV Keys once from the app list. The TV asks to allow a new adb key. Tick "Always allow" and confirm. This key belongs to the app, not to your computer.
  5. Find the codes of your spare keys. Press them while this runs:
    adb shell /data/local/tmp/tvkeys/tvkeys learn
    
  6. Write a keys.conf and copy it to the TV:
    adb push keys.conf /data/local/tmp/tvkeys/keys.conf
    

keys.conf

Each line is a key and an action. Lines that start with # are comments. The key is a key name or a scan code.

# open an app, key given by name
TCL_NETFLIX app:com.netflix.ninja
# run a shell command, key given by scan code
561 am start -a android.settings.SETTINGS

app:<package> opens the app. Anything else runs as a shell command. The daemon reloads the file when it changes. You do not need to restart it.

Names come from the TV's own key layout file, for example TCL_NETFLIX. A name keeps working on other models of the same brand, even when the code is different. Case does not matter. Codes are Linux scan codes, not Android key codes. Use a code when the name is too generic, like BUTTON_12. When a line with the code and a line with the name both match, the code wins.

tvkeys learn shows the code and the name of each key you press. See examples/ for ready files.

Commands

adb shell /data/local/tmp/tvkeys/tvkeys status
adb shell /data/local/tmp/tvkeys/tvkeys learn
adb shell /data/local/tmp/tvkeys/tvkeys try app:com.netflix.ninja
adb shell /data/local/tmp/tvkeys/tvkeys stop
adb shell /data/local/tmp/tvkeys/tvkeys start
adb shell cat /data/local/tmp/tvkeys/tvkeys.log

try runs one action now, so you can check a line before you map a key. The log has a line for every key press, mapped or not.

Security

The app keeps an adb key in its private storage. That key gives shell access to this TV, the same access your computer gets over adb. The key never leaves the TV.

Network adb on port 5555 is open to your local network. That is true with or without tvkeys. The TV still asks before a new key may connect. To undo everything, uninstall the app and revoke the keys in Developer options.

The code is small on purpose. Please read it before you install it.

Uninstall

adb shell /data/local/tmp/tvkeys/tvkeys stop
adb shell rm -r /data/local/tmp/tvkeys
adb uninstall io.github.urtuba.tvkeys

Then use "Revoke USB debugging authorizations" in Developer options.

Limits

  • Android also handles every mapped key, see above.
  • tvkeys reads key codes only. Some remotes, for example on Chromecast with Google TV, send several app keys with the same key code and tell them apart in another field. tvkeys cannot tell those keys apart yet.
  • Some TVs delay boot broadcasts. On the TCL the daemon starts about 1.5 minutes after boot.
  • If the TV kills the app before the daemon starts, the 15 minute job starts it.

Build

Needs Go, JDK 17 and the Android SDK packages platforms;android-30 and build-tools;34.0.0.

./build.sh

This makes a debug build in build/tvkeys.apk. See the top of build.sh for a release build.

About

Give spare Android TV remote keys a new job. No root, no accessibility service, no input lag.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages