Class: DeviceAPI::Android::ADB
- Inherits:
-
Execution
- Object
- Execution
- DeviceAPI::Android::ADB
- Defined in:
- lib/device_api/android/adb.rb
Overview
Namespace for all methods encapsulating adb calls
Class Method Summary collapse
-
.am(qualifier, command) ⇒ Object
Starts intent using adb Returns stdout DeviceAPI::ADB.am(qualifier, “start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings”).
-
.block_package(qualifier, package) ⇒ Object
Blocks a package, used on Android versions less than KitKat Returns boolean.
- .change_apk(options = {}) ⇒ Object
- .check_ip_address(ip_address_and_port) ⇒ Object
-
.connect(ip_address, port = 5555) ⇒ Object
Connects to remote android device.
-
.devices ⇒ Array
Returns an array representing connected devices DeviceAPI::ADB.devices #=> { ‘1232132’ => ‘device’ }.
-
.disconnect(ip_address, port = 5555) ⇒ Object
Disconnects from remote android device.
-
.dumpsys(qualifier, command) ⇒ Array
Returns the ‘dumpsys’ information from the specified device.
-
.get_battery_info(qualifier) ⇒ Hash
Get the ‘battery’ information from dumpsys.
- .get_device_dpi(qualifier) ⇒ Object
-
.get_network_info(qualifier) ⇒ Object
Get the network information.
- .get_network_interface(qualifier, interface) ⇒ Object
-
.get_state(qualifier) ⇒ String
Retrieve device state for a single device.
-
.get_uptime(qualifier) ⇒ Float
Returns the uptime of the specified device.
-
.getdumpsys(qualifier) ⇒ Hash
Get the ‘input’ information from dumpsys.
-
.getphoneinfo(qualifier) ⇒ Hash
Get the ‘iphonesubinfo’ from dumpsys.
-
.getpowerinfo(qualifier) ⇒ Hash
Get the ‘power’ information from dumpsys.
-
.getprop(qualifier) ⇒ Hash
Get the properties of a specified device.
-
.hide_package(qualifier, package) ⇒ Object
Blocks a package on KitKat and above Returns boolean.
-
.install_apk(options = {}) ⇒ String
Installs a specified apk to a specific device.
-
.keyevent(qualifier, keyevent) ⇒ Object
Sends a key event to the specified device.
-
.monkey(qualifier, args) ⇒ Object
Runs monkey testing.
-
.pm(qualifier, command) ⇒ Object
Package manager commands.
-
.process_dumpsys(regex_string, data) ⇒ Hash
Processes the results from dumpsys to format them into a hash.
-
.reboot(qualifier, remote) ⇒ nil
Reboots the specified device Remote devices are rebooted and disconnected from system.
-
.screencap(qualifier, args) ⇒ Object
Take a screenshot from the device.
-
.shell(qualifier, command) ⇒ Object
ADB Shell command.
-
.swipe(qualifier, coords = {x_from: 0, y_from: 0, x_to: 0, y_to: 0 }) ⇒ Object
Sends a swipe command to the specified device.
-
.uninstall_apk(options = {}) ⇒ String
Uninstalls a specified package from a specified device.
-
.wifi(qualifier) ⇒ Object
Returns wifi status and access point name.
Class Method Details
.am(qualifier, command) ⇒ Object
Starts intent using adb Returns stdout DeviceAPI::ADB.am(qualifier, “start -a android.intent.action.MAIN -n com.android.settings/.wifi.WifiSettings”)
335 336 337 |
# File 'lib/device_api/android/adb.rb', line 335 def self.am(qualifier, command) shell(qualifier, "am #{command}").stdout end |
.block_package(qualifier, package) ⇒ Object
Blocks a package, used on Android versions less than KitKat Returns boolean
351 352 353 354 |
# File 'lib/device_api/android/adb.rb', line 351 def self.block_package(qualifier, package) result = pm(qualifier, "block #{package}") result.include?('true') end |
.change_apk(options = {}) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/device_api/android/adb.rb', line 149 def self.change_apk( = {}) package_name = [:package_name] apk = [:apk] qualifier = [:qualifier] action = [:action] case action when :install command = "adb -s #{qualifier} install #{apk}" when :uninstall command = "adb -s #{qualifier} uninstall #{package_name}" else raise ADBCommandError.new('No action specified') end result = execute(command) raise ADBCommandError.new(result.stderr) if result.exit != 0 lines = result.stdout.split("\n").map { |line| line.strip } lines.last end |
.check_ip_address(ip_address_and_port) ⇒ Object
365 366 367 368 369 |
# File 'lib/device_api/android/adb.rb', line 365 def self.check_ip_address(ip_address_and_port) unless ip_address_and_port =~ /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):[0-9]+\Z/ raise ADBCommandError.new("Invalid IP address and port #{ip_address_and_port}") end end |
.connect(ip_address, port = 5555) ⇒ Object
Connects to remote android device
255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/device_api/android/adb.rb', line 255 def self.connect(ip_address, port=5555) ip_address_and_port = "#{ip_address}:#{port}" check_ip_address(ip_address_and_port) cmd = "adb connect #{ip_address_and_port}" result = execute(cmd) if result.stdout.to_s =~ /.*already connected to.*/ raise DeviceAlreadyConnectedError.new("Device #{ip_address_and_port} already connected") else unless result.stdout.to_s =~ /.*connected to.*/ raise ADBCommandError.new("Unable to adb connect to #{ip_address_and_port} result was: #{result.stdout}") end end end |
.devices ⇒ Array
Returns an array representing connected devices DeviceAPI::ADB.devices #=> { ‘1232132’ => ‘device’ }
17 18 19 20 21 22 |
# File 'lib/device_api/android/adb.rb', line 17 def self.devices result = execute_with_timeout_and_retry('adb devices') raise ADBCommandError.new(result.stderr) if result.exit != 0 result.stdout.scan(/(.*)\t(.*)/).map { |a,b| {a => b}} end |
.disconnect(ip_address, port = 5555) ⇒ Object
Disconnects from remote android device
274 275 276 277 278 279 280 281 282 |
# File 'lib/device_api/android/adb.rb', line 274 def self.disconnect(ip_address, port=5555) ip_address_and_port = "#{ip_address}:#{port}" check_ip_address(ip_address_and_port) cmd = "adb disconnect #{ip_address_and_port}" result = execute(cmd) unless result.exit == 0 raise ADBCommandError.new("Unable to adb disconnect to #{ip_address_and_port} result was: #{result.stdout}") end end |
.dumpsys(qualifier, command) ⇒ Array
Returns the ‘dumpsys’ information from the specified device
124 125 126 127 |
# File 'lib/device_api/android/adb.rb', line 124 def self.dumpsys(qualifier, command) result = shell(qualifier, "dumpsys #{command}") result.stdout.split("\n").map { |line| line.strip } end |
.get_battery_info(qualifier) ⇒ Hash
Get the ‘battery’ information from dumpsys
67 68 69 70 |
# File 'lib/device_api/android/adb.rb', line 67 def self.get_battery_info(qualifier) lines = dumpsys(qualifier, 'battery') process_dumpsys('(.*):\s+(.*)', lines) end |
.get_device_dpi(qualifier) ⇒ Object
110 111 112 113 114 115 116 117 118 119 |
# File 'lib/device_api/android/adb.rb', line 110 def self.get_device_dpi(qualifier) lines = dumpsys(qualifier, 'window') dpi = nil lines.each do |line| if /sw(\d*)dp/.match(line) dpi = Regexp.last_match[1] end end dpi end |
.get_network_info(qualifier) ⇒ Object
Get the network information
78 79 80 81 82 83 84 |
# File 'lib/device_api/android/adb.rb', line 78 def self.get_network_info(qualifier) lines = shell(qualifier, 'netcfg') lines.stdout.split("\n").map do |a| b = a.split(" ") { name: b[0], ip: b[2].split('/')[0], mac: b[4] } end end |
.get_network_interface(qualifier, interface) ⇒ Object
72 73 74 75 |
# File 'lib/device_api/android/adb.rb', line 72 def self.get_network_interface(qualifier, interface) result = shell(qualifier, "ifconfig #{interface}") result.stdout end |
.get_state(qualifier) ⇒ String
Retrieve device state for a single device
27 28 29 30 31 32 33 34 35 |
# File 'lib/device_api/android/adb.rb', line 27 def self.get_state(qualifier) result = execute('adb -s #{qualifier} get-state') raise ADBCommandError.new(result.stderr) if result.exit != 0 lines = result.stdout.split("\n") /(.*)/.match(lines.last) Regexp.last_match[0].strip end |
.get_uptime(qualifier) ⇒ Float
Returns the uptime of the specified device
176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/device_api/android/adb.rb', line 176 def self.get_uptime(qualifier) result = shell(qualifier, 'cat /proc/uptime') lines = result.stdout.split("\n") uptime = 0 lines.each do |l| if /([\d.]*)\s+[\d.]*/.match(l) uptime = Regexp.last_match[0].to_f.round end end uptime end |
.getdumpsys(qualifier) ⇒ Hash
Get the ‘input’ information from dumpsys
51 52 53 54 |
# File 'lib/device_api/android/adb.rb', line 51 def self.getdumpsys(qualifier) lines = dumpsys(qualifier, 'input') process_dumpsys('(.*):\s+(.*)', lines) end |
.getphoneinfo(qualifier) ⇒ Hash
Get the ‘iphonesubinfo’ from dumpsys
59 60 61 62 |
# File 'lib/device_api/android/adb.rb', line 59 def self.getphoneinfo(qualifier) lines = dumpsys(qualifier, 'iphonesubinfo') process_dumpsys('(.*) =\s+(.*)', lines) end |
.getpowerinfo(qualifier) ⇒ Hash
Get the ‘power’ information from dumpsys
105 106 107 108 |
# File 'lib/device_api/android/adb.rb', line 105 def self.getpowerinfo(qualifier) lines = dumpsys(qualifier, 'power') process_dumpsys('(.*)=(.*)', lines) end |
.getprop(qualifier) ⇒ Hash
Get the properties of a specified device
40 41 42 43 44 45 46 |
# File 'lib/device_api/android/adb.rb', line 40 def self.getprop(qualifier) result = shell(qualifier, 'getprop') lines = result.stdout.encode('UTF-16', 'UTF-8', invalid: :replace, replace: '').encode('UTF-8', 'UTF-16').split("\n") process_dumpsys('\[(.*)\]:\s+\[(.*)\]', lines) end |
.hide_package(qualifier, package) ⇒ Object
Blocks a package on KitKat and above Returns boolean
360 361 362 363 |
# File 'lib/device_api/android/adb.rb', line 360 def self.hide_package(qualifier, package) result = pm(qualifier, "hide #{package}") result.include?('true') end |
.install_apk(options = {}) ⇒ String
Installs a specified apk to a specific device
134 135 136 137 |
# File 'lib/device_api/android/adb.rb', line 134 def self.install_apk( = {}) [:action] = :install change_apk() end |
.keyevent(qualifier, keyevent) ⇒ Object
Sends a key event to the specified device
297 298 299 |
# File 'lib/device_api/android/adb.rb', line 297 def self.keyevent(qualifier, keyevent) shell(qualifier, "input keyevent #{keyevent}").stdout end |
.monkey(qualifier, args) ⇒ Object
Runs monkey testing
216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/device_api/android/adb.rb', line 216 def self.monkey(qualifier, args) events = args[:events] || 10000 package = args[:package] or raise "package name not provided (:package => 'bbc.iplayer')" seed = args[:seed] throttle = args[:throttle] cmd = "monkey -p #{package} -v #{events}" cmd = cmd + " -s #{seed}" if seed cmd = cmd + " -t #{throttle}" if throttle shell(qualifier, cmd) end |
.pm(qualifier, command) ⇒ Object
Package manager commands
343 344 345 |
# File 'lib/device_api/android/adb.rb', line 343 def self.pm(qualifier, command) shell(qualifier, "pm #{command}").stdout end |
.process_dumpsys(regex_string, data) ⇒ Hash
Processes the results from dumpsys to format them into a hash
90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/device_api/android/adb.rb', line 90 def self.process_dumpsys(regex_string, data) props = {} regex = Regexp.new(regex_string) data.each do |line| if regex.match(line) props[Regexp.last_match[1]] = Regexp.last_match[2] end end props end |
.reboot(qualifier, remote) ⇒ nil
Reboots the specified device Remote devices are rebooted and disconnected from system
193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/device_api/android/adb.rb', line 193 def self.reboot(qualifier, remote) if remote begin system("adb -s #{qualifier} reboot &") self.disconnect(qualifier.split(":").first) rescue => e raise ADBCommandError.new(e) end else result = execute("adb -s #{qualifier} reboot && adb -s #{qualifier} wait-for-device shell 'while [[ $(getprop dev.bootcomplete | tr -d '\r') != 1 ] ]; do sleep 1; printf .; done'") raise ADBCommandError.new(result.stderr) if result.exit != 0 end end |
.screencap(qualifier, args) ⇒ Object
Take a screenshot from the device
236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/device_api/android/adb.rb', line 236 def self.screencap( qualifier, args ) filename = args[:filename] or raise "filename not provided (:filename => '/tmp/myfile.png')" if getprop(qualifier)['ro.build.version.release'].to_i < 7 convert_carriage_returns = %q{perl -pe 's/\x0D\x0A/\x0A/g'} cmd = "screencap -p | #{convert_carriage_returns} > #{filename}" else cmd = "screencap -p > #{filename}" end shell(qualifier, cmd) end |
.shell(qualifier, command) ⇒ Object
ADB Shell command
304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/device_api/android/adb.rb', line 304 def self.shell(qualifier, command) result = execute("adb -s '#{qualifier}' shell #{command}") case result.stderr when /^error: device unauthorized./ raise DeviceAPI::UnauthorizedDevice, result.stderr when /^error: device not found/ raise DeviceAPI::DeviceNotFound, result.stderr else raise ADBCommandError.new(result.stderr) end if result.exit != 0 result end |
.swipe(qualifier, coords = {x_from: 0, y_from: 0, x_to: 0, y_to: 0 }) ⇒ Object
Sends a swipe command to the specified device
325 326 327 |
# File 'lib/device_api/android/adb.rb', line 325 def self.swipe(qualifier, coords = {x_from: 0, y_from: 0, x_to: 0, y_to: 0 }) shell(qualifier, "input swipe #{coords[:x_from]} #{coords[:y_from]} #{coords[:x_to]} #{coords[:y_to]}").stdout end |
.uninstall_apk(options = {}) ⇒ String
Uninstalls a specified package from a specified device
144 145 146 147 |
# File 'lib/device_api/android/adb.rb', line 144 def self.uninstall_apk( = {}) [:action] = :uninstall change_apk() end |
.wifi(qualifier) ⇒ Object
Returns wifi status and access point name
288 289 290 291 292 |
# File 'lib/device_api/android/adb.rb', line 288 def self.wifi(qualifier) result = shell(qualifier, 'dumpsys wifi | grep mNetworkInfo') {:status => result.stdout.match("state:(.*?),")[1].strip, :access_point => result.stdout.match("extra:(.*?),")[1].strip.gsub(/"/,'')} end |