1 ˆ 0þÁˆ 0þÁ# ˆl–Ãa¾”ÔD¨ µÕÆ™¸ÛªbÑ¿À „^yÿ¿Â.q -- WirePlumber -- -- Copyright © 2021-2022 Collabora Ltd. -- @author George Kiagiadakis -- -- Based on default-routes.c from pipewire-media-session -- Copyright © 2020 Wim Taymans -- -- SPDX-License-Identifier: MIT -- -- This file contains all the logic related to saving device routes and their -- properties to a state file and restoring both the routes selection and -- the properties of routes later on. -- cutils = require ("common-utils") devinfo = require ("device-info-cache") log = Log.open_topic ("s-device") -- the state storage state = nil state_table = nil -- hook to restore routes selection for a newly selected profile find_stored_routes_hook = SimpleEventHook { name = "device/find-stored-routes", interests = { EventInterest { Constraint { "event.type", "=", "select-routes" }, Constraint { "profile.changed", "=", "true" }, Constraint { "profile.active-device-ids", "is-present" }, }, }, execute = function (event) local device = event:get_subject () local event_properties = event:get_properties () local profile_name = event_properties ["profile.name"] local active_ids = event_properties ["profile.active-device-ids"] local selected_routes = event:get_data ("selected-routes") or {} local dev_info = devinfo:get_device_info (device) assert (dev_info) -- get the stored routes for this profile -- skip the hook if there are no stored routes, there is no point local spr = getStoredProfileRoutes (dev_info, profile_name) if #spr == 0 then return end -- active IDs are exchanged in JSON format active_ids = Json.Raw (active_ids):parse () for _, device_id in ipairs (active_ids) do -- if a previous hook already selected a route for this device_id, skip it if selected_routes [tostring (device_id)] then goto next_device_id end log:info (device, "restoring route for device ID " .. tostring (device_id)); local route_info = nil -- find a route that was previously stored for a device_id for _, ri in pairs (dev_info.route_infos) do if cutils.arrayContains (ri.devices, tonumber (device_id)) and (ri.profiles == nil or cutils.arrayContains (ri.profiles, dev_info.active_profile)) and cutils.arrayContains (spr, ri.name) then route_info = ri break end end if route_info then -- we found a stored route if route_info.available == "no" then log:info (device, "stored route '" .. route_info.name .. "' not available") -- not available, try to find next best route_info = nil else log:info (device, "found stored route: " .. route_info.name) end end if route_info then selected_routes [tostring (device_id)] = Json.Object { index = route_info.index }:to_string () end ::next_device_id:: end -- save the selected routes for the apply-routes hook event:set_data ("selected-routes", selected_routes) end } -- extract the "selected-routes" event data and augment it to include -- the route properties, as they were stored in the state file; -- this is the last step before applying the routes apply_route_props_hook = SimpleEventHook { name = "device/apply-route-props", after = { "device/find-stored-routes", "device/find-best-routes" }, interests = { EventInterest { Constraint { "event.type", "=", "select-routes" }, }, }, execute = function (event) local device = event:get_subject () local selected_routes = event:get_data ("selected-routes") or {} local new_selected_routes = {} local dev_info = devinfo:get_device_info (device) assert (dev_info) if next (selected_routes) == nil then log:info (device, "No routes selected to set on " .. dev_info.name) return end for device_id, route in pairs (selected_routes) do