Introduce command handlers for adb and aapt
Change-Id: I76e79405e3a6ff5efeeded3ff8c47e3d70f48cc0
diff --git a/deploy.py b/deploy.py
index d70e26d..590e150 100755
--- a/deploy.py
+++ b/deploy.py
@@ -1,13 +1,119 @@
#!/usr/bin/env python3
+import os
import time
from uiautomator import Device
import sys
import subprocess
import pathlib
+
+PREBUILTS_PATH = '../../vendor/smartviser/viser/prebuilts/apk'
+
+PREBUILT_APKS = [
+ 'com.smartviser.demogame.apk',
+ 'com.lunarlabs.panda.proxy.apk',
+ 'com.lunarlabs.panda.apk',
+]
+
+
+def adb(*args, serial = None):
+ """Run ADB command attached to serial.
+
+ Example:
+ >>> process = adb('shell', 'getprop', 'ro.build.fingerprint', serial='cc60c021')
+ >>> process.returncode
+ 0
+ >>> process.stdout.strip()
+ 'Fairphone/FP2/FP2:6.0.1/FP2-gms-18.02.0/FP2-gms-18.02.0:user/release-keys'
+
+ :param *args:
+ List of options to ADB (including command).
+ :param str serial:
+ Identifier for ADB connection to device.
+ :returns subprocess.CompletedProcess:
+ Completed process.
+ """
+
+ # Make sure the adb server is started to avoid the infamous "out of date"
+ # message that pollutes stdout.
+ subprocess.run(
+ ['adb', 'start-server'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ universal_newlines=True)
+
+ command = ['adb']
+ if serial:
+ command += ['-s', serial]
+ if args:
+ command += list(args)
+ return subprocess.run(
+ command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ universal_newlines=True)
+
+
+def aapt(*args):
+ """Run an AAPT command.
+
+ :param *args:
+ The AAPT command with its options.
+ :returns subprocess.CompletedProcess:
+ Completed process.
+ """
+ command = ['aapt']
+ if args:
+ command += list(args)
+ return subprocess.run(
+ command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ universal_newlines=True)
+
+
+def uninstall_apk(serial, filename, prebuilts_dir):
+ """Uninstall apk from prebuilts_dir on device."""
+ ret = aapt('dump', 'badging', '{}/{}'.format(prebuilts_dir, filename))
+ if 0 < ret.returncode:
+ print('Could retrieve app `{}` info, error was: {}'.format(
+ filename, ret.stderr), file=sys.stderr)
+ else:
+ package = None
+ for line in ret.stdout.splitlines():
+ if line.startswith('package'):
+ for token in line.split(' '):
+ if token.startswith('name='):
+ # Extract the package name out of the token
+ # (name='some.package.name')
+ package = token[6:-1]
+ break
+ if not package:
+ print('Could not find package of app `{}`'.format(filename),
+ file=sys.stderr)
+ else:
+ print('Uninstalling `{}`'.format(package))
+ ret = adb('uninstall', package, serial=serial)
+ if 0 < ret.returncode:
+ print('Could not uninstall app `{}`, error was: {}'.format(
+ filename, ret.stderr), file=sys.stderr)
+ else:
+ print('App `{}` uninstalled.'.format(filename))
+
+
+def install_apk(serial, filename, prebuilts_dir):
+ """Install apk from prebuilts_dir on device."""
+ print('Installing {}.'.format(filename))
+ path = os.path.join(prebuilts_dir, filename)
+ ret = adb('install', '-r', path, serial=serial)
+ if 0 < ret.returncode:
+ print('Could not install app `{}`, error was: {}'.format(
+ filename, ret.stderr), file=sys.stderr)
+ else:
+ print('App `{}` installed.'.format(filename))
+
+
# Prepare the DUT
-def prepare_dut(serial, scenarios_dir, data_dir, apps):
+def prepare_dut(serial, scenarios_dir, data_dir, prebuilts_dir):
+ # Uninstall the smartviser apps
+ for app in PREBUILT_APKS:
+ uninstall_apk(serial, app, prebuilts_dir)
+
# Copy the scenarios
ret = subprocess.run(['adb', '-s', serial, 'push', scenarios_dir,
'/sdcard/viser'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
@@ -29,15 +135,9 @@
print('Scenarios data pushed.')
# Install the smartviser apps
- for app in apps:
- ret = subprocess.run(['adb', '-s', serial, 'install', '-r', app],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- universal_newlines=True)
- if 0 < ret.returncode:
- print('Could not install app `{}`, error was: {}'.format(app,
- ret.stderr), file=sys.stderr)
- else:
- print('App `{}` installed.'.format(app))
+ for app in PREBUILT_APKS:
+ install_apk(serial, app, prebuilts_dir)
+
# Grant the permissions through the UI
def configure_perms(dut):
@@ -143,11 +243,7 @@
dut = Device(serial)
# Push the scenarios, their data, and install the apps
- prepare_dut(serial, '../scenarios', '../scenarios-data', [
- '../../vendor/smartviser/viser/prebuilts/apk/com.smartviser.demogame.apk',
- '../../vendor/smartviser/viser/prebuilts/apk/com.lunarlabs.panda.proxy.apk',
- '../../vendor/smartviser/viser/prebuilts/apk/com.lunarlabs.panda.apk'
- ])
+ prepare_dut(serial, '../scenarios', '../scenarios-data', PREBUILTS_PATH)
# Start the viser app
ret = subprocess.run(['adb', '-s', serial, 'shell', 'monkey', '-p',