Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/scripts/device/autoswitch-bluetooth-profile.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,16 @@ autoswitch_hooks_registered = false

local PROFILE_RESTORE_TIMEOUT_MSEC = 2000
local PROFILE_SWITCH_TIMEOUT_MSEC = 500
local PROFILE_SWITCH_MAX_RETRIES = 6

local state = nil
local headset_profiles = {}
local non_headset_profiles = {}
local capture_stream_links = {}
local restore_timeout_source = {}
local switch_timeout_source = {}
local switch_retry_count = {}
local restore_retry_count = {}

function saveHeadsetProfile (device, profile_name, persistent)
local key = "saved-headset-profile:" .. device.properties ["device.name"]
Expand Down Expand Up @@ -136,6 +139,43 @@ function hasProfileInputRoute (device, profile_index)
return false
end

function hasEnumRoutes (device)
for _ in device:iterate_params ("EnumRoute") do
return true
end
return false
end

function deferSwitchToHeadset (dev_id, device_om, reason)
local retries = (switch_retry_count[dev_id] or 0) + 1
switch_retry_count[dev_id] = retries
if retries > PROFILE_SWITCH_MAX_RETRIES then
log:warning ("Giving up profile switch on device " .. tostring (dev_id)
.. " after " .. tostring (retries - 1) .. " retries (" .. reason .. ")")
return false
end

log:info ("Deferring profile switch on device " .. tostring (dev_id)
.. " (" .. reason .. ")")
triggerSwitchDeviceToHeadsetProfile (dev_id, device_om)
return true
end

function deferRestoreProfile (dev_id, device_om, reason)
local retries = (restore_retry_count[dev_id] or 0) + 1
restore_retry_count[dev_id] = retries
if retries > PROFILE_SWITCH_MAX_RETRIES then
log:warning ("Giving up profile restore on device " .. tostring (dev_id)
.. " after " .. tostring (retries - 1) .. " retries (" .. reason .. ")")
return false
end

log:info ("Deferring profile restore on device " .. tostring (dev_id)
.. " (" .. reason .. ")")
triggerRestoreProfile (dev_id, device_om)
return true
end

function switchDeviceToHeadsetProfile (dev_id, device_om)
-- Find the actual device
local device = device_om:lookup {
Expand All @@ -146,6 +186,11 @@ function switchDeviceToHeadsetProfile (dev_id, device_om)
return
end

if not hasEnumRoutes (device) then
deferSwitchToHeadset (dev_id, device_om, "EnumRoute not available yet")
return
end

-- Do not switch if the current profile is already a headset profile
local cur_profile = getCurrentProfile (device)
if cur_profile ~= nil and
Expand All @@ -170,6 +215,7 @@ function switchDeviceToHeadsetProfile (dev_id, device_om)

-- Switch if headset profile was found
if profile ~= nil then
switch_retry_count[dev_id] = nil
local pod = Pod.Object {
"Spa:Pod:Object:Param:Profile", "Profile",
index = profile.index,
Expand All @@ -193,6 +239,11 @@ function restoreProfile (dev_id, device_om)
return
end

if not hasEnumRoutes (device) then
deferRestoreProfile (dev_id, device_om, "EnumRoute not available yet")
return
end

-- Do not restore if the current profile is already a non-headset profile
local cur_profile = getCurrentProfile (device)
if cur_profile ~= nil and
Expand All @@ -217,6 +268,7 @@ function restoreProfile (dev_id, device_om)

-- Restore if non-headset profile was found
if profile ~= nil then
restore_retry_count[dev_id] = nil
local pod = Pod.Object {
"Spa:Pod:Object:Param:Profile", "Profile",
index = profile.index,
Expand Down