android: sync OS mic mute state with Microsoft Teams via NotificationListenerService#581
Open
ntsour wants to merge 2 commits intokavishdevar:mainfrom
Open
android: sync OS mic mute state with Microsoft Teams via NotificationListenerService#581ntsour wants to merge 2 commits intokavishdevar:mainfrom
ntsour wants to merge 2 commits intokavishdevar:mainfrom
Conversation
Replace the single "Head Gestures" master toggle with two independent feature
toggles in the Head Tracking screen:
* Answer/decline incoming calls (nod = answer, shake = decline)
* Mute/unmute during a call (shake = mute, nod = unmute)
The two behaviors operate in different call phases (ringing vs. active) and
never overlap, so they are exposed as separate prefs (head_gestures_answer_call
and head_gestures_mute_call) rather than a single switch.
Additional gesture-related polish:
* Stem-press toggleMicMute now plays the same confirm_yes/confirm_no tones
used for head gestures (audible mute/unmute feedback over the AirPods).
* New MUTE_CALL StemAction so a stem press can be mapped to mute toggling.
* Periodic 15-second low-volume "still muted" reminder while the mic is muted
during a call, cancelled automatically on unmute or call end.
* Active-call gesture loop now mutes/unmutes directionally (shake mutes, nod
unmutes) instead of toggling, fixing the case where the gesture detector
re-fires the same direction during a missed restart.
* Restart bug fix in GestureDetector: callback is now invoked AFTER
stopDetection() so a callback that re-arms detection doesn't hit
isRunning=true and silently no-op.
* Removed per-movement "blip" sounds on every head turn; only the final
confirmation tone is played.
* Stale-state fix in testHeadGestures(): force a stop before re-arming so
isRunning=true left over from a previous test no longer breaks the next.
* Threshold tuning for the gesture detector to reduce accidental triggers.
24cd3f0 to
ede9ff0
Compare
Teams on Android does not register VoIP calls with the Telecom framework,
so InCallService.setMuted() cannot drive its in-app mute UI. Instead, watch
Teams' ongoing-call notification and fire the cached Mute/Unmute action
PendingIntent — Teams reacts as if the user had tapped the action in the
notification, which keeps the in-app mute icon in sync with the OS mute set
by hardware controls (stem press, head gesture).
* New TeamsNotifListener service (BIND_NOTIFICATION_LISTENER_SERVICE) that
caches the latest Mute and Unmute actions from notifications posted by
com.microsoft.teams (and a couple of related package variants).
* AirPodsService.toggleMicMute() and the active-call gesture loop now also
call TeamsNotifListener.setMuted() alongside AudioManager.setMicrophoneMute,
so Teams' UI follows the OS state.
* Notification access permission is requested from the initial setup screen,
matching the existing permission cards. The "Ask for regular permissions"
button now also opens the system Notification access settings if not yet
granted.
The user must enable LibrePods in Settings → Apps → Notification access for
the sync to work; without it the call is a no-op and OS-level mute still
applies, just without Teams' UI updating.
ede9ff0 to
3510d7f
Compare
6 tasks
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.
the problem
When LibrePods mutes the OS microphone (via head gesture or stem press), the mute indicator inside the Microsoft Teams app does not update. Teams manages its own mute state and does not register with the Android Telecom framework, so
InCallServicenever fires.what changed
TeamsNotifListener(newNotificationListenerService) watches for Teams' ongoing-call notification (com.microsoft.teamsand variant package names)MuteandUnmutePendingIntents from its notification actionsAirPodsService.toggleMicMute()callsTeamsNotifListener.setMuted()after each OS mute toggle, which fires the appropriate cached intent to sync Teams' in-app indicatorwhy NotificationListenerService and not InCallService
Teams does not use the Android Telecom stack. Logcat confirmed
setMutedAll(...): no instance boundon every attempt withInCallService. Teams exposes Mute/UnmutePendingIntents in its ongoing notification, which is the only reliable hook available without modifying Teams.what this does NOT change
Non-Teams calls are unaffected. The listener holds no wakelock and does nothing when Teams is not posting a call notification.
depends on
Tests
This branch is based on #580.