forked from mvidner/ruby-dbus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathservice_newapi.rb
executable file
·227 lines (194 loc) · 6.76 KB
/
service_newapi.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require_relative "spec_helper"
SimpleCov.command_name "Service Tests" if Object.const_defined? "SimpleCov"
# find the library without external help
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
require "dbus"
PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties".freeze
class Test < DBus::Object
INTERFACE = "org.ruby.SampleInterface".freeze
def initialize(path)
super path
@read_me = "READ ME"
@read_or_write_me = "READ OR WRITE ME"
end
# Create an interface aggregating all upcoming dbus_method defines.
dbus_interface INTERFACE do
dbus_method :hello, "in name:s, in name2:s" do |name, name2|
puts "hello(#{name}, #{name2})"
end
dbus_method :test_variant, "in stuff:v" do |variant|
DBus.logger.debug variant.inspect
end
dbus_method :bounce_variant, "in stuff:v, out chaff:v" do |variant|
[variant]
end
dbus_method :variant_size, "in stuff:v, out size:u" do |variant|
[variant.size]
end
dbus_method :the_answer, "out answer:i" do
42
end
dbus_method :will_raise, "" do
raise "Handle this"
end
dbus_method :will_raise_error_failed, "" do
raise DBus.error, "failed as designed"
end
dbus_method :will_raise_name_error, "" do
"foo".frobnicate
end
dbus_method :Error, "in name:s, in description:s" do |name, description|
raise DBus.error(name), description
end
dbus_method :mirror_byte_array, "in bytes:ay, out mirrored:ay" do |bytes|
[bytes]
end
end
# closing and reopening the same interface
dbus_interface INTERFACE do
dbus_method :multibyte_string, "out string:s" do
"あいうえお"
end
dbus_signal :SomethingJustHappened, "toto:s, tutu:u"
end
dbus_interface "org.ruby.AnotherInterface" do
dbus_method :ThatsALongMethodNameIThink do
puts "ThatsALongMethodNameIThink"
end
dbus_method :Reverse, "in instr:s, out outstr:s" do |instr|
outstr = instr.split(//).reverse.join
[outstr]
end
end
dbus_interface "org.ruby.Ticket30" do
dbus_method :Sybilla, "in choices:av, out advice:s" do |choices|
["Do #{choices[0]}"]
end
end
dbus_interface "org.ruby.Duplicates" do
dbus_method :the_answer, "out answer:i" do
[0]
end
dbus_method :interfaces, "out answer:i" do
raise "This DBus method is currently shadowed by ProxyObject#interfaces"
end
end
dbus_interface "org.ruby.Loop" do
# starts doing something long, but returns immediately
# and sends a signal when done
dbus_method :LongTaskBegin, "in delay:i" do |delay|
# FIXME: did not complain about mismatch between signature and block args
self.LongTaskStart
DBus.logger.debug "Long task began"
task = Thread.new do
DBus.logger.debug "Long task thread started (#{delay}s)"
sleep delay
DBus.logger.debug "Long task will signal end"
self.LongTaskEnd
end
task.abort_on_exception = true # protect from test case bugs
end
dbus_signal :LongTaskStart
dbus_signal :LongTaskEnd
end
# Properties:
# ReadMe:string, returns "READ ME" at first, then what WriteMe received
# WriteMe:string
# ReadOrWriteMe:string, returns "READ OR WRITE ME" at first
dbus_interface PROPERTY_INTERFACE do
dbus_method :Get, "in interface:s, in propname:s, out value:v" do |interface, propname|
unless interface == INTERFACE
raise DBus.error("org.freedesktop.DBus.Error.UnknownInterface"),
"Interface '#{interface}' not found on object '#{@path}'"
end
case propname
when "ReadMe"
[@read_me]
when "ReadOrWriteMe"
[@read_or_write_me]
when "WriteMe"
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Property '#{interface}.#{propname}' (on object '#{@path}') is not readable"
else
# what should happen for unknown properties
# plasma: InvalidArgs (propname), UnknownInterface (interface)
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Property '#{interface}.#{propname}' not found on object '#{@path}'"
end
end
dbus_method :Set, "in interface:s, in propname:s, in value:v" do |interface, propname, value|
unless interface == INTERFACE
raise DBus.error("org.freedesktop.DBus.Error.UnknownInterface"),
"Interface '#{interface}' not found on object '#{@path}'"
end
case propname
when "ReadMe"
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Property '#{interface}.#{propname}' (on object '#{@path}') is not writable"
when "ReadOrWriteMe"
@read_or_write_me = value
self.PropertiesChanged(interface, { propname => value }, [])
when "WriteMe"
@read_me = value
self.PropertiesChanged(interface, { "ReadMe" => value }, [])
else
raise DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Property '#{interface}.#{propname}' not found on object '#{@path}'"
end
end
dbus_method :GetAll, "in interface:s, out value:a{sv}" do |interface|
unless interface == INTERFACE
raise DBus.error("org.freedesktop.DBus.Error.UnknownInterface"),
"Interface '#{interface}' not found on object '#{@path}'"
end
[
{
"ReadMe" => @read_me,
"ReadOrWriteMe" => @read_or_write_me
}
]
end
dbus_signal :PropertiesChanged, "interface:s, changed_properties:a{sv}, invalidated_properties:as"
end
end
class Derived < Test
end
class Test2 < DBus::Object
dbus_interface "org.ruby.Test2" do
dbus_method :hi, "in name:s, out greeting:s" do |name|
"Hi, #{name}!"
end
end
end
bus = DBus::SessionBus.instance
service = bus.request_service("org.ruby.service")
myobj = Test.new("/org/ruby/MyInstance")
service.export(myobj)
derived = Derived.new "/org/ruby/MyDerivedInstance"
service.export derived
test2 = Test2.new "/org/ruby/MyInstance2"
service.export test2
# introspect every other connection, Ticket #34
# (except the one that activates us - it has already emitted
# NOC by the time we run this. Therefore the test for #34 will not work
# by running t2.rb alone, one has to run t1 before it; 'rake' does it)
mr = DBus::MatchRule.new.from_s "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'"
bus.add_match(mr) do |msg|
new_unique_name = msg.params[2]
unless new_unique_name.empty?
DBus.logger.debug "RRRING #{new_unique_name}"
bus.introspect_data(new_unique_name, "/") do
# ignore the result
end
end
end
puts "listening, with ruby-#{RUBY_VERSION}"
main = DBus::Main.new
main << bus
begin
main.run
rescue SystemCallError
# the test driver will kill the bus, that's OK
end