RFC: sync Respect Phone DND to the watch (companion half)#304
Draft
vvzvlad wants to merge 1 commit into
Draft
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
notifRespectPhoneSilence— aBoolWatchPrefwithuserVisible = 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
respectDoNotDisturbconfig (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
respectDoNotDisturbtoggle 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 whenmatchesInterruptionFilter()is false, per-notification, so Focus per-sender exceptions still alert).Tests
TimelineFlagSilentTest(commonTest):TimelineItem.Flag.SILENT.value == 6andmakeFlags(listOf(SILENT))emits bit 6 (0x40).Not run locally (no toolchain) — see the warning at the top.
Known trade-offs
respectDoNotDisturbconfig 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.