signal app for wearos; works with/without a molly client companion
  • Kotlin 89.9%
  • C 7%
  • Shell 2.3%
  • Makefile 0.8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Kate 9898c374ce Media: view incoming images on the watch
The endpoint flags messages with a downloaded image attachment (querying
attachments directly, since the conversation reader doesn't populate the
slide deck) and includes image-only messages. On demand, the watch
requests a thumbnail by attachment id; Molly decrypts the attachment,
downscales it (longest edge 320px, JPEG capped under the MessageClient
size limit), and the bridge relays the bytes. The watch decodes and
renders the image inline, with a 📷 placeholder while it loads.

Thumbnails are cached in memory only (never persisted), keeping
decrypted image bytes out of watch storage.

Verified on-device: real photos render inline in conversations
(11-18KB thumbnails delivered).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JSqhgY5GUKUyVbCqvYjaee
2026-07-29 17:52:23 +02:00
gradle/wrapper Tier 1: notification-bridge phone/watch pair for Signal on Wear OS 2026-07-29 04:21:01 +02:00
native-utils 16 KB fix: auditable native-utils reimplementation + argon2 rebuild 2026-07-29 13:22:25 +02:00
phone Media: view incoming images on the watch 2026-07-29 17:52:23 +02:00
shared Media: view incoming images on the watch 2026-07-29 17:52:23 +02:00
wear Media: view incoming images on the watch 2026-07-29 17:52:23 +02:00
.gitignore Tier 1: notification-bridge phone/watch pair for Signal on Wear OS 2026-07-29 04:21:01 +02:00
build.gradle.kts Tier 1: notification-bridge phone/watch pair for Signal on Wear OS 2026-07-29 04:21:01 +02:00
gradle.properties Tier 1: notification-bridge phone/watch pair for Signal on Wear OS 2026-07-29 04:21:01 +02:00
gradlew Tier 1: notification-bridge phone/watch pair for Signal on Wear OS 2026-07-29 04:21:01 +02:00
README.md Tier 1: notification-bridge phone/watch pair for Signal on Wear OS 2026-07-29 04:21:01 +02:00
settings.gradle.kts Tier 1: notification-bridge phone/watch pair for Signal on Wear OS 2026-07-29 04:21:01 +02:00

signal-watchapp

Signal on an Android (Wear OS) watch, built as a phone/watch pair. The watch never touches Signal's servers or crypto; the phone does all the work and the watch is a thin UI over the encrypted Bluetooth link.

Architecture (Tier 1 — notification bridge)

┌─────────────┐  notifications   ┌──────────────────┐  Wearable Data Layer  ┌───────────┐
│ Signal /    │ ───────────────► │ :phone           │ ◄───────────────────► │ :wear     │
│ Molly (app) │ ◄─────────────── │ SignalWear Bridge│   (MessageClient,     │ SignalWear│
└─────────────┘  RemoteInput     └──────────────────┘    BT, device-to-     └───────────┘
                 reply injection                          device only)
  • :phone — a small bridge app (not a Signal fork). A NotificationListenerService mirrors Signal's MessagingStyle notifications into an in-memory conversation store; replies from the watch are injected back through the notification's own RemoteInput action, so Signal itself sends the message. Nothing extra talks to Signal's servers.
  • :wear — Compose for Wear OS app: conversation list, message view, reply via the system voice/keyboard input, mark-as-read.
  • :shared — JSON wire protocol between the two (kotlinx-serialization).

Both APKs share the net.deprekated.signalwear applicationId — the Wearable Data Layer only routes between same-package, same-signature apps. Debug builds of both are signed with the same debug keystore, so this works out of the box.

Known Tier 1 limitations (by design)

  • Only conversations that produce notifications are visible; no deep history.
  • Dismissing/reading a notification on the phone makes that conversation read-only on the watch until the next message arrives.
  • Can't start a brand-new conversation from the watch.
  • Message plaintext is mirrored to the watch (that's the point, but know it).

Tier 2 (planned): replace the notification bridge with a Molly-based fork running as a linked device, keeping this watch app and wire protocol unchanged — only the phone-side data source swaps.

Building

./gradlew :phone:assembleDebug :wear:assembleDebug

Requires JDK 17 and an Android SDK with platform 36 (local.properties points at ~/Android/Sdk).

Installing

  1. adb install phone/build/outputs/apk/debug/phone-debug.apk (on the phone)
  2. adb install wear/build/outputs/apk/debug/wear-debug.apk (on the watch — pair via adb pair / wireless debugging on the watch)
  3. Open SignalWear Bridge on the phone and grant notification access.
  4. Open SignalWear on the watch; conversations appear as Signal notifications arrive.