Files
Thomas Göttgens 14eaa5587d Honor mute when waking the screen for a received message (#11688)
* fix(ui): honor mute when waking the screen for a received message

TextMessageModule fired powerFSM.trigger(EVENT_RECEIVED_MSG) for every text
packet, gated only by shouldWakeOnReceivedMessage(), which checks external
notification, device role and battery level but never the mute flags. A muted
channel therefore suppressed the banner and still lit the screen.

MessageRenderer::handleNewMessage() only computed mute for MessageType::BROADCAST,
so a DM from a muted node produced a banner and a wake.

Add isMutedForPacket() in Channels: a DM addressed to us reads the sender's
NodeInfoLite mute bit, every other packet reads the mute bit of the channel it
arrived on. This is the predicate ExternalNotificationModule already applied to
the buzzer, vibra and LED outputs, hoisted so all three call sites share it.

Bell and alert messages still break through mute on both paths, unchanged.

No protobuf or config change: ChannelSettings.module_settings.is_muted and the
NodeInfoLite mute bit already exist and are already settable from the device menu
and via AdminMessage.toggle_muted_node.

Closes #11674

* fix(ui): let an alert break through mute on the screen wake path

In COLOR display mode TextMessageModule skips handleNewMessage(), so
powerFSM.trigger(EVENT_RECEIVED_MSG) is the only wake an alert gets. Gating it
on mute alone dropped that wake for a bell on a muted channel.

Add MeshService::isAlertPayload(): an ASCII BEL in the payload while at least one
alert_bell_* output is enabled. The wake gate is now "not muted, or an alert".
MessageRenderer uses the same predicate instead of its own inline bell scan,
which also lifts that scan's arbitrary 100 byte cap.

Rename three test cases. Their names carried exactly 35 characters after the
test_ prefix, which matches the Lob API key format and tripped trufflehog in the
trunk check gate.
2026-09-01 11:52:40 +00:00
..