104 lines
2.8 KiB
Go
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
|
|
}
|