Millet Porridge

English version of https://corvo.myseu.cn

0%

Control Your Android TV and Mac with the iPhone Remote — the atv-core Project

Conclusion First

If you’re like me — with an Android TV at home (or a TV box flashed with Android) while also being an iPhone user, you’ve definitely experienced the pain of hunting for the remote. In the sofa cracks, under the coffee table, even carried off by the cat… but the phone is always with you.

I made a project called atv-core; its core function in one sentence: let the Apple TV remote built into iPhone Control Center directly control Android TV and macOS.

No third-party remote app to install, no Apple TV to buy. Open iPhone Control Center, select your device, and start controlling. Touchpad swipes, direction keys, volume adjustment, play/pause — all supported.

Some friends may not know the iPhone comes with an Apple TV remote. Open Control Center (swipe down from the top-right corner), find the remote icon circled in red below, and tap to open it. If it’s not in Control Center, go to Settings → Control Center and add it manually.

Swipe down from top-rightControl CenterApple TV Remote

Tapping in shows the remote interface — touchpad area on top, function keys below:

The Apple TV remote entry in iPhone Control Center
1. Find the remoteTap the button marked in the image.
The Apple TV remote interface in iPhone Control Center
2. Use the remoteSwipe above, tap the function keys below.

Why I Built This

There are quite a few phone remote apps on the market, but I always felt something was missing:

  1. A separate app must be opened: the operation path is too long — unlock → find the app → wait for loading → start using. The Control Center remote is system-level: swipe down from any screen to summon it.
  2. Inconsistent touch experience: the touchpad feel varies wildly between apps — some have high latency, some have drifting direction recognition. The Apple TV remote’s touch feel was polished by Apple itself — very silky.
  3. Macs also need remote scenarios: my Mac mini is connected to the living-room TV as an HTPC; adjusting volume, switching tracks and moving the mouse while lying on the sofa all rely on this remote.

Simply put, what I wanted: no extra app installed, using the system’s native interaction to handle both TV and computer at once.

What It Looks Like

On Android TV

After installing atv-core’s APK on Android TV, you’ll see a control panel showing the pairing PIN (default 1111), connection status, key injection mode and other information:

The atv-core control panel on Android TV
Android TV control panelConfirm the PIN, service status and current input mode here before connecting.

After a successful connection, you can use the iPhone remote to swipe and browse content on the TV. Swipe the touchpad and focus moves smoothly between Android TV cards:

Focus on the first card After swiping, focus moves to the next
Android TV home screen Effect after focus switch

On macOS

The Mac-side experience is richer. atv-core provides a Web debug panel to view all the remote’s operation states in real time — touch trajectories, key events, volume, configuration parameters — at a glance:

The Web debug panel on macOS
macOS debug panelTouch trajectories, key events and runtime parameters update here in real time.

On Mac, touchpad operations convert to mouse movement. I also built a dynamic acceleration algorithm — a light swipe moves precisely a few pixels; a hard flick sends the cursor flying across the whole 4K screen. Tuning this feel took quite a while.

How to Get Started

Prerequisites

  • iPhone and target device (Android TV / Mac) on the same Wi-Fi LAN
  • Router without AP isolation / guest mode enabled (otherwise mDNS broadcasts get blocked)

Android TV Setup

  1. Install the APK: install the compiled APK onto the TV via ADB
1
2
adb install -r app-debug.apk
adb shell am start -n com.corvofeng.fakeatv/.MainActivity
  1. Enable the accessibility service: go to the TV’s Settings → Accessibility → find “Apple TV Remote Receiver” → enable it
Find the accessibility service Confirm enabling permission
Accessibility service list Permission confirmation dialog

If your TV system hides the accessibility menu (some domestic custom systems do), you can enable it directly with ADB commands:

1
2
3
adb shell settings put secure enabled_accessibility_services \
com.corvofeng.fakeatv/.AtvAccessibilityService
adb shell settings put secure accessibility_enabled 1
  1. Connect from the iPhone: open iPhone Control Center → Apple TV Remote → select your device → enter PIN 1111 → start using!

