device-profile-hooks: add hook to select Voice Call profile

A "Voice Call" profile is supposed to be active during a call, even if
there is a higher priority device profile. Add a hook to select the
Voice Call profile when a call is active, and select a profile when
transitioning in and out of an active call.
This commit is contained in:
Richard Acayan 2025-07-29 18:36:24 -04:00 committed by George Kiagiadakis
parent 2794764d5a
commit 0fd1b05b01
2 changed files with 89 additions and 1 deletions

View file

@ -501,6 +501,11 @@ wireplumber.components = [
name = device/select-profile.lua, type = script/lua
provides = hooks.device.profile.select
}
{
name = device/find-voice-call-profile.lua, type = script/lua
provides = hooks.device.profile.find-voice-call
requires = [ support.modem-manager, support.standard-event-source ]
}
{
name = device/find-preferred-profile.lua, type = script/lua
provides = hooks.device.profile.find-preferred
@ -526,7 +531,9 @@ wireplumber.components = [
requires = [ hooks.device.profile.select,
hooks.device.profile.autoswitch-bluetooth,
hooks.device.profile.apply ]
wants = [ hooks.device.profile.find-best, hooks.device.profile.find-preferred,
wants = [ hooks.device.profile.find-voice-call,
hooks.device.profile.find-best,
hooks.device.profile.find-preferred,
hooks.device.profile.state ]
}

View file

@ -0,0 +1,81 @@
-- WirePlumber
--
-- Copyright © 2022 Collabora Ltd.
-- Copyright © 2025 Richard Acayan
--
-- SPDX-License-Identifier: MIT
--
-- Find the best Voice Call profile for a device if there is an active call
-- (adapted from device/find-best-profile.lua)
cutils = require ("common-utils")
log = Log.open_topic ("s-device")
started = false
alsa_devs_om = ObjectManager {
Interest {
type = "device",
Constraint { "device.api", "=", "alsa" },
}
}
mm = Plugin.find ("modem-manager")
mm:connect ("voice-call-start", function ()
started = true
source = source or Plugin.find ("standard-event-source")
for device in alsa_devs_om:iterate () do
event = source:call ("push-event", "select-profile", device, nil)
end
end)
mm:connect ("voice-call-stop", function ()
started = false
source = source or Plugin.find ("standard-event-source")
for device in alsa_devs_om:iterate () do
event = source:call ("push-event", "select-profile", device, nil)
end
end)
SimpleEventHook {
name = "device/find-calling-profile",
before = "device/find-stored-profile",
interests = {
EventInterest {
Constraint { "event.type", "=", "select-profile" },
},
},
execute = function (event)
local selected_profile = event:get_data ("selected-profile")
if selected_profile then
return
end
if not started then
return
end
local device = event:get_subject ()
local dev_name = device.properties["device.name"] or ""
for p in device:iterate_params ("EnumProfile") do
local profile = cutils.parseParam (p, "EnumProfile")
local found = string.find (profile.name, "^Voice Call")
if profile.available == "yes" and found ~= nil then
if (not selected_profile) or selected_profile.priority < profile.priority then
selected_profile = profile
end
end
end
if selected_profile then
log:info (device, string.format (
"Found best profile '%s' (%d) for device %s",
selected_profile.name, selected_profile.index, dev_name))
event:set_data ("selected-profile", selected_profile)
end
end
}:register ()
alsa_devs_om:activate ()