Apply the toolchain

Issue: INFRA-228
Change-Id: Ie271954879f0b8f645929f9dd6402a4742ef0135
diff --git a/deploy.py b/deploy.py
index a245d19..a0a0b98 100755
--- a/deploy.py
+++ b/deploy.py
@@ -1,62 +1,54 @@
 #!/usr/bin/env python3
 
 import os
-import time
-from uiautomator import Device
-import re
-import sys
-import subprocess
 import pathlib
+import re
+import subprocess
+import sys
+import time
+
+from uiautomator import Device
+
+VWS_CREDENTIALS = {"user": "fairphonetesting@gmail.com", "password": "aish3echi:uwaiSh"}
 
 
-VWS_CREDENTIALS = {
-    'user': 'fairphonetesting@gmail.com',
-    'password': 'aish3echi:uwaiSh'
-}
+PREBUILTS_PATH = "../../vendor/smartviser/viser/prebuilts/apk"
 
+PREBUILT_PROXY_APK_PATTERN = "com.lunarlabs.panda.proxy-latest-sdk{sdk}-{flavour}.apk"
 
-PREBUILTS_PATH = '../../vendor/smartviser/viser/prebuilts/apk'
-
-PREBUILT_PROXY_APK_PATTERN = (
-    'com.lunarlabs.panda.proxy-latest-sdk{sdk}-{flavour}.apk')
-
-PREBUILT_APKS = [
-    'com.smartviser.demogame-latest.apk',
-    'com.lunarlabs.panda-latest.apk',
-]
+PREBUILT_APKS = ["com.smartviser.demogame-latest.apk", "com.lunarlabs.panda-latest.apk"]
 
 FAIRPHONE_WIFI_NETWORKS = {
-    'Fairphone Guest': {'security': 'WPA/WPA2 PSK', 'password': 'fairwifi'},
-    'Fairphone DEV (2.4 GHz)': {
-        'security': 'WPA/WPA2 PSK', 'password': 'fdev@adm'},
-    'Fairphone DEV (5 GHz)': {
-        'security': 'WPA/WPA2 PSK', 'password': 'fdev@adm'},
+    "Fairphone Guest": {"security": "WPA/WPA2 PSK", "password": "fairwifi"},
+    "Fairphone DEV (2.4 GHz)": {"security": "WPA/WPA2 PSK", "password": "fdev@adm"},
+    "Fairphone DEV (5 GHz)": {"security": "WPA/WPA2 PSK", "password": "fdev@adm"},
 }
 
-ADB_DEVICES_PATTERN = re.compile(r'^([a-z0-9-]+)\s+device$', flags=re.M)
+ADB_DEVICES_PATTERN = re.compile(r"^([a-z0-9-]+)\s+device$", flags=re.M)
 
 
 class HostCommandError(BaseException):
     """An error happened while issuing a command on the host."""
+
     def __init__(self, command, error_message):
         self.command = command
         self.error_message = error_message
-        message = 'Command `{}` failed: {}'.format(command, error_message)
+        message = "Command `{}` failed: {}".format(command, error_message)
         super(HostCommandError, self).__init__(message)
 
 
 class DeviceCommandError(BaseException):
     """An error happened while sending a command to a device."""
+
     def __init__(self, serial, command, error_message):
         self.serial = serial
         self.command = command
         self.error_message = error_message
-        message = 'Command `{}` failed on {}: {}'.format(
-            command, serial, error_message)
+        message = "Command `{}` failed on {}: {}".format(command, serial, error_message)
         super(DeviceCommandError, self).__init__(message)
 
 
-def adb(*args, serial = None, raise_on_error = True):
+def adb(*args, serial=None, raise_on_error=True):
     """Run ADB command attached to serial.
 
     Example:
@@ -82,27 +74,28 @@
     # Make sure the adb server is started to avoid the infamous "out of date"
     # message that pollutes stdout.
     ret = subprocess.run(
-        ['adb', 'start-server'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-        universal_newlines=True)
+        ["adb", "start-server"],
+        stdout=subprocess.PIPE,
+        stderr=subprocess.PIPE,
+        universal_newlines=True,
+    )
     if ret.returncode < 0:
         if raise_on_error:
-            raise DeviceCommandError(
-                serial if serial else '??', str(args), ret.stderr)
+            raise DeviceCommandError(serial if serial else "??", str(args), ret.stderr)
         else:
             return None
 
-    command = ['adb']
+    command = ["adb"]
     if serial:
-        command += ['-s', serial]
+        command += ["-s", serial]
     if args:
         command += list(args)
     ret = subprocess.run(
-        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-        universal_newlines=True)
+        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
+    )
 
     if raise_on_error and ret.returncode < 0:
-        raise DeviceCommandError(
-            serial if serial else '??', str(args), ret.stderr)
+        raise DeviceCommandError(serial if serial else "??", str(args), ret.stderr)
 
     return ret
 
@@ -113,11 +106,11 @@
     Raises:
         DeviceCommandError: If the underlying adb command failed.
     """
-    process = adb('devices')
+    process = adb("devices")
     return ADB_DEVICES_PATTERN.findall(process.stdout)
 
 
-def aapt(*args, raise_on_error = True):
+def aapt(*args, raise_on_error=True):
     """Run an AAPT command.
 
     :param *args:
@@ -130,12 +123,12 @@
     :raises HostCommandError:
         If the command failed.
     """
-    command = ['aapt']
+    command = ["aapt"]
     if args:
         command += list(args)
     ret = subprocess.run(
-        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-        universal_newlines=True)
+        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
+    )
 
     if raise_on_error and ret.returncode < 0:
         raise HostCommandError(str(args), ret.stderr)
@@ -149,8 +142,11 @@
     Raises:
         DeviceCommandError: If the underlying adb command failed.
     """
-    adb('shell', 'svc power stayon {}'.format(
-        'true' if always else 'false'), serial=serial)
+    adb(
+        "shell",
+        "svc power stayon {}".format("true" if always else "false"),
+        serial=serial,
+    )
 
 
 def unlock(dut):
@@ -159,15 +155,15 @@
     Raises:
         DeviceCommandError: If the underlying adb commands failed.
     """
-    if not dut.info['screenOn']:
-        adb('shell', 'input keyevent KEYCODE_POWER', serial=dut.serial)
+    if not dut.info["screenOn"]:
+        adb("shell", "input keyevent KEYCODE_POWER", serial=dut.serial)
         time.sleep(1)
     # The KEYCODE_MENU input is enough to unlock a "swipe up to unlock"
     # lockscreen on Android 6, but unfortunately not Android 7. So we use a
     # swipe up (that depends on the screen resolution) instead.
-    adb('shell', 'input touchscreen swipe 930 880 930 380', serial=dut.serial)
+    adb("shell", "input touchscreen swipe 930 880 930 380", serial=dut.serial)
     time.sleep(1)
-    adb('shell', 'input keyevent KEYCODE_HOME', serial=dut.serial)
+    adb("shell", "input keyevent KEYCODE_HOME", serial=dut.serial)
 
 
 def getprop(serial, key):
@@ -185,7 +181,7 @@
         Value of system property.
     :raise DeviceCommandError: If the underlying adb command failed.
     """
-    process = adb('shell', 'getprop', key, serial=serial)
+    process = adb("shell", "getprop", key, serial=serial)
     return process.stdout.strip()
 
 
@@ -202,9 +198,9 @@
         True if device runs GMS, false otherwise.
     :raise DeviceCommandError: If the underlying adb command failed.
     """
-    return (
-        getprop(serial, 'ro.build.id').startswith('FP2-gms-')
-        or getprop(serial, 'ro.build.version.incremental').startswith('gms-'))
+    return getprop(serial, "ro.build.id").startswith("FP2-gms-") or getprop(
+        serial, "ro.build.version.incremental"
+    ).startswith("gms-")
 
 
 def uninstall_apk(serial, filename, prebuilts_dir):
@@ -214,21 +210,20 @@
         ValueError: If the package name could not be read from the apk.
         DeviceCommandError: If the uninstall command failed.
     """
-    ret = aapt('dump', 'badging', '{}/{}'.format(prebuilts_dir, filename))
+    ret = aapt("dump", "badging", "{}/{}".format(prebuilts_dir, filename))
     package = None
     for line in ret.stdout.splitlines():
-        if line.startswith('package'):
-            for token in line.split(' '):
-                if token.startswith('name='):
+        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:
-        raise ValueError('Could not find package of app `{}`'.format(
-            filename))
+        raise ValueError("Could not find package of app `{}`".format(filename))
 
-    adb('uninstall', package, serial=serial)
+    adb("uninstall", package, serial=serial)
 
 
 def install_apk(dut, filename, prebuilts_dir):
@@ -238,10 +233,10 @@
         DeviceCommandError: If the install command failed.
     """
     path = os.path.join(prebuilts_dir, filename)
-    command = ['install', '-r']
+    command = ["install", "-r"]
     if dut.sdk >= 23:
         # From Marshmallow onwards, adb has a flag to grant default permissions
-        command.append('-g')
+        command.append("-g")
     adb(*command, path, serial=dut.serial)
 
 
@@ -262,20 +257,22 @@
             DeviceCommandError: If the UI automation fails.
     """
     # Open the Wi-Fi settings
-    adb('shell', ('am start -a android.settings.WIFI_SETTINGS '
-        '--activity-clear-task'), serial=dut.serial)
+    adb(
+        "shell",
+        "am start -a android.settings.WIFI_SETTINGS --activity-clear-task",
+        serial=dut.serial,
+    )
 
     # Make sure Wi-Fi is enabled
-    wifi_enabler = dut(text='OFF',
-        resourceId='com.android.settings:id/switch_widget')
+    wifi_enabler = dut(text="OFF", resourceId="com.android.settings:id/switch_widget")
     if wifi_enabler.exists:
         wifi_enabler.click()
 
     # Check for registered networks
     registered_networks = set()
-    dut(description='More options').click.wait()
+    dut(description="More options").click.wait()
     time.sleep(1)
-    saved_networks = dut(text='Saved networks')
+    saved_networks = dut(text="Saved networks")
     if saved_networks.exists:
         saved_networks.click.wait()
         for ssid in networks.keys():
@@ -286,40 +283,34 @@
     missing_networks = networks.keys() - registered_networks
 
     for ssid in registered_networks:
-        print('Ignoring `{}` Wi-Fi network, already configured.'.format(ssid))
+        print("Ignoring `{}` Wi-Fi network, already configured.".format(ssid))
 
     for ssid in missing_networks:
-        print('Configuring `{}` Wi-Fi network…'.format(ssid))
+        print("Configuring `{}` Wi-Fi network…".format(ssid))
 
-        dut(description='More options').click.wait()
-        dut(text='Add network').click.wait()
-        dut(resourceId='com.android.settings:id/ssid') \
-            .set_text(ssid)
-        dut(resourceId='com.android.settings:id/security') \
-            .click()
-        dut(text=networks[ssid]['security']) \
-            .click()
-        password_field = dut(resourceId='com.android.settings:id/password')
+        dut(description="More options").click.wait()
+        dut(text="Add network").click.wait()
+        dut(resourceId="com.android.settings:id/ssid").set_text(ssid)
+        dut(resourceId="com.android.settings:id/security").click()
+        dut(text=networks[ssid]["security"]).click()
+        password_field = dut(resourceId="com.android.settings:id/password")
         time.sleep(1)
-        if 'password' in networks[ssid] and networks[ssid]['password']:
+        if "password" in networks[ssid] and networks[ssid]["password"]:
             if not password_field.exists:
-                dut(text='Cancel').click()
-                raise DeviceCommandError(dut, 'UI: add Wi-Fi',
-                    'missing password field')
-            password_field.set_text(networks[ssid]['password'])
+                dut(text="Cancel").click()
+                raise DeviceCommandError(dut, "UI: add Wi-Fi", "missing password field")
+            password_field.set_text(networks[ssid]["password"])
         elif password_field.exists:
-            dut(text='Cancel').click()
-            raise DeviceCommandError(dut, 'UI: add Wi-Fi',
-                'missing password data')
-        save_button = dut(text='Save')
+            dut(text="Cancel").click()
+            raise DeviceCommandError(dut, "UI: add Wi-Fi", "missing password data")
+        save_button = dut(text="Save")
         if not save_button.click():
-            dut(text='Cancel').click()
-            raise DeviceCommandError(dut, 'UI: add Wi-Fi',
-                'could not save network')
+            dut(text="Cancel").click()
+            raise DeviceCommandError(dut, "UI: add Wi-Fi", "could not save network")
 
     # Force the Wi-Fi on and off to pick the best network available
-    dut(text='ON', resourceId='com.android.settings:id/switch_widget').click()
-    dut(text='OFF', resourceId='com.android.settings:id/switch_widget').click()
+    dut(text="ON", resourceId="com.android.settings:id/switch_widget").click()
+    dut(text="OFF", resourceId="com.android.settings:id/switch_widget").click()
 
     # Leave the settings
     dut.press.back()
@@ -331,13 +322,16 @@
     This simplifies UI automation. Disabling the feature globally is more robust
     than clicking through the the Privacy Impact screen per app.
     """
-    print('Disabling the Privacy Impact screen…')
-    adb('shell',
-        ('am start -a android.intent.action.MAIN '
-            'com.fairphone.privacyimpact/.PrivacyImpactPreferenceActivity'),
-        serial=dut.serial
+    print("Disabling the Privacy Impact screen…")
+    adb(
+        "shell",
+        (
+            "am start -a android.intent.action.MAIN "
+            "com.fairphone.privacyimpact/.PrivacyImpactPreferenceActivity"
+        ),
+        serial=dut.serial,
     )
-    disable_privacy_impact_checkbox = dut(className='android.widget.CheckBox')
+    disable_privacy_impact_checkbox = dut(className="android.widget.CheckBox")
     if not disable_privacy_impact_checkbox.checked:
         disable_privacy_impact_checkbox.click()
 
@@ -348,91 +342,88 @@
     else:
         return PREBUILT_PROXY_APK_PATTERN.format(sdk=19, flavour=flavour)
 
+
 # Prepare the DUT
 def prepare_dut(dut, scenarios_dir, data_dir, prebuilts_dir):
-    flavour = 'gms' if is_gms_device(dut.serial) else 'sibon'
+    flavour = "gms" if is_gms_device(dut.serial) else "sibon"
     proxy_apk = get_proxy_apk(dut.sdk, flavour)
 
     # Uninstall the smartviser apps
     for app in PREBUILT_APKS + [proxy_apk]:
-        print('Uninstalling `{}`…'.format(app))
+        print("Uninstalling `{}`…".format(app))
         uninstall_apk(dut.serial, app, prebuilts_dir)
 
     # Copy the scenarios
-    print('Pushing scenarios from `{}`…'.format(scenarios_dir))
-    adb('push', scenarios_dir, '/sdcard/viser', serial=dut.serial)
+    print("Pushing scenarios from `{}`…".format(scenarios_dir))
+    adb("push", scenarios_dir, "/sdcard/viser", serial=dut.serial)
 
     # Copy the scenarios data
-    print('Pushing scenarios data from `{}`…'.format(data_dir))
-    adb('push', data_dir, '/sdcard/viser/data', serial=dut.serial)
+    print("Pushing scenarios data from `{}`…".format(data_dir))
+    adb("push", data_dir, "/sdcard/viser/data", serial=dut.serial)
 
     # Install the smartviser apps (starting with the proxy app)
     for app in [proxy_apk] + PREBUILT_APKS:
-        print('Installing `{}`…'.format(app))
+        print("Installing `{}`…".format(app))
         install_apk(dut, app, prebuilts_dir)
 
 
 # Grant the permissions through the UI
 def configure_perms(dut):
     # Input the credentials
-    dut(resourceId='android:id/content') \
-        .child(text='Username') \
-        .child(className='android.widget.EditText') \
-        .set_text(VWS_CREDENTIALS['user'])
-    dut(resourceId='android:id/content') \
-        .child(text='Password') \
-        .child(className='android.widget.EditText') \
-        .set_text(VWS_CREDENTIALS['password'])
+    dut(resourceId="android:id/content").child(text="Username").child(
+        className="android.widget.EditText"
+    ).set_text(VWS_CREDENTIALS["user"])
+    dut(resourceId="android:id/content").child(text="Password").child(
+        className="android.widget.EditText"
+    ).set_text(VWS_CREDENTIALS["password"])
 
     # Sign in
-    signin_label = 'SIGN IN' if dut.sdk >= 24 else 'Sign in'
-    dut(resourceId='android:id/content') \
-        .child(text=signin_label, className='android.widget.Button') \
-        .click()
+    signin_label = "SIGN IN" if dut.sdk >= 24 else "Sign in"
+    dut(resourceId="android:id/content").child(
+        text=signin_label, className="android.widget.Button"
+    ).click()
+
 
 def configure_sms(dut):
     # TODO wait for the connection to be established and time-out
-    prompt = dut(resourceId='android:id/content') \
-        .child(text='Viser must be your SMS app to send messages')
+    prompt = dut(resourceId="android:id/content").child(
+        text="Viser must be your SMS app to send messages"
+    )
     while not prompt.exists:
         time.sleep(1)
 
     # Make viser the default SMS app
-    dut(resourceId='android:id/content') \
-        .child_by_text('Viser must be your SMS app to send messages',
-                className='android.widget.LinearLayout') \
-        .child(text='OK', className='android.widget.Button') \
-        .click()
+    dut(resourceId="android:id/content").child_by_text(
+        "Viser must be your SMS app to send messages",
+        className="android.widget.LinearLayout",
+    ).child(text="OK", className="android.widget.Button").click()
 
-    dut(resourceId='android:id/content') \
-        .child_by_text('Change SMS app?', className='android.widget.LinearLayout') \
-        .child(text='Yes', className='android.widget.Button') \
-        .click()
+    dut(resourceId="android:id/content").child_by_text(
+        "Change SMS app?", className="android.widget.LinearLayout"
+    ).child(text="Yes", className="android.widget.Button").click()
+
 
 def configure_settings(dut):
     # Set the e-mail account
-    dut(text='Settings', className='android.widget.TextView') \
-        .click()
-    dut(resourceId='android:id/list') \
-        .child_by_text('User settings', className='android.widget.LinearLayout') \
-        .click()
-    dut(resourceId='android:id/list') \
-        .child_by_text('Email account', className='android.widget.LinearLayout') \
-        .click()
-    prompt = dut(resourceId='android:id/content') \
-        .child_by_text('Email account', className='android.widget.LinearLayout')
-    prompt.child(resourceId='android:id/edit') \
-        .set_text('fairphone.viser@gmail.com')
-    prompt.child(text='OK', className='android.widget.Button') \
-        .click()
-    dut(resourceId='android:id/list') \
-        .child_by_text('Email password', className='android.widget.LinearLayout') \
-        .click()
-    dut(text='Password :') \
-        .child(className='android.widget.EditText') \
-        .set_text('fairphoneviser2017')
-    dut(description='OK', className='android.widget.TextView') \
-        .click()
+    dut(text="Settings", className="android.widget.TextView").click()
+    dut(resourceId="android:id/list").child_by_text(
+        "User settings", className="android.widget.LinearLayout"
+    ).click()
+    dut(resourceId="android:id/list").child_by_text(
+        "Email account", className="android.widget.LinearLayout"
+    ).click()
+    prompt = dut(resourceId="android:id/content").child_by_text(
+        "Email account", className="android.widget.LinearLayout"
+    )
+    prompt.child(resourceId="android:id/edit").set_text("fairphone.viser@gmail.com")
+    prompt.child(text="OK", className="android.widget.Button").click()
+    dut(resourceId="android:id/list").child_by_text(
+        "Email password", className="android.widget.LinearLayout"
+    ).click()
+    dut(text="Password :").child(className="android.widget.EditText").set_text(
+        "fairphoneviser2017"
+    )
+    dut(description="OK", className="android.widget.TextView").click()
     dut.press.back()
     dut.press.back()
 
@@ -446,13 +437,13 @@
         serials = list_devices()
 
     for serial in serials:
-        print('Configuring device {}…'.format(serial))
+        print("Configuring device {}…".format(serial))
 
         dut = Device(serial)
         # Work around the not-so-easy Device class
         dut.serial = serial
         # Cache the Android SDK version (dut.info fetches system properties)
-        dut.sdk = dut.info['sdkInt']
+        dut.sdk = dut.info["sdkInt"]
 
         try:
             # Make sure the screen stays on - we're going to use UI automation
@@ -463,21 +454,29 @@
             if dut.sdk < 24:
                 configure_wifi_networks(dut, FAIRPHONE_WIFI_NETWORKS)
             else:
-                print('Uh oh, the device is running Android SDK {} on which we '
-                    'do not deploy Wi-Fi networks yet.'.format(dut.sdk))
+                print(
+                    "Uh oh, the device is running Android SDK {} on which we "
+                    "do not deploy Wi-Fi networks yet.".format(dut.sdk)
+                )
 
             # Disable Privacy Impact popup on Android 5.
             if dut.sdk <= 22:
                 disable_privacy_impact_popup(dut)
 
             # Push the scenarios, their data, and install the apps
-            prepare_dut(
-                dut, '../scenarios', '../scenarios-data', PREBUILTS_PATH)
+            prepare_dut(dut, "../scenarios", "../scenarios-data", PREBUILTS_PATH)
 
             # Start the viser app
             adb(
-                'shell', 'monkey', '-p', 'com.lunarlabs.panda', '-c',
-                'android.intent.category.LAUNCHER', '1', serial=serial)
+                "shell",
+                "monkey",
+                "-p",
+                "com.lunarlabs.panda",
+                "-c",
+                "android.intent.category.LAUNCHER",
+                "1",
+                serial=serial,
+            )
 
             configure_perms(dut)
 
@@ -487,14 +486,14 @@
 
             configure_settings(dut)
         except (HostCommandError, DeviceCommandError) as e:
-            print('ERROR {}'.format(e), file=sys.stderr)
+            print("ERROR {}".format(e), file=sys.stderr)
         finally:
             try:
                 # Leave the device alone now
                 force_awake(serial, always=False)
             except DeviceCommandError as e:
-                print('WARNING {}'.format(e), file=sys.stderr)
+                print("WARNING {}".format(e), file=sys.stderr)
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     deploy()