subsonic-tui/vendor/github.com/quarckster/go-mpris-server/internal/orgFreedesktopDBusProperties.go
Sagi Dayan a3923cf42c initial commit
Signed-off-by: Sagi Dayan <sagidayan@gmail.com>
2024-03-29 17:56:39 +03:00

104 lines
2.8 KiB
Go

package internal
import (
"reflect"
"sync"
"github.com/godbus/dbus/v5"
"github.com/godbus/dbus/v5/prop"
)
type iface = string
type property = string
type methodsMap = map[iface]map[property]interface{}
func NewOrgFreedesktopDBusProperties(
root *OrgMprisMediaPlayer2,
player *OrgMprisMediaPlayer2Player,
) *OrgFreedesktopDBusProperties {
gm := make(methodsMap)
gm["org.mpris.MediaPlayer2"] = root.GetMethods()
gm["org.mpris.MediaPlayer2.Player"] = player.GetMethods()
sm := make(methodsMap)
sm["org.mpris.MediaPlayer2"] = root.SetMethods()
sm["org.mpris.MediaPlayer2.Player"] = player.SetMethods()
conn, _ := dbus.SessionBus()
return &OrgFreedesktopDBusProperties{
getMethods: gm,
setMethods: sm,
conn: conn,
}
}
type OrgFreedesktopDBusProperties struct {
mut sync.RWMutex
getMethods methodsMap
setMethods methodsMap
conn *dbus.Conn
}
func (p *OrgFreedesktopDBusProperties) Get(iface string, property string) (dbus.Variant, *dbus.Error) {
p.mut.RLock()
defer p.mut.RUnlock()
properties, ok := p.getMethods[iface]
if !ok {
return dbus.Variant{}, prop.ErrIfaceNotFound
}
method, ok := properties[property]
if !ok {
return dbus.Variant{}, prop.ErrPropNotFound
}
reflectValue := reflect.ValueOf(method).Call([]reflect.Value{})
// get methods should return a value and an error
variant := dbus.MakeVariant(reflectValue[0].Interface())
err, _ := reflectValue[1].Interface().(error)
if err != nil {
return dbus.Variant{}, dbus.MakeFailedError(err)
}
return variant, nil
}
func (p *OrgFreedesktopDBusProperties) GetAll(iface string) (map[string]dbus.Variant, *dbus.Error) {
p.mut.RLock()
defer p.mut.RUnlock()
properties, ok := p.getMethods[iface]
if !ok {
return nil, prop.ErrIfaceNotFound
}
result := map[string]dbus.Variant{}
for k, v := range properties {
reflectValue := reflect.ValueOf(v).Call([]reflect.Value{})
variant := dbus.MakeVariant(reflectValue[0].Interface())
err, _ := reflectValue[1].Interface().(error)
if err != nil {
return map[string]dbus.Variant{}, dbus.MakeFailedError(err)
}
result[k] = variant
}
return result, nil
}
func (p *OrgFreedesktopDBusProperties) Set(iface string, property string, newv dbus.Variant) *dbus.Error {
p.mut.Lock()
defer p.mut.Unlock()
properties, ok := p.setMethods[iface]
if !ok {
return prop.ErrIfaceNotFound
}
method, ok := properties[property]
if !ok {
return prop.ErrPropNotFound
}
arg := reflect.ValueOf(newv.Value())
args := []reflect.Value{arg}
// set methods should always return an error
err, _ := reflect.ValueOf(method).Call(args)[0].Interface().(error)
if err != nil {
return dbus.MakeFailedError(err)
}
err = EmitPropertiesChanged(p.conn, iface, map[string]dbus.Variant{property: newv})
if err != nil {
return dbus.MakeFailedError(err)
}
return nil
}