macOS Setup

The Mac side is simpler. Compile or download the DMG, double-click to install, and launch the app. A remote icon appears in the menu bar.

1
2
# if compiling from source
./scripts/build_dmg.sh

If the system says “developer cannot be verified”, run:

1
xattr -dr com.apple.quarantine /Applications/AppleTVRemote.app

How It Works Technically

This part goes a bit deeper; interested friends can read on.

Core Idea

The Apple TV remote communicates with Apple TV through a private protocol called Companion Link. This protocol is based on mDNS service discovery + SRP encrypted handshake + OPACK message encoding. What atv-core does is simulate an Apple TV Companion Link server on Android TV and Mac, making the iPhone think it’s talking to a real Apple TV.

The whole data flow is roughly like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
iPhone Control Center remote
│
│ Companion Link / MRP protocol
│ (ChaCha20-Poly1305 encryption)
│
▼
atv-core event dispatch engine
│
├─ decrypt OPACK messages (_touchMove / _hidEvent)
│
├─ mode parsing
│ ├─ D-pad mode: dy < -25px => DPAD_UP
│ └─ mouse mode: dynamic acceleration curve
│
└─ dual-end dispatch
├─ Android TV: LocalADB / accessibility service → KEYCODE_DPAD_*
└─ macOS: CGEvent → cursor movement / NX_KEYTYPE → media keys

Gesture Recognition and the Accumulator

The iPhone remote’s touchpad sends tiny coordinate offsets (dx, dy) at very high frequency. Converting each offset directly into a key press means a slight finger movement triggers several direction keys — a terrible experience.

So atv-core implements a zero-jitter accumulator: continuously collecting these micro-displacements until the accumulated amount exceeds a threshold, then triggering one direction-key event. There’s also directional dead-zone filtering — diagonal swipes only recognize the main direction, avoiding the awkward up+right simultaneous trigger.

Two Channels for Key Injection

On Android TV, atv-core has two ways to “inject” keys into the system:

Channel Principle Latency Use case
Local ADB (Dadb) sends Linux input events directly via 127.0.0.1:5555 < 8ms direction keys, confirm key, media keys
Accessibility service Android system-level global operations ~15ms back, Home, power and other system keys

The two complement each other. The ADB channel is extremely fast but cannot trigger system-level actions (like the back key); the accessibility service can, but with slightly higher latency. atv-core automatically selects the optimal channel by key type.

Key Mapping Overview

Finally, a complete key mapping table for reference:

Apple TV remote action Android TV macOS
Touchpad swipe (D-pad mode) DPAD_UP / DOWN / LEFT / RIGHT arrow keys ↑↓←→
Touchpad swipe (mouse mode) touch-drag simulation smooth cursor movement
Tap / SELECT DPAD_CENTER Enter / left mouse button
Back < system back Escape
Home 📺 system Home show desktop
Play/pause ⏯ single click MEDIA_PLAY_PAUSE play / pause
Play/pause ⏯ double click fast-forward / next episode next track ⏭
Play/pause ⏯ triple click rewind / previous episode previous track ⏮
Volume +/- VOLUME_UP / DOWN system volume + native HUD
Mute VOLUME_MUTE system mute
Siri key voice search toggle mouse/D-pad mode
Power key power menu screen off / wake

Project Address and Future Plans

The project uses Rust for the core logic (atv-core); the Android side bridges via JNI, the Mac side wraps via Swift. The code is open sourced under the MIT license:

If you want to start from source, just clone the repository:

1
git clone https://github.com/corvofeng/atv-core.git

There are still some things I want to do:

  • Support text input (typing from the iPhone keyboard directly into Android TV’s search box)
  • Support more gestures (long press, double click, etc.)
  • Provide precompiled APK and DMG downloads to lower the barrier to use

If you have similar needs, welcome to try it. For problems, file a GitHub Issue or discuss in the comments.

References