forked from yyzhuang/sensibility
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest.repy
330 lines (273 loc) · 12.4 KB
/
test.repy
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
"""
test_sl4a_sensor.repy -- check out SL4A's *Facade's into Android sensors,
http://www.mithril.com.au/android/doc/index.html
Albert Rafetseder, Datenkugerl e.U., Austria
Change log:
v 0.0.1, 20140101 1200 AR
Refactored off test_phone.repy, which itself was based on an older
rendition of test_sensors.repy
"""
# This is the big "sensors" dict. Its entries are of form
# {FACADE1: {
# 'initialize': sensor_description_methods_and_examples,
# 'deactivate': sensor_description_methods_and_examples,
# 'use': {
# SENSOR1: sensor1_description_methods_and_examples,
# SENSOR2: sensor2_description_methods_and_examples,
# ... }
# },
# FACADE2: {
# ....
# }
# }
#
# Please provide meaningful 'example args' to the sensors so we can
# showcase them properly!
grace_period = 1
sensors = {
'AndroidFacade': { # See http://www.mithril.com.au/android/doc/AndroidFacade.html
'use': {
'environment': {
'usage': 'Returns a string of various useful environment details.',
'arguments': 'None.',
'returns': 'String',
'example args': None,
'example returned values': '{"error":null,"id":200000,"result":{"appcache":"\/data\/data\/com.googlecode.android_scripting\/cache","download":"\/mnt\/sdcard\/Download","TZ":{"id":"America\/Los_Angeles","offset":-28800000,"display":"Pacific Standard Time"},"SDK":"15","sdcard":{"blocksize":4096,"blockcount":3357270,"availblocks":3321917}}}'},
'getIntent': {
'usage': 'Returns the intent that launched the script.',
'arguments': 'None.',
'returns': 'String',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":{"action":"com.googlecode.android_scripting.action.LAUNCH_SERVER","categories":null,"flags":268435456,"classname":"com.googlecode.android_scripting.activity.ScriptingLayerService","packagename":"com.googlecode.android_scripting","extras":{"com.googlecode.android_scripting.extra.USE_SERVICE_PORT":45678}}}'},
'makeToast': {
'usage': 'Returns the intent that launched the script.',
'arguments': 'message (String).',
'returns': 'None',
'example args': ['Happy holidays!'],
'example returned values': '{"error":null,"id":0,"result":null}'},
'vibrate': {
'usage': 'Returns the intent that launched the script.',
'arguments': 'Integer (optional, in ms).',
'returns': 'None',
'example args': [3000],
'example returned values': '{"error":null,"id":0,"result":null}'} } # End use
}, # End Android
'ApplicationFacade': { # See http://www.mithril.com.au/android/doc/ApplicationManagerFacade.html
'use': {
'getLaunchableApplications': {
'usage': 'Returns a list of all launchable application class names.',
'arguments': 'None',
'returns': 'String',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":{"Voice Dialer":"com.android.voicedialer.VoiceDialerActivity",...}}'},
'getRunningPackages': {
'usage': 'Returns a list of packages running activities or services.',
'arguments': 'None',
'returns': 'String',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":["com.google.android.location","at.univie.sensorium","android","com.android.providers.contacts", ...]}'} } # End use
}, # End Application
'BatteryFacade': { # See http://www.mithril.com.au/android/doc/BatteryManagerFacade.html
'initialize': {
'batteryStartMonitoring': {
'usage': 'Starts tracking battery events. Call this before attempting any of the other battery-related calls.',
'arguments': 'None.',
'returns': '{"error":null,"id":0,"result":null}',
'example args': None,
'example returned values': ''} },
'deactivate': {
'batteryStopMonitoring': {
'usage': 'Stops tracking battery events. Call this after you are done with all of your other battery-related calls.',
'arguments': 'None.',
'returns': 'null',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":null}'} },
'use': {
'batteryCheckPresent': {
'usage': 'Returns the most recently received battery presence data.',
'arguments': 'None.',
'returns': 'Boolean',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":true}'},
'batteryGetHealth': {
'usage': 'Returns the most recently received battery health data.',
'arguments': 'None.',
'returns': 'Interger: 1 - unknown; 2 - good; 3 - overheat; 4 - dead; 5 - over voltage; 6 - unspecified failure.',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":2}'},
'batteryGetLevel': {
'usage': 'Returns the most recently received battery level (percentage).',
'arguments': 'None.',
'returns': 'Integer',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":99}'},
'batteryGetPlugType': {
'usage': 'Returns the most recently received plug type data.',
'arguments': 'None.',
'returns': 'Interger: -1 - unknown; 0 - unplugged; 1 - power source is an AC charger; 2 - power source is a USB port.',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":2}'},
'batteryGetStatus': {
'usage': 'Returns the most recently received battery status data.',
'arguments': 'None.',
'returns': 'Interger: 1 - unknown; 2 - charging; 3 - discharging; 4 - not charging; 5 - full.',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":3}'},
'batteryGetTechnology': {
'usage': 'Returns the most recently received battery technology data.',
'arguments': 'None.',
'returns': 'String.',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":"Li-ion"}'},
'readBatteryData': {
'usage': 'Returns the most recently recorded battery data (all data).',
'arguments': 'None.',
'returns': 'String.',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":{"level":98,"technology":"Li-ion","status":3,"voltage":4140,"plugged":2,"battery_present":true,"health":2,"temperature":269}}'}
}
}, # End Battery
'TextToSpeechFacade': { # See http://www.mithril.com.au/android/doc/TextToSpeechFacade.html
'use': {
'ttsSpeak': {
'usage': 'Speaks the provided message via TTS.',
'arguments': 'message (String)',
'returns': 'null',
'example args': ['Okay, human!'],
'example returned values': '{"error":null,"id":0,"result":null}'},
'ttsIsSpeaking': {
'usage': 'Returns True if speech is currently in progress.',
'arguments': 'None.',
'returns': 'Boolean',
'example args': None,
'example returned values': '{"error":null,"id":0,"result":false}'} }
}, # End TextToSpeech
} # End of big sensors dict
def usage():
log("""
test_sl4a_sensor.repy
-- check out SL4A's different ``Facade''s into Android sensors.
Usage:
1) On your shell, specify the AP_PORT for SL4A to listen on, e.g.
export AP_PORT=45678
2) Start SL4A in server mode using am, the Activity Manager, on that port:
(CAUTION: That's one long line!)
am start -a com.googlecode.android_scripting.action.LAUNCH_SERVER -n com.googlecode.android_scripting/.activity.ScriptingLayerServiceLauncher --ei com.googlecode.android_scripting.extra.USE_SERVICE_PORT $AP_PORT
3) Finally, run this program and supply it with the AP_PORT:
python repy.py restrictionsfile test_sl4a_sensor.repy [ $AP_PORT \
[ FACADE [ SENSOR [ ARGUMENT_LIST ]]]]
Omitting AP_PORT and further options at all lists this usage information, and
all Facades and sensor methods I know.
Omitting FACADE demoes (i.e. tests with some exemplary default arguments)
all sensor methods of all facades I know.
With any other FACADE arg, demo all of the sensor methods of this facade.
With both FACADE and SENSOR, demo that sensor method with default call
arguments.
Given FACADE and SENSOR plus any additional arguments making up the
ARGUMENT_LIST, test exactly that sensor method with exactly those args.
Initialization and deactivation methods will be called automatically
as required.
""")
mycontext['id'] = 0
def send_rpc_request(socket_object, method_name, parameter_list):
# Sanitize the parameters, None becomes an empty list
parameter_list = parameter_list or []
json_request_string = '{"params": ' + str(parameter_list) + ', "id": ' + \
str(mycontext['id']) + ', "method": "' + \
str(method_name) + '"}\n'
mycontext['id'] += 1
bytes_sent = 0
while bytes_sent<len(json_request_string):
sendstring = json_request_string[bytes_sent:]
bytes_sent += socket_object.send(sendstring)
log(sendstring)
def get_rpc_response(socket_object, timeout=5):
received_string = ""
time_started = getruntime()
while getruntime() < time_started + timeout:
try:
chunk = socket_object.recv(1024)
received_string += chunk
except SocketWouldBlockError:
if received_string != "":
break
pass
except SocketClosedRemote:
pass
return received_string
if callfunc=="initialize":
# Parse the callargs.
# No callargs means print usage and info about all sensors.
if len(callargs) == 0:
usage()
log(sensors, "\n")
exitall()
# If we reach this line, we have at least one callarg, the AP_PORT
try:
ap_port = int(callargs[0])
except:
# Not castable (-> ValueError)? That's the user's fault! Teach them!
usage()
exitall()
facadelist = [] # List of facades to work through
method = None # User-specified method to demo (if any)
argslist = [] # User-specified argument list (if any)
if len(callargs) == 1: # No Facade etc. was specified, demo them all
facadelist = sensors.keys()
elif len(callargs) == 2: # Demo the specified Facade
facadelist = [callargs[1]]
if facadelist[0] not in sensors.keys():
usage()
log("\nSorry, I don't know the Facade you specified.\n")
exitall()
elif len(callargs) >= 3: # Demo one specific sensor method (possibly w/args)
facadelist = [callargs[1]]
method = [callargs[2]]
if facadelist[0] not in sensors.keys() or \
method[0] not in sensors[facadelist[0]]["use"]:
usage()
log("\nSorry, I don't know the Facade or sensor method you specified.\n")
exitall()
# Add any remaining arguments to the argslist
argslist = callargs[3:]
# Showtime! Connect to SL4A, run the previously configured test(s).
# XXX Do getresources() to find a possible source port, not hardcode it!
sl4a_socket = openconnection("127.0.0.1", ap_port, "127.0.0.1", 12345, 5)
for facade in facadelist:
# Initialize if required
if "initialize" in sensors[facade].keys():
init_method = sensors[facade]["initialize"].keys()[0]
init_args = sensors[facade]["initialize"][init_method]["example args"]
log("Initializing " + facade + "...")
send_rpc_request(sl4a_socket, init_method, init_args)
sleep(grace_period)
response = get_rpc_response(sl4a_socket)
log(" -- Done, returned ", response, "\n")
# Perform the requested method (or all of them)
# if method is neither None nor []: methodlist = method
# else: methodlist = that subsubdict's keys
methodlist = method or sensors[facade]["use"].keys()
log("Time for", methodlist, "\n")
for method in methodlist:
args = argslist or sensors[facade]["use"][method]["example args"]
log("Performing " + method + "...")
send_rpc_request(sl4a_socket, method, args)
response = get_rpc_response(sl4a_socket)
log("-- Done, returned " + response + "\n")
sleep(grace_period)
# Finally, disarm the facade again.
if "deactivate" in sensors[facade].keys():
init_method = sensors[facade]["deactivate"].keys()[0]
init_args = sensors[facade]["deactivate"][init_method]["example args"]
log("Deactivating " + facade + "...")
send_rpc_request(sl4a_socket, init_method, init_args)
sleep(grace_period)
response = get_rpc_response(sl4a_socket)
log(" -- Done, returned ", response, "\n")
# This is only required to "forget" methods of the current facade
# in demo-all mode; otherwise method would we would contain the
# methods of the past facade and try them with the next facade
# (which won't work.)
method = None
log("That's all, folks!\n\n")
sl4a_socket.close()