device_api-android 1.2.9 → 1.2.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|