object.go (6020B)
1 package dbus 2 3 import ( 4 "context" 5 "errors" 6 "strings" 7 ) 8 9 // BusObject is the interface of a remote object on which methods can be 10 // invoked. 11 type BusObject interface { 12 Call(method string, flags Flags, args ...interface{}) *Call 13 CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call 14 Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call 15 GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call 16 AddMatchSignal(iface, member string, options ...MatchOption) *Call 17 RemoveMatchSignal(iface, member string, options ...MatchOption) *Call 18 GetProperty(p string) (Variant, error) 19 StoreProperty(p string, value interface{}) error 20 SetProperty(p string, v interface{}) error 21 Destination() string 22 Path() ObjectPath 23 } 24 25 // Object represents a remote object on which methods can be invoked. 26 type Object struct { 27 conn *Conn 28 dest string 29 path ObjectPath 30 } 31 32 // Call calls a method with (*Object).Go and waits for its reply. 33 func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call { 34 return <-o.createCall(context.Background(), method, flags, make(chan *Call, 1), args...).Done 35 } 36 37 // CallWithContext acts like Call but takes a context 38 func (o *Object) CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call { 39 return <-o.createCall(ctx, method, flags, make(chan *Call, 1), args...).Done 40 } 41 42 // AddMatchSignal subscribes BusObject to signals from specified interface, 43 // method (member). Additional filter rules can be added via WithMatch* option constructors. 44 // Note: To filter events by object path you have to specify this path via an option. 45 // 46 // Deprecated: use (*Conn) AddMatchSignal instead. 47 func (o *Object) AddMatchSignal(iface, member string, options ...MatchOption) *Call { 48 base := []MatchOption{ 49 withMatchType("signal"), 50 WithMatchInterface(iface), 51 WithMatchMember(member), 52 } 53 54 options = append(base, options...) 55 return o.conn.BusObject().Call( 56 "org.freedesktop.DBus.AddMatch", 57 0, 58 formatMatchOptions(options), 59 ) 60 } 61 62 // RemoveMatchSignal unsubscribes BusObject from signals from specified interface, 63 // method (member). Additional filter rules can be added via WithMatch* option constructors 64 // 65 // Deprecated: use (*Conn) RemoveMatchSignal instead. 66 func (o *Object) RemoveMatchSignal(iface, member string, options ...MatchOption) *Call { 67 base := []MatchOption{ 68 withMatchType("signal"), 69 WithMatchInterface(iface), 70 WithMatchMember(member), 71 } 72 73 options = append(base, options...) 74 return o.conn.BusObject().Call( 75 "org.freedesktop.DBus.RemoveMatch", 76 0, 77 formatMatchOptions(options), 78 ) 79 } 80 81 // Go calls a method with the given arguments asynchronously. It returns a 82 // Call structure representing this method call. The passed channel will 83 // return the same value once the call is done. If ch is nil, a new channel 84 // will be allocated. Otherwise, ch has to be buffered or Go will panic. 85 // 86 // If the flags include FlagNoReplyExpected, ch is ignored and a Call structure 87 // is returned with any error in Err and a closed channel in Done containing 88 // the returned Call as it's one entry. 89 // 90 // If the method parameter contains a dot ('.'), the part before the last dot 91 // specifies the interface on which the method is called. 92 func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call { 93 return o.createCall(context.Background(), method, flags, ch, args...) 94 } 95 96 // GoWithContext acts like Go but takes a context 97 func (o *Object) GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call { 98 return o.createCall(ctx, method, flags, ch, args...) 99 } 100 101 func (o *Object) createCall(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call { 102 if ctx == nil { 103 panic("nil context") 104 } 105 iface := "" 106 i := strings.LastIndex(method, ".") 107 if i != -1 { 108 iface = method[:i] 109 } 110 method = method[i+1:] 111 msg := new(Message) 112 msg.Type = TypeMethodCall 113 msg.Flags = flags & (FlagNoAutoStart | FlagNoReplyExpected) 114 msg.Headers = make(map[HeaderField]Variant) 115 msg.Headers[FieldPath] = MakeVariant(o.path) 116 msg.Headers[FieldDestination] = MakeVariant(o.dest) 117 msg.Headers[FieldMember] = MakeVariant(method) 118 if iface != "" { 119 msg.Headers[FieldInterface] = MakeVariant(iface) 120 } 121 msg.Body = args 122 if len(args) > 0 { 123 msg.Headers[FieldSignature] = MakeVariant(SignatureOf(args...)) 124 } 125 return o.conn.SendWithContext(ctx, msg, ch) 126 } 127 128 // GetProperty calls org.freedesktop.DBus.Properties.Get on the given 129 // object. The property name must be given in interface.member notation. 130 func (o *Object) GetProperty(p string) (Variant, error) { 131 var result Variant 132 err := o.StoreProperty(p, &result) 133 return result, err 134 } 135 136 // StoreProperty calls org.freedesktop.DBus.Properties.Get on the given 137 // object. The property name must be given in interface.member notation. 138 // It stores the returned property into the provided value. 139 func (o *Object) StoreProperty(p string, value interface{}) error { 140 idx := strings.LastIndex(p, ".") 141 if idx == -1 || idx+1 == len(p) { 142 return errors.New("dbus: invalid property " + p) 143 } 144 145 iface := p[:idx] 146 prop := p[idx+1:] 147 148 return o.Call("org.freedesktop.DBus.Properties.Get", 0, iface, prop). 149 Store(value) 150 } 151 152 // SetProperty calls org.freedesktop.DBus.Properties.Set on the given 153 // object. The property name must be given in interface.member notation. 154 func (o *Object) SetProperty(p string, v interface{}) error { 155 idx := strings.LastIndex(p, ".") 156 if idx == -1 || idx+1 == len(p) { 157 return errors.New("dbus: invalid property " + p) 158 } 159 160 iface := p[:idx] 161 prop := p[idx+1:] 162 163 return o.Call("org.freedesktop.DBus.Properties.Set", 0, iface, prop, v).Err 164 } 165 166 // Destination returns the destination that calls on (o *Object) are sent to. 167 func (o *Object) Destination() string { 168 return o.dest 169 } 170 171 // Path returns the path that calls on (o *Object") are sent to. 172 func (o *Object) Path() ObjectPath { 173 return o.path 174 }