2022-12-02 17:22:14 +02:00
|
|
|
-- WirePlumber
|
|
|
|
|
--
|
|
|
|
|
-- Copyright © 2022 Collabora Ltd.
|
|
|
|
|
--
|
|
|
|
|
-- SPDX-License-Identifier: MIT
|
|
|
|
|
--
|
|
|
|
|
-- This file contains all the logic related to saving device profiles
|
|
|
|
|
-- to a state file and restoring them later on.
|
|
|
|
|
|
2023-06-22 16:28:56 +05:30
|
|
|
-- A devices profile needs to be selected for any new device. the script selects
|
|
|
|
|
-- the device profile from the user preferences, as well as store the user
|
|
|
|
|
-- selected device profile to state file
|
|
|
|
|
|
2022-12-02 17:22:14 +02:00
|
|
|
cutils = require ("common-utils")
|
2023-05-19 20:12:08 +03:00
|
|
|
log = Log.open_topic ("s-device")
|
2022-12-02 17:22:14 +02:00
|
|
|
|
2022-12-09 19:03:56 +02:00
|
|
|
-- the state storage
|
|
|
|
|
state = nil
|
|
|
|
|
state_table = nil
|
2022-12-02 17:22:14 +02:00
|
|
|
|
2022-12-09 19:03:56 +02:00
|
|
|
find_stored_profile_hook = SimpleEventHook {
|
2023-01-04 20:43:15 +02:00
|
|
|
name = "device/find-stored-profile",
|
2022-12-02 17:22:14 +02:00
|
|
|
interests = {
|
|
|
|
|
EventInterest {
|
|
|
|
|
Constraint { "event.type", "=", "select-profile" },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
execute = function (event)
|
|
|
|
|
local selected_profile = event:get_data ("selected-profile")
|
|
|
|
|
|
|
|
|
|
-- skip hook if profile is already selected
|
|
|
|
|
if selected_profile then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
2024-02-08 13:19:26 +05:30
|
|
|
local device = event:get_subject ()
|
|
|
|
|
local dev_name = device.properties["device.name"]
|
2022-12-02 17:22:14 +02:00
|
|
|
if not dev_name then
|
2023-05-19 20:12:08 +03:00
|
|
|
log:critical (device, "invalid device.name")
|
2022-12-02 17:22:14 +02:00
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local profile_name = state_table[dev_name]
|
|
|
|
|
|
|
|
|
|
if profile_name then
|
|
|
|
|
for p in device:iterate_params ("EnumProfile") do
|
|
|
|
|
local profile = cutils.parseParam (p, "EnumProfile")
|
2024-05-31 12:14:19 +03:00
|
|
|
if profile.name == profile_name and profile.available ~= "no" then
|
2022-12-02 17:22:14 +02:00
|
|
|
selected_profile = profile
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if selected_profile then
|
2023-05-19 20:12:08 +03:00
|
|
|
log:info (device, string.format (
|
2022-12-02 17:22:14 +02:00
|
|
|
"Found stored profile '%s' (%d) for device '%s'",
|
|
|
|
|
selected_profile.name, selected_profile.index, dev_name))
|
|
|
|
|
event:set_data ("selected-profile", selected_profile)
|
|
|
|
|
end
|
|
|
|
|
end
|
2022-12-09 19:03:56 +02:00
|
|
|
}
|
2022-12-02 17:22:14 +02:00
|
|
|
|
2022-12-09 19:03:56 +02:00
|
|
|
store_user_selected_profile_hook = SimpleEventHook {
|
2023-01-04 20:43:15 +02:00
|
|
|
name = "device/store-user-selected-profile",
|
2022-12-02 17:22:14 +02:00
|
|
|
interests = {
|
|
|
|
|
EventInterest {
|
|
|
|
|
Constraint { "event.type", "=", "device-params-changed" },
|
|
|
|
|
Constraint { "event.subject.param-id", "=", "Profile" },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
execute = function (event)
|
|
|
|
|
local device = event:get_subject ()
|
|
|
|
|
|
|
|
|
|
for p in device:iterate_params ("Profile") do
|
|
|
|
|
local profile = cutils.parseParam (p, "Profile")
|
|
|
|
|
if profile.save then
|
|
|
|
|
-- store only if this was a user-generated action (save == true)
|
|
|
|
|
updateStoredProfile (device, profile)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2022-12-09 19:03:56 +02:00
|
|
|
}
|
2022-12-02 17:22:14 +02:00
|
|
|
|
|
|
|
|
function updateStoredProfile (device, profile)
|
|
|
|
|
local dev_name = device.properties["device.name"]
|
|
|
|
|
local index = nil
|
|
|
|
|
|
|
|
|
|
if not dev_name then
|
2023-05-19 20:12:08 +03:00
|
|
|
log:critical (device, "invalid device.name")
|
2022-12-02 17:22:14 +02:00
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
2023-05-19 20:12:08 +03:00
|
|
|
log:debug (device, string.format (
|
2022-12-02 17:22:14 +02:00
|
|
|
"update stored profile to '%s' (%d) for device '%s'",
|
|
|
|
|
profile.name, profile.index, dev_name))
|
|
|
|
|
|
|
|
|
|
-- check if the new profile is the same as the current one
|
|
|
|
|
if state_table[dev_name] == profile.name then
|
2023-05-19 20:12:08 +03:00
|
|
|
log:debug (device, " ... profile is already stored")
|
2022-12-02 17:22:14 +02:00
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- find the full profile from EnumProfile, making also sure that the
|
|
|
|
|
-- user / client application has actually set an existing profile
|
|
|
|
|
for p in device:iterate_params ("EnumProfile") do
|
|
|
|
|
local enum_profile = cutils.parseParam (p, "EnumProfile")
|
|
|
|
|
if enum_profile.name == profile.name then
|
|
|
|
|
index = enum_profile.index
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if not index then
|
2023-05-19 20:12:08 +03:00
|
|
|
log:info (device, string.format (
|
2022-12-02 17:22:14 +02:00
|
|
|
"profile '%s' (%d) is not valid on device '%s'",
|
|
|
|
|
profile.name, profile.index, dev_name))
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
state_table[dev_name] = profile.name
|
2024-01-04 16:38:33 +02:00
|
|
|
state:save_after_timeout (state_table)
|
2022-12-02 17:22:14 +02:00
|
|
|
|
2023-05-19 20:12:08 +03:00
|
|
|
log:info (device, string.format (
|
2022-12-02 17:22:14 +02:00
|
|
|
"stored profile '%s' (%d) for device '%s'",
|
|
|
|
|
profile.name, index, dev_name))
|
|
|
|
|
end
|
2022-12-09 19:03:56 +02:00
|
|
|
|
2023-12-08 11:50:00 +02:00
|
|
|
function toggleState (enable)
|
2022-12-09 19:03:56 +02:00
|
|
|
if enable and not state then
|
|
|
|
|
state = State ("default-profile")
|
|
|
|
|
state_table = state:load ()
|
|
|
|
|
find_stored_profile_hook:register ()
|
|
|
|
|
store_user_selected_profile_hook:register ()
|
|
|
|
|
elseif not enable and state then
|
|
|
|
|
state = nil
|
|
|
|
|
state_table = nil
|
|
|
|
|
find_stored_profile_hook:remove ()
|
|
|
|
|
store_user_selected_profile_hook:remove ()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-02-26 12:20:12 -05:00
|
|
|
Settings.subscribe ("device.restore-profile", function ()
|
|
|
|
|
toggleState (Settings.get_boolean ("device.restore-profile"))
|
|
|
|
|
end)
|
|
|
|
|
toggleState (Settings.get_boolean ("device.restore-profile"))
|