device_api-android 1.2.9 → 1.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/lib/device_api/android/adb.rb +99 -89
- data/lib/device_api/android/device.rb +55 -28
- data/lib/device_api/android/device/kindle.rb +4 -3
- data/lib/device_api/android/plugins/audio.rb +5 -5
- data/lib/device_api/android/plugins/battery.rb +2 -2
- data/lib/device_api/android/plugins/disk.rb +3 -3
- data/lib/device_api/android/plugins/memory.rb +3 -3
- data/lib/device_api/android/signing.rb +2 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2949c4bb240ed0f093b79db016d0d36156db4b4
|
4
|
+
data.tar.gz: 18bf69ed9c381eee30d2229efff6481a5adab406
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77e3bd2c0c489a7a4334203bbc37ee3bb7a2792e048894aa845a998069b25016f73953af459ff724b2772749645820143334f29970fc24d8c829e5a5369913d4
|
7
|
+
data.tar.gz: 80b1257860b39542b8b088db4086d876fe9bb2cf4c82cd75668a4e69715e94fbd5712e3ef1e171dc101823f5cc1f032afc5879a7429efee7d870fdaec8db8f5a
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# DeviceAPI-Android
|
2
2
|
|
3
|
-
*DeviceAPI-Android* is the android implementation of device_api -- an initiative to allow full automation of device activities.
|
3
|
+
*DeviceAPI-Android* is the android implementation of device_api -- an initiative to allow full automation of device activities. For a full list of release notes, see the [change log](CHANGELOG.md)
|
4
4
|
|
5
5
|
## Dependencies
|
6
6
|
|
@@ -104,6 +104,7 @@ This allows you to setup a keystore with the options required by any testing fra
|
|
104
104
|
## Testing
|
105
105
|
|
106
106
|
device_api-android is defended with unit and integration level rspec tests. You can run the tests with:
|
107
|
+
|
107
108
|
bundle exec rspec
|
108
109
|
|
109
110
|
## Issues
|
@@ -22,10 +22,10 @@ module DeviceAPI
|
|
22
22
|
end
|
23
23
|
|
24
24
|
# Retrieve device state for a single device
|
25
|
-
# @param
|
25
|
+
# @param qualifier qualifier of device
|
26
26
|
# @return (String) device state
|
27
|
-
def self.get_state(
|
28
|
-
result = execute('adb get-state -s #{
|
27
|
+
def self.get_state(qualifier)
|
28
|
+
result = execute('adb get-state -s #{qualifier}')
|
29
29
|
|
30
30
|
raise ADBCommandError.new(result.stderr) if result.exit != 0
|
31
31
|
|
@@ -35,10 +35,10 @@ module DeviceAPI
|
|
35
35
|
end
|
36
36
|
|
37
37
|
# Get the properties of a specified device
|
38
|
-
# @param
|
38
|
+
# @param qualifier qualifier of device
|
39
39
|
# @return (Hash) hash containing device properties
|
40
|
-
def self.getprop(
|
41
|
-
result = shell(
|
40
|
+
def self.getprop(qualifier)
|
41
|
+
result = shell(qualifier, 'getprop')
|
42
42
|
|
43
43
|
lines = result.stdout.encode('UTF-16', 'UTF-8', invalid: :replace, replace: '').encode('UTF-8', 'UTF-16').split("\n")
|
44
44
|
|
@@ -46,37 +46,37 @@ module DeviceAPI
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# Get the 'input' information from dumpsys
|
49
|
-
# @param
|
49
|
+
# @param qualifier qualifier of device
|
50
50
|
# @return (Hash) hash containing input information from dumpsys
|
51
|
-
def self.getdumpsys(
|
52
|
-
lines = dumpsys(
|
51
|
+
def self.getdumpsys(qualifier)
|
52
|
+
lines = dumpsys(qualifier, 'input')
|
53
53
|
process_dumpsys('(.*):\s+(.*)', lines)
|
54
54
|
end
|
55
55
|
|
56
56
|
# Get the 'iphonesubinfo' from dumpsys
|
57
|
-
# @param
|
57
|
+
# @param qualifier qualifier of device
|
58
58
|
# @return (Hash) hash containing iphonesubinfo information from dumpsys
|
59
|
-
def self.getphoneinfo(
|
60
|
-
lines = dumpsys(
|
59
|
+
def self.getphoneinfo(qualifier)
|
60
|
+
lines = dumpsys(qualifier, 'iphonesubinfo')
|
61
61
|
process_dumpsys('(.*) =\s+(.*)', lines)
|
62
62
|
end
|
63
63
|
|
64
64
|
# Get the 'battery' information from dumpsys
|
65
|
-
# @param [String]
|
65
|
+
# @param [String] qualifier qualifier of device
|
66
66
|
# @return [Hash] hash containing battery information from dumpsys
|
67
|
-
def self.get_battery_info(
|
68
|
-
lines = dumpsys(
|
67
|
+
def self.get_battery_info(qualifier)
|
68
|
+
lines = dumpsys(qualifier, 'battery')
|
69
69
|
process_dumpsys('(.*):\s+(.*)', lines)
|
70
70
|
end
|
71
71
|
|
72
|
-
def self.get_network_interface(
|
73
|
-
result = shell(
|
72
|
+
def self.get_network_interface(qualifier, interface)
|
73
|
+
result = shell(qualifier, "ifconfig #{interface}")
|
74
74
|
result.stdout
|
75
75
|
end
|
76
76
|
|
77
77
|
# Get the network information
|
78
|
-
def self.get_network_info(
|
79
|
-
lines = shell(
|
78
|
+
def self.get_network_info(qualifier)
|
79
|
+
lines = shell(qualifier, 'netcfg')
|
80
80
|
lines.stdout.split("\n").map do |a|
|
81
81
|
b = a.split(" ")
|
82
82
|
{ name: b[0], ip: b[2].split('/')[0], mac: b[4] }
|
@@ -100,15 +100,15 @@ module DeviceAPI
|
|
100
100
|
end
|
101
101
|
|
102
102
|
# Get the 'power' information from dumpsys
|
103
|
-
# @param [String]
|
103
|
+
# @param [String] qualifier qualifier of device
|
104
104
|
# @return [Hash] hash containing power information from dumpsys
|
105
|
-
def self.getpowerinfo(
|
106
|
-
lines = dumpsys(
|
105
|
+
def self.getpowerinfo(qualifier)
|
106
|
+
lines = dumpsys(qualifier, 'power')
|
107
107
|
process_dumpsys('(.*)=(.*)', lines)
|
108
108
|
end
|
109
109
|
|
110
|
-
def self.get_device_dpi(
|
111
|
-
lines = dumpsys(
|
110
|
+
def self.get_device_dpi(qualifier)
|
111
|
+
lines = dumpsys(qualifier, 'window')
|
112
112
|
dpi = nil
|
113
113
|
lines.each do |line|
|
114
114
|
if /sw(\d*)dp/.match(line)
|
@@ -119,17 +119,17 @@ module DeviceAPI
|
|
119
119
|
end
|
120
120
|
|
121
121
|
# Returns the 'dumpsys' information from the specified device
|
122
|
-
# @param
|
122
|
+
# @param qualifier qualifier of device
|
123
123
|
# @return (Array) array of results from adb shell dumpsys
|
124
|
-
def self.dumpsys(
|
125
|
-
result = shell(
|
124
|
+
def self.dumpsys(qualifier, command)
|
125
|
+
result = shell(qualifier, "dumpsys #{command}")
|
126
126
|
result.stdout.split("\n").map { |line| line.strip }
|
127
127
|
end
|
128
128
|
|
129
129
|
# Installs a specified apk to a specific device
|
130
130
|
# @param [Hash] options the options used for installing an apk
|
131
131
|
# @option options [String] :apk path to apk to install
|
132
|
-
# @option options [String] :
|
132
|
+
# @option options [String] :qualifier qualifier of device
|
133
133
|
# @return (String) return result from adb install command
|
134
134
|
def self.install_apk(options = {})
|
135
135
|
options[:action] = :install
|
@@ -139,7 +139,7 @@ module DeviceAPI
|
|
139
139
|
# Uninstalls a specified package from a specified device
|
140
140
|
# @param [Hash] options the options used for uninstalling a package
|
141
141
|
# @option options [String] :package_name package to uninstall
|
142
|
-
# @option options [String] :
|
142
|
+
# @option options [String] :qualifier qualifier of device
|
143
143
|
# @return (String) return result from adb uninstall command
|
144
144
|
def self.uninstall_apk(options = {})
|
145
145
|
options[:action] = :uninstall
|
@@ -149,14 +149,14 @@ module DeviceAPI
|
|
149
149
|
def self.change_apk(options = {})
|
150
150
|
package_name = options[:package_name]
|
151
151
|
apk = options[:apk]
|
152
|
-
|
152
|
+
qualifier = options[:qualifier]
|
153
153
|
action = options[:action]
|
154
154
|
|
155
155
|
case action
|
156
156
|
when :install
|
157
|
-
command = "adb -s #{
|
157
|
+
command = "adb -s #{qualifier} install #{apk}"
|
158
158
|
when :uninstall
|
159
|
-
command = "adb -s #{
|
159
|
+
command = "adb -s #{qualifier} uninstall #{package_name}"
|
160
160
|
else
|
161
161
|
raise ADBCommandError.new('No action specified')
|
162
162
|
end
|
@@ -171,10 +171,10 @@ module DeviceAPI
|
|
171
171
|
end
|
172
172
|
|
173
173
|
# Returns the uptime of the specified device
|
174
|
-
# @param
|
174
|
+
# @param qualifier qualifier of device
|
175
175
|
# @return (Float) uptime in seconds
|
176
|
-
def self.get_uptime(
|
177
|
-
result = shell(
|
176
|
+
def self.get_uptime(qualifier)
|
177
|
+
result = shell(qualifier, 'cat /proc/uptime')
|
178
178
|
|
179
179
|
lines = result.stdout.split("\n")
|
180
180
|
uptime = 0
|
@@ -187,23 +187,23 @@ module DeviceAPI
|
|
187
187
|
end
|
188
188
|
|
189
189
|
# Reboots the specified device
|
190
|
-
# @param
|
190
|
+
# @param qualifier qualifier of device
|
191
191
|
# @return (nil) Nil if successful, otherwise an error is raised
|
192
|
-
def self.reboot(
|
193
|
-
result = execute("adb -s #{
|
192
|
+
def self.reboot(qualifier)
|
193
|
+
result = execute("adb -s #{qualifier} reboot")
|
194
194
|
raise ADBCommandError.new(result.stderr) if result.exit != 0
|
195
195
|
end
|
196
196
|
|
197
197
|
# Runs monkey testing
|
198
|
-
# @param
|
198
|
+
# @param qualifier qualifier of device
|
199
199
|
# @param [Hash] args hash of arguments used for starting testing
|
200
200
|
# @option args [String] :events (10000) number of events to run
|
201
201
|
# @option args [String] :package name of package to run the tests against
|
202
202
|
# @option args [String] :seed pass the seed number (optional)
|
203
203
|
# @option args [String] :throttle throttle value (optional)
|
204
204
|
# @example
|
205
|
-
# DeviceAPI::ADB.monkey(
|
206
|
-
def self.monkey(
|
205
|
+
# DeviceAPI::ADB.monkey( qualifier, :package => 'my.lovely.app' )
|
206
|
+
def self.monkey(qualifier, args)
|
207
207
|
|
208
208
|
events = args[:events] || 10000
|
209
209
|
package = args[:package] or raise "package name not provided (:package => 'bbc.iplayer')"
|
@@ -214,71 +214,81 @@ module DeviceAPI
|
|
214
214
|
cmd = cmd + " -s #{seed}" if seed
|
215
215
|
cmd = cmd + " -t #{throttle}" if throttle
|
216
216
|
|
217
|
-
shell(
|
217
|
+
shell(qualifier, cmd)
|
218
218
|
end
|
219
219
|
|
220
220
|
# Take a screenshot from the device
|
221
|
-
# @param
|
221
|
+
# @param qualifier qualifier of device
|
222
222
|
# @param [Hash] args hash of arguments
|
223
223
|
# @option args [String] :filename name (with full path) required to save the image
|
224
224
|
# @example
|
225
|
-
# DeviceAPI::ADB.screenshot(
|
226
|
-
def self.screencap(
|
225
|
+
# DeviceAPI::ADB.screenshot( qualifier, :filename => '/tmp/filename.png' )
|
226
|
+
def self.screencap( qualifier, args )
|
227
227
|
|
228
228
|
filename = args[:filename] or raise "filename not provided (:filename => '/tmp/myfile.png')"
|
229
229
|
|
230
230
|
convert_carriage_returns = %q{perl -pe 's/\x0D\x0A/\x0A/g'}
|
231
231
|
cmd = "screencap -p | #{convert_carriage_returns} > #{filename}"
|
232
232
|
|
233
|
-
shell(
|
233
|
+
shell(qualifier, cmd)
|
234
234
|
end
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
235
|
+
|
236
|
+
# Connects to remote android device
|
237
|
+
# @param [String] ip_address
|
238
|
+
# @param [String] port
|
239
|
+
# @example
|
240
|
+
# DeviceAPI::ADB.connect(ip_address, port)
|
241
|
+
def self.connect(ip_address, port=5555)
|
242
|
+
ip_address_and_port = "#{ip_address}:#{port}"
|
243
|
+
check_ip_address(ip_address_and_port)
|
244
|
+
cmd = "adb connect #{ip_address_and_port}"
|
240
245
|
result = execute(cmd)
|
241
246
|
if result.stdout.to_s =~ /.*already connected to.*/
|
242
|
-
raise DeviceAlreadyConnectedError.new("Device #{
|
247
|
+
raise DeviceAlreadyConnectedError.new("Device #{ip_address_and_port} already connected")
|
243
248
|
else
|
244
249
|
unless result.stdout.to_s =~ /.*connected to.*/
|
245
|
-
raise ADBCommandError.new("Unable to adb connect to #{
|
250
|
+
raise ADBCommandError.new("Unable to adb connect to #{ip_address_and_port} result was: #{result.stdout}")
|
246
251
|
end
|
247
252
|
end
|
248
253
|
end
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
+
|
255
|
+
# Disconnects from remote android device
|
256
|
+
# @param [String] ip_address
|
257
|
+
# @param [String] port
|
258
|
+
# @example
|
259
|
+
# DeviceAPI::ADB.disconnect(ip_address, port)
|
260
|
+
def self.disconnect(ip_address, port=5555)
|
261
|
+
ip_address_and_port = "#{ip_address}:#{port}"
|
262
|
+
check_ip_address(ip_address_and_port)
|
263
|
+
cmd = "adb disconnect #{ip_address_and_port}"
|
254
264
|
result = execute(cmd)
|
255
265
|
unless result.exit == 0
|
256
|
-
raise ADBCommandError.new("Unable to adb disconnect to #{
|
266
|
+
raise ADBCommandError.new("Unable to adb disconnect to #{ip_address_and_port} result was: #{result.stdout}")
|
257
267
|
end
|
258
268
|
end
|
259
269
|
|
260
270
|
# Returns wifi status and access point name
|
261
|
-
# @param
|
271
|
+
# @param qualifier qualifier of device
|
262
272
|
# @example
|
263
|
-
# DeviceAPI::ADB.wifi(
|
264
|
-
def self.wifi(
|
265
|
-
result = shell(
|
273
|
+
# DeviceAPI::ADB.wifi(qualifier)
|
274
|
+
def self.wifi(qualifier)
|
275
|
+
result = shell(qualifier, 'dumpsys wifi | grep mNetworkInfo')
|
266
276
|
|
267
277
|
{:status => result.stdout.match("state:(.*?),")[1].strip, :access_point => result.stdout.match("extra:(.*?),")[1].strip.gsub(/"/,'')}
|
268
278
|
end
|
269
279
|
|
270
280
|
# Sends a key event to the specified device
|
271
|
-
# @param [String]
|
281
|
+
# @param [String] qualifier qualifier of device
|
272
282
|
# @param [String] keyevent keyevent to send to the device
|
273
|
-
def self.keyevent(
|
274
|
-
shell(
|
283
|
+
def self.keyevent(qualifier, keyevent)
|
284
|
+
shell(qualifier, "input keyevent #{keyevent}").stdout
|
275
285
|
end
|
276
286
|
|
277
287
|
# ADB Shell command
|
278
|
-
# @param [String]
|
288
|
+
# @param [String] qualifier qualifier of device
|
279
289
|
# @param [String] command command to execute
|
280
|
-
def self.shell(
|
281
|
-
result = execute("adb -s '#{
|
290
|
+
def self.shell(qualifier, command)
|
291
|
+
result = execute("adb -s '#{qualifier}' shell #{command}")
|
282
292
|
case result.stderr
|
283
293
|
when /^error: device unauthorized./
|
284
294
|
raise DeviceAPI::UnauthorizedDevice, result.stderr
|
@@ -292,55 +302,55 @@ module DeviceAPI
|
|
292
302
|
end
|
293
303
|
|
294
304
|
# Sends a swipe command to the specified device
|
295
|
-
# @param [String]
|
305
|
+
# @param [String] qualifier qualifier of the device
|
296
306
|
# @param [Hash] coords hash of coordinates to swipe from / to
|
297
307
|
# @option coords [String] :x_from (0) Coordinate to start from on the X axis
|
298
308
|
# @option coords [String] :x_to (0) Coordinate to end on on the X axis
|
299
309
|
# @option coords [String] :y_from (0) Coordinate to start from on the Y axis
|
300
310
|
# @option coords [String] :y_to (0) Coordinate to end on on the Y axis
|
301
|
-
def self.swipe(
|
302
|
-
shell(
|
311
|
+
def self.swipe(qualifier, coords = {x_from: 0, y_from: 0, x_to: 0, y_to: 0 })
|
312
|
+
shell(qualifier, "input swipe #{coords[:x_from]} #{coords[:y_from]} #{coords[:x_to]} #{coords[:y_to]}").stdout
|
303
313
|
end
|
304
314
|
|
305
315
|
# Starts intent using adb
|
306
316
|
# Returns stdout
|
307
|
-
# @param
|
317
|
+
# @param qualifier qualifier of device
|
308
318
|
# @param command -option activity
|
309
319
|
# @example
|
310
|
-
# DeviceAPI::ADB.am(
|
311
|
-
def self.am(
|
312
|
-
shell(
|
320
|
+
# DeviceAPI::ADB.am(qualifier, "start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings")
|
321
|
+
def self.am(qualifier, command)
|
322
|
+
shell(qualifier, "am #{command}").stdout
|
313
323
|
end
|
314
324
|
|
315
325
|
# Package manager commands
|
316
|
-
# @param
|
326
|
+
# @param qualifier qualifier of device
|
317
327
|
# @param command command to issue to the package manager
|
318
|
-
# @example DeviceAPI::ADB.pm(
|
319
|
-
def self.pm(
|
320
|
-
shell(
|
328
|
+
# @example DeviceAPI::ADB.pm(qualifier, 'list packages')
|
329
|
+
def self.pm(qualifier, command)
|
330
|
+
shell(qualifier, "pm #{command}").stdout
|
321
331
|
end
|
322
332
|
|
323
333
|
# Blocks a package, used on Android versions less than KitKat
|
324
334
|
# Returns boolean
|
325
|
-
# @param
|
335
|
+
# @param qualifier qualifier of device
|
326
336
|
# @param package to block
|
327
|
-
def self.block_package(
|
328
|
-
result = pm(
|
337
|
+
def self.block_package(qualifier, package)
|
338
|
+
result = pm(qualifier, "block #{package}")
|
329
339
|
result.include?('true')
|
330
340
|
end
|
331
341
|
|
332
342
|
# Blocks a package on KitKat and above
|
333
343
|
# Returns boolean
|
334
|
-
# @param
|
344
|
+
# @param qualifier qualifier of device
|
335
345
|
# @param package to hide
|
336
|
-
def self.hide_package(
|
337
|
-
result = pm(
|
346
|
+
def self.hide_package(qualifier, package)
|
347
|
+
result = pm(qualifier, "hide #{package}")
|
338
348
|
result.include?('true')
|
339
349
|
end
|
340
350
|
|
341
|
-
def self.check_ip_address(
|
342
|
-
unless
|
343
|
-
raise ADBCommandError.new("Invalid IP address and port #{
|
351
|
+
def self.check_ip_address(ip_address_and_port)
|
352
|
+
unless ip_address_and_port =~ /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):[0-9]+\Z/
|
353
|
+
raise ADBCommandError.new("Invalid IP address and port #{ip_address_and_port}")
|
344
354
|
end
|
345
355
|
end
|
346
356
|
end
|
@@ -9,6 +9,7 @@ module DeviceAPI
|
|
9
9
|
module Android
|
10
10
|
# Device class used for containing the accessors of the physical device information
|
11
11
|
class Device < DeviceAPI::Device
|
12
|
+
attr_reader :qualifier
|
12
13
|
|
13
14
|
@@subclasses; @@subclasses = {}
|
14
15
|
|
@@ -25,11 +26,22 @@ module DeviceAPI
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def initialize(options = {})
|
28
|
-
|
29
|
+
# For devices connected with USB, qualifier and serial are same
|
30
|
+
@qualifier = @serial = options[:serial]
|
29
31
|
@state = options[:state]
|
30
32
|
@remote = options[:remote] ? true : false
|
33
|
+
if is_remote?
|
34
|
+
set_ip_and_port
|
35
|
+
@serial = self.serial_no
|
36
|
+
end
|
31
37
|
end
|
32
38
|
|
39
|
+
def set_ip_and_port
|
40
|
+
address = @qualifier.split(":")
|
41
|
+
@ip_address = address.first
|
42
|
+
@port = address.last
|
43
|
+
end
|
44
|
+
|
33
45
|
def is_remote?
|
34
46
|
@remote || false
|
35
47
|
end
|
@@ -45,12 +57,21 @@ module DeviceAPI
|
|
45
57
|
'no permissions' => :no_permissions
|
46
58
|
}[@state]
|
47
59
|
end
|
60
|
+
|
61
|
+
def connect
|
62
|
+
ADB.connect(@ip_address, @port)
|
63
|
+
end
|
48
64
|
|
49
65
|
def disconnect
|
50
66
|
unless is_remote?
|
51
|
-
raise DeviceAPI::Android::DeviceDisconnectedWhenNotARemoteDevice.new("Asked to disconnect device #{
|
67
|
+
raise DeviceAPI::Android::DeviceDisconnectedWhenNotARemoteDevice.new("Asked to disconnect device #{qualifier} when it is not a remote device")
|
52
68
|
end
|
53
|
-
ADB.disconnect(
|
69
|
+
ADB.disconnect(@ip_address, @port)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Return whether device is connected or not
|
73
|
+
def is_connected?
|
74
|
+
ADB.devices.any? {|device| device.include? qualifier}
|
54
75
|
end
|
55
76
|
|
56
77
|
# Return the device range
|
@@ -63,6 +84,12 @@ module DeviceAPI
|
|
63
84
|
"#{device}_#{model}"
|
64
85
|
end
|
65
86
|
|
87
|
+
# Return the serial number of device
|
88
|
+
# @return (String) serial number
|
89
|
+
def serial_no
|
90
|
+
get_prop('ro.serialno')
|
91
|
+
end
|
92
|
+
|
66
93
|
# Return the device type
|
67
94
|
# @return (String) device type string
|
68
95
|
def device
|
@@ -101,9 +128,9 @@ module DeviceAPI
|
|
101
128
|
|
102
129
|
def block_package(package)
|
103
130
|
if version < "5.0.0"
|
104
|
-
ADB.block_package(
|
131
|
+
ADB.block_package(qualifier, package)
|
105
132
|
else
|
106
|
-
ADB.hide_package(
|
133
|
+
ADB.hide_package(qualifier, package)
|
107
134
|
end
|
108
135
|
end
|
109
136
|
|
@@ -163,7 +190,7 @@ module DeviceAPI
|
|
163
190
|
end
|
164
191
|
|
165
192
|
def list_installed_packages
|
166
|
-
packages = ADB.pm(
|
193
|
+
packages = ADB.pm(qualifier, 'list packages')
|
167
194
|
packages.split("\r\n")
|
168
195
|
end
|
169
196
|
|
@@ -180,13 +207,13 @@ module DeviceAPI
|
|
180
207
|
# Initiate monkey tests
|
181
208
|
# @param [Hash] args arguments to pass on to ADB.monkey
|
182
209
|
def monkey(args)
|
183
|
-
ADB.monkey(
|
210
|
+
ADB.monkey(qualifier, args)
|
184
211
|
end
|
185
212
|
|
186
213
|
# Capture screenshot on device
|
187
214
|
# @param [Hash] args arguments to pass on to ADB.screencap
|
188
215
|
def screenshot(args)
|
189
|
-
ADB.screencap(
|
216
|
+
ADB.screencap(qualifier, args)
|
190
217
|
end
|
191
218
|
|
192
219
|
# Get the IMEI number of the device
|
@@ -215,13 +242,13 @@ module DeviceAPI
|
|
215
242
|
|
216
243
|
# Unlock the device by sending a wakeup command
|
217
244
|
def unlock
|
218
|
-
ADB.keyevent(
|
245
|
+
ADB.keyevent(qualifier, '26') unless screen_on?
|
219
246
|
end
|
220
247
|
|
221
248
|
# Return the DPI of the attached device
|
222
249
|
# @return [String] DPI of attached device
|
223
250
|
def dpi
|
224
|
-
get_dpi(
|
251
|
+
get_dpi(qualifier)
|
225
252
|
end
|
226
253
|
|
227
254
|
# Return the device type based on the DPI
|
@@ -237,23 +264,23 @@ module DeviceAPI
|
|
237
264
|
# Returns wifi status and access point name
|
238
265
|
# @return [Hash] :status and :access_point
|
239
266
|
def wifi_status
|
240
|
-
ADB.wifi(
|
267
|
+
ADB.wifi(qualifier)
|
241
268
|
end
|
242
269
|
|
243
270
|
def battery_info
|
244
|
-
ADB.get_battery_info(
|
271
|
+
ADB.get_battery_info(qualifier)
|
245
272
|
end
|
246
273
|
|
247
274
|
# @param [String] command to start the intent
|
248
275
|
# Return the stdout of executed intent
|
249
276
|
# @return [String] stdout
|
250
277
|
def intent(command)
|
251
|
-
ADB.am(
|
278
|
+
ADB.am(qualifier, command)
|
252
279
|
end
|
253
280
|
|
254
281
|
#Reboots the device
|
255
282
|
def reboot
|
256
|
-
ADB.reboot(
|
283
|
+
ADB.reboot(qualifier)
|
257
284
|
end
|
258
285
|
|
259
286
|
# Returns disk status
|
@@ -264,12 +291,12 @@ module DeviceAPI
|
|
264
291
|
|
265
292
|
# Returns the device uptime
|
266
293
|
def uptime
|
267
|
-
ADB.get_uptime(
|
294
|
+
ADB.get_uptime(qualifier)
|
268
295
|
end
|
269
296
|
|
270
297
|
# Returns the Wifi IP address
|
271
298
|
def ip_address
|
272
|
-
interface = ADB.get_network_interface(
|
299
|
+
interface = ADB.get_network_interface(qualifier, 'wlan0')
|
273
300
|
if interface.match(/ip (.*) mask/)
|
274
301
|
Regexp.last_match[1]
|
275
302
|
elsif interface.match(/inet addr:(.*)\s+Bcast/)
|
@@ -281,7 +308,7 @@ module DeviceAPI
|
|
281
308
|
|
282
309
|
# Returns the Wifi mac address
|
283
310
|
def wifi_mac_address
|
284
|
-
interface = ADB.get_network_interface(
|
311
|
+
interface = ADB.get_network_interface(qualifier, 'wlan0')
|
285
312
|
if interface.match(/HWaddr (.*)/)
|
286
313
|
Regexp.last_match[1].strip
|
287
314
|
else
|
@@ -294,21 +321,21 @@ module DeviceAPI
|
|
294
321
|
private
|
295
322
|
|
296
323
|
def get_network_info
|
297
|
-
ADB.get_network_info(
|
324
|
+
ADB.get_network_info(qualifier)
|
298
325
|
end
|
299
326
|
|
300
327
|
def get_disk_info
|
301
|
-
@diskstat = DeviceAPI::Android::Plugin::Disk.new(
|
328
|
+
@diskstat = DeviceAPI::Android::Plugin::Disk.new(qualifier: qualifier) unless @diskstat
|
302
329
|
@diskstat.process_stats
|
303
330
|
end
|
304
331
|
|
305
332
|
def get_battery_info
|
306
|
-
@battery = DeviceAPI::Android::Plugin::Battery.new(
|
333
|
+
@battery = DeviceAPI::Android::Plugin::Battery.new(qualifier: qualifier) unless @battery
|
307
334
|
@battery
|
308
335
|
end
|
309
336
|
|
310
337
|
def get_memory_info
|
311
|
-
@memory = DeviceAPI::Android::Plugin::Memory.new(
|
338
|
+
@memory = DeviceAPI::Android::Plugin::Memory.new(qualifier: qualifier) unless @memory
|
312
339
|
@memory
|
313
340
|
end
|
314
341
|
|
@@ -321,34 +348,34 @@ module DeviceAPI
|
|
321
348
|
|
322
349
|
def get_prop(key)
|
323
350
|
if !@props || !@props[key]
|
324
|
-
@props = ADB.getprop(
|
351
|
+
@props = ADB.getprop(qualifier)
|
325
352
|
end
|
326
353
|
@props[key]
|
327
354
|
end
|
328
355
|
|
329
356
|
def get_dumpsys(key)
|
330
|
-
@props = ADB.getdumpsys(
|
357
|
+
@props = ADB.getdumpsys(qualifier)
|
331
358
|
@props[key]
|
332
359
|
end
|
333
360
|
|
334
361
|
def get_powerinfo
|
335
|
-
ADB.getpowerinfo(
|
362
|
+
ADB.getpowerinfo(qualifier)
|
336
363
|
end
|
337
364
|
|
338
365
|
def get_phoneinfo
|
339
|
-
ADB.getphoneinfo(
|
366
|
+
ADB.getphoneinfo(qualifier)
|
340
367
|
end
|
341
368
|
|
342
369
|
def install_apk(apk)
|
343
|
-
ADB.install_apk(apk: apk,
|
370
|
+
ADB.install_apk(apk: apk, qualifier: qualifier)
|
344
371
|
end
|
345
372
|
|
346
373
|
def uninstall_apk(package_name)
|
347
|
-
ADB.uninstall_apk(package_name: package_name,
|
374
|
+
ADB.uninstall_apk(package_name: package_name, qualifier: qualifier)
|
348
375
|
end
|
349
376
|
|
350
377
|
def get_dpi
|
351
|
-
ADB.get_device_dpi(
|
378
|
+
ADB.get_device_dpi(qualifier)
|
352
379
|
end
|
353
380
|
end
|
354
381
|
|
@@ -6,11 +6,12 @@ module DeviceAPI
|
|
6
6
|
# you can unlock that device by broadcasting a 'WakeUp' intent. On Kindle devices, this does not
|
7
7
|
# work due to Amazons implementation of the Keyguard.
|
8
8
|
def unlock
|
9
|
-
ADB.keyevent(
|
9
|
+
ADB.keyevent(qualifier, '26') unless screen_on?
|
10
10
|
if orientation == :landscape
|
11
|
-
ADB.swipe(
|
11
|
+
ADB.swipe(qualifier, { x_from: 500, y_from: 750, x_to: 500, y_to: 250 } ) if version.split('.').first.to_i >= 5
|
12
|
+
ADB.swipe(qualifier, { x_from: 900, y_from: 500, x_to: 300, y_to: 500 } ) if version.split('.').first.to_i < 5
|
12
13
|
else
|
13
|
-
ADB.swipe(
|
14
|
+
ADB.swipe(qualifier, { x_from: 300, y_from: 900, x_to: 300, y_to: 600 } )
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
@@ -3,14 +3,14 @@ module DeviceAPI
|
|
3
3
|
module Plugin
|
4
4
|
class Audio
|
5
5
|
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :qualifier
|
7
7
|
|
8
8
|
def initialize(options)
|
9
|
-
@
|
9
|
+
@qualifier = options #[:serial]
|
10
10
|
end
|
11
11
|
|
12
12
|
def get_volume_steps
|
13
|
-
audio = ADB.dumpsys( @
|
13
|
+
audio = ADB.dumpsys( @qualifier, 'audio' )
|
14
14
|
vol_steps = audio.detect { |a| a.include?('volume steps:') }
|
15
15
|
return nil if vol_steps.nil?
|
16
16
|
|
@@ -58,12 +58,12 @@ module DeviceAPI
|
|
58
58
|
|
59
59
|
def change_volume(op, key)
|
60
60
|
op.times do
|
61
|
-
ADB.keyevent(@
|
61
|
+
ADB.keyevent(@qualifier, key )
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
def get_system_volume
|
66
|
-
audio = ADB.dumpsys( @
|
66
|
+
audio = ADB.dumpsys( @qualifier, 'audio' )
|
67
67
|
index = audio.index('- STREAM_SYSTEM:')
|
68
68
|
|
69
69
|
return nil if index.nil?
|
@@ -5,8 +5,8 @@ module DeviceAPI
|
|
5
5
|
attr_reader :current_temp, :max_temp, :max_current, :voltage, :level, :health, :status
|
6
6
|
|
7
7
|
def initialize(options = {})
|
8
|
-
|
9
|
-
props = ADB.get_battery_info(
|
8
|
+
qualifier = options[:qualifier]
|
9
|
+
props = ADB.get_battery_info(qualifier)
|
10
10
|
@current_temp = props["temperature"]
|
11
11
|
@max_temp = props["mBatteryMaxTemp"]
|
12
12
|
@max_current = props["mBatteryMaxCurrent"]
|
@@ -3,14 +3,14 @@ module DeviceAPI
|
|
3
3
|
module Plugin
|
4
4
|
class Disk
|
5
5
|
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :qualifier
|
7
7
|
def initialize(options = {})
|
8
|
-
@
|
8
|
+
@qualifier = options[:qualifier]
|
9
9
|
end
|
10
10
|
|
11
11
|
def process_stats(options = {})
|
12
12
|
disk_info = {}
|
13
|
-
stats = options[:data] || ADB.dumpsys(@
|
13
|
+
stats = options[:data] || ADB.dumpsys(@qualifier, 'diskstats')
|
14
14
|
stats.each do |stat|
|
15
15
|
if /(.*)-.*:\s(.*)\s\/\s([0-9]*[A-Z])\s[a-z]*\s=\s([0-9]*%)/.match(stat)
|
16
16
|
disk_info["#{Regexp.last_match[1].downcase}_total"] = Regexp.last_match[3]
|
@@ -31,8 +31,8 @@ module DeviceAPI
|
|
31
31
|
attr_accessor :processes, :mem_info
|
32
32
|
|
33
33
|
def initialize(options = {})
|
34
|
-
@
|
35
|
-
info = options[:data] || ADB.dumpsys(@
|
34
|
+
@qualifier = options[:qualifier]
|
35
|
+
info = options[:data] || ADB.dumpsys(@qualifier, 'meminfo')
|
36
36
|
process_data(info)
|
37
37
|
end
|
38
38
|
|
@@ -46,7 +46,7 @@ module DeviceAPI
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def update
|
49
|
-
meminfo = ADB.dumpsys(@
|
49
|
+
meminfo = ADB.dumpsys(@qualifier, 'meminfo')
|
50
50
|
process_data(meminfo)
|
51
51
|
end
|
52
52
|
|
@@ -54,6 +54,7 @@ module DeviceAPI
|
|
54
54
|
# @param [String] apk_path full path to apk to check
|
55
55
|
# @return returns false if the apk is unsigned, true if it is signed
|
56
56
|
def self.is_apk_signed?(apk_path)
|
57
|
+
raise SigningCommandError.new('AAPT not available') unless DeviceAPI::Android::AAPT.aapt_available?
|
57
58
|
result = execute("aapt list #{apk_path} | grep '^META-INF\/.*'")
|
58
59
|
return false if result.stdout.empty?
|
59
60
|
true
|
@@ -63,6 +64,7 @@ module DeviceAPI
|
|
63
64
|
# @param [String] apk_path full path to the apk
|
64
65
|
# @return [Boolean, Exception] returns true if the apk is successfully unsigned, otherwise an exception is raised
|
65
66
|
def self.unsign_apk(apk_path)
|
67
|
+
raise SigningCommandError.new('AAPT not available') unless DeviceAPI::Android::AAPT.aapt_available?
|
66
68
|
file_list = execute("aapt list #{apk_path} | grep '^META-INF\/.*'")
|
67
69
|
result = execute("aapt remove #{apk_path} #{file_list.stdout.split(/\s+/).join(' ')}")
|
68
70
|
raise SigningCommandError.new(result.stderr) if result.exit != 0
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: device_api-android
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Buckhurst
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2016-
|
14
|
+
date: 2016-10-03 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: device_api
|
@@ -79,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
79
|
version: '0'
|
80
80
|
requirements: []
|
81
81
|
rubyforge_project:
|
82
|
-
rubygems_version: 2.
|
82
|
+
rubygems_version: 2.5.1
|
83
83
|
signing_key:
|
84
84
|
specification_version: 4
|
85
85
|
summary: Android Device Management API
|