Skip to content

RFC: sync Respect Phone DND to the watch (companion half) - #304

Closed
vvzvlad wants to merge 1 commit into
coredevices:masterfrom
vvzvlad:rfc/respect-phone-dnd
Closed

vvzvlad wants to merge 1 commit into
coredevices:masterfrom
vvzvlad:rfc/respect-phone-dnd

Conversation

@vvzvlad

@vvzvlad vvzvlad commented Jul 22, 2026 •

Copy link
Copy Markdown

Paired PR: the firmware half lives in coredevices/PebbleOS#1772 (branch rfc/phone-dnd-silent) — it reads the ANCS silent flag, honours the wire SILENT bit platform-neutrally, and enforces quiet delivery when the synced notifRespectPhoneSilence pref is on. Each PR stands alone: firmware without this app change is inert; this app change without the firmware syncs a pref no watch reads.

Not compiled: this machine has no JDK 17 / Android SDK, so the change was verified by manual compile-correctness passes (property/interface threading, exhaustive whens, signatures, wire encoding) but has NOT been built. Build + run before treating as working code.

What this does

The firmware half honors a per-notification "silent" wire flag (bit 6 of the TimelineItem flags byte) and a syncable watch pref notifRespectPhoneSilence: when the pref is on, silent-flagged notifications get quiet delivery — stored and listed, no popup/vibration/backlight. This PR is the minimal app side that turns it on, reusing the existing toggle instead of adding a second one.

The single control is the existing "Respect Phone Do Not Disturb" toggle (Phone → Notifications). It was Android-only — gated on notification-filtering support, which iOS lacks because ANCS delivers notifications straight to the watch, bypassing the app. This PR:

  • un-gates that one toggle so it shows on both platforms, and
  • on change, mirrors it to a hidden synced watch pref notifRespectPhoneSilence — a BoolWatchPref with userVisible = false, so it is the firmware key and rides the existing watch-pref sync, but renders no row of its own (no duplicate toggle).

iOS — the app can't see the notification stream (ANCS goes phone→watch directly), so enforcement is firmware-side (coredevices/PebbleOS#1772); toggling just syncs the pref and the firmware acts on the ANCS silent bit.

Android — unchanged: the toggle still writes the existing respectDoNotDisturb config (the local-drop behaviour), and additionally syncs the pref, which is a harmless no-op there. See the next section for why the Android behaviour is deliberately left as-is.

This PR also declares TimelineItem.Flag.SILENT(6) — the wire-protocol counterpart of the firmware header bit — so the contract is documented in one place, even though nothing in this PR emits it.

⚖️ The Android wiring is a maintainer decision — this PR deliberately does NOT change Android

On Android the app is in the notification path, so unlike iOS it can act on DND itself. What should it do with a notification the phone delivered silently (DND/Focus)? Two defensible answers, and which one ships is your call — this PR takes neither on Android, it leaves the status quo in place:

Option A — drop (status quo, what this PR keeps). The existing respectDoNotDisturb toggle doesn't forward DND-suppressed notifications; they never reach the watch. Pros: watch stays clean, zero new moving parts, no firmware dependency. Cons: the notification is gone from the watch — it exists in the phone's shade but leaves no trace on the wrist; and it diverges from what the firmware currently does on iOS (lists it silently). That divergence is a design choice, not a platform limit — the firmware could equally discard silent notifications on iOS instead of listing them — but as written, iOS lists and Android drops.

Option B — forward-but-quiet (NOT implemented here). The app would forward the notification tagged with SILENT; the firmware stores and lists it without alerting. Pros: the watch stays a complete mirror of the phone's list, just without the buzz — identical to iOS, and matches how the phone itself treats DND (deliver quietly, not discard). Cons: changes what existing Android users see (notifications that used to vanish would appear, silently); on old firmware that ignores bit 6 they would arrive alerting.

My preference: Option B (keep them on the watch). I think keeping the notifications on the watch is the more correct behaviour — they can still be read, they just don't interrupt while DND is on. That mirrors the phone itself, where DND'd notifications stay visible in the shade rather than being discarded; dropping them on the watch throws away information the user may still want. I've left this PR on the conservative status quo (Option A) rather than change Android behaviour unilaterally, but my vote is Option B on both platforms.

The only Android-relevant addition here is the SILENT(6) wire-flag definition, so that if maintainers later choose Option B it needs no protocol change — just the emit path (set the flag when matchesInterruptionFilter() is false, per-notification, so Focus per-sender exceptions still alert).

Tests

  • TimelineFlagSilentTest (commonTest): TimelineItem.Flag.SILENT.value == 6 and makeFlags(listOf(SILENT)) emits bit 6 (0x40).

Not run locally (no toolchain) — see the warning at the top.

Known trade-offs

  • Old firmware + new pref: on iOS, enabling the toggle while running firmware that doesn't understand the pref simply does nothing (the firmware ignores an unknown synced pref). No misbehaviour — the feature just stays off until the firmware half ships.
  • No reverse sync: the toggle's checked state reads the respectDoNotDisturb config and its handler mirrors that value to the synced pref, so the two stay consistent from the UI (reset-to-defaults also skips the hidden pref). Nothing reads the pref back into the config, so they could only diverge if something wrote the pref watch-side independently — a path that doesn't exist today (the pref has no watch UI). Noted for completeness.

The existing phone-side "Respect Phone Do Not Disturb" toggle was
Android-only (gated on notification filtering, which iOS lacks because
ANCS delivers notifications straight to the watch). Un-gate it so it
shows on both platforms and, on change, mirror it to a synced watch
pref (notifRespectPhoneSilence) that the firmware reads to enforce quiet
delivery from the ANCS silent flag on iOS.

The synced pref is a hidden BoolWatchPref (userVisible = false) so it
does not render a second, duplicate row - the phone toggle stays the
sole UI control. Also declare the TimelineItem SILENT wire flag (bit 6)
as the documented counterpart of the firmware header bit; Android
notification handling is intentionally unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Vlad Zaytsev <git@vvzvlad.xyz>
@CLAassistant

CLAassistant commented Jul 22, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@Raketemensch

Raketemensch commented Jul 29, 2026 •

Copy link
Copy Markdown

I was 99% of the way down this path when I discovered that you'd already done this work. It looks good.

The thought of being to use my VIP/break through contacts in iOS is very attractive, I have a son with type 1 diabetes and the alarms when he has an urgent low blood sugar alert can be lifesaving.

Doing this through ANCS is a very good idea.

@sjp4

sjp4 commented Aug 20, 2026

Copy link
Copy Markdown
Member

Thanks! Here's my take (I think I underdtand but correct me if I don't):

  • I would make it completely symmetrical with iOS: both platforms send notifications with the new flag set where appropriate. So we would remove the logic on android which doesn't send notifications when in DND, but instead set the flag on them.
  • Remove the existing android-only pref (and also the complexity trying to hide the new pref/make the old pref do double-duty)
  • Ideally everything would work the same way for calls. Does iOS expose any equivalent for calls? In which case we could update Respect phone Do Not Disturb for incoming calls #260 to set a flag on the call message from android.
  • (comment on the firmware PR): we should default to notifications showing on the watch, but with no sound/vibe; then users can configure this behaviour with the existing s_dnd_show_notifications preference if they want them to not appear at all.

Meta comment: I like this approach, but I'm not sure if there's a "right" answer between this (phone is in DND, sets flags on notifications) vs the alternative: phone is in DND, which also puts watch in Quiet Time automatically (I'm not sure if that's feasible on both platforms, and would probably need an inverse of the flag, to enable priority notifcations getting shown which are configured to bypass the phone's DND).

@vvzvlad
vvzvlad marked this pull request as ready for review September 15, 2026 00:53
sjp4 pushed a commit that referenced this pull request Oct 23, 2026
The watch weather app can now show wind in m/s and knots as well as
km/h and mph. Offer the two new values (3 and 4) in the Wind Speed
pref.

Related: coredevices/PebbleOS#2414

Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@gmarull

gmarull commented Oct 27, 2026

Copy link
Copy Markdown
Member

FYI: the firmware side has moved to coredevices/PebbleOS#2590, which replaces coredevices/PebbleOS#1772. It has no notifRespectPhoneSilence preference: the watch always follows the ANCS silent flag (silenced notifications are listed quietly, silenced calls don't ring). So syncing that pref from the app is no longer needed on iOS.

What still applies is the TimelineItem.Flag.SILENT wire flag (bit 6). The firmware honors it on any notification, so it's what the Android forward-but-quiet option would use if we go that way.

icewall905 pushed a commit to icewall905/gravelex that referenced this pull request Oct 27, 2026
The watch weather app can now show wind in m/s and knots as well as
km/h and mph. Offer the two new values (3 and 4) in the Wind Speed
pref.

Related: coredevices/PebbleOS#2414

Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit f21cba0)
@gmarull

gmarull commented Oct 27, 2026

Copy link
Copy Markdown
Member

Update to my previous comment: the firmware now has the preference after all. coredevices/PebbleOS#2590 (merged) adds quiet delivery for notifications carrying the ANCS silent flag, and coredevices/PebbleOS#2603 puts it behind notifRespectPhoneSilence (bool, default off), the same key this PR syncs. So syncing the pref from the app is needed again: with it off (default) silenced notifications alert as before; with it on they are stored and listed without popup, vibration or backlight, including silenced missed calls.

The TimelineItem.Flag.SILENT wire flag (bit 6) is honored under the same preference, so it is still what an Android forward-but-quiet path would use.

@sjp4

sjp4 commented Oct 27, 2026

Copy link
Copy Markdown
Member

Implemented the plan from my comment, on main - will pushed here on next sync (add global pref, on android remove previous phone-side filtering + set silent flag appropriately on notifications for watch to filter according to pref)

@sjp4 sjp4 closed this Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants