Format python files using yapf

Change-Id: I8b7b97efb6bfdcceef9efc533cdaa0675ab7db40
diff --git a/tools/startup/adb_utils.py b/tools/startup/adb_utils.py
index d4f70a1..6ce19ab 100755
--- a/tools/startup/adb_utils.py
+++ b/tools/startup/adb_utils.py
@@ -17,458 +17,511 @@
 import profile_utils
 import utils
 
-DEVNULL=subprocess.DEVNULL
+DEVNULL = subprocess.DEVNULL
+
 
 class ProcessReader(threading.Thread):
 
-  def __init__(self, process):
-    threading.Thread.__init__(self)
-    self.lines = []
-    self.process = process
+    def __init__(self, process):
+        threading.Thread.__init__(self)
+        self.lines = []
+        self.process = process
 
-  def run(self):
-    for line in self.process.stdout:
-      line = line.decode('utf-8').strip()
-      self.lines.append(line)
+    def run(self):
+        for line in self.process.stdout:
+            line = line.decode('utf-8').strip()
+            self.lines.append(line)
 
-  def stop(self):
-    self.process.kill()
+    def stop(self):
+        self.process.kill()
+
 
 class ScreenState(Enum):
-  OFF_LOCKED = 1,
-  OFF_UNLOCKED = 2
-  ON_LOCKED = 3
-  ON_UNLOCKED = 4
+    OFF_LOCKED = 1,
+    OFF_UNLOCKED = 2
+    ON_LOCKED = 3
+    ON_UNLOCKED = 4
 
-  def is_off(self):
-    return self == ScreenState.OFF_LOCKED or self == ScreenState.OFF_UNLOCKED
+    def is_off(self):
+        return self == ScreenState.OFF_LOCKED or self == ScreenState.OFF_UNLOCKED
 
-  def is_on(self):
-    return self == ScreenState.ON_LOCKED or self == ScreenState.ON_UNLOCKED
+    def is_on(self):
+        return self == ScreenState.ON_LOCKED or self == ScreenState.ON_UNLOCKED
 
-  def is_on_and_locked(self):
-    return self == ScreenState.ON_LOCKED
+    def is_on_and_locked(self):
+        return self == ScreenState.ON_LOCKED
 
-  def is_on_and_unlocked(self):
-    return self == ScreenState.ON_UNLOCKED
+    def is_on_and_unlocked(self):
+        return self == ScreenState.ON_UNLOCKED
+
 
 def broadcast(action, component, device_id=None):
-  print('Sending broadcast %s' % action)
-  cmd = create_adb_cmd('shell am broadcast -a %s %s' % (action, component), device_id)
-  return subprocess.check_output(cmd).decode('utf-8').strip().splitlines()
+    print('Sending broadcast %s' % action)
+    cmd = create_adb_cmd('shell am broadcast -a %s %s' % (action, component),
+                         device_id)
+    return subprocess.check_output(cmd).decode('utf-8').strip().splitlines()
+
 
 def build_apks_from_bundle(bundle, output, overwrite=False):
-  print('Building %s' % bundle)
-  cmd = [
-      'java', '-jar', utils.BUNDLETOOL_JAR,
-      'build-apks',
-      '--bundle=%s' % bundle,
-      '--output=%s' % output]
-  if overwrite:
-    cmd.append('--overwrite')
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+    print('Building %s' % bundle)
+    cmd = [
+        'java', '-jar', utils.BUNDLETOOL_JAR, 'build-apks',
+        '--bundle=%s' % bundle,
+        '--output=%s' % output
+    ]
+    if overwrite:
+        cmd.append('--overwrite')
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+
 
 def capture_screen(target, device_id=None):
-  print('Taking screenshot to %s' % target)
-  tmp = '/sdcard/screencap.png'
-  cmd = create_adb_cmd('shell screencap -p %s' % tmp, device_id)
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
-  pull(tmp, target, device_id)
+    print('Taking screenshot to %s' % target)
+    tmp = '/sdcard/screencap.png'
+    cmd = create_adb_cmd('shell screencap -p %s' % tmp, device_id)
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+    pull(tmp, target, device_id)
+
 
 def create_adb_cmd(arguments, device_id=None):
-  assert isinstance(arguments, list) or isinstance(arguments, str)
-  cmd = ['adb']
-  if device_id is not None:
-    cmd.append('-s')
-    cmd.append(device_id)
-  cmd.extend(arguments if isinstance(arguments, list) else arguments.split(' '))
-  return cmd
+    assert isinstance(arguments, list) or isinstance(arguments, str)
+    cmd = ['adb']
+    if device_id is not None:
+        cmd.append('-s')
+        cmd.append(device_id)
+    cmd.extend(
+        arguments if isinstance(arguments, list) else arguments.split(' '))
+    return cmd
+
 
 def capture_app_profile_data(app_id, device_id=None):
-  ps_cmd = create_adb_cmd('shell ps -o NAME', device_id)
-  stdout = subprocess.check_output(ps_cmd).decode('utf-8').strip()
-  killed_any = False
-  for process_name in stdout.splitlines():
-    if process_name.startswith(app_id):
-      print('Flushing profile for process %s' % process_name)
-      killall_cmd = create_adb_cmd(
-          'shell killall -s SIGUSR1 %s' % process_name, device_id)
-      killall_result = subprocess.run(killall_cmd, capture_output=True)
-      stdout = killall_result.stdout.decode('utf-8')
-      stderr = killall_result.stderr.decode('utf-8')
-      if killall_result.returncode == 0:
-        killed_any = True
-      else:
-        print('Error: stdout: %s, stderr: %s' % (stdout, stderr))
-      time.sleep(5)
-  assert killed_any, 'Expected to find at least one process'
+    ps_cmd = create_adb_cmd('shell ps -o NAME', device_id)
+    stdout = subprocess.check_output(ps_cmd).decode('utf-8').strip()
+    killed_any = False
+    for process_name in stdout.splitlines():
+        if process_name.startswith(app_id):
+            print('Flushing profile for process %s' % process_name)
+            killall_cmd = create_adb_cmd(
+                'shell killall -s SIGUSR1 %s' % process_name, device_id)
+            killall_result = subprocess.run(killall_cmd, capture_output=True)
+            stdout = killall_result.stdout.decode('utf-8')
+            stderr = killall_result.stderr.decode('utf-8')
+            if killall_result.returncode == 0:
+                killed_any = True
+            else:
+                print('Error: stdout: %s, stderr: %s' % (stdout, stderr))
+            time.sleep(5)
+    assert killed_any, 'Expected to find at least one process'
+
 
 def check_app_has_profile_data(app_id, device_id=None):
-  profile_path = get_profile_path(app_id)
-  cmd = create_adb_cmd(
-      'shell du /data/misc/profiles/cur/0/%s/primary.prof' % app_id,
-      device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
-  size_str = stdout[:stdout.index('\t')]
-  assert size_str.isdigit()
-  size = int(size_str)
-  if size == 4:
-    raise ValueError('Expected size of profile at %s to be > 4K' % profile_path)
+    profile_path = get_profile_path(app_id)
+    cmd = create_adb_cmd(
+        'shell du /data/misc/profiles/cur/0/%s/primary.prof' % app_id,
+        device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    size_str = stdout[:stdout.index('\t')]
+    assert size_str.isdigit()
+    size = int(size_str)
+    if size == 4:
+        raise ValueError('Expected size of profile at %s to be > 4K' %
+                         profile_path)
+
 
 def clear_logcat(device_id=None):
-  cmd = create_adb_cmd('logcat -c', device_id)
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+    cmd = create_adb_cmd('logcat -c', device_id)
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+
 
 def clear_profile_data(app_id, device_id=None):
-  cmd = create_adb_cmd(
-      'shell cmd package compile --reset %s' % app_id, device_id)
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+    cmd = create_adb_cmd('shell cmd package compile --reset %s' % app_id,
+                         device_id)
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+
 
 def drop_caches(device_id=None):
-  cmd = create_adb_cmd(
-      ['shell', 'echo 3 > /proc/sys/vm/drop_caches'], device_id)
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+    cmd = create_adb_cmd(['shell', 'echo 3 > /proc/sys/vm/drop_caches'],
+                         device_id)
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+
 
 def ensure_screen_on(device_id=None):
-  if get_screen_state(device_id).is_off():
-    toggle_screen(device_id)
-  assert get_screen_state(device_id).is_on()
+    if get_screen_state(device_id).is_off():
+        toggle_screen(device_id)
+    assert get_screen_state(device_id).is_on()
+
 
 def ensure_screen_off(device_id=None):
-  if get_screen_state(device_id).is_on():
-    toggle_screen(device_id)
-  assert get_screen_state(device_id).is_off()
+    if get_screen_state(device_id).is_on():
+        toggle_screen(device_id)
+    assert get_screen_state(device_id).is_off()
+
 
 def force_compilation(app_id, device_id=None):
-  print('Applying AOT (full)')
-  cmd = create_adb_cmd(
-      'shell cmd package compile -m speed -f %s' % app_id, device_id)
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+    print('Applying AOT (full)')
+    cmd = create_adb_cmd('shell cmd package compile -m speed -f %s' % app_id,
+                         device_id)
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+
 
 def force_profile_compilation(app_id, device_id=None):
-  print('Applying AOT (profile)')
-  cmd = create_adb_cmd(
-      'shell cmd package compile -m speed-profile -f %s' % app_id, device_id)
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+    print('Applying AOT (profile)')
+    cmd = create_adb_cmd(
+        'shell cmd package compile -m speed-profile -f %s' % app_id, device_id)
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+
 
 def get_apk_path(app_id, device_id=None):
-  cmd = create_adb_cmd('shell pm path %s' % app_id, device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
-  if not stdout.startswith('package:'):
-    raise ValueError(
-        'Expected stdout to start with "package:", was: %s' % stdout)
-  apk_path = stdout[len('package:'):]
-  if not apk_path.endswith('.apk'):
-    raise ValueError(
-        'Expected stdout to end with ".apk", was: %s' % stdout)
-  return apk_path
+    cmd = create_adb_cmd('shell pm path %s' % app_id, device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    if not stdout.startswith('package:'):
+        raise ValueError('Expected stdout to start with "package:", was: %s' %
+                         stdout)
+    apk_path = stdout[len('package:'):]
+    if not apk_path.endswith('.apk'):
+        raise ValueError('Expected stdout to end with ".apk", was: %s' % stdout)
+    return apk_path
+
 
 def get_component_name(app_id, activity):
-  if activity.startswith(app_id):
-    return '%s/.%s' % (app_id, activity[len(app_id)+1:])
-  else:
-    return '%s/%s' % (app_id, activity)
+    if activity.startswith(app_id):
+        return '%s/.%s' % (app_id, activity[len(app_id) + 1:])
+    else:
+        return '%s/%s' % (app_id, activity)
+
 
 def get_meminfo(app_id, device_id=None):
-  cmd = create_adb_cmd('shell dumpsys meminfo -s %s' % app_id, device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
-  for line in stdout.splitlines():
-    if 'TOTAL PSS: ' in line:
-      elements = [s for s in line.replace('TOTAL ', 'TOTAL_').split()]
-      assert elements[0] == 'TOTAL_PSS:', elements[0]
-      assert elements[1].isdigit()
-      assert elements[2] == 'TOTAL_RSS:'
-      assert elements[3].isdigit()
-      return { 'total_pss': int(elements[1]), 'total_rss': int(elements[3]) }
-  raise ValueError('Unexpected stdout: %s' % stdout)
+    cmd = create_adb_cmd('shell dumpsys meminfo -s %s' % app_id, device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    for line in stdout.splitlines():
+        if 'TOTAL PSS: ' in line:
+            elements = [s for s in line.replace('TOTAL ', 'TOTAL_').split()]
+            assert elements[0] == 'TOTAL_PSS:', elements[0]
+            assert elements[1].isdigit()
+            assert elements[2] == 'TOTAL_RSS:'
+            assert elements[3].isdigit()
+            return {
+                'total_pss': int(elements[1]),
+                'total_rss': int(elements[3])
+            }
+    raise ValueError('Unexpected stdout: %s' % stdout)
+
 
 def get_profile_data(app_id, device_id=None):
-  with utils.TempDir() as temp:
-    source = get_profile_path(app_id)
-    target = os.path.join(temp, 'primary.prof')
-    pull(source, target, device_id)
-    with open(target, 'rb') as f:
-      return f.read()
+    with utils.TempDir() as temp:
+        source = get_profile_path(app_id)
+        target = os.path.join(temp, 'primary.prof')
+        pull(source, target, device_id)
+        with open(target, 'rb') as f:
+            return f.read()
+
 
 def get_profile_path(app_id):
-  return '/data/misc/profiles/cur/0/%s/primary.prof' % app_id
+    return '/data/misc/profiles/cur/0/%s/primary.prof' % app_id
+
 
 def get_minor_major_page_faults(app_id, device_id=None):
-  pid = get_pid(app_id, device_id)
-  cmd = create_adb_cmd('shell ps -p %i -o MINFL,MAJFL' % pid, device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8')
-  lines_it = iter(stdout.splitlines())
-  first_line = next(lines_it)
-  assert first_line == ' MINFL  MAJFL'
-  second_line = next(lines_it)
-  minfl, majfl = second_line.split()
-  assert minfl.isdigit()
-  assert majfl.isdigit()
-  return (int(minfl), int(majfl))
+    pid = get_pid(app_id, device_id)
+    cmd = create_adb_cmd('shell ps -p %i -o MINFL,MAJFL' % pid, device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8')
+    lines_it = iter(stdout.splitlines())
+    first_line = next(lines_it)
+    assert first_line == ' MINFL  MAJFL'
+    second_line = next(lines_it)
+    minfl, majfl = second_line.split()
+    assert minfl.isdigit()
+    assert majfl.isdigit()
+    return (int(minfl), int(majfl))
+
 
 def get_pid(app_id, device_id=None):
-  cmd = create_adb_cmd('shell pidof %s' % app_id, device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
-  assert stdout.isdigit()
-  pid = int(stdout)
-  return pid
+    cmd = create_adb_cmd('shell pidof %s' % app_id, device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    assert stdout.isdigit()
+    pid = int(stdout)
+    return pid
+
 
 def get_screen_state(device_id=None):
-  cmd = create_adb_cmd('shell dumpsys nfc', device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
-  screen_state_value = None
-  for line in stdout.splitlines():
-    if line.startswith('mScreenState='):
-      value_start_index = len('mScreenState=')
-      screen_state_value=line[value_start_index:]
-  if screen_state_value is None:
-    raise ValueError('Expected to find mScreenState in: adb shell dumpsys nfc')
-  if not hasattr(ScreenState, screen_state_value):
-    raise ValueError(
-        'Expected mScreenState to be a value of ScreenState, was: %s'
-            % screen_state_value)
-  return ScreenState[screen_state_value]
+    cmd = create_adb_cmd('shell dumpsys nfc', device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    screen_state_value = None
+    for line in stdout.splitlines():
+        if line.startswith('mScreenState='):
+            value_start_index = len('mScreenState=')
+            screen_state_value = line[value_start_index:]
+    if screen_state_value is None:
+        raise ValueError(
+            'Expected to find mScreenState in: adb shell dumpsys nfc')
+    if not hasattr(ScreenState, screen_state_value):
+        raise ValueError(
+            'Expected mScreenState to be a value of ScreenState, was: %s' %
+            screen_state_value)
+    return ScreenState[screen_state_value]
+
 
 def get_classes_and_methods_from_app_profile(app_id, device_id=None):
-  apk_path = get_apk_path(app_id, device_id)
-  profile_path = get_profile_path(app_id)
-  cmd = create_adb_cmd(
-    'shell profman --dump-classes-and-methods'
-    ' --profile-file=%s --apk=%s --dex-location=%s'
-        % (profile_path, apk_path, apk_path), device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
-  lines = stdout.splitlines()
-  return profile_utils.parse_art_profile(lines)
+    apk_path = get_apk_path(app_id, device_id)
+    profile_path = get_profile_path(app_id)
+    cmd = create_adb_cmd(
+        'shell profman --dump-classes-and-methods'
+        ' --profile-file=%s --apk=%s --dex-location=%s' %
+        (profile_path, apk_path, apk_path), device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    lines = stdout.splitlines()
+    return profile_utils.parse_art_profile(lines)
+
 
 def get_screen_off_timeout(device_id=None):
-  cmd = create_adb_cmd(
-      'shell settings get system screen_off_timeout', device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
-  assert stdout.isdigit()
-  screen_off_timeout = int(stdout)
-  return screen_off_timeout
+    cmd = create_adb_cmd('shell settings get system screen_off_timeout',
+                         device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    assert stdout.isdigit()
+    screen_off_timeout = int(stdout)
+    return screen_off_timeout
+
 
 def grant(app_id, permission, device_id=None):
-  cmd = create_adb_cmd('shell pm grant %s %s' % (app_id, permission), device_id)
-  subprocess.check_call(cmd)
+    cmd = create_adb_cmd('shell pm grant %s %s' % (app_id, permission),
+                         device_id)
+    subprocess.check_call(cmd)
+
 
 def install(apk, device_id=None):
-  print('Installing %s' % apk)
-  cmd = create_adb_cmd('install %s' % apk, device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8')
-  assert 'Success' in stdout
+    print('Installing %s' % apk)
+    cmd = create_adb_cmd('install %s' % apk, device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8')
+    assert 'Success' in stdout
+
 
 def install_apks(apks, device_id=None, max_attempts=3):
-  print('Installing %s' % apks)
-  cmd = [
-      'java', '-jar', utils.BUNDLETOOL_JAR,
-      'install-apks',
-      '--apks=%s' % apks]
-  if device_id is not None:
-    cmd.append('--device-id=%s' % device_id)
-  for i in range(max_attempts):
+    print('Installing %s' % apks)
+    cmd = [
+        'java', '-jar', utils.BUNDLETOOL_JAR, 'install-apks',
+        '--apks=%s' % apks
+    ]
+    if device_id is not None:
+        cmd.append('--device-id=%s' % device_id)
+    for i in range(max_attempts):
+        process_result = subprocess.run(cmd, capture_output=True)
+        stdout = process_result.stdout.decode('utf-8')
+        stderr = process_result.stderr.decode('utf-8')
+        if process_result.returncode == 0:
+            return
+        print('Failed to install %s' % apks)
+        print('Stdout: %s' % stdout)
+        print('Stderr: %s' % stderr)
+        print('Retrying...')
+    raise Exception('Unable to install apks in %s attempts' % max_attempts)
+
+
+def install_bundle(bundle, device_id=None):
+    print('Installing %s' % bundle)
+    with utils.TempDir() as temp:
+        apks = os.path.join(temp, 'Bundle.apks')
+        build_apks_from_bundle(bundle, apks)
+        install_apks(apks, device_id)
+
+
+def install_profile_using_adb(app_id, host_profile_path, device_id=None):
+    device_profile_path = get_profile_path(app_id)
+    cmd = create_adb_cmd('push %s %s' %
+                         (host_profile_path, device_profile_path))
+    subprocess.check_call(cmd)
+    stop_app(app_id, device_id)
+    force_profile_compilation(app_id, device_id)
+
+
+def install_profile_using_profileinstaller(app_id, device_id=None):
+    # This assumes that the profileinstaller library has been added to the app,
+    # https://developer.android.com/jetpack/androidx/releases/profileinstaller.
+    action = 'androidx.profileinstaller.action.INSTALL_PROFILE'
+    component = '%s/androidx.profileinstaller.ProfileInstallReceiver' % app_id
+    stdout = broadcast(action, component, device_id)
+    assert len(stdout) == 2
+    assert stdout[0] == ('Broadcasting: Intent { act=%s flg=0x400000 cmp=%s }' %
+                         (action, component))
+    assert stdout[1] == 'Broadcast completed: result=1', stdout[1]
+    stop_app(app_id, device_id)
+    force_profile_compilation(app_id, device_id)
+
+
+def issue_key_event(key_event, device_id=None, sleep_in_seconds=1):
+    cmd = create_adb_cmd('shell input keyevent %s' % key_event, device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    assert len(stdout) == 0
+    time.sleep(sleep_in_seconds)
+
+
+def launch_activity(app_id,
+                    activity,
+                    device_id=None,
+                    intent_data_uri=None,
+                    wait_for_activity_to_launch=False):
+    args = ['shell', 'am', 'start', '-n', '%s/%s' % (app_id, activity)]
+    if intent_data_uri:
+        args.extend(['-d', intent_data_uri])
+    if wait_for_activity_to_launch:
+        args.append('-W')
+    cmd = create_adb_cmd(args, device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    assert stdout.startswith('Starting: Intent {')
+    expected_component = 'cmp=%s' % get_component_name(app_id, activity)
+    assert expected_component in stdout, \
+        'was %s, expected %s' % (stdout, expected_component)
+    lines = stdout.splitlines()
+    result = {}
+    for line in lines:
+        if line.startswith('TotalTime: '):
+            total_time_str = line.removeprefix('TotalTime: ')
+            assert total_time_str.isdigit()
+            result['total_time'] = int(total_time_str)
+    assert not wait_for_activity_to_launch or 'total_time' in result, lines
+    return result
+
+
+def navigate_to_home_screen(device_id=None):
+    cmd = create_adb_cmd('shell input keyevent KEYCODE_HOME', device_id)
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+
+
+def prepare_for_interaction_with_device(device_id=None, device_pin=None):
+    # Increase screen off timeout to avoid device screen turns off.
+    twenty_four_hours_in_millis = 24 * 60 * 60 * 1000
+    previous_screen_off_timeout = get_screen_off_timeout(device_id)
+    set_screen_off_timeout(twenty_four_hours_in_millis, device_id)
+
+    # Unlock device.
+    unlock(device_id, device_pin)
+
+    teardown_options = {
+        'previous_screen_off_timeout': previous_screen_off_timeout
+    }
+    return teardown_options
+
+
+def pull(source, target, device_id=None):
+    cmd = create_adb_cmd('pull %s %s' % (source, target), device_id)
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+
+
+def root(device_id=None):
+    cmd = create_adb_cmd('root', device_id)
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+
+
+def set_screen_off_timeout(screen_off_timeout_in_millis, device_id=None):
+    cmd = create_adb_cmd(
+        'shell settings put system screen_off_timeout %i' %
+        screen_off_timeout_in_millis, device_id)
+    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    assert len(stdout) == 0
+
+
+def start_logcat(device_id=None, format=None, filter=None, silent=False):
+    args = ['logcat']
+    if format:
+        args.extend(['--format', format])
+    if silent:
+        args.append('-s')
+    if filter:
+        args.append(filter)
+    cmd = create_adb_cmd(args, device_id)
+    logcat_process = subprocess.Popen(cmd,
+                                      bufsize=1024 * 1024,
+                                      stdout=subprocess.PIPE,
+                                      stderr=subprocess.PIPE)
+    reader = ProcessReader(logcat_process)
+    reader.start()
+    return reader
+
+
+def stop_logcat(logcat_reader):
+    logcat_reader.stop()
+    logcat_reader.join()
+    return logcat_reader.lines
+
+
+def stop_app(app_id, device_id=None):
+    print('Shutting down %s' % app_id)
+    cmd = create_adb_cmd('shell am force-stop %s' % app_id, device_id)
+    subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
+
+
+def teardown_after_interaction_with_device(teardown_options, device_id=None):
+    # Reset screen off timeout.
+    set_screen_off_timeout(teardown_options['previous_screen_off_timeout'],
+                           device_id)
+
+
+def toggle_screen(device_id=None):
+    issue_key_event('KEYCODE_POWER', device_id)
+
+
+def uninstall(app_id, device_id=None):
+    print('Uninstalling %s' % app_id)
+    cmd = create_adb_cmd('uninstall %s' % app_id, device_id)
     process_result = subprocess.run(cmd, capture_output=True)
     stdout = process_result.stdout.decode('utf-8')
     stderr = process_result.stderr.decode('utf-8')
     if process_result.returncode == 0:
-      return
-    print('Failed to install %s' % apks)
-    print('Stdout: %s' % stdout)
-    print('Stderr: %s' % stderr)
-    print('Retrying...')
-  raise Exception('Unable to install apks in %s attempts' % max_attempts)
+        assert 'Success' in stdout
+    elif stdout.startswith('cmd: Failure calling service package: Broken pipe'):
+        assert app_id == 'com.google.android.youtube'
+        print('Waiting after broken pipe')
+        time.sleep(15)
+    else:
+        expected_error = (
+            'java.lang.IllegalArgumentException: Unknown package: %s' % app_id)
+        assert 'Failure [DELETE_FAILED_INTERNAL_ERROR]' in stdout \
+            or expected_error in stderr, \
+            'stdout: %s, stderr: %s' % (stdout, stderr)
 
-def install_bundle(bundle, device_id=None):
-  print('Installing %s' % bundle)
-  with utils.TempDir() as temp:
-    apks = os.path.join(temp, 'Bundle.apks')
-    build_apks_from_bundle(bundle, apks)
-    install_apks(apks, device_id)
-
-def install_profile_using_adb(app_id, host_profile_path, device_id=None):
-  device_profile_path = get_profile_path(app_id)
-  cmd = create_adb_cmd('push %s %s' % (host_profile_path, device_profile_path))
-  subprocess.check_call(cmd)
-  stop_app(app_id, device_id)
-  force_profile_compilation(app_id, device_id)
-
-def install_profile_using_profileinstaller(app_id, device_id=None):
-  # This assumes that the profileinstaller library has been added to the app,
-  # https://developer.android.com/jetpack/androidx/releases/profileinstaller.
-  action = 'androidx.profileinstaller.action.INSTALL_PROFILE'
-  component = '%s/androidx.profileinstaller.ProfileInstallReceiver' % app_id
-  stdout = broadcast(action, component, device_id)
-  assert len(stdout) == 2
-  assert stdout[0] == ('Broadcasting: Intent { act=%s flg=0x400000 cmp=%s }' % (action, component))
-  assert stdout[1] == 'Broadcast completed: result=1', stdout[1]
-  stop_app(app_id, device_id)
-  force_profile_compilation(app_id, device_id)
-
-def issue_key_event(key_event, device_id=None, sleep_in_seconds=1):
-  cmd = create_adb_cmd('shell input keyevent %s' % key_event, device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
-  assert len(stdout) == 0
-  time.sleep(sleep_in_seconds)
-
-def launch_activity(
-    app_id,
-    activity,
-    device_id=None,
-    intent_data_uri=None,
-    wait_for_activity_to_launch=False):
-  args = ['shell', 'am', 'start', '-n', '%s/%s' % (app_id, activity)]
-  if intent_data_uri:
-    args.extend(['-d', intent_data_uri])
-  if wait_for_activity_to_launch:
-    args.append('-W')
-  cmd = create_adb_cmd(args, device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
-  assert stdout.startswith('Starting: Intent {')
-  expected_component = 'cmp=%s' % get_component_name(app_id, activity)
-  assert expected_component in stdout, \
-      'was %s, expected %s' % (stdout, expected_component)
-  lines = stdout.splitlines()
-  result = {}
-  for line in lines:
-    if line.startswith('TotalTime: '):
-      total_time_str = line.removeprefix('TotalTime: ')
-      assert total_time_str.isdigit()
-      result['total_time'] = int(total_time_str)
-  assert not wait_for_activity_to_launch or 'total_time' in result, lines
-  return result
-
-def navigate_to_home_screen(device_id=None):
-  cmd = create_adb_cmd('shell input keyevent KEYCODE_HOME', device_id)
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
-
-def prepare_for_interaction_with_device(device_id=None, device_pin=None):
-  # Increase screen off timeout to avoid device screen turns off.
-  twenty_four_hours_in_millis = 24 * 60 * 60 * 1000
-  previous_screen_off_timeout = get_screen_off_timeout(device_id)
-  set_screen_off_timeout(twenty_four_hours_in_millis, device_id)
-
-  # Unlock device.
-  unlock(device_id, device_pin)
-
-  teardown_options = {
-    'previous_screen_off_timeout': previous_screen_off_timeout
-  }
-  return teardown_options
-
-def pull(source, target, device_id=None):
-  cmd = create_adb_cmd('pull %s %s' % (source, target), device_id)
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
-
-def root(device_id=None):
-  cmd = create_adb_cmd('root', device_id)
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
-
-def set_screen_off_timeout(screen_off_timeout_in_millis, device_id=None):
-  cmd = create_adb_cmd(
-      'shell settings put system screen_off_timeout %i'
-          % screen_off_timeout_in_millis,
-      device_id)
-  stdout = subprocess.check_output(cmd).decode('utf-8').strip()
-  assert len(stdout) == 0
-
-def start_logcat(device_id=None, format=None, filter=None, silent=False):
-  args = ['logcat']
-  if format:
-    args.extend(['--format', format])
-  if silent:
-    args.append('-s')
-  if filter:
-    args.append(filter)
-  cmd = create_adb_cmd(args, device_id)
-  logcat_process = subprocess.Popen(
-      cmd, bufsize=1024*1024, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-  reader = ProcessReader(logcat_process)
-  reader.start()
-  return reader
-
-def stop_logcat(logcat_reader):
-  logcat_reader.stop()
-  logcat_reader.join()
-  return logcat_reader.lines
-
-def stop_app(app_id, device_id=None):
-  print('Shutting down %s' % app_id)
-  cmd = create_adb_cmd('shell am force-stop %s' % app_id, device_id)
-  subprocess.check_call(cmd, stdout=DEVNULL, stderr=DEVNULL)
-
-def teardown_after_interaction_with_device(teardown_options, device_id=None):
-  # Reset screen off timeout.
-  set_screen_off_timeout(
-      teardown_options['previous_screen_off_timeout'],
-      device_id)
-
-def toggle_screen(device_id=None):
-  issue_key_event('KEYCODE_POWER', device_id)
-
-def uninstall(app_id, device_id=None):
-  print('Uninstalling %s' % app_id)
-  cmd = create_adb_cmd('uninstall %s' % app_id, device_id)
-  process_result = subprocess.run(cmd, capture_output=True)
-  stdout = process_result.stdout.decode('utf-8')
-  stderr = process_result.stderr.decode('utf-8')
-  if process_result.returncode == 0:
-    assert 'Success' in stdout
-  elif stdout.startswith('cmd: Failure calling service package: Broken pipe'):
-    assert app_id == 'com.google.android.youtube'
-    print('Waiting after broken pipe')
-    time.sleep(15)
-  else:
-    expected_error = (
-        'java.lang.IllegalArgumentException: Unknown package: %s' % app_id)
-    assert 'Failure [DELETE_FAILED_INTERNAL_ERROR]' in stdout \
-        or expected_error in stderr, \
-        'stdout: %s, stderr: %s' % (stdout, stderr)
 
 def unlock(device_id=None, device_pin=None):
-  ensure_screen_on(device_id)
-  screen_state = get_screen_state(device_id)
-  assert screen_state.is_on(), 'was %s' % screen_state
-  if screen_state.is_on_and_locked():
-    if device_pin is not None:
-      raise NotImplementedError('Device unlocking with pin not implemented')
-    issue_key_event('KEYCODE_MENU', device_id)
+    ensure_screen_on(device_id)
     screen_state = get_screen_state(device_id)
-  assert screen_state.is_on_and_unlocked(), 'was %s' % screen_state
+    assert screen_state.is_on(), 'was %s' % screen_state
+    if screen_state.is_on_and_locked():
+        if device_pin is not None:
+            raise NotImplementedError(
+                'Device unlocking with pin not implemented')
+        issue_key_event('KEYCODE_MENU', device_id)
+        screen_state = get_screen_state(device_id)
+    assert screen_state.is_on_and_unlocked(), 'was %s' % screen_state
+
 
 def parse_options(argv):
-  result = argparse.ArgumentParser(description='Run adb utils.')
-  result.add_argument('--capture-screen',
-                      help='Capture screen to given file')
-  result.add_argument('--device-id',
-                      help='Device id (e.g., emulator-5554).')
-  result.add_argument('--device-pin',
-                      help='Device pin code (e.g., 1234)')
-  result.add_argument('--ensure-screen-off',
-                      help='Ensure screen off',
-                      action='store_true',
-                      default=False)
-  result.add_argument('--get-screen-state',
-                      help='Get screen state',
-                      action='store_true',
-                      default=False)
-  result.add_argument('--unlock',
-                      help='Unlock device',
-                      action='store_true',
-                      default=False)
-  options, args = result.parse_known_args(argv)
-  return options, args
+    result = argparse.ArgumentParser(description='Run adb utils.')
+    result.add_argument('--capture-screen', help='Capture screen to given file')
+    result.add_argument('--device-id', help='Device id (e.g., emulator-5554).')
+    result.add_argument('--device-pin', help='Device pin code (e.g., 1234)')
+    result.add_argument('--ensure-screen-off',
+                        help='Ensure screen off',
+                        action='store_true',
+                        default=False)
+    result.add_argument('--get-screen-state',
+                        help='Get screen state',
+                        action='store_true',
+                        default=False)
+    result.add_argument('--unlock',
+                        help='Unlock device',
+                        action='store_true',
+                        default=False)
+    options, args = result.parse_known_args(argv)
+    return options, args
+
 
 def main(argv):
-  (options, args) = parse_options(argv)
-  if options.capture_screen:
-    capture_screen(options.capture_screen, options.device_id)
-  if options.ensure_screen_off:
-    ensure_screen_off(options.device_id)
-  elif options.get_screen_state:
-    print(get_screen_state(options.device_id))
-  elif options.unlock:
-    unlock(options.device_id, options.device_pin)
+    (options, args) = parse_options(argv)
+    if options.capture_screen:
+        capture_screen(options.capture_screen, options.device_id)
+    if options.ensure_screen_off:
+        ensure_screen_off(options.device_id)
+    elif options.get_screen_state:
+        print(get_screen_state(options.device_id))
+    elif options.unlock:
+        unlock(options.device_id, options.device_pin)
 
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
+    sys.exit(main(sys.argv[1:]))
diff --git a/tools/startup/generate_startup_descriptors.py b/tools/startup/generate_startup_descriptors.py
index adae239..211be89 100755
--- a/tools/startup/generate_startup_descriptors.py
+++ b/tools/startup/generate_startup_descriptors.py
@@ -11,445 +11,474 @@
 import sys
 import time
 
+
 class Device:
 
-  def __init__(self, device_id, device_pin):
-    self.device_id = device_id
-    self.device_pin = device_pin
+    def __init__(self, device_id, device_pin):
+        self.device_id = device_id
+        self.device_pin = device_pin
+
 
 def extend_startup_descriptors(startup_descriptors, iteration, device, options):
-  (logcat, profile, profile_classes_and_methods) = \
-      generate_startup_profile(device, options)
-  if options.logcat:
-    write_tmp_logcat(logcat, iteration, options)
-    current_startup_descriptors = get_r8_startup_descriptors_from_logcat(
-        logcat, options)
-  else:
-    write_tmp_profile(profile, iteration, options)
-    write_tmp_profile_classes_and_methods(
-        profile_classes_and_methods, iteration, options)
-    current_startup_descriptors = \
-        profile_utils.transform_art_profile_to_r8_startup_list(
-            profile_classes_and_methods, options.generalize_synthetics)
-  write_tmp_startup_descriptors(current_startup_descriptors, iteration, options)
-  new_startup_descriptors = add_r8_startup_descriptors(
-      startup_descriptors, current_startup_descriptors)
-  number_of_new_startup_descriptors = \
-      len(new_startup_descriptors) - len(startup_descriptors)
-  if options.out is not None:
-    print(
-        'Found %i new startup descriptors in iteration %i'
-            % (number_of_new_startup_descriptors, iteration + 1))
-  return new_startup_descriptors
+    (logcat, profile, profile_classes_and_methods) = \
+        generate_startup_profile(device, options)
+    if options.logcat:
+        write_tmp_logcat(logcat, iteration, options)
+        current_startup_descriptors = get_r8_startup_descriptors_from_logcat(
+            logcat, options)
+    else:
+        write_tmp_profile(profile, iteration, options)
+        write_tmp_profile_classes_and_methods(profile_classes_and_methods,
+                                              iteration, options)
+        current_startup_descriptors = \
+            profile_utils.transform_art_profile_to_r8_startup_list(
+                profile_classes_and_methods, options.generalize_synthetics)
+    write_tmp_startup_descriptors(current_startup_descriptors, iteration,
+                                  options)
+    new_startup_descriptors = add_r8_startup_descriptors(
+        startup_descriptors, current_startup_descriptors)
+    number_of_new_startup_descriptors = \
+        len(new_startup_descriptors) - len(startup_descriptors)
+    if options.out is not None:
+        print('Found %i new startup descriptors in iteration %i' %
+              (number_of_new_startup_descriptors, iteration + 1))
+    return new_startup_descriptors
+
 
 def generate_startup_profile(device, options):
-  logcat = None
-  profile = None
-  profile_classes_and_methods = None
-  if options.use_existing_profile:
-    # Verify presence of profile.
-    adb_utils.check_app_has_profile_data(options.app_id, device.device_id)
-    profile = adb_utils.get_profile_data(options.app_id, device.device_id)
-    profile_classes_and_methods = \
-        adb_utils.get_classes_and_methods_from_app_profile(
-            options.app_id, device.device_id)
-  else:
-    # Unlock device.
-    tear_down_options = adb_utils.prepare_for_interaction_with_device(
-        device.device_id, device.device_pin)
-
-    logcat_process = None
-    if options.logcat:
-      # Clear logcat and start capturing logcat.
-      adb_utils.clear_logcat(device.device_id)
-      logcat_process = adb_utils.start_logcat(
-          device.device_id, format='tag', filter='R8:I ActivityTaskManager:I *:S')
+    logcat = None
+    profile = None
+    profile_classes_and_methods = None
+    if options.use_existing_profile:
+        # Verify presence of profile.
+        adb_utils.check_app_has_profile_data(options.app_id, device.device_id)
+        profile = adb_utils.get_profile_data(options.app_id, device.device_id)
+        profile_classes_and_methods = \
+            adb_utils.get_classes_and_methods_from_app_profile(
+                options.app_id, device.device_id)
     else:
-      # Clear existing profile data.
-      adb_utils.clear_profile_data(options.app_id, device.device_id)
+        # Unlock device.
+        tear_down_options = adb_utils.prepare_for_interaction_with_device(
+            device.device_id, device.device_pin)
 
-    # Launch activity to generate startup profile on device.
-    adb_utils.launch_activity(
-        options.app_id, options.main_activity, device.device_id)
+        logcat_process = None
+        if options.logcat:
+            # Clear logcat and start capturing logcat.
+            adb_utils.clear_logcat(device.device_id)
+            logcat_process = adb_utils.start_logcat(
+                device.device_id,
+                format='tag',
+                filter='R8:I ActivityTaskManager:I *:S')
+        else:
+            # Clear existing profile data.
+            adb_utils.clear_profile_data(options.app_id, device.device_id)
 
-    # Wait for activity startup.
-    time.sleep(options.startup_duration)
+        # Launch activity to generate startup profile on device.
+        adb_utils.launch_activity(options.app_id, options.main_activity,
+                                  device.device_id)
 
-    if options.logcat:
-      # Get startup descriptors from logcat.
-      logcat = adb_utils.stop_logcat(logcat_process)
-    else:
-      # Capture startup profile.
-      adb_utils.capture_app_profile_data(options.app_id, device.device_id)
-      profile = adb_utils.get_profile_data(options.app_id, device.device_id)
-      profile_classes_and_methods = \
-          adb_utils.get_classes_and_methods_from_app_profile(
-              options.app_id, device.device_id)
+        # Wait for activity startup.
+        time.sleep(options.startup_duration)
 
-    # Shutdown app.
-    adb_utils.stop_app(options.app_id, device.device_id)
-    adb_utils.teardown_after_interaction_with_device(
-        tear_down_options, device.device_id)
+        if options.logcat:
+            # Get startup descriptors from logcat.
+            logcat = adb_utils.stop_logcat(logcat_process)
+        else:
+            # Capture startup profile.
+            adb_utils.capture_app_profile_data(options.app_id, device.device_id)
+            profile = adb_utils.get_profile_data(options.app_id,
+                                                 device.device_id)
+            profile_classes_and_methods = \
+                adb_utils.get_classes_and_methods_from_app_profile(
+                    options.app_id, device.device_id)
 
-  return (logcat, profile, profile_classes_and_methods)
+        # Shutdown app.
+        adb_utils.stop_app(options.app_id, device.device_id)
+        adb_utils.teardown_after_interaction_with_device(
+            tear_down_options, device.device_id)
+
+    return (logcat, profile, profile_classes_and_methods)
+
 
 def get_r8_startup_descriptors_from_logcat(logcat, options):
-  post_startup = False
-  startup_descriptors = {}
-  for line in logcat:
-    line_elements = parse_logcat_line(line)
-    if line_elements is None:
-      continue
-    (priority, tag, message) = line_elements
-    if tag == 'ActivityTaskManager':
-      if message.startswith('START') \
-          or message.startswith('Activity pause timeout for') \
-          or message.startswith('Activity top resumed state loss timeout for') \
-          or message.startswith('Force removing') \
-          or message.startswith(
-              'Launch timeout has expired, giving up wake lock!'):
-        continue
-      elif message.startswith('Displayed %s/' % options.app_id):
-        print('Entering post startup: %s' % message)
-        post_startup = True
-        continue
-    elif tag == 'R8':
-      if is_startup_descriptor(message):
-        startup_descriptors[message] = {
-          'conditional_startup': False,
-          'hot': False,
-          'post_startup': post_startup,
-          'startup': True
-        }
-        continue
-    # Reaching here means we didn't expect this line.
-    report_unrecognized_logcat_line(line)
-  return startup_descriptors
+    post_startup = False
+    startup_descriptors = {}
+    for line in logcat:
+        line_elements = parse_logcat_line(line)
+        if line_elements is None:
+            continue
+        (priority, tag, message) = line_elements
+        if tag == 'ActivityTaskManager':
+            if message.startswith('START') \
+                or message.startswith('Activity pause timeout for') \
+                or message.startswith('Activity top resumed state loss timeout for') \
+                or message.startswith('Force removing') \
+                or message.startswith(
+                    'Launch timeout has expired, giving up wake lock!'):
+                continue
+            elif message.startswith('Displayed %s/' % options.app_id):
+                print('Entering post startup: %s' % message)
+                post_startup = True
+                continue
+        elif tag == 'R8':
+            if is_startup_descriptor(message):
+                startup_descriptors[message] = {
+                    'conditional_startup': False,
+                    'hot': False,
+                    'post_startup': post_startup,
+                    'startup': True
+                }
+                continue
+        # Reaching here means we didn't expect this line.
+        report_unrecognized_logcat_line(line)
+    return startup_descriptors
+
 
 def is_startup_descriptor(string):
-  # The descriptor should start with the holder (possibly prefixed with 'S').
-  if not any(string.startswith('%sL' % flags) for flags in ['', 'S']):
-    return False
-  # The descriptor should end with ';', a primitive type, or void.
-  if not string.endswith(';') \
-      and not any(string.endswith(c) for c in get_primitive_descriptors()) \
-      and not string.endswith('V'):
-    return False
-  return True
+    # The descriptor should start with the holder (possibly prefixed with 'S').
+    if not any(string.startswith('%sL' % flags) for flags in ['', 'S']):
+        return False
+    # The descriptor should end with ';', a primitive type, or void.
+    if not string.endswith(';') \
+        and not any(string.endswith(c) for c in get_primitive_descriptors()) \
+        and not string.endswith('V'):
+        return False
+    return True
+
 
 def get_primitive_descriptors():
-  return ['Z', 'B', 'S', 'C', 'I', 'F', 'J', 'D']
+    return ['Z', 'B', 'S', 'C', 'I', 'F', 'J', 'D']
+
 
 def parse_logcat_line(line):
-  if line == '--------- beginning of kernel':
-    return None
-  if line == '--------- beginning of main':
-    return None
-  if line == '--------- beginning of system':
-    return None
+    if line == '--------- beginning of kernel':
+        return None
+    if line == '--------- beginning of main':
+        return None
+    if line == '--------- beginning of system':
+        return None
 
-  priority = None
-  tag = None
+    priority = None
+    tag = None
 
-  try:
-    priority_end = line.index('/')
-    priority = line[0:priority_end]
-    line = line[priority_end + 1:]
-  except ValueError:
-    return report_unrecognized_logcat_line(line)
+    try:
+        priority_end = line.index('/')
+        priority = line[0:priority_end]
+        line = line[priority_end + 1:]
+    except ValueError:
+        return report_unrecognized_logcat_line(line)
 
-  try:
-    tag_end = line.index(':')
-    tag = line[0:tag_end].strip()
-    line = line[tag_end + 1 :]
-  except ValueError:
-    return report_unrecognized_logcat_line(line)
+    try:
+        tag_end = line.index(':')
+        tag = line[0:tag_end].strip()
+        line = line[tag_end + 1:]
+    except ValueError:
+        return report_unrecognized_logcat_line(line)
 
-  message = line.strip()
-  return (priority, tag, message)
+    message = line.strip()
+    return (priority, tag, message)
+
 
 def report_unrecognized_logcat_line(line):
-  print('Unrecognized line in logcat: %s' % line)
+    print('Unrecognized line in logcat: %s' % line)
 
-def add_r8_startup_descriptors(old_startup_descriptors, startup_descriptors_to_add):
-  new_startup_descriptors = {}
-  if len(old_startup_descriptors) == 0:
-    for startup_descriptor, flags in startup_descriptors_to_add.items():
-      new_startup_descriptors[startup_descriptor] = flags.copy()
-  else:
-    # Merge the new startup descriptors with the old descriptors in a way so
-    # that new startup descriptors are added next to the startup descriptors
-    # they are close to in the newly generated list of startup descriptors.
-    startup_descriptors_to_add_after_key = {}
-    startup_descriptors_to_add_in_the_end = {}
-    closest_seen_startup_descriptor = None
-    for startup_descriptor, flags in startup_descriptors_to_add.items():
-      if startup_descriptor in old_startup_descriptors:
-        closest_seen_startup_descriptor = startup_descriptor
-      else:
-        if closest_seen_startup_descriptor is None:
-          # Insert this new startup descriptor in the end of the result.
-          startup_descriptors_to_add_in_the_end[startup_descriptor] = flags
-        else:
-          # Record that this should be inserted after
-          # closest_seen_startup_descriptor.
-          pending_startup_descriptors = \
-              startup_descriptors_to_add_after_key.setdefault(
-                  closest_seen_startup_descriptor, {})
-          pending_startup_descriptors[startup_descriptor] = flags
-    for startup_descriptor, flags in old_startup_descriptors.items():
-      # Merge flags if this also exists in startup_descriptors_to_add.
-      if startup_descriptor in startup_descriptors_to_add:
-        merged_flags = flags.copy()
-        other_flags = startup_descriptors_to_add[startup_descriptor]
-        assert not other_flags['conditional_startup']
-        merged_flags['hot'] = \
-            merged_flags['hot'] or other_flags['hot']
-        merged_flags['startup'] = \
-            merged_flags['startup'] or other_flags['startup']
-        merged_flags['post_startup'] = \
-            merged_flags['post_startup'] or other_flags['post_startup']
-        new_startup_descriptors[startup_descriptor] = merged_flags
-      else:
-        new_startup_descriptors[startup_descriptor] = flags.copy()
-      # Flush startup descriptors that followed this item in the new trace.
-      if startup_descriptor in startup_descriptors_to_add_after_key:
-        pending_startup_descriptors = \
-            startup_descriptors_to_add_after_key[startup_descriptor]
-        for pending_startup_descriptor, pending_flags \
-            in pending_startup_descriptors.items():
-          new_startup_descriptors[pending_startup_descriptor] = \
-              pending_flags.copy()
-    # Insert remaining new startup descriptors in the end.
-    for startup_descriptor, flags \
-        in startup_descriptors_to_add_in_the_end.items():
-      assert startup_descriptor not in new_startup_descriptors
-      new_startup_descriptors[startup_descriptor] = flags.copy()
-  return new_startup_descriptors
+
+def add_r8_startup_descriptors(old_startup_descriptors,
+                               startup_descriptors_to_add):
+    new_startup_descriptors = {}
+    if len(old_startup_descriptors) == 0:
+        for startup_descriptor, flags in startup_descriptors_to_add.items():
+            new_startup_descriptors[startup_descriptor] = flags.copy()
+    else:
+        # Merge the new startup descriptors with the old descriptors in a way so
+        # that new startup descriptors are added next to the startup descriptors
+        # they are close to in the newly generated list of startup descriptors.
+        startup_descriptors_to_add_after_key = {}
+        startup_descriptors_to_add_in_the_end = {}
+        closest_seen_startup_descriptor = None
+        for startup_descriptor, flags in startup_descriptors_to_add.items():
+            if startup_descriptor in old_startup_descriptors:
+                closest_seen_startup_descriptor = startup_descriptor
+            else:
+                if closest_seen_startup_descriptor is None:
+                    # Insert this new startup descriptor in the end of the result.
+                    startup_descriptors_to_add_in_the_end[
+                        startup_descriptor] = flags
+                else:
+                    # Record that this should be inserted after
+                    # closest_seen_startup_descriptor.
+                    pending_startup_descriptors = \
+                        startup_descriptors_to_add_after_key.setdefault(
+                            closest_seen_startup_descriptor, {})
+                    pending_startup_descriptors[startup_descriptor] = flags
+        for startup_descriptor, flags in old_startup_descriptors.items():
+            # Merge flags if this also exists in startup_descriptors_to_add.
+            if startup_descriptor in startup_descriptors_to_add:
+                merged_flags = flags.copy()
+                other_flags = startup_descriptors_to_add[startup_descriptor]
+                assert not other_flags['conditional_startup']
+                merged_flags['hot'] = \
+                    merged_flags['hot'] or other_flags['hot']
+                merged_flags['startup'] = \
+                    merged_flags['startup'] or other_flags['startup']
+                merged_flags['post_startup'] = \
+                    merged_flags['post_startup'] or other_flags['post_startup']
+                new_startup_descriptors[startup_descriptor] = merged_flags
+            else:
+                new_startup_descriptors[startup_descriptor] = flags.copy()
+            # Flush startup descriptors that followed this item in the new trace.
+            if startup_descriptor in startup_descriptors_to_add_after_key:
+                pending_startup_descriptors = \
+                    startup_descriptors_to_add_after_key[startup_descriptor]
+                for pending_startup_descriptor, pending_flags \
+                    in pending_startup_descriptors.items():
+                    new_startup_descriptors[pending_startup_descriptor] = \
+                        pending_flags.copy()
+        # Insert remaining new startup descriptors in the end.
+        for startup_descriptor, flags \
+            in startup_descriptors_to_add_in_the_end.items():
+            assert startup_descriptor not in new_startup_descriptors
+            new_startup_descriptors[startup_descriptor] = flags.copy()
+    return new_startup_descriptors
+
 
 def write_tmp_binary_artifact(artifact, iteration, options, name):
-  if not options.tmp_dir:
-    return
-  out_dir = os.path.join(options.tmp_dir, str(iteration))
-  os.makedirs(out_dir, exist_ok=True)
-  path = os.path.join(out_dir, name)
-  with open(path, 'wb') as f:
-    f.write(artifact)
+    if not options.tmp_dir:
+        return
+    out_dir = os.path.join(options.tmp_dir, str(iteration))
+    os.makedirs(out_dir, exist_ok=True)
+    path = os.path.join(out_dir, name)
+    with open(path, 'wb') as f:
+        f.write(artifact)
 
-def write_tmp_textual_artifact(artifact, iteration, options, name, item_to_string=None):
-  if not options.tmp_dir:
-    return
-  out_dir = os.path.join(options.tmp_dir, str(iteration))
-  os.makedirs(out_dir, exist_ok=True)
-  path = os.path.join(out_dir, name)
-  with open(path, 'w') as f:
-    for item in artifact:
-      f.write(item if item_to_string is None else item_to_string(item))
-      f.write('\n')
+
+def write_tmp_textual_artifact(artifact,
+                               iteration,
+                               options,
+                               name,
+                               item_to_string=None):
+    if not options.tmp_dir:
+        return
+    out_dir = os.path.join(options.tmp_dir, str(iteration))
+    os.makedirs(out_dir, exist_ok=True)
+    path = os.path.join(out_dir, name)
+    with open(path, 'w') as f:
+        for item in artifact:
+            f.write(item if item_to_string is None else item_to_string(item))
+            f.write('\n')
+
 
 def write_tmp_logcat(logcat, iteration, options):
-  write_tmp_textual_artifact(logcat, iteration, options, 'logcat.txt')
+    write_tmp_textual_artifact(logcat, iteration, options, 'logcat.txt')
+
 
 def write_tmp_profile(profile, iteration, options):
-  write_tmp_binary_artifact(profile, iteration, options, 'primary.prof')
+    write_tmp_binary_artifact(profile, iteration, options, 'primary.prof')
 
-def write_tmp_profile_classes_and_methods(
-    profile_classes_and_methods, iteration, options):
-  def item_to_string(item):
-    (descriptor, flags) = item
-    return '%s%s%s%s' % (
-        'H' if flags.get('hot') else '',
-        'S' if flags.get('startup') else '',
-        'P' if flags.get('post_startup') else '',
-        descriptor)
-  write_tmp_textual_artifact(
-      profile_classes_and_methods.items(),
-      iteration,
-      options,
-      'profile.txt',
-      item_to_string)
+
+def write_tmp_profile_classes_and_methods(profile_classes_and_methods,
+                                          iteration, options):
+
+    def item_to_string(item):
+        (descriptor, flags) = item
+        return '%s%s%s%s' % ('H' if flags.get('hot') else '',
+                             'S' if flags.get('startup') else '', 'P'
+                             if flags.get('post_startup') else '', descriptor)
+
+    write_tmp_textual_artifact(profile_classes_and_methods.items(), iteration,
+                               options, 'profile.txt', item_to_string)
+
 
 def write_tmp_startup_descriptors(startup_descriptors, iteration, options):
-  lines = [
-      startup_descriptor_to_string(startup_descriptor, flags)
-      for startup_descriptor, flags in startup_descriptors.items()]
-  write_tmp_textual_artifact(
-      lines, iteration, options, 'startup-descriptors.txt')
+    lines = [
+        startup_descriptor_to_string(startup_descriptor, flags)
+        for startup_descriptor, flags in startup_descriptors.items()
+    ]
+    write_tmp_textual_artifact(lines, iteration, options,
+                               'startup-descriptors.txt')
+
 
 def startup_descriptor_to_string(startup_descriptor, flags):
-  result = ''
-  if flags['hot']:
-    result += 'H'
-  if flags['startup']:
-    result += 'S'
-  if flags['post_startup']:
-    result += 'P'
-  result += startup_descriptor
-  return result
+    result = ''
+    if flags['hot']:
+        result += 'H'
+    if flags['startup']:
+        result += 'S'
+    if flags['post_startup']:
+        result += 'P'
+    result += startup_descriptor
+    return result
+
 
 def should_include_startup_descriptor(descriptor, flags, options):
-  if flags.get('conditional_startup') \
-      and not options.include_conditional_startup:
-    return False
-  if flags.get('post_startup') \
-      and not flags.get('startup') \
-      and not options.include_post_startup:
-    return False
-  return True
+    if flags.get('conditional_startup') \
+        and not options.include_conditional_startup:
+        return False
+    if flags.get('post_startup') \
+        and not flags.get('startup') \
+        and not options.include_post_startup:
+        return False
+    return True
+
 
 def parse_options(argv):
-  result = argparse.ArgumentParser(
-      description='Generate a perfetto trace file.')
-  result.add_argument('--apk',
-                      help='Path to the .apk')
-  result.add_argument('--apks',
-                      help='Path to the .apks')
-  result.add_argument('--app-id',
-                      help='The application ID of interest',
-                      required=True)
-  result.add_argument('--bundle',
-                      help='Path to the .aab')
-  result.add_argument('--device-id',
-                      help='Device id (e.g., emulator-5554).',
-                      action='append')
-  result.add_argument('--device-pin',
-                      help='Device pin code (e.g., 1234)',
-                      action='append')
-  result.add_argument('--generalize-synthetics',
-                      help='Whether synthetics should be abstracted into their '
-                           'synthetic contexts',
-                      action='store_true',
-                      default=False)
-  result.add_argument('--grant-post-notification-permission',
-                      help='Grants the android.permission.POST_NOTIFICATIONS '
-                           'permission before launching the app',
-                      default=False,
-                      action='store_true')
-  result.add_argument('--logcat',
-                      action='store_true',
-                      default=False)
-  result.add_argument('--include-conditional-startup',
-                      help='Include conditional startup classes and methods in '
-                           'the R8 startup descriptors',
-                      action='store_true',
-                      default=False)
-  result.add_argument('--include-post-startup',
-                      help='Include post startup classes and methods in the R8 '
-                           'startup descriptors',
-                      action='store_true',
-                      default=False)
-  result.add_argument('--iterations',
-                      help='Number of profiles to generate',
-                      default=1,
-                      type=int)
-  result.add_argument('--main-activity',
-                      help='Main activity class name')
-  result.add_argument('--out',
-                      help='File where to store startup descriptors (defaults '
-                           'to stdout)')
-  result.add_argument('--startup-duration',
-                      help='Duration in seconds before shutting down app',
-                      default=15,
-                      type=int)
-  result.add_argument('--tmp-dir',
-                      help='Directory where to store intermediate artifacts'
-                            ' (by default these are not emitted)')
-  result.add_argument('--until-stable',
-                      help='Repeat profile generation until no new startup '
-                           'descriptors are found',
-                      action='store_true',
-                      default=False)
-  result.add_argument('--until-stable-iterations',
-                      help='Number of times that profile generation must must '
-                           'not find new startup descriptors before exiting',
-                      default=1,
-                      type=int)
-  result.add_argument('--use-existing-profile',
-                      help='Do not launch app to generate startup profile',
-                      action='store_true',
-                      default=False)
-  options, args = result.parse_known_args(argv)
+    result = argparse.ArgumentParser(
+        description='Generate a perfetto trace file.')
+    result.add_argument('--apk', help='Path to the .apk')
+    result.add_argument('--apks', help='Path to the .apks')
+    result.add_argument('--app-id',
+                        help='The application ID of interest',
+                        required=True)
+    result.add_argument('--bundle', help='Path to the .aab')
+    result.add_argument('--device-id',
+                        help='Device id (e.g., emulator-5554).',
+                        action='append')
+    result.add_argument('--device-pin',
+                        help='Device pin code (e.g., 1234)',
+                        action='append')
+    result.add_argument(
+        '--generalize-synthetics',
+        help='Whether synthetics should be abstracted into their '
+        'synthetic contexts',
+        action='store_true',
+        default=False)
+    result.add_argument('--grant-post-notification-permission',
+                        help='Grants the android.permission.POST_NOTIFICATIONS '
+                        'permission before launching the app',
+                        default=False,
+                        action='store_true')
+    result.add_argument('--logcat', action='store_true', default=False)
+    result.add_argument(
+        '--include-conditional-startup',
+        help='Include conditional startup classes and methods in '
+        'the R8 startup descriptors',
+        action='store_true',
+        default=False)
+    result.add_argument(
+        '--include-post-startup',
+        help='Include post startup classes and methods in the R8 '
+        'startup descriptors',
+        action='store_true',
+        default=False)
+    result.add_argument('--iterations',
+                        help='Number of profiles to generate',
+                        default=1,
+                        type=int)
+    result.add_argument('--main-activity', help='Main activity class name')
+    result.add_argument(
+        '--out',
+        help='File where to store startup descriptors (defaults '
+        'to stdout)')
+    result.add_argument('--startup-duration',
+                        help='Duration in seconds before shutting down app',
+                        default=15,
+                        type=int)
+    result.add_argument('--tmp-dir',
+                        help='Directory where to store intermediate artifacts'
+                        ' (by default these are not emitted)')
+    result.add_argument('--until-stable',
+                        help='Repeat profile generation until no new startup '
+                        'descriptors are found',
+                        action='store_true',
+                        default=False)
+    result.add_argument(
+        '--until-stable-iterations',
+        help='Number of times that profile generation must must '
+        'not find new startup descriptors before exiting',
+        default=1,
+        type=int)
+    result.add_argument('--use-existing-profile',
+                        help='Do not launch app to generate startup profile',
+                        action='store_true',
+                        default=False)
+    options, args = result.parse_known_args(argv)
 
-  # Read the device pins.
-  device_pins = options.device_pin or []
-  del options.device_pin
+    # Read the device pins.
+    device_pins = options.device_pin or []
+    del options.device_pin
 
-  # Convert the device ids and pins into a list of devices.
-  options.devices = []
-  if options.device_id is None:
-    # Assume a single device is attached.
-    options.devices.append(
-        Device(None, device_pins[0] if len(device_pins) > 0 else None))
-  else:
-    for i in range(len(options.device_id)):
-      device_id = options.device_id[i]
-      device_pin = device_pins[i] if i < len(device_pins) else None
-      options.devices.append(Device(device_id, device_pin))
-  del options.device_id
+    # Convert the device ids and pins into a list of devices.
+    options.devices = []
+    if options.device_id is None:
+        # Assume a single device is attached.
+        options.devices.append(
+            Device(None, device_pins[0] if len(device_pins) > 0 else None))
+    else:
+        for i in range(len(options.device_id)):
+            device_id = options.device_id[i]
+            device_pin = device_pins[i] if i < len(device_pins) else None
+            options.devices.append(Device(device_id, device_pin))
+    del options.device_id
 
-  paths = [
-      path for path in [options.apk, options.apks, options.bundle]
-      if path is not None]
-  assert len(paths) <= 1, 'Expected at most one .apk, .apks, or .aab file.'
-  assert options.main_activity is not None or options.use_existing_profile, \
-      'Argument --main-activity is required except when running with ' \
-      '--use-existing-profile.'
+    paths = [
+        path for path in [options.apk, options.apks, options.bundle]
+        if path is not None
+    ]
+    assert len(paths) <= 1, 'Expected at most one .apk, .apks, or .aab file.'
+    assert options.main_activity is not None or options.use_existing_profile, \
+        'Argument --main-activity is required except when running with ' \
+        '--use-existing-profile.'
 
-  return options, args
+    return options, args
+
 
 def run_on_device(device, options, startup_descriptors):
-  adb_utils.root(device.device_id)
-  if options.apk:
-    adb_utils.uninstall(options.app_id, device.device_id)
-    adb_utils.install(options.apk, device.device_id)
-  elif options.apks:
-    adb_utils.uninstall(options.app_id, device.device_id)
-    adb_utils.install_apks(options.apks, device.device_id)
-  elif options.bundle:
-    adb_utils.uninstall(options.app_id, device.device_id)
-    adb_utils.install_bundle(options.bundle, device.device_id)
-  # Grant notifications.
-  if options.grant_post_notification_permission:
-    adb_utils.grant(
-        options.app_id,
-        'android.permission.POST_NOTIFICATIONS',
-        device.device_id)
-  if options.until_stable:
-    iteration = 0
-    stable_iterations = 0
-    while True:
-      old_startup_descriptors = startup_descriptors
-      startup_descriptors = extend_startup_descriptors(
-          old_startup_descriptors, iteration, device, options)
-      diff = len(startup_descriptors) - len(old_startup_descriptors)
-      if diff == 0:
-        stable_iterations = stable_iterations + 1
-        if stable_iterations == options.until_stable_iterations:
-          break
-      else:
+    adb_utils.root(device.device_id)
+    if options.apk:
+        adb_utils.uninstall(options.app_id, device.device_id)
+        adb_utils.install(options.apk, device.device_id)
+    elif options.apks:
+        adb_utils.uninstall(options.app_id, device.device_id)
+        adb_utils.install_apks(options.apks, device.device_id)
+    elif options.bundle:
+        adb_utils.uninstall(options.app_id, device.device_id)
+        adb_utils.install_bundle(options.bundle, device.device_id)
+    # Grant notifications.
+    if options.grant_post_notification_permission:
+        adb_utils.grant(options.app_id, 'android.permission.POST_NOTIFICATIONS',
+                        device.device_id)
+    if options.until_stable:
+        iteration = 0
         stable_iterations = 0
-      iteration = iteration + 1
-  else:
-    for iteration in range(options.iterations):
-      startup_descriptors = extend_startup_descriptors(
-          startup_descriptors, iteration, device, options)
-  return startup_descriptors
+        while True:
+            old_startup_descriptors = startup_descriptors
+            startup_descriptors = extend_startup_descriptors(
+                old_startup_descriptors, iteration, device, options)
+            diff = len(startup_descriptors) - len(old_startup_descriptors)
+            if diff == 0:
+                stable_iterations = stable_iterations + 1
+                if stable_iterations == options.until_stable_iterations:
+                    break
+            else:
+                stable_iterations = 0
+            iteration = iteration + 1
+    else:
+        for iteration in range(options.iterations):
+            startup_descriptors = extend_startup_descriptors(
+                startup_descriptors, iteration, device, options)
+    return startup_descriptors
+
 
 def main(argv):
-  (options, args) = parse_options(argv)
-  startup_descriptors = {}
-  for device in options.devices:
-    startup_descriptors = run_on_device(device, options, startup_descriptors)
-  if options.out is not None:
-    with open(options.out, 'w') as f:
-      for startup_descriptor, flags in startup_descriptors.items():
-        if should_include_startup_descriptor(startup_descriptor, flags, options):
-          f.write(startup_descriptor_to_string(startup_descriptor, flags))
-          f.write('\n')
-  else:
-    for startup_descriptor, flags in startup_descriptors.items():
-      if should_include_startup_descriptor(startup_descriptor, flags, options):
-        print(startup_descriptor_to_string(startup_descriptor, flags))
+    (options, args) = parse_options(argv)
+    startup_descriptors = {}
+    for device in options.devices:
+        startup_descriptors = run_on_device(device, options,
+                                            startup_descriptors)
+    if options.out is not None:
+        with open(options.out, 'w') as f:
+            for startup_descriptor, flags in startup_descriptors.items():
+                if should_include_startup_descriptor(startup_descriptor, flags,
+                                                     options):
+                    f.write(
+                        startup_descriptor_to_string(startup_descriptor, flags))
+                    f.write('\n')
+    else:
+        for startup_descriptor, flags in startup_descriptors.items():
+            if should_include_startup_descriptor(startup_descriptor, flags,
+                                                 options):
+                print(startup_descriptor_to_string(startup_descriptor, flags))
+
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
+    sys.exit(main(sys.argv[1:]))
diff --git a/tools/startup/instrument.py b/tools/startup/instrument.py
index ecefe55..9752670 100755
--- a/tools/startup/instrument.py
+++ b/tools/startup/instrument.py
@@ -18,117 +18,126 @@
 import utils
 import zip_utils
 
+
 def parse_options(argv):
-  result = argparse.ArgumentParser(
-      description='Instrument the dex files of a given apk to print what is '
-                  'executed.')
-  result.add_argument('--apk',
-                      help='Path to the .apk',
-                      required=True)
-  result.add_argument('--dex-files',
-                      action='append',
-                      help='Name of dex files to instrument')
-  result.add_argument('--discard',
-                      action='append',
-                      help='Name of dex files to discard')
-  result.add_argument('--out',
-                      help='Destination of resulting apk',
-                      required=True)
-  options, args = result.parse_known_args(argv)
-  return options, args
+    result = argparse.ArgumentParser(
+        description='Instrument the dex files of a given apk to print what is '
+        'executed.')
+    result.add_argument('--apk', help='Path to the .apk', required=True)
+    result.add_argument('--dex-files',
+                        action='append',
+                        help='Name of dex files to instrument')
+    result.add_argument('--discard',
+                        action='append',
+                        help='Name of dex files to discard')
+    result.add_argument('--out',
+                        help='Destination of resulting apk',
+                        required=True)
+    options, args = result.parse_known_args(argv)
+    return options, args
+
 
 def add_instrumented_dex(dex_file, instrumented_dex_index, instrumented_dir):
-  dex_name = get_dex_name(instrumented_dex_index)
-  destination = os.path.join(instrumented_dir, dex_name)
-  shutil.move(dex_file, destination)
+    dex_name = get_dex_name(instrumented_dex_index)
+    destination = os.path.join(instrumented_dir, dex_name)
+    shutil.move(dex_file, destination)
+
 
 def get_dex_name(dex_index):
-  assert dex_index > 0
-  return 'classes.dex' if dex_index == 1 else ('classes%s.dex' % dex_index)
+    assert dex_index > 0
+    return 'classes.dex' if dex_index == 1 else ('classes%s.dex' % dex_index)
 
-def instrument_dex_file(dex_file, include_instrumentation_server, options, tmp_dir):
-  d8_cmd = [
-      'java',
-      '-cp', utils.R8_JAR,
-      '-Dcom.android.tools.r8.startup.instrumentation.instrument=1',
-      '-Dcom.android.tools.r8.startup.instrumentation.instrumentationtag=R8']
-  if not include_instrumentation_server:
-    # We avoid injecting the InstrumentationServer by specifying it should only
-    # be added if foo.bar.Baz is in the program.
-    d8_cmd.append(
-        '-Dcom.android.tools.r8.startup.instrumentation.instrumentationserversyntheticcontext=foo.bar.Baz')
-  d8_cmd.extend([
-      'com.android.tools.r8.D8',
-      '--min-api', str(apk_utils.get_min_api(options.apk)),
-      '--output', tmp_dir,
-      '--release',
-      dex_file])
-  subprocess.check_call(d8_cmd)
-  instrumented_dex_files = []
-  instrumented_dex_index = 1
-  while True:
-    instrumented_dex_name = get_dex_name(instrumented_dex_index)
-    instrumented_dex_file = os.path.join(tmp_dir, instrumented_dex_name)
-    if not os.path.exists(instrumented_dex_file):
-      break
-    instrumented_dex_files.append(instrumented_dex_file)
-    instrumented_dex_index = instrumented_dex_index + 1
-  assert len(instrumented_dex_files) > 0
-  return instrumented_dex_files
+
+def instrument_dex_file(dex_file, include_instrumentation_server, options,
+                        tmp_dir):
+    d8_cmd = [
+        'java', '-cp', utils.R8_JAR,
+        '-Dcom.android.tools.r8.startup.instrumentation.instrument=1',
+        '-Dcom.android.tools.r8.startup.instrumentation.instrumentationtag=R8'
+    ]
+    if not include_instrumentation_server:
+        # We avoid injecting the InstrumentationServer by specifying it should only
+        # be added if foo.bar.Baz is in the program.
+        d8_cmd.append(
+            '-Dcom.android.tools.r8.startup.instrumentation.instrumentationserversyntheticcontext=foo.bar.Baz'
+        )
+    d8_cmd.extend([
+        'com.android.tools.r8.D8', '--min-api',
+        str(apk_utils.get_min_api(options.apk)), '--output', tmp_dir,
+        '--release', dex_file
+    ])
+    subprocess.check_call(d8_cmd)
+    instrumented_dex_files = []
+    instrumented_dex_index = 1
+    while True:
+        instrumented_dex_name = get_dex_name(instrumented_dex_index)
+        instrumented_dex_file = os.path.join(tmp_dir, instrumented_dex_name)
+        if not os.path.exists(instrumented_dex_file):
+            break
+        instrumented_dex_files.append(instrumented_dex_file)
+        instrumented_dex_index = instrumented_dex_index + 1
+    assert len(instrumented_dex_files) > 0
+    return instrumented_dex_files
+
 
 def should_discard_dex_file(dex_name, options):
-  return options.discard is not None and dex_name in options.discard
+    return options.discard is not None and dex_name in options.discard
+
 
 def should_instrument_dex_file(dex_name, options):
-  return options.dex_files is not None and dex_name in options.dex_files
+    return options.dex_files is not None and dex_name in options.dex_files
+
 
 def main(argv):
-  options, args = parse_options(argv)
-  with utils.TempDir() as tmp_dir:
-    # Extract the dex files of the apk.
-    uninstrumented_dir = os.path.join(tmp_dir, 'uninstrumented')
-    os.mkdir(uninstrumented_dir)
+    options, args = parse_options(argv)
+    with utils.TempDir() as tmp_dir:
+        # Extract the dex files of the apk.
+        uninstrumented_dir = os.path.join(tmp_dir, 'uninstrumented')
+        os.mkdir(uninstrumented_dir)
 
-    dex_predicate = \
-        lambda name : name.startswith('classes') and name.endswith('.dex')
-    zip_utils.extract_all_that_matches(
-        options.apk, uninstrumented_dir, dex_predicate)
+        dex_predicate = \
+            lambda name : name.startswith('classes') and name.endswith('.dex')
+        zip_utils.extract_all_that_matches(options.apk, uninstrumented_dir,
+                                           dex_predicate)
 
-    # Instrument each dex one by one.
-    instrumented_dir = os.path.join(tmp_dir, 'instrumented')
-    os.mkdir(instrumented_dir)
+        # Instrument each dex one by one.
+        instrumented_dir = os.path.join(tmp_dir, 'instrumented')
+        os.mkdir(instrumented_dir)
 
-    include_instrumentation_server = True
-    instrumented_dex_index = 1
-    uninstrumented_dex_index = 1
-    while True:
-      dex_name = get_dex_name(uninstrumented_dex_index)
-      dex_file = os.path.join(uninstrumented_dir, dex_name)
-      if not os.path.exists(dex_file):
-        break
-      if not should_discard_dex_file(dex_name, options):
-        if should_instrument_dex_file(dex_name, options):
-          with utils.TempDir() as tmp_instrumentation_dir:
-            instrumented_dex_files = \
-                instrument_dex_file(
-                    dex_file,
-                    include_instrumentation_server,
-                    options,
-                    tmp_instrumentation_dir)
-            for instrumented_dex_file in instrumented_dex_files:
-              add_instrumented_dex(
-                  instrumented_dex_file, instrumented_dex_index, instrumented_dir)
-              instrumented_dex_index = instrumented_dex_index + 1
-            include_instrumentation_server = False
-        else:
-          add_instrumented_dex(dex_file, instrumented_dex_index, instrumented_dir)
-          instrumented_dex_index = instrumented_dex_index + 1
-      uninstrumented_dex_index = uninstrumented_dex_index + 1
+        include_instrumentation_server = True
+        instrumented_dex_index = 1
+        uninstrumented_dex_index = 1
+        while True:
+            dex_name = get_dex_name(uninstrumented_dex_index)
+            dex_file = os.path.join(uninstrumented_dir, dex_name)
+            if not os.path.exists(dex_file):
+                break
+            if not should_discard_dex_file(dex_name, options):
+                if should_instrument_dex_file(dex_name, options):
+                    with utils.TempDir() as tmp_instrumentation_dir:
+                        instrumented_dex_files = \
+                            instrument_dex_file(
+                                dex_file,
+                                include_instrumentation_server,
+                                options,
+                                tmp_instrumentation_dir)
+                        for instrumented_dex_file in instrumented_dex_files:
+                            add_instrumented_dex(instrumented_dex_file,
+                                                 instrumented_dex_index,
+                                                 instrumented_dir)
+                            instrumented_dex_index = instrumented_dex_index + 1
+                        include_instrumentation_server = False
+                else:
+                    add_instrumented_dex(dex_file, instrumented_dex_index,
+                                         instrumented_dir)
+                    instrumented_dex_index = instrumented_dex_index + 1
+            uninstrumented_dex_index = uninstrumented_dex_index + 1
 
-    assert instrumented_dex_index > 1
+        assert instrumented_dex_index > 1
 
-    # Masseur APK.
-    apk_masseur.masseur(options.apk, dex=instrumented_dir, out=options.out)
+        # Masseur APK.
+        apk_masseur.masseur(options.apk, dex=instrumented_dir, out=options.out)
+
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
+    sys.exit(main(sys.argv[1:]))
diff --git a/tools/startup/measure_startup.py b/tools/startup/measure_startup.py
index 57f6cb4..7e97735 100755
--- a/tools/startup/measure_startup.py
+++ b/tools/startup/measure_startup.py
@@ -18,446 +18,461 @@
 import perfetto_utils
 import utils
 
+
 def setup(options):
-  # Increase screen off timeout to avoid device screen turns off.
-  twenty_four_hours_in_millis = 24 * 60 * 60 * 1000
-  previous_screen_off_timeout = adb_utils.get_screen_off_timeout(
-      options.device_id)
-  adb_utils.set_screen_off_timeout(
-      twenty_four_hours_in_millis, options.device_id)
+    # Increase screen off timeout to avoid device screen turns off.
+    twenty_four_hours_in_millis = 24 * 60 * 60 * 1000
+    previous_screen_off_timeout = adb_utils.get_screen_off_timeout(
+        options.device_id)
+    adb_utils.set_screen_off_timeout(twenty_four_hours_in_millis,
+                                     options.device_id)
 
-  # Unlock device.
-  adb_utils.unlock(options.device_id, options.device_pin)
+    # Unlock device.
+    adb_utils.unlock(options.device_id, options.device_pin)
 
-  teardown_options = {
-    'previous_screen_off_timeout': previous_screen_off_timeout
-  }
-  return teardown_options
+    teardown_options = {
+        'previous_screen_off_timeout': previous_screen_off_timeout
+    }
+    return teardown_options
+
 
 def teardown(options, teardown_options):
-  # Reset screen off timeout.
-  adb_utils.set_screen_off_timeout(
-      teardown_options['previous_screen_off_timeout'],
-      options.device_id)
+    # Reset screen off timeout.
+    adb_utils.set_screen_off_timeout(
+        teardown_options['previous_screen_off_timeout'], options.device_id)
+
 
 def run_all(apk_or_apks, options, tmp_dir):
-  # Launch app while collecting information.
-  data_total = {}
-  for iteration in range(1, options.iterations + 1):
-    print('Starting iteration %i' % iteration)
-    out_dir = os.path.join(options.out_dir, str(iteration))
-    teardown_options = setup_for_run(apk_or_apks, out_dir, options)
-    data = run(out_dir, options, tmp_dir)
-    teardown_for_run(out_dir, options, teardown_options)
-    add_data(data_total, data)
-    print('Result:')
-    print(data)
-    print(compute_data_summary(data_total))
-    print('Done')
-  print('Average result:')
-  data_summary = compute_data_summary(data_total)
-  print(data_summary)
-  write_data_to_dir(options.out_dir, data_summary)
-  if options.out:
-    write_data_to_file(options.out, data_summary)
+    # Launch app while collecting information.
+    data_total = {}
+    for iteration in range(1, options.iterations + 1):
+        print('Starting iteration %i' % iteration)
+        out_dir = os.path.join(options.out_dir, str(iteration))
+        teardown_options = setup_for_run(apk_or_apks, out_dir, options)
+        data = run(out_dir, options, tmp_dir)
+        teardown_for_run(out_dir, options, teardown_options)
+        add_data(data_total, data)
+        print('Result:')
+        print(data)
+        print(compute_data_summary(data_total))
+        print('Done')
+    print('Average result:')
+    data_summary = compute_data_summary(data_total)
+    print(data_summary)
+    write_data_to_dir(options.out_dir, data_summary)
+    if options.out:
+        write_data_to_file(options.out, data_summary)
+
 
 def compute_data_summary(data_total):
-  data_summary = {}
-  for key, value in data_total.items():
-    if not isinstance(value, list):
-      data_summary[key] = value
-      continue
-    data_summary['%s_avg' % key] = round(statistics.mean(value), 1)
-    data_summary['%s_med' % key] = statistics.median(value)
-    data_summary['%s_min' % key] = min(value)
-    data_summary['%s_max' % key] = max(value)
-  return data_summary
+    data_summary = {}
+    for key, value in data_total.items():
+        if not isinstance(value, list):
+            data_summary[key] = value
+            continue
+        data_summary['%s_avg' % key] = round(statistics.mean(value), 1)
+        data_summary['%s_med' % key] = statistics.median(value)
+        data_summary['%s_min' % key] = min(value)
+        data_summary['%s_max' % key] = max(value)
+    return data_summary
+
 
 def setup_for_run(apk_or_apks, out_dir, options):
-  adb_utils.root(options.device_id)
+    adb_utils.root(options.device_id)
 
-  print('Installing')
-  adb_utils.uninstall(options.app_id, options.device_id)
-  if apk_or_apks['apk']:
-    adb_utils.install(apk_or_apks['apk'], options.device_id)
-  else:
-    assert apk_or_apks['apks']
-    adb_utils.install_apks(apk_or_apks['apks'], options.device_id)
-
-  os.makedirs(out_dir, exist_ok=True)
-
-  # Grant notifications.
-  if options.grant_post_notification_permission:
-    adb_utils.grant(
-        options.app_id,
-        'android.permission.POST_NOTIFICATIONS',
-        options.device_id)
-
-  # AOT compile.
-  if options.aot:
-    print('AOT compiling')
-    if options.baseline_profile:
-      adb_utils.clear_profile_data(options.app_id, options.device_id)
-      if options.baseline_profile_install == 'adb':
-        adb_utils.install_profile_using_adb(
-            options.app_id, options.baseline_profile, options.device_id)
-      else:
-        assert options.baseline_profile_install == 'profileinstaller'
-        adb_utils.install_profile_using_profileinstaller(
-            options.app_id, options.device_id)
+    print('Installing')
+    adb_utils.uninstall(options.app_id, options.device_id)
+    if apk_or_apks['apk']:
+        adb_utils.install(apk_or_apks['apk'], options.device_id)
     else:
-      adb_utils.force_compilation(options.app_id, options.device_id)
+        assert apk_or_apks['apks']
+        adb_utils.install_apks(apk_or_apks['apks'], options.device_id)
 
-  # Cooldown and then unlock device.
-  if options.cooldown > 0:
-    print('Cooling down for %i seconds' % options.cooldown)
-    assert adb_utils.get_screen_state(options.device_id).is_off()
-    time.sleep(options.cooldown)
-    teardown_options = adb_utils.prepare_for_interaction_with_device(
-        options.device_id, options.device_pin)
-  else:
-    teardown_options = None
+    os.makedirs(out_dir, exist_ok=True)
 
-  # Prelaunch for hot startup.
-  if options.hot_startup:
-    print('Prelaunching')
-    adb_utils.launch_activity(
+    # Grant notifications.
+    if options.grant_post_notification_permission:
+        adb_utils.grant(options.app_id, 'android.permission.POST_NOTIFICATIONS',
+                        options.device_id)
+
+    # AOT compile.
+    if options.aot:
+        print('AOT compiling')
+        if options.baseline_profile:
+            adb_utils.clear_profile_data(options.app_id, options.device_id)
+            if options.baseline_profile_install == 'adb':
+                adb_utils.install_profile_using_adb(options.app_id,
+                                                    options.baseline_profile,
+                                                    options.device_id)
+            else:
+                assert options.baseline_profile_install == 'profileinstaller'
+                adb_utils.install_profile_using_profileinstaller(
+                    options.app_id, options.device_id)
+        else:
+            adb_utils.force_compilation(options.app_id, options.device_id)
+
+    # Cooldown and then unlock device.
+    if options.cooldown > 0:
+        print('Cooling down for %i seconds' % options.cooldown)
+        assert adb_utils.get_screen_state(options.device_id).is_off()
+        time.sleep(options.cooldown)
+        teardown_options = adb_utils.prepare_for_interaction_with_device(
+            options.device_id, options.device_pin)
+    else:
+        teardown_options = None
+
+    # Prelaunch for hot startup.
+    if options.hot_startup:
+        print('Prelaunching')
+        adb_utils.launch_activity(options.app_id,
+                                  options.main_activity,
+                                  options.device_id,
+                                  wait_for_activity_to_launch=False)
+        time.sleep(options.startup_duration)
+        adb_utils.navigate_to_home_screen(options.device_id)
+        time.sleep(1)
+
+    # Drop caches before run.
+    adb_utils.drop_caches(options.device_id)
+    return teardown_options
+
+
+def teardown_for_run(out_dir, options, teardown_options):
+    assert adb_utils.get_screen_state(options.device_id).is_on_and_unlocked()
+
+    if options.capture_screen:
+        target = os.path.join(out_dir, 'screen.png')
+        adb_utils.capture_screen(target, options.device_id)
+
+    if options.cooldown > 0:
+        adb_utils.teardown_after_interaction_with_device(
+            teardown_options, options.device_id)
+        adb_utils.ensure_screen_off(options.device_id)
+    else:
+        assert teardown_options is None
+
+
+def run(out_dir, options, tmp_dir):
+    assert adb_utils.get_screen_state(options.device_id).is_on_and_unlocked()
+
+    # Start logcat for time to fully drawn.
+    logcat_process = None
+    if options.fully_drawn_logcat_message:
+        adb_utils.clear_logcat(options.device_id)
+        logcat_process = adb_utils.start_logcat(
+            options.device_id,
+            format='time',
+            filter='%s ActivityTaskManager:I' %
+            options.fully_drawn_logcat_filter,
+            silent=True)
+
+    # Start perfetto trace collector.
+    perfetto_process = None
+    perfetto_trace_path = None
+    if options.perfetto:
+        perfetto_process, perfetto_trace_path = perfetto_utils.record_android_trace(
+            out_dir, tmp_dir, options.device_id)
+
+    # Launch main activity.
+    launch_activity_result = adb_utils.launch_activity(
         options.app_id,
         options.main_activity,
         options.device_id,
-        wait_for_activity_to_launch=False)
-    time.sleep(options.startup_duration)
-    adb_utils.navigate_to_home_screen(options.device_id)
-    time.sleep(1)
+        intent_data_uri=options.intent_data_uri,
+        wait_for_activity_to_launch=True)
 
-  # Drop caches before run.
-  adb_utils.drop_caches(options.device_id)
-  return teardown_options
+    # Wait for app to be fully drawn.
+    logcat = None
+    if logcat_process is not None:
+        wait_until_fully_drawn(logcat_process, options)
+        logcat = adb_utils.stop_logcat(logcat_process)
 
-def teardown_for_run(out_dir, options, teardown_options):
-  assert adb_utils.get_screen_state(options.device_id).is_on_and_unlocked()
+    # Wait for perfetto trace collector to stop.
+    if options.perfetto:
+        perfetto_utils.stop_record_android_trace(perfetto_process, out_dir)
 
-  if options.capture_screen:
-    target = os.path.join(out_dir, 'screen.png')
-    adb_utils.capture_screen(target, options.device_id)
+    # Get minor and major page faults from app process.
+    data = compute_data(launch_activity_result, logcat, perfetto_trace_path,
+                        options)
+    write_data_to_dir(out_dir, data)
+    return data
 
-  if options.cooldown > 0:
-    adb_utils.teardown_after_interaction_with_device(
-        teardown_options, options.device_id)
-    adb_utils.ensure_screen_off(options.device_id)
-  else:
-    assert teardown_options is None
-
-def run(out_dir, options, tmp_dir):
-  assert adb_utils.get_screen_state(options.device_id).is_on_and_unlocked()
-
-  # Start logcat for time to fully drawn.
-  logcat_process = None
-  if options.fully_drawn_logcat_message:
-    adb_utils.clear_logcat(options.device_id)
-    logcat_process = adb_utils.start_logcat(
-        options.device_id,
-        format='time',
-        filter='%s ActivityTaskManager:I' % options.fully_drawn_logcat_filter,
-        silent=True)
-
-  # Start perfetto trace collector.
-  perfetto_process = None
-  perfetto_trace_path = None
-  if options.perfetto:
-    perfetto_process, perfetto_trace_path = perfetto_utils.record_android_trace(
-        out_dir, tmp_dir, options.device_id)
-
-  # Launch main activity.
-  launch_activity_result = adb_utils.launch_activity(
-      options.app_id,
-      options.main_activity,
-      options.device_id,
-      intent_data_uri=options.intent_data_uri,
-      wait_for_activity_to_launch=True)
-
-  # Wait for app to be fully drawn.
-  logcat = None
-  if logcat_process is not None:
-    wait_until_fully_drawn(logcat_process, options)
-    logcat = adb_utils.stop_logcat(logcat_process)
-
-  # Wait for perfetto trace collector to stop.
-  if options.perfetto:
-    perfetto_utils.stop_record_android_trace(perfetto_process, out_dir)
-
-  # Get minor and major page faults from app process.
-  data = compute_data(
-    launch_activity_result, logcat, perfetto_trace_path, options)
-  write_data_to_dir(out_dir, data)
-  return data
 
 def wait_until_fully_drawn(logcat_process, options):
-  print('Waiting until app is fully drawn')
-  while True:
-    is_fully_drawn = any(
-        is_app_fully_drawn_logcat_message(line, options) \
-        for line in logcat_process.lines)
-    if is_fully_drawn:
-      break
-    time.sleep(1)
-  print('Done')
+    print('Waiting until app is fully drawn')
+    while True:
+        is_fully_drawn = any(
+            is_app_fully_drawn_logcat_message(line, options) \
+            for line in logcat_process.lines)
+        if is_fully_drawn:
+            break
+        time.sleep(1)
+    print('Done')
+
 
 def compute_time_to_fully_drawn_from_time_to_first_frame(logcat, options):
-  displayed_time = None
-  fully_drawn_time = None
-  for line in logcat:
-    if is_app_displayed_logcat_message(line, options):
-      displayed_time = get_timestamp_from_logcat_message(line)
-    elif is_app_fully_drawn_logcat_message(line, options):
-      fully_drawn_time = get_timestamp_from_logcat_message(line)
-  assert displayed_time is not None
-  assert fully_drawn_time is not None
-  assert fully_drawn_time >= displayed_time
-  return fully_drawn_time - displayed_time
+    displayed_time = None
+    fully_drawn_time = None
+    for line in logcat:
+        if is_app_displayed_logcat_message(line, options):
+            displayed_time = get_timestamp_from_logcat_message(line)
+        elif is_app_fully_drawn_logcat_message(line, options):
+            fully_drawn_time = get_timestamp_from_logcat_message(line)
+    assert displayed_time is not None
+    assert fully_drawn_time is not None
+    assert fully_drawn_time >= displayed_time
+    return fully_drawn_time - displayed_time
+
 
 def get_timestamp_from_logcat_message(line):
-  time_end_index = len('00-00 00:00:00.000')
-  time_format = '%m-%d %H:%M:%S.%f'
-  time_str = line[0:time_end_index] + '000'
-  time_seconds = datetime.datetime.strptime(time_str, time_format).timestamp()
-  return int(time_seconds * 1000)
+    time_end_index = len('00-00 00:00:00.000')
+    time_format = '%m-%d %H:%M:%S.%f'
+    time_str = line[0:time_end_index] + '000'
+    time_seconds = datetime.datetime.strptime(time_str, time_format).timestamp()
+    return int(time_seconds * 1000)
+
 
 def is_app_displayed_logcat_message(line, options):
-  substring = 'Displayed %s' % adb_utils.get_component_name(
-      options.app_id, options.main_activity)
-  return substring in line
+    substring = 'Displayed %s' % adb_utils.get_component_name(
+        options.app_id, options.main_activity)
+    return substring in line
+
 
 def is_app_fully_drawn_logcat_message(line, options):
-  return re.search(options.fully_drawn_logcat_message, line)
+    return re.search(options.fully_drawn_logcat_message, line)
+
 
 def add_data(data_total, data):
-  for key, value in data.items():
-    if key == 'app_id':
-      assert data_total.get(key, value) == value
-      data_total[key] = value
-    if key == 'time':
-      continue
-    if key in data_total:
-      if key == 'app_id':
-        assert data_total[key] == value
-      else:
-        existing_value = data_total[key]
-        assert isinstance(value, int)
-        assert isinstance(existing_value, list)
-        existing_value.append(value)
-    else:
-      assert isinstance(value, int), key
-      data_total[key] = [value]
+    for key, value in data.items():
+        if key == 'app_id':
+            assert data_total.get(key, value) == value
+            data_total[key] = value
+        if key == 'time':
+            continue
+        if key in data_total:
+            if key == 'app_id':
+                assert data_total[key] == value
+            else:
+                existing_value = data_total[key]
+                assert isinstance(value, int)
+                assert isinstance(existing_value, list)
+                existing_value.append(value)
+        else:
+            assert isinstance(value, int), key
+            data_total[key] = [value]
+
 
 def compute_data(launch_activity_result, logcat, perfetto_trace_path, options):
-  minfl, majfl = adb_utils.get_minor_major_page_faults(
-      options.app_id, options.device_id)
-  meminfo = adb_utils.get_meminfo(options.app_id, options.device_id)
-  data = {
-    'app_id': options.app_id,
-    'time': time.ctime(time.time()),
-    'minfl': minfl,
-    'majfl': majfl
-  }
-  data.update(meminfo)
-  startup_data = compute_startup_data(
-      launch_activity_result, logcat, perfetto_trace_path, options)
-  return data | startup_data
+    minfl, majfl = adb_utils.get_minor_major_page_faults(
+        options.app_id, options.device_id)
+    meminfo = adb_utils.get_meminfo(options.app_id, options.device_id)
+    data = {
+        'app_id': options.app_id,
+        'time': time.ctime(time.time()),
+        'minfl': minfl,
+        'majfl': majfl
+    }
+    data.update(meminfo)
+    startup_data = compute_startup_data(launch_activity_result, logcat,
+                                        perfetto_trace_path, options)
+    return data | startup_data
 
-def compute_startup_data(
-    launch_activity_result, logcat, perfetto_trace_path, options):
-  time_to_first_frame = launch_activity_result.get('total_time')
-  startup_data = {
-    'adb_startup': time_to_first_frame
-  }
 
-  # Time to fully drawn.
-  if options.fully_drawn_logcat_message:
-    startup_data['time_to_fully_drawn'] = \
-        compute_time_to_fully_drawn_from_time_to_first_frame(logcat, options) \
-            + time_to_first_frame
+def compute_startup_data(launch_activity_result, logcat, perfetto_trace_path,
+                         options):
+    time_to_first_frame = launch_activity_result.get('total_time')
+    startup_data = {'adb_startup': time_to_first_frame}
 
-  # Perfetto stats.
-  perfetto_startup_data = {}
-  if options.perfetto:
-    TraceProcessor = perfetto_utils.get_trace_processor()
-    trace_processor = TraceProcessor(file_path=perfetto_trace_path)
+    # Time to fully drawn.
+    if options.fully_drawn_logcat_message:
+        startup_data['time_to_fully_drawn'] = \
+            compute_time_to_fully_drawn_from_time_to_first_frame(logcat, options) \
+                + time_to_first_frame
 
-    # Compute time to first frame according to the builtin android_startup
-    # metric.
-    startup_metric = trace_processor.metric(['android_startup'])
-    time_to_first_frame_ms = \
-        startup_metric.android_startup.startup[0].to_first_frame.dur_ms
-    perfetto_startup_data['perfetto_startup'] = round(time_to_first_frame_ms)
+    # Perfetto stats.
+    perfetto_startup_data = {}
+    if options.perfetto:
+        TraceProcessor = perfetto_utils.get_trace_processor()
+        trace_processor = TraceProcessor(file_path=perfetto_trace_path)
 
-    if not options.hot_startup:
-      # Compute time to first and last doFrame event.
-      bind_application_slice = perfetto_utils.find_unique_slice_by_name(
-          'bindApplication', options, trace_processor)
-      activity_start_slice = perfetto_utils.find_unique_slice_by_name(
-          'activityStart', options, trace_processor)
-      do_frame_slices = perfetto_utils.find_slices_by_name(
-          'Choreographer#doFrame', options, trace_processor)
-      first_do_frame_slice = next(do_frame_slices)
-      *_, last_do_frame_slice = do_frame_slices
+        # Compute time to first frame according to the builtin android_startup
+        # metric.
+        startup_metric = trace_processor.metric(['android_startup'])
+        time_to_first_frame_ms = \
+            startup_metric.android_startup.startup[0].to_first_frame.dur_ms
+        perfetto_startup_data['perfetto_startup'] = round(
+            time_to_first_frame_ms)
 
-      perfetto_startup_data.update({
-        'time_to_first_choreographer_do_frame_ms':
-            round(perfetto_utils.get_slice_end_since_start(
-                first_do_frame_slice, bind_application_slice)),
-        'time_to_last_choreographer_do_frame_ms':
-            round(perfetto_utils.get_slice_end_since_start(
-                last_do_frame_slice, bind_application_slice))
-      })
+        if not options.hot_startup:
+            # Compute time to first and last doFrame event.
+            bind_application_slice = perfetto_utils.find_unique_slice_by_name(
+                'bindApplication', options, trace_processor)
+            activity_start_slice = perfetto_utils.find_unique_slice_by_name(
+                'activityStart', options, trace_processor)
+            do_frame_slices = perfetto_utils.find_slices_by_name(
+                'Choreographer#doFrame', options, trace_processor)
+            first_do_frame_slice = next(do_frame_slices)
+            *_, last_do_frame_slice = do_frame_slices
 
-  # Return combined startup data.
-  return startup_data | perfetto_startup_data
+            perfetto_startup_data.update({
+                'time_to_first_choreographer_do_frame_ms':
+                    round(
+                        perfetto_utils.get_slice_end_since_start(
+                            first_do_frame_slice, bind_application_slice)),
+                'time_to_last_choreographer_do_frame_ms':
+                    round(
+                        perfetto_utils.get_slice_end_since_start(
+                            last_do_frame_slice, bind_application_slice))
+            })
+
+    # Return combined startup data.
+    return startup_data | perfetto_startup_data
+
 
 def write_data_to_dir(out_dir, data):
-  data_path = os.path.join(out_dir, 'data.txt')
-  write_data_to_file(data_path, data)
+    data_path = os.path.join(out_dir, 'data.txt')
+    write_data_to_file(data_path, data)
+
 
 def write_data_to_file(out_file, data):
-  with open(out_file, 'w') as f:
-    for key, value in data.items():
-      f.write('%s=%s\n' % (key, str(value)))
+    with open(out_file, 'w') as f:
+        for key, value in data.items():
+            f.write('%s=%s\n' % (key, str(value)))
+
 
 def parse_options(argv):
-  result = argparse.ArgumentParser(
-      description='Generate a perfetto trace file.')
-  result.add_argument('--app-id',
-                      help='The application ID of interest',
-                      required=True)
-  result.add_argument('--aot',
-                      help='Enable force compilation',
-                      default=False,
-                      action='store_true')
-  result.add_argument('--apk',
-                      help='Path to the .apk')
-  result.add_argument('--apks',
-                      help='Path to the .apks')
-  result.add_argument('--bundle',
-                      help='Path to the .aab')
-  result.add_argument('--capture-screen',
-                      help='Take a screenshot after each test',
-                      default=False,
-                      action='store_true')
-  result.add_argument('--cooldown',
-                      help='Seconds to wait before running each iteration',
-                      default=0,
-                      type=int)
-  result.add_argument('--device-id',
-                      help='Device id (e.g., emulator-5554).')
-  result.add_argument('--device-pin',
-                      help='Device pin code (e.g., 1234)')
-  result.add_argument('--fully-drawn-logcat-filter',
-                      help='Logcat filter for the fully drawn message '
-                           '(e.g., "tag:I")')
-  result.add_argument('--fully-drawn-logcat-message',
-                      help='Logcat message that indicates that the app is '
-                           'fully drawn (regexp)')
-  result.add_argument('--grant-post-notification-permission',
-                      help='Grants the android.permission.POST_NOTIFICATIONS '
-                           'permission before launching the app',
-                      default=False,
-                      action='store_true')
-  result.add_argument('--hot-startup',
-                      help='Measure hot startup instead of cold startup',
-                      default=False,
-                      action='store_true')
-  result.add_argument('--intent-data-uri',
-                      help='Value to use for the -d argument to the intent '
-                           'that is used to launch the app')
-  result.add_argument('--iterations',
-                      help='Number of traces to generate',
-                      default=1,
-                      type=int)
-  result.add_argument('--main-activity',
-                      help='Main activity class name',
-                      required=True)
-  result.add_argument('--no-perfetto',
-                      help='Disables perfetto trace generation',
-                      action='store_true',
-                      default=False)
-  result.add_argument('--out',
-                      help='File to store result in')
-  result.add_argument('--out-dir',
-                      help='Directory to store trace files in',
-                      required=True)
-  result.add_argument('--baseline-profile',
-                      help='Baseline profile (.prof) in binary format')
-  result.add_argument('--baseline-profile-metadata',
-                      help='Baseline profile metadata (.profm) in binary '
-                           'format')
-  result.add_argument('--baseline-profile-install',
-                      help='Whether to install profile using adb or '
-                           'profileinstaller',
-                      choices=['adb', 'profileinstaller'],
-                      default='profileinstaller')
-  result.add_argument('--startup-duration',
-                      help='Duration in seconds before shutting down app',
-                      default=15,
-                      type=int)
-  options, args = result.parse_known_args(argv)
-  setattr(options, 'perfetto', not options.no_perfetto)
+    result = argparse.ArgumentParser(
+        description='Generate a perfetto trace file.')
+    result.add_argument('--app-id',
+                        help='The application ID of interest',
+                        required=True)
+    result.add_argument('--aot',
+                        help='Enable force compilation',
+                        default=False,
+                        action='store_true')
+    result.add_argument('--apk', help='Path to the .apk')
+    result.add_argument('--apks', help='Path to the .apks')
+    result.add_argument('--bundle', help='Path to the .aab')
+    result.add_argument('--capture-screen',
+                        help='Take a screenshot after each test',
+                        default=False,
+                        action='store_true')
+    result.add_argument('--cooldown',
+                        help='Seconds to wait before running each iteration',
+                        default=0,
+                        type=int)
+    result.add_argument('--device-id', help='Device id (e.g., emulator-5554).')
+    result.add_argument('--device-pin', help='Device pin code (e.g., 1234)')
+    result.add_argument('--fully-drawn-logcat-filter',
+                        help='Logcat filter for the fully drawn message '
+                        '(e.g., "tag:I")')
+    result.add_argument('--fully-drawn-logcat-message',
+                        help='Logcat message that indicates that the app is '
+                        'fully drawn (regexp)')
+    result.add_argument('--grant-post-notification-permission',
+                        help='Grants the android.permission.POST_NOTIFICATIONS '
+                        'permission before launching the app',
+                        default=False,
+                        action='store_true')
+    result.add_argument('--hot-startup',
+                        help='Measure hot startup instead of cold startup',
+                        default=False,
+                        action='store_true')
+    result.add_argument('--intent-data-uri',
+                        help='Value to use for the -d argument to the intent '
+                        'that is used to launch the app')
+    result.add_argument('--iterations',
+                        help='Number of traces to generate',
+                        default=1,
+                        type=int)
+    result.add_argument('--main-activity',
+                        help='Main activity class name',
+                        required=True)
+    result.add_argument('--no-perfetto',
+                        help='Disables perfetto trace generation',
+                        action='store_true',
+                        default=False)
+    result.add_argument('--out', help='File to store result in')
+    result.add_argument('--out-dir',
+                        help='Directory to store trace files in',
+                        required=True)
+    result.add_argument('--baseline-profile',
+                        help='Baseline profile (.prof) in binary format')
+    result.add_argument('--baseline-profile-metadata',
+                        help='Baseline profile metadata (.profm) in binary '
+                        'format')
+    result.add_argument('--baseline-profile-install',
+                        help='Whether to install profile using adb or '
+                        'profileinstaller',
+                        choices=['adb', 'profileinstaller'],
+                        default='profileinstaller')
+    result.add_argument('--startup-duration',
+                        help='Duration in seconds before shutting down app',
+                        default=15,
+                        type=int)
+    options, args = result.parse_known_args(argv)
+    setattr(options, 'perfetto', not options.no_perfetto)
 
-  paths = [
-      path for path in [options.apk, options.apks, options.bundle]
-      if path is not None]
-  assert len(paths) == 1, 'Expected exactly one .apk, .apks, or .aab file.'
+    paths = [
+        path for path in [options.apk, options.apks, options.bundle]
+        if path is not None
+    ]
+    assert len(paths) == 1, 'Expected exactly one .apk, .apks, or .aab file.'
 
-  # Build .apks file up front to avoid building the bundle upon each install.
-  if options.bundle:
-    os.makedirs(options.out_dir, exist_ok=True)
-    options.apks = os.path.join(options.out_dir, 'Bundle.apks')
-    adb_utils.build_apks_from_bundle(
-        options.bundle, options.apks, overwrite=True)
-    del options.bundle
+    # Build .apks file up front to avoid building the bundle upon each install.
+    if options.bundle:
+        os.makedirs(options.out_dir, exist_ok=True)
+        options.apks = os.path.join(options.out_dir, 'Bundle.apks')
+        adb_utils.build_apks_from_bundle(options.bundle,
+                                         options.apks,
+                                         overwrite=True)
+        del options.bundle
 
-  # Profile is only used with --aot.
-  assert options.aot or not options.baseline_profile
+    # Profile is only used with --aot.
+    assert options.aot or not options.baseline_profile
 
-  # Fully drawn logcat filter and message is absent or both present.
-  assert (options.fully_drawn_logcat_filter is None) == \
-      (options.fully_drawn_logcat_message is None)
+    # Fully drawn logcat filter and message is absent or both present.
+    assert (options.fully_drawn_logcat_filter is None) == \
+        (options.fully_drawn_logcat_message is None)
 
-  return options, args
+    return options, args
+
 
 def global_setup(options):
-  # If there is no cooldown then unlock the screen once. Otherwise we turn off
-  # the screen during the cooldown and unlock the screen before each iteration.
-  teardown_options = None
-  if options.cooldown == 0:
-    teardown_options = adb_utils.prepare_for_interaction_with_device(
-        options.device_id, options.device_pin)
-    assert adb_utils.get_screen_state(options.device_id).is_on()
-  else:
-    adb_utils.ensure_screen_off(options.device_id)
-  return teardown_options
+    # If there is no cooldown then unlock the screen once. Otherwise we turn off
+    # the screen during the cooldown and unlock the screen before each iteration.
+    teardown_options = None
+    if options.cooldown == 0:
+        teardown_options = adb_utils.prepare_for_interaction_with_device(
+            options.device_id, options.device_pin)
+        assert adb_utils.get_screen_state(options.device_id).is_on()
+    else:
+        adb_utils.ensure_screen_off(options.device_id)
+    return teardown_options
+
 
 def global_teardown(options, teardown_options):
-  if options.cooldown == 0:
-    adb_utils.teardown_after_interaction_with_device(
-        teardown_options, options.device_id)
-  else:
-    assert teardown_options is None
+    if options.cooldown == 0:
+        adb_utils.teardown_after_interaction_with_device(
+            teardown_options, options.device_id)
+    else:
+        assert teardown_options is None
+
 
 def main(argv):
-  (options, args) = parse_options(argv)
-  with utils.TempDir() as tmp_dir:
-    apk_or_apks = { 'apk': options.apk, 'apks': options.apks }
-    if options.baseline_profile \
-        and options.baseline_profile_install == 'profileinstaller':
-      assert not options.apks, 'Unimplemented'
-      apk_or_apks['apk'] = apk_utils.add_baseline_profile_to_apk(
-          options.apk,
-          options.baseline_profile,
-          options.baseline_profile_metadata,
-          tmp_dir)
-    teardown_options = global_setup(options)
-    run_all(apk_or_apks, options, tmp_dir)
-    global_teardown(options, teardown_options)
+    (options, args) = parse_options(argv)
+    with utils.TempDir() as tmp_dir:
+        apk_or_apks = {'apk': options.apk, 'apks': options.apks}
+        if options.baseline_profile \
+            and options.baseline_profile_install == 'profileinstaller':
+            assert not options.apks, 'Unimplemented'
+            apk_or_apks['apk'] = apk_utils.add_baseline_profile_to_apk(
+                options.apk, options.baseline_profile,
+                options.baseline_profile_metadata, tmp_dir)
+        teardown_options = global_setup(options)
+        run_all(apk_or_apks, options, tmp_dir)
+        global_teardown(options, teardown_options)
+
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
\ No newline at end of file
+    sys.exit(main(sys.argv[1:]))
diff --git a/tools/startup/perfetto_utils.py b/tools/startup/perfetto_utils.py
index eb32722..4cf8613 100644
--- a/tools/startup/perfetto_utils.py
+++ b/tools/startup/perfetto_utils.py
@@ -7,85 +7,85 @@
 import subprocess
 import sys
 
+
 def get_trace_processor():
-  try:
-    from perfetto.trace_processor import TraceProcessor
-  except ImportError:
-    sys.exit(
-        'Unable to analyze perfetto trace without the perfetto library. '
-        'Install instructions:\n'
-        '    sudo apt install python3-pip\n'
-        '    pip3 install perfetto')
-  return TraceProcessor
+    try:
+        from perfetto.trace_processor import TraceProcessor
+    except ImportError:
+        sys.exit(
+            'Unable to analyze perfetto trace without the perfetto library. '
+            'Install instructions:\n'
+            '    sudo apt install python3-pip\n'
+            '    pip3 install perfetto')
+    return TraceProcessor
+
 
 def ensure_record_android_trace(tmp_dir):
-  record_android_trace_path = os.path.join(tmp_dir, 'record_android_trace')
-  if not os.path.exists(record_android_trace_path):
-    cmd = [
-        'curl',
-        '--output',
-        record_android_trace_path,
-        '--silent',
-        'https://raw.githubusercontent.com/google/perfetto/master/tools/'
+    record_android_trace_path = os.path.join(tmp_dir, 'record_android_trace')
+    if not os.path.exists(record_android_trace_path):
+        cmd = [
+            'curl', '--output', record_android_trace_path, '--silent',
+            'https://raw.githubusercontent.com/google/perfetto/master/tools/'
             'record_android_trace'
-    ]
-    subprocess.check_call(cmd)
-    assert os.path.exists(record_android_trace_path)
-  return record_android_trace_path
+        ]
+        subprocess.check_call(cmd)
+        assert os.path.exists(record_android_trace_path)
+    return record_android_trace_path
+
 
 def record_android_trace(out_dir, tmp_dir, device_id=None):
-  record_android_trace_path = ensure_record_android_trace(tmp_dir)
-  config_path = os.path.join(os.path.dirname(__file__), 'config.pbtx')
-  perfetto_trace_path = os.path.join(out_dir, 'trace.perfetto-trace')
-  cmd = [
-      sys.executable,
-      record_android_trace_path,
-      '--config',
-      config_path,
-      '--out',
-      perfetto_trace_path,
-      '--no-open']
-  if device_id is not None:
-    cmd.extend(['--serial', device_id])
-  perfetto_process = subprocess.Popen(
-      cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-  lines = []
-  for line in perfetto_process.stdout:
-    line = line.decode('utf-8')
-    lines.append(line)
-    if 'enabled ftrace' in line.strip():
-      return perfetto_process, perfetto_trace_path
-  raise ValueError(
-      'Expected to find line containing: enabled ftrace, got: %s' % lines)
+    record_android_trace_path = ensure_record_android_trace(tmp_dir)
+    config_path = os.path.join(os.path.dirname(__file__), 'config.pbtx')
+    perfetto_trace_path = os.path.join(out_dir, 'trace.perfetto-trace')
+    cmd = [
+        sys.executable, record_android_trace_path, '--config', config_path,
+        '--out', perfetto_trace_path, '--no-open'
+    ]
+    if device_id is not None:
+        cmd.extend(['--serial', device_id])
+    perfetto_process = subprocess.Popen(cmd,
+                                        stdout=subprocess.PIPE,
+                                        stderr=subprocess.PIPE)
+    lines = []
+    for line in perfetto_process.stdout:
+        line = line.decode('utf-8')
+        lines.append(line)
+        if 'enabled ftrace' in line.strip():
+            return perfetto_process, perfetto_trace_path
+    raise ValueError(
+        'Expected to find line containing: enabled ftrace, got: %s' % lines)
+
 
 def stop_record_android_trace(perfetto_process, out_dir):
-  if perfetto_process.poll() is not None:
-    raise ValueError('Expected perfetto process to be running')
-  # perfetto should terminate in at most 15 seconds, 
-  perfetto_config_duration=15
-  stdout, stderr = perfetto_process.communicate(
-      timeout=perfetto_config_duration*2)
-  stdout = stdout.decode('utf-8')
-  stderr = stderr.decode('utf-8')
-  assert perfetto_process.returncode == 0
-  assert os.path.exists(os.path.join(out_dir, 'trace.perfetto-trace'))
+    if perfetto_process.poll() is not None:
+        raise ValueError('Expected perfetto process to be running')
+    # perfetto should terminate in at most 15 seconds,
+    perfetto_config_duration = 15
+    stdout, stderr = perfetto_process.communicate(
+        timeout=perfetto_config_duration * 2)
+    stdout = stdout.decode('utf-8')
+    stderr = stderr.decode('utf-8')
+    assert perfetto_process.returncode == 0
+    assert os.path.exists(os.path.join(out_dir, 'trace.perfetto-trace'))
+
 
 # https://perfetto.dev/docs/analysis/sql-tables
 def find_slices_by_name(slice_name, options, trace_processor):
-  return trace_processor.query(
-      'SELECT slice.dur, slice.ts FROM slice'
-          ' INNER JOIN thread_track ON (slice.track_id = thread_track.id)'
-          ' INNER JOIN thread using (utid)'
-          ' INNER JOIN process using (upid)'
-          ' WHERE slice.name = "%s"'
-          ' AND process.name = "%s"'
-          ' ORDER BY slice.ts ASC'
-          % (slice_name, options.app_id))
+    return trace_processor.query(
+        'SELECT slice.dur, slice.ts FROM slice'
+        ' INNER JOIN thread_track ON (slice.track_id = thread_track.id)'
+        ' INNER JOIN thread using (utid)'
+        ' INNER JOIN process using (upid)'
+        ' WHERE slice.name = "%s"'
+        ' AND process.name = "%s"'
+        ' ORDER BY slice.ts ASC' % (slice_name, options.app_id))
+
 
 def find_unique_slice_by_name(slice_name, options, trace_processor):
-  query_it = find_slices_by_name(slice_name, options, trace_processor)
-  assert len(query_it) == 1
-  return next(query_it)
+    query_it = find_slices_by_name(slice_name, options, trace_processor)
+    assert len(query_it) == 1
+    return next(query_it)
+
 
 def get_slice_end_since_start(slice, initial_slice):
-  return (slice.ts + slice.dur - initial_slice.ts) / 1000000
+    return (slice.ts + slice.dur - initial_slice.ts) / 1000000
diff --git a/tools/startup/profile_utils.py b/tools/startup/profile_utils.py
index 5c74a5c..7a8de4a 100755
--- a/tools/startup/profile_utils.py
+++ b/tools/startup/profile_utils.py
@@ -10,6 +10,7 @@
 EXTERNAL_SYNTHETIC_SUFFIX = '$$ExternalSynthetic'
 SYNTHETIC_PREFIX = 'S'
 
+
 # Parses a list of class and method descriptors, prefixed with one or more flags
 # 'H' (hot), 'S' (startup), 'P' (post startup).
 #
@@ -24,86 +25,93 @@
 #
 # See also https://developer.android.com/studio/profile/baselineprofiles.
 def parse_art_profile(lines):
-  art_profile = {}
-  flags_to_name = { 'H': 'hot', 'S': 'startup', 'P': 'post_startup' }
-  for line in lines:
-    line = line.strip()
-    if not line:
-      continue
-    flags = { 'hot': False, 'startup': False, 'post_startup': False }
-    while line[0] in flags_to_name:
-      flag_abbreviation = line[0]
-      flag_name = flags_to_name.get(flag_abbreviation)
-      flags[flag_name] = True
-      line = line[1:]
-    while line.startswith('['):
-      line = line[1:]
-    assert line.startswith('L'), line
-    descriptor = line
-    art_profile[descriptor] = flags
-  return art_profile
+    art_profile = {}
+    flags_to_name = {'H': 'hot', 'S': 'startup', 'P': 'post_startup'}
+    for line in lines:
+        line = line.strip()
+        if not line:
+            continue
+        flags = {'hot': False, 'startup': False, 'post_startup': False}
+        while line[0] in flags_to_name:
+            flag_abbreviation = line[0]
+            flag_name = flags_to_name.get(flag_abbreviation)
+            flags[flag_name] = True
+            line = line[1:]
+        while line.startswith('['):
+            line = line[1:]
+        assert line.startswith('L'), line
+        descriptor = line
+        art_profile[descriptor] = flags
+    return art_profile
 
-def transform_art_profile_to_r8_startup_list(
-    art_profile, generalize_synthetics=False):
-  r8_startup_list = {}
-  for startup_descriptor, flags in art_profile.items():
-    transformed_startup_descriptor = transform_synthetic_descriptor(
-        startup_descriptor) if generalize_synthetics else startup_descriptor
-    r8_startup_list[transformed_startup_descriptor] = {
-      'conditional_startup': False,
-      'hot': flags['hot'],
-      'startup': flags['startup'],
-      'post_startup': flags['post_startup']
-    }
-  return r8_startup_list
+
+def transform_art_profile_to_r8_startup_list(art_profile,
+                                             generalize_synthetics=False):
+    r8_startup_list = {}
+    for startup_descriptor, flags in art_profile.items():
+        transformed_startup_descriptor = transform_synthetic_descriptor(
+            startup_descriptor) if generalize_synthetics else startup_descriptor
+        r8_startup_list[transformed_startup_descriptor] = {
+            'conditional_startup': False,
+            'hot': flags['hot'],
+            'startup': flags['startup'],
+            'post_startup': flags['post_startup']
+        }
+    return r8_startup_list
+
 
 def transform_synthetic_descriptor(descriptor):
-  companion_class_index = descriptor.find(COMPANION_CLASS_SUFFIX)
-  if companion_class_index >= 0:
-    return SYNTHETIC_PREFIX + descriptor[0:companion_class_index] + ';'
-  external_synthetic_index = descriptor.find(EXTERNAL_SYNTHETIC_SUFFIX)
-  if external_synthetic_index >= 0:
-    return SYNTHETIC_PREFIX + descriptor[0:external_synthetic_index] + ';'
-  return descriptor
+    companion_class_index = descriptor.find(COMPANION_CLASS_SUFFIX)
+    if companion_class_index >= 0:
+        return SYNTHETIC_PREFIX + descriptor[0:companion_class_index] + ';'
+    external_synthetic_index = descriptor.find(EXTERNAL_SYNTHETIC_SUFFIX)
+    if external_synthetic_index >= 0:
+        return SYNTHETIC_PREFIX + descriptor[0:external_synthetic_index] + ';'
+    return descriptor
+
 
 def filter_r8_startup_list(r8_startup_list, options):
-  filtered_r8_startup_list = {}
-  for startup_descriptor, flags in r8_startup_list.items():
-    if not options.include_post_startup \
-        and flags.get('post_startup') \
-        and not flags.get('startup'):
-      continue
-    filtered_r8_startup_list[startup_descriptor] = flags
-  return filtered_r8_startup_list
+    filtered_r8_startup_list = {}
+    for startup_descriptor, flags in r8_startup_list.items():
+        if not options.include_post_startup \
+            and flags.get('post_startup') \
+            and not flags.get('startup'):
+            continue
+        filtered_r8_startup_list[startup_descriptor] = flags
+    return filtered_r8_startup_list
+
 
 def parse_options(argv):
-  result = argparse.ArgumentParser(
-      description='Utilities for converting an ART profile into an R8 startup '
-                  'list.')
-  result.add_argument('--art-profile', help='Path to the ART profile')
-  result.add_argument('--include-post-startup',
-                      help='Include post startup classes and methods in the R8 '
-                           'startup list',
-                      action='store_true',
-                      default=False)
-  result.add_argument('--out', help='Where to store the R8 startup list')
-  options, args = result.parse_known_args(argv)
-  return options, args
+    result = argparse.ArgumentParser(
+        description='Utilities for converting an ART profile into an R8 startup '
+        'list.')
+    result.add_argument('--art-profile', help='Path to the ART profile')
+    result.add_argument(
+        '--include-post-startup',
+        help='Include post startup classes and methods in the R8 '
+        'startup list',
+        action='store_true',
+        default=False)
+    result.add_argument('--out', help='Where to store the R8 startup list')
+    options, args = result.parse_known_args(argv)
+    return options, args
+
 
 def main(argv):
-  (options, args) = parse_options(argv)
-  with open(options.art_profile, 'r') as f:
-    art_profile = parse_art_profile(f.read().splitlines())
-  r8_startup_list = transform_art_profile_to_r8_startup_list(art_profile)
-  filtered_r8_startup_list = filter_r8_startup_list(r8_startup_list, options)
-  if options.out is not None:
-    with open(options.out, 'w') as f:
-      for startup_descriptor, flags in filtered_r8_startup_list.items():
-        f.write(startup_descriptor)
-        f.write('\n')
-  else:
-    for startup_descriptor, flags in filtered_r8_startup_list.items():
-      print(startup_descriptor)
+    (options, args) = parse_options(argv)
+    with open(options.art_profile, 'r') as f:
+        art_profile = parse_art_profile(f.read().splitlines())
+    r8_startup_list = transform_art_profile_to_r8_startup_list(art_profile)
+    filtered_r8_startup_list = filter_r8_startup_list(r8_startup_list, options)
+    if options.out is not None:
+        with open(options.out, 'w') as f:
+            for startup_descriptor, flags in filtered_r8_startup_list.items():
+                f.write(startup_descriptor)
+                f.write('\n')
+    else:
+        for startup_descriptor, flags in filtered_r8_startup_list.items():
+            print(startup_descriptor)
+
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
+    sys.exit(main(sys.argv[1:]))
diff --git a/tools/startup/relayout.py b/tools/startup/relayout.py
index b0f8aac..3d0cd94 100755
--- a/tools/startup/relayout.py
+++ b/tools/startup/relayout.py
@@ -17,79 +17,85 @@
 import utils
 import zip_utils
 
-LOWEST_SUPPORTED_MIN_API = 21 # Android L (native multi dex)
+LOWEST_SUPPORTED_MIN_API = 21  # Android L (native multi dex)
+
 
 def parse_options(argv):
-  result = argparse.ArgumentParser(
-      description='Relayout a given APK using a startup profile.')
-  result.add_argument('--apk',
-                      help='Path to the .apk',
-                      required=True)
-  result.add_argument('--desugared-library',
-                      choices=['auto', 'true', 'false'],
-                      default='auto',
-                      help='Whether the last dex file of the app is desugared '
-                           'library')
-  result.add_argument('--no-build',
-                      action='store_true',
-                      default=False,
-                      help='To disable building using gradle')
-  result.add_argument('--out',
-                      help='Destination of resulting apk',
-                      required=True)
-  result.add_argument('--profile',
-                      help='Path to the startup profile')
-  options, args = result.parse_known_args(argv)
-  return options, args
+    result = argparse.ArgumentParser(
+        description='Relayout a given APK using a startup profile.')
+    result.add_argument('--apk', help='Path to the .apk', required=True)
+    result.add_argument(
+        '--desugared-library',
+        choices=['auto', 'true', 'false'],
+        default='auto',
+        help='Whether the last dex file of the app is desugared '
+        'library')
+    result.add_argument('--no-build',
+                        action='store_true',
+                        default=False,
+                        help='To disable building using gradle')
+    result.add_argument('--out',
+                        help='Destination of resulting apk',
+                        required=True)
+    result.add_argument('--profile', help='Path to the startup profile')
+    options, args = result.parse_known_args(argv)
+    return options, args
+
 
 def get_dex_to_relayout(options, temp):
-  marker = extractmarker.extractmarker(options.apk, build=not options.no_build)
-  if '~~L8' not in marker:
-    return [options.apk], None
-  dex_dir = os.path.join(temp, 'dex')
-  dex_predicate = \
-      lambda name : name.startswith('classes') and name.endswith('.dex')
-  extracted_dex_files = \
-      zip_utils.extract_all_that_matches(options.apk, dex_dir, dex_predicate)
-  desugared_library_dex = 'classes%s.dex' % len(extracted_dex_files)
-  assert desugared_library_dex in extracted_dex_files
-  return [
-      os.path.join(dex_dir, name) \
-          for name in extracted_dex_files if name != desugared_library_dex], \
-      os.path.join(dex_dir, desugared_library_dex)
+    marker = extractmarker.extractmarker(options.apk,
+                                         build=not options.no_build)
+    if '~~L8' not in marker:
+        return [options.apk], None
+    dex_dir = os.path.join(temp, 'dex')
+    dex_predicate = \
+        lambda name : name.startswith('classes') and name.endswith('.dex')
+    extracted_dex_files = \
+        zip_utils.extract_all_that_matches(options.apk, dex_dir, dex_predicate)
+    desugared_library_dex = 'classes%s.dex' % len(extracted_dex_files)
+    assert desugared_library_dex in extracted_dex_files
+    return [
+        os.path.join(dex_dir, name) \
+            for name in extracted_dex_files if name != desugared_library_dex], \
+        os.path.join(dex_dir, desugared_library_dex)
+
 
 def has_desugared_library_dex(options):
-  if options.desugared_library == 'auto':
-    marker = extractmarker.extractmarker(
-        options.apk, build=not options.no_build)
-    return '~~L8' in marker
-  return options.desugared_library == 'true'
+    if options.desugared_library == 'auto':
+        marker = extractmarker.extractmarker(options.apk,
+                                             build=not options.no_build)
+        return '~~L8' in marker
+    return options.desugared_library == 'true'
+
 
 def main(argv):
-  (options, args) = parse_options(argv)
-  with utils.TempDir() as temp:
-    dex = os.path.join(temp, 'dex.zip')
-    d8_args = [
-        '--min-api',
-        str(max(apk_utils.get_min_api(options.apk), LOWEST_SUPPORTED_MIN_API)),
-        '--output', dex,
-        '--no-desugaring',
-        '--release']
-    if options.profile:
-      d8_args.extend(['--startup-profile', options.profile])
-    dex_to_relayout, desugared_library_dex = get_dex_to_relayout(options, temp)
-    d8_args.extend(dex_to_relayout)
-    toolhelper.run(
-        'd8',
-        d8_args,
-        build=not options.no_build,
-        main='com.android.tools.r8.D8')
-    if desugared_library_dex is not None:
-      dex_files = [name for name in \
-          zip_utils.get_names_that_matches(dex, lambda x : True)]
-      zip_utils.add_file_to_zip(
-          desugared_library_dex, 'classes%s.dex' % str(len(dex_files) + 1), dex)
-    apk_masseur.masseur(options.apk, dex=dex, out=options.out)
+    (options, args) = parse_options(argv)
+    with utils.TempDir() as temp:
+        dex = os.path.join(temp, 'dex.zip')
+        d8_args = [
+            '--min-api',
+            str(
+                max(apk_utils.get_min_api(options.apk),
+                    LOWEST_SUPPORTED_MIN_API)), '--output', dex,
+            '--no-desugaring', '--release'
+        ]
+        if options.profile:
+            d8_args.extend(['--startup-profile', options.profile])
+        dex_to_relayout, desugared_library_dex = get_dex_to_relayout(
+            options, temp)
+        d8_args.extend(dex_to_relayout)
+        toolhelper.run('d8',
+                       d8_args,
+                       build=not options.no_build,
+                       main='com.android.tools.r8.D8')
+        if desugared_library_dex is not None:
+            dex_files = [name for name in \
+                zip_utils.get_names_that_matches(dex, lambda x : True)]
+            zip_utils.add_file_to_zip(desugared_library_dex,
+                                      'classes%s.dex' % str(len(dex_files) + 1),
+                                      dex)
+        apk_masseur.masseur(options.apk, dex=dex, out=options.out)
+
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
+    sys.exit(main(sys.argv[1:]))