[recipes] Move app_name into flavor.setup()

This allows us to move iOS-specific stuff from individual recipes into
the flavor module.

First in a long series of CLs to clean up recipes and move to task drivers.

Change-Id: Iff01610f76c71920639328ead5209e0cd5d93f31
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/273762
Commit-Queue: Eric Boren <borenet@google.com>
Reviewed-by: Ben Wagner aka dogben <benjaminwagner@google.com>
diff --git a/infra/bots/recipe_modules/flavor/android.py b/infra/bots/recipe_modules/flavor/android.py
index d6d2b188..fb9da9c 100644
--- a/infra/bots/recipe_modules/flavor/android.py
+++ b/infra/bots/recipe_modules/flavor/android.py
@@ -13,8 +13,8 @@
 
 
 class AndroidFlavor(default.DefaultFlavor):
-  def __init__(self, m):
-    super(AndroidFlavor, self).__init__(m)
+  def __init__(self, m, app_name):
+    super(AndroidFlavor, self).__init__(m, app_name)
     self._ever_ran_adb = False
     self.ADB_BINARY = '/usr/bin/adb.1.0.35'
     self.ADB_PUB_KEY = '/home/chrome-bot/.android/adbkey'
@@ -353,7 +353,7 @@
         'lib64', 'clang', '8.0.7', 'bin', 'asan_device_setup')
 
 
-  def install(self, app_to_push):
+  def install(self):
     self._adb('mkdir ' + self.device_dirs.resource_dir,
               'shell', 'mkdir', '-p', self.device_dirs.resource_dir)
     if 'ASAN' in self.m.vars.extra_tokens:
@@ -435,13 +435,13 @@
                  infra_step=True,
                  timeout=300,
                  abort_on_failure=True)
-    if app_to_push:
-      if (app_to_push == 'nanobench'):
+    if self.app_name:
+      if (self.app_name == 'nanobench'):
         self._scale_for_nanobench()
       else:
         self._scale_for_dm()
-      app_path = self.host_dirs.bin_dir.join(app_to_push)
-      self._adb('push %s' % app_to_push,
+      app_path = self.host_dirs.bin_dir.join(self.app_name)
+      self._adb('push %s' % self.app_name,
                 'push', app_path, self.device_dirs.bin_dir)
 
 
diff --git a/infra/bots/recipe_modules/flavor/api.py b/infra/bots/recipe_modules/flavor/api.py
index b703474..9ce4f90 100644
--- a/infra/bots/recipe_modules/flavor/api.py
+++ b/infra/bots/recipe_modules/flavor/api.py
@@ -65,25 +65,25 @@
 
 
 class SkiaFlavorApi(recipe_api.RecipeApi):
-  def get_flavor(self, vars_api):
+  def get_flavor(self, vars_api, app_name):
     """Return a flavor utils object specific to the given builder."""
     if is_chromebook(vars_api):
-      return chromebook.ChromebookFlavor(self)
+      return chromebook.ChromebookFlavor(self, app_name)
     if is_android(vars_api) and not is_test_skqp(vars_api):
-      return android.AndroidFlavor(self)
+      return android.AndroidFlavor(self, app_name)
     elif is_docker(vars_api):
-      return docker.DockerFlavor(self)
+      return docker.DockerFlavor(self, app_name)
     elif is_ios(vars_api):
-      return ios.iOSFlavor(self)
+      return ios.iOSFlavor(self, app_name)
     elif is_valgrind(vars_api):
-      return valgrind.ValgrindFlavor(self)
+      return valgrind.ValgrindFlavor(self, app_name)
     elif is_win_ssh(vars_api):
-      return win_ssh.WinSSHFlavor(self)
+      return win_ssh.WinSSHFlavor(self, app_name)
     else:
-      return default.DefaultFlavor(self)
+      return default.DefaultFlavor(self, app_name)
 
-  def setup(self):
-    self._f = self.get_flavor(self.m.vars)
+  def setup(self, app_name):
+    self._f = self.get_flavor(self.m.vars, app_name)
     self.device_dirs = self._f.device_dirs
     self.host_dirs = self._f.host_dirs
     self._skia_dir = self.m.path['start_dir'].join('skia')
@@ -115,9 +115,9 @@
   def remove_file_on_device(self, path):
     return self._f.remove_file_on_device(path)
 
-  def install(self, app_to_push, skps=False, images=False, lotties=False,
-              svgs=False, resources=False, mskps=False, texttraces=False):
-    self._f.install(app_to_push)
+  def install(self, skps=False, images=False, lotties=False, svgs=False,
+              resources=False, mskps=False, texttraces=False):
+    self._f.install()
 
     if texttraces:
       self._copy_texttraces()
diff --git a/infra/bots/recipe_modules/flavor/chromebook.py b/infra/bots/recipe_modules/flavor/chromebook.py
index 6d5902e..9125973 100644
--- a/infra/bots/recipe_modules/flavor/chromebook.py
+++ b/infra/bots/recipe_modules/flavor/chromebook.py
@@ -14,8 +14,8 @@
 
 class ChromebookFlavor(ssh.SSHFlavor):
 
-  def __init__(self, m):
-    super(ChromebookFlavor, self).__init__(m)
+  def __init__(self, m, app_name):
+    super(ChromebookFlavor, self).__init__(m, app_name)
     self.chromeos_homedir = '/home/chronos/user/'
     self.device_dirs = default.DeviceDirs(
       bin_dir        = self.chromeos_homedir + 'bin',
@@ -30,8 +30,8 @@
       tmp_dir        = self.chromeos_homedir,
       texttraces_dir = '')
 
-  def install(self, app_to_push):
-    super(ChromebookFlavor, self).install(app_to_push)
+  def install(self):
+    super(ChromebookFlavor, self).install()
 
     # Ensure the home dir is marked executable
     self.ssh('remount %s as exec' % self.chromeos_homedir,
diff --git a/infra/bots/recipe_modules/flavor/default.py b/infra/bots/recipe_modules/flavor/default.py
index 6396fe3..db2cd62 100644
--- a/infra/bots/recipe_modules/flavor/default.py
+++ b/infra/bots/recipe_modules/flavor/default.py
@@ -24,7 +24,11 @@
 
 
 class DefaultFlavor(object):
-  def __init__(self, module):
+  def __init__(self, module, app_name):
+    # Name of the app we're going to run. May be used in various ways by
+    # different flavors.
+    self.app_name = app_name
+
     # Store a pointer to the parent recipe module (SkiaFlavorApi) so that
     # FlavorUtils objects can do recipe module-like things, like run steps or
     # access module-level resources.
@@ -100,7 +104,7 @@
     """Removes the specified file."""
     return self.m.file.remove('remove %s' % path, path)
 
-  def install(self, app_to_push):
+  def install(self):
     """Run device-specific installation steps."""
     pass
 
diff --git a/infra/bots/recipe_modules/flavor/docker.py b/infra/bots/recipe_modules/flavor/docker.py
index 1b6d701..80cb04e 100644
--- a/infra/bots/recipe_modules/flavor/docker.py
+++ b/infra/bots/recipe_modules/flavor/docker.py
@@ -21,8 +21,8 @@
 
 
 class DockerFlavor(default.DefaultFlavor):
-  def __init__(self, m):
-    super(DockerFlavor, self).__init__(m)
+  def __init__(self, m, app_name):
+    super(DockerFlavor, self).__init__(m, app_name)
 
   def _map_host_path_to_docker(self, path):
     """Returns the path in the Docker container mapped to the given path.
diff --git a/infra/bots/recipe_modules/flavor/examples/full.expected/ios_rerun_with_debug.json b/infra/bots/recipe_modules/flavor/examples/full.expected/ios_rerun_with_debug.json
index 2036b9a..05b1e10 100644
--- a/infra/bots/recipe_modules/flavor/examples/full.expected/ios_rerun_with_debug.json
+++ b/infra/bots/recipe_modules/flavor/examples/full.expected/ios_rerun_with_debug.json
@@ -7,6 +7,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -19,6 +21,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -31,6 +35,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -71,6 +77,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -83,6 +91,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -95,6 +105,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -107,6 +119,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "name": "list mounted image"
@@ -122,6 +136,10 @@
       "[START_DIR]",
       "ios-dev-image*"
     ],
+    "env": {
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
+    },
     "infra_step": true,
     "name": "locate ios-dev-image package",
     "~followup_annotations": [
@@ -139,6 +157,10 @@
       "listdir",
       "[START_DIR]/ios-dev-image-13.2"
     ],
+    "env": {
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
+    },
     "infra_step": true,
     "name": "locate image and signature",
     "~followup_annotations": [
@@ -155,6 +177,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "name": "mount developer image"
@@ -167,6 +191,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -180,6 +206,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -228,6 +256,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -240,6 +270,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -252,6 +284,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -264,6 +298,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -277,6 +313,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -290,6 +328,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -338,6 +378,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -350,6 +392,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -362,6 +406,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -374,6 +420,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -387,6 +435,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -400,6 +450,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -448,6 +500,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -460,6 +514,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -472,6 +528,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -484,6 +542,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -497,6 +557,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -510,6 +572,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -524,6 +588,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "name": "dm",
@@ -541,6 +607,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "name": "dm with full debug output"
diff --git a/infra/bots/recipe_modules/flavor/examples/full.expected/retry_ios_install.json b/infra/bots/recipe_modules/flavor/examples/full.expected/retry_ios_install.json
index c249048..3338d70 100644
--- a/infra/bots/recipe_modules/flavor/examples/full.expected/retry_ios_install.json
+++ b/infra/bots/recipe_modules/flavor/examples/full.expected/retry_ios_install.json
@@ -7,6 +7,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -19,6 +21,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -31,6 +35,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -71,6 +77,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -83,6 +91,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -95,6 +105,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -107,6 +119,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "name": "list mounted image"
@@ -122,6 +136,10 @@
       "[START_DIR]",
       "ios-dev-image*"
     ],
+    "env": {
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
+    },
     "infra_step": true,
     "name": "locate ios-dev-image package",
     "~followup_annotations": [
@@ -139,6 +157,10 @@
       "listdir",
       "[START_DIR]/ios-dev-image-13.2"
     ],
+    "env": {
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
+    },
     "infra_step": true,
     "name": "locate image and signature",
     "~followup_annotations": [
@@ -155,6 +177,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "name": "mount developer image"
@@ -167,6 +191,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -183,6 +209,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -196,6 +224,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -209,6 +239,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -257,6 +289,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -269,6 +303,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -281,6 +317,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -293,6 +331,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -306,6 +346,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -319,6 +361,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -367,6 +411,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -379,6 +425,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -391,6 +439,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -403,6 +453,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -416,6 +468,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -429,6 +483,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -477,6 +533,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -489,6 +547,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -501,6 +561,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -513,6 +575,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -526,6 +590,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -539,6 +605,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -553,6 +621,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "name": "dm"
@@ -565,6 +635,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
diff --git a/infra/bots/recipe_modules/flavor/examples/full.expected/retry_ios_install_retries_exhausted.json b/infra/bots/recipe_modules/flavor/examples/full.expected/retry_ios_install_retries_exhausted.json
index 69f74a1..977679d 100644
--- a/infra/bots/recipe_modules/flavor/examples/full.expected/retry_ios_install_retries_exhausted.json
+++ b/infra/bots/recipe_modules/flavor/examples/full.expected/retry_ios_install_retries_exhausted.json
@@ -7,6 +7,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -19,6 +21,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -31,6 +35,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -71,6 +77,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -83,6 +91,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -95,6 +105,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -107,6 +119,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "name": "list mounted image"
@@ -122,6 +136,10 @@
       "[START_DIR]",
       "ios-dev-image*"
     ],
+    "env": {
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
+    },
     "infra_step": true,
     "name": "locate ios-dev-image package",
     "~followup_annotations": [
@@ -139,6 +157,10 @@
       "listdir",
       "[START_DIR]/ios-dev-image-13.2"
     ],
+    "env": {
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
+    },
     "infra_step": true,
     "name": "locate image and signature",
     "~followup_annotations": [
@@ -155,6 +177,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "name": "mount developer image"
@@ -167,6 +191,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -183,6 +209,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -196,6 +224,8 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
+      "IOS_BUNDLE_ID": "com.google.dm",
+      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
diff --git a/infra/bots/recipe_modules/flavor/examples/full.py b/infra/bots/recipe_modules/flavor/examples/full.py
index e0a8081..2bedf1c 100644
--- a/infra/bots/recipe_modules/flavor/examples/full.py
+++ b/infra/bots/recipe_modules/flavor/examples/full.py
@@ -30,52 +30,51 @@
 
 def RunSteps(api):
   api.vars.setup()
-  api.flavor.setup()
+
+  builder = api.properties['buildername']
+  app = None
+  if 'SkottieTracing' in builder:
+    app = None
+  elif 'Test' in builder:
+    app = 'dm'
+  elif 'Perf' in builder:
+    app = 'nanobench'
+  api.flavor.setup(app)
 
   if api.properties.get('is_testing_exceptions') == 'True':
     return test_exceptions(api)
 
-  builder = api.properties['buildername']
-  if 'Build' not in builder:
-    try:
-      api.flavor.copy_file_to_device('file.txt', 'file.txt')
-      api.flavor.read_file_on_device('file.txt')
-      api.flavor.remove_file_on_device('file.txt')
-      api.flavor.create_clean_host_dir('results_dir')
-      api.flavor.create_clean_device_dir('device_results_dir')
+  try:
+    api.flavor.copy_file_to_device('file.txt', 'file.txt')
+    api.flavor.read_file_on_device('file.txt')
+    api.flavor.remove_file_on_device('file.txt')
+    api.flavor.create_clean_host_dir('results_dir')
+    api.flavor.create_clean_device_dir('device_results_dir')
 
-      app = None
+    if 'Lottie' in builder:
+      api.flavor.install(lotties=True)
+    elif 'Mskp' in builder:
+      api.flavor.install(mskps=True)
+    elif all(v in builder for v in ['Perf', 'Android', 'CPU']):
+      api.flavor.install(skps=True, images=True, svgs=True,
+                         resources=True, texttraces=True)
+    else:
+      api.flavor.install(skps=True, images=True, lotties=False,
+                         svgs=True, resources=True)
+    if 'Test' in builder:
+      api.flavor.step('dm', ['dm', '--some-flag'])
+      api.flavor.copy_directory_contents_to_host(
+          api.flavor.device_dirs.dm_dir, api.flavor.host_dirs.dm_dir)
+    elif 'Perf' in builder:
       if 'SkottieTracing' in builder:
-        app = None
-      elif 'Test' in builder:
-        app = 'dm'
-      elif 'Perf' in builder:
-        app = 'nanobench'
-
-      if 'Lottie' in builder:
-        api.flavor.install(app, lotties=True)
-      elif 'Mskp' in builder:
-        api.flavor.install(app, mskps=True)
-      elif all(v in builder for v in ['Perf', 'Android', 'CPU']):
-        api.flavor.install(app, skps=True, images=True, svgs=True,
-                           resources=True, texttraces=True)
-      else:
-        api.flavor.install(app, skps=True, images=True, lotties=False,
-                           svgs=True, resources=True)
-      if 'Test' in builder:
         api.flavor.step('dm', ['dm', '--some-flag'])
-        api.flavor.copy_directory_contents_to_host(
-            api.flavor.device_dirs.dm_dir, api.flavor.host_dirs.dm_dir)
-      elif 'Perf' in builder:
-        if 'SkottieTracing' in builder:
-          api.flavor.step('dm', ['dm', '--some-flag'])
-        else:
-          api.flavor.step('nanobench', ['nanobench', '--some-flag'])
-        api.flavor.copy_directory_contents_to_host(
-            api.flavor.device_dirs.perf_data_dir,
-            api.flavor.host_dirs.perf_data_dir)
-    finally:
-      api.flavor.cleanup_steps()
+      else:
+        api.flavor.step('nanobench', ['nanobench', '--some-flag'])
+      api.flavor.copy_directory_contents_to_host(
+          api.flavor.device_dirs.perf_data_dir,
+          api.flavor.host_dirs.perf_data_dir)
+  finally:
+    api.flavor.cleanup_steps()
   api.run.check_failure()
 
 
diff --git a/infra/bots/recipe_modules/flavor/ios.py b/infra/bots/recipe_modules/flavor/ios.py
index b1856c6..0b0682e 100644
--- a/infra/bots/recipe_modules/flavor/ios.py
+++ b/infra/bots/recipe_modules/flavor/ios.py
@@ -10,8 +10,8 @@
 
 
 class iOSFlavor(default.DefaultFlavor):
-  def __init__(self, m):
-    super(iOSFlavor, self).__init__(m)
+  def __init__(self, m, app_name):
+    super(iOSFlavor, self).__init__(m, app_name)
     self.device_dirs = default.DeviceDirs(
         bin_dir='[unused]',
         dm_dir='dm',
@@ -25,6 +25,16 @@
         tmp_dir='tmp',
         texttraces_dir='')
 
+  @property
+  def env(self):
+    return {
+      'IOS_BUNDLE_ID': 'com.google.%s' % self.app_name,
+      'IOS_MOUNT_POINT': self.m.vars.slave_dir.join('mnt_iosdevice'),
+    }
+
+  def context(self):
+    return self.m.context(env=self.env)
+
   def _run(self, title, *cmd, **kwargs):
     def sleep(attempt):
       self.m.python.inline('sleep before attempt %d' % attempt, """
@@ -34,7 +44,11 @@
     return self.m.run.with_retry(self.m.step, title, 3, cmd=list(cmd),
                                  between_attempts_fn=sleep, **kwargs)
 
-  def install(self, app_to_push):
+  def install(self):
+    with self.context():
+      self._install()
+
+  def _install(self):
     # We assume a single device is connected.
 
     # Pair the device.
@@ -79,21 +93,21 @@
       self._run('mount developer image', 'ideviceimagemounter', image, sig)
 
     # Install app (necessary before copying any resources to the device).
-    if app_to_push:
-      app_package = self.host_dirs.bin_dir.join('%s.app' % app_to_push)
+    if self.app_name:
+      app_package = self.host_dirs.bin_dir.join('%s.app' % self.app_name)
 
       def uninstall_app(attempt):
         # If app ID changes, upgrade will fail, so try uninstalling.
         self.m.run(self.m.step,
-                   'uninstall %s' % app_to_push,
+                   'uninstall %s' % self.app_name,
                    cmd=['ideviceinstaller', '-U',
-                        'com.google.%s' % app_to_push],
+                        'com.google.%s' % self.app_name],
                    infra_step=True,
                    # App may not be installed.
                    abort_on_failure=False, fail_build_on_failure=False)
 
       num_attempts = 2
-      self.m.run.with_retry(self.m.step, 'install %s' % app_to_push,
+      self.m.run.with_retry(self.m.step, 'install %s' % self.app_name,
                             num_attempts,
                             cmd=['ideviceinstaller', '-i', app_package],
                             between_attempts_fn=uninstall_app,
@@ -104,22 +118,24 @@
     bundle_id = 'com.google.%s' % app_name
     args = [bundle_id] + map(str, cmd[1:])
     success = False
-    try:
-      self.m.run(self.m.step, name, cmd=['idevicedebug', 'run'] + args)
-      success = True
-    finally:
-      if not success:
-        self.m.run(self.m.python, '%s with full debug output' % name,
-                   script=self.module.resource('ios_debug_cmd.py'),
-                   args=args)
+    with self.context():
+      try:
+        self.m.run(self.m.step, name, cmd=['idevicedebug', 'run'] + args)
+        success = True
+      finally:
+        if not success:
+          self.m.run(self.m.python, '%s with full debug output' % name,
+                     script=self.module.resource('ios_debug_cmd.py'),
+                     args=args)
 
   def _run_ios_script(self, script, first, *rest):
-    full = self.m.path['start_dir'].join(
-        'skia', 'platform_tools', 'ios', 'bin', 'ios_' + script)
-    self.m.run(self.m.step,
-               name = '%s %s' % (script, first),
-               cmd = [full, first] + list(rest),
-               infra_step=True)
+    with self.context():
+      full = self.m.path['start_dir'].join(
+          'skia', 'platform_tools', 'ios', 'bin', 'ios_' + script)
+      self.m.run(self.m.step,
+                 name = '%s %s' % (script, first),
+                 cmd = [full, first] + list(rest),
+                 infra_step=True)
 
   def copy_file_to_device(self, host, device):
     self._run_ios_script('push_file', host, device)
@@ -138,12 +154,13 @@
     self._run_ios_script('mkdir', path)
 
   def read_file_on_device(self, path, **kwargs):
-    full = self.m.path['start_dir'].join(
-        'skia', 'platform_tools', 'ios', 'bin', 'ios_cat_file')
-    rv = self.m.run(self.m.step,
-                    name = 'cat_file %s' % path,
-                    cmd = [full, path],
-                    stdout=self.m.raw_io.output(),
-                    infra_step=True,
-                    **kwargs)
-    return rv.stdout.rstrip() if rv and rv.stdout else None
+    with self.context():
+      full = self.m.path['start_dir'].join(
+          'skia', 'platform_tools', 'ios', 'bin', 'ios_cat_file')
+      rv = self.m.run(self.m.step,
+                      name = 'cat_file %s' % path,
+                      cmd = [full, path],
+                      stdout=self.m.raw_io.output(),
+                      infra_step=True,
+                      **kwargs)
+      return rv.stdout.rstrip() if rv and rv.stdout else None
diff --git a/infra/bots/recipe_modules/flavor/ssh.py b/infra/bots/recipe_modules/flavor/ssh.py
index eaceb5d..09694cc 100644
--- a/infra/bots/recipe_modules/flavor/ssh.py
+++ b/infra/bots/recipe_modules/flavor/ssh.py
@@ -17,8 +17,8 @@
 
 class SSHFlavor(default.DefaultFlavor):
 
-  def __init__(self, m):
-    super(SSHFlavor, self).__init__(m)
+  def __init__(self, m, app_name):
+    super(SSHFlavor, self).__init__(m, app_name)
     self._user_ip = ''
 
   @property
@@ -42,14 +42,14 @@
   def ensure_device_dir(self, path):
     self.ssh('mkdir %s' % path, 'mkdir', '-p', path)
 
-  def install(self, app_to_push):
+  def install(self):
     self.ensure_device_dir(self.device_dirs.resource_dir)
-    if app_to_push:
+    if self.app_name:
       self.create_clean_device_dir(self.device_dirs.bin_dir)
-      host_path = self.host_dirs.bin_dir.join(app_to_push)
-      device_path = self.device_path_join(self.device_dirs.bin_dir, app_to_push)
+      host_path = self.host_dirs.bin_dir.join(self.app_name)
+      device_path = self.device_path_join(self.device_dirs.bin_dir, self.app_name)
       self.copy_file_to_device(host_path, device_path)
-      self.ssh('make %s executable' % app_to_push, 'chmod', '+x', device_path)
+      self.ssh('make %s executable' % self.app_name, 'chmod', '+x', device_path)
 
   def create_clean_device_dir(self, path):
     # use -f to silently return if path doesn't exist
diff --git a/infra/bots/recipe_modules/flavor/valgrind.py b/infra/bots/recipe_modules/flavor/valgrind.py
index ab31c72..7ef8750 100644
--- a/infra/bots/recipe_modules/flavor/valgrind.py
+++ b/infra/bots/recipe_modules/flavor/valgrind.py
@@ -10,8 +10,8 @@
 
 
 class ValgrindFlavor(default.DefaultFlavor):
-  def __init__(self, m):
-    super(ValgrindFlavor, self).__init__(m)
+  def __init__(self, m, app_name):
+    super(ValgrindFlavor, self).__init__(m, app_name)
     self._suppressions_file = self.m.path['start_dir'].join(
         'skia', 'tools', 'valgrind.supp')
     self._valgrind_cipd_dir = self.m.vars.slave_dir.join('valgrind')
diff --git a/infra/bots/recipe_modules/flavor/win_ssh.py b/infra/bots/recipe_modules/flavor/win_ssh.py
index 99cc605..beffb7f 100644
--- a/infra/bots/recipe_modules/flavor/win_ssh.py
+++ b/infra/bots/recipe_modules/flavor/win_ssh.py
@@ -19,8 +19,8 @@
 
 class WinSSHFlavor(ssh.SSHFlavor):
 
-  def __init__(self, m):
-    super(WinSSHFlavor, self).__init__(m)
+  def __init__(self, m, app_name):
+    super(WinSSHFlavor, self).__init__(m, app_name)
     self.remote_homedir = 'C:\\Users\\chrome-bot\\botdata\\'
     self.device_dirs = default.DeviceDirs(
       bin_dir        = self.device_path_join(self.remote_homedir, 'bin'),
@@ -52,14 +52,14 @@
   def device_path_join(self, *args):
     return ntpath.join(*args)
 
-  def install(self, app_to_push):
-    # We install apps below.
-    super(WinSSHFlavor, self).install(None)
+  def install(self):
+    self.ensure_device_dir(self.device_dirs.resource_dir)
+
     # Ensure that our empty dir is actually empty.
     self._rmdir(self._empty_dir)
     self.ensure_device_dir(self._empty_dir)
 
-    if app_to_push:
+    if self.app_name:
       # There may be DLLs in the same dir as the executable that must be loaded
       # (yes, Windows allows overriding system DLLs with files in the local
       # directory). For simplicity, just copy the entire dir to the device.
diff --git a/infra/bots/recipes/check_generated_files.py b/infra/bots/recipes/check_generated_files.py
index 59e6ece..59e9f98 100644
--- a/infra/bots/recipes/check_generated_files.py
+++ b/infra/bots/recipes/check_generated_files.py
@@ -16,7 +16,6 @@
   'recipe_engine/raw_io',
   'recipe_engine/step',
   'checkout',
-  'flavor',
   'run',
   'vars',
 ]
@@ -28,7 +27,6 @@
   checkout_root = api.checkout.default_checkout_root
   api.checkout.bot_update(checkout_root=checkout_root)
   api.file.ensure_directory('makedirs tmp_dir', api.vars.tmp_dir)
-  api.flavor.setup()
 
   cwd = api.path['checkout']
 
diff --git a/infra/bots/recipes/compute_test.py b/infra/bots/recipes/compute_test.py
index cbe1fd2..ac1926b 100644
--- a/infra/bots/recipes/compute_test.py
+++ b/infra/bots/recipes/compute_test.py
@@ -15,10 +15,8 @@
 
 def RunSteps(api):
   api.vars.setup()
-  api.flavor.setup()
-
+  api.flavor.setup('hello-opencl')
   api.run(api.flavor.step, 'hello-opencl', cmd=['hello-opencl'])
-
   api.run.check_failure()
 
 def GenTests(api):
diff --git a/infra/bots/recipes/housekeeper.py b/infra/bots/recipes/housekeeper.py
index a8fd1ee..cfa13ae 100644
--- a/infra/bots/recipes/housekeeper.py
+++ b/infra/bots/recipes/housekeeper.py
@@ -12,7 +12,6 @@
 DEPS = [
   'checkout',
   'doxygen',
-  'flavor',
   'recipe_engine/file',
   'recipe_engine/path',
   'recipe_engine/properties',
@@ -27,7 +26,6 @@
   checkout_root = api.checkout.default_checkout_root
   api.checkout.bot_update(checkout_root=checkout_root)
   api.file.ensure_directory('makedirs tmp_dir', api.vars.tmp_dir)
-  api.flavor.setup()
 
   # TODO(borenet): Detect static initializers?
 
diff --git a/infra/bots/recipes/perf.expected/Perf-iOS-Clang-iPadPro-GPU-PowerVRGT7800-arm64-Release-All.json b/infra/bots/recipes/perf.expected/Perf-iOS-Clang-iPadPro-GPU-PowerVRGT7800-arm64-Release-All.json
index 6dcbb12..9f3a831 100644
--- a/infra/bots/recipes/perf.expected/Perf-iOS-Clang-iPadPro-GPU-PowerVRGT7800-arm64-Release-All.json
+++ b/infra/bots/recipes/perf.expected/Perf-iOS-Clang-iPadPro-GPU-PowerVRGT7800-arm64-Release-All.json
@@ -140,10 +140,6 @@
       "[START_DIR]/skia/infra/bots/assets/skp/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get skp VERSION",
     "~followup_annotations": [
@@ -162,10 +158,6 @@
       "42",
       "[START_DIR]/tmp/SKP_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SKP_VERSION",
     "~followup_annotations": [
@@ -270,10 +262,6 @@
       "[START_DIR]/skia/infra/bots/assets/skimage/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get skimage VERSION",
     "~followup_annotations": [
@@ -292,10 +280,6 @@
       "42",
       "[START_DIR]/tmp/SK_IMAGE_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SK_IMAGE_VERSION",
     "~followup_annotations": [
@@ -400,10 +384,6 @@
       "[START_DIR]/skia/infra/bots/assets/svg/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get svg VERSION",
     "~followup_annotations": [
@@ -422,10 +402,6 @@
       "42",
       "[START_DIR]/tmp/SVG_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SVG_VERSION",
     "~followup_annotations": [
@@ -553,10 +529,6 @@
       "-u",
       "import os\nprint os.environ.get('SWARMING_BOT_ID', '')\n"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "name": "get swarming bot id",
     "~followup_annotations": [
       "@@@STEP_LOG_LINE@python.inline@import os@@@",
@@ -570,10 +542,6 @@
       "-u",
       "import os\nprint os.environ.get('SWARMING_TASK_ID', '')\n"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "name": "get swarming task id",
     "~followup_annotations": [
       "@@@STEP_LOG_LINE@python.inline@import os@@@",
@@ -676,10 +644,6 @@
       "0777",
       "[START_DIR]/[SWARM_OUT_DIR]"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "makedirs perf_dir"
   },
diff --git a/infra/bots/recipes/perf.expected/Perf-iOS-Clang-iPhone6-GPU-PowerVRGX6450-arm64-Release-All-Metal.json b/infra/bots/recipes/perf.expected/Perf-iOS-Clang-iPhone6-GPU-PowerVRGX6450-arm64-Release-All-Metal.json
index 2fa015f..dd89c75 100644
--- a/infra/bots/recipes/perf.expected/Perf-iOS-Clang-iPhone6-GPU-PowerVRGX6450-arm64-Release-All-Metal.json
+++ b/infra/bots/recipes/perf.expected/Perf-iOS-Clang-iPhone6-GPU-PowerVRGX6450-arm64-Release-All-Metal.json
@@ -140,10 +140,6 @@
       "[START_DIR]/skia/infra/bots/assets/skp/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get skp VERSION",
     "~followup_annotations": [
@@ -162,10 +158,6 @@
       "42",
       "[START_DIR]/tmp/SKP_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SKP_VERSION",
     "~followup_annotations": [
@@ -270,10 +262,6 @@
       "[START_DIR]/skia/infra/bots/assets/skimage/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get skimage VERSION",
     "~followup_annotations": [
@@ -292,10 +280,6 @@
       "42",
       "[START_DIR]/tmp/SK_IMAGE_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SK_IMAGE_VERSION",
     "~followup_annotations": [
@@ -400,10 +384,6 @@
       "[START_DIR]/skia/infra/bots/assets/svg/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get svg VERSION",
     "~followup_annotations": [
@@ -422,10 +402,6 @@
       "42",
       "[START_DIR]/tmp/SVG_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SVG_VERSION",
     "~followup_annotations": [
@@ -553,10 +529,6 @@
       "-u",
       "import os\nprint os.environ.get('SWARMING_BOT_ID', '')\n"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "name": "get swarming bot id",
     "~followup_annotations": [
       "@@@STEP_LOG_LINE@python.inline@import os@@@",
@@ -570,10 +542,6 @@
       "-u",
       "import os\nprint os.environ.get('SWARMING_TASK_ID', '')\n"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "name": "get swarming task id",
     "~followup_annotations": [
       "@@@STEP_LOG_LINE@python.inline@import os@@@",
@@ -679,10 +647,6 @@
       "0777",
       "[START_DIR]/[SWARM_OUT_DIR]"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.nanobench",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "makedirs perf_dir"
   },
diff --git a/infra/bots/recipes/perf.py b/infra/bots/recipes/perf.py
index 382ea9c..9d3b711 100644
--- a/infra/bots/recipes/perf.py
+++ b/infra/bots/recipes/perf.py
@@ -330,24 +330,18 @@
 def RunSteps(api):
   api.vars.setup()
   api.file.ensure_directory('makedirs tmp_dir', api.vars.tmp_dir)
-  api.flavor.setup()
+  api.flavor.setup('nanobench')
 
-  env = {}
-  if 'iOS' in api.vars.builder_name:
-    env['IOS_BUNDLE_ID'] = 'com.google.nanobench'
-    env['IOS_MOUNT_POINT'] = api.vars.slave_dir.join('mnt_iosdevice')
-  with api.env(env):
-    try:
-      if all(v in api.vars.builder_name for v in ['Android', 'CPU']):
-        api.flavor.install('nanobench', skps=True, images=True, svgs=True,
-                           resources=True, texttraces=True)
-      else:
-        api.flavor.install('nanobench', skps=True, images=True, svgs=True,
-                           resources=True)
-      perf_steps(api)
-    finally:
-      api.flavor.cleanup_steps()
-    api.run.check_failure()
+  try:
+    if all(v in api.vars.builder_name for v in ['Android', 'CPU']):
+      api.flavor.install(skps=True, images=True, svgs=True, resources=True,
+                         texttraces=True)
+    else:
+      api.flavor.install(skps=True, images=True, svgs=True, resources=True)
+    perf_steps(api)
+  finally:
+    api.flavor.cleanup_steps()
+  api.run.check_failure()
 
 
 TEST_BUILDERS = [
diff --git a/infra/bots/recipes/perf_skottietrace.py b/infra/bots/recipes/perf_skottietrace.py
index 0cceae2..6e6605b 100644
--- a/infra/bots/recipes/perf_skottietrace.py
+++ b/infra/bots/recipes/perf_skottietrace.py
@@ -221,11 +221,11 @@
 def RunSteps(api):
   api.vars.setup()
   api.file.ensure_directory('makedirs tmp_dir', api.vars.tmp_dir)
-  api.flavor.setup()
+  api.flavor.setup('dm')
 
   with api.context():
     try:
-      api.flavor.install('dm', resources=True, lotties=True)
+      api.flavor.install(resources=True, lotties=True)
       perf_steps(api)
     finally:
       api.flavor.cleanup_steps()
diff --git a/infra/bots/recipes/perf_skottiewasm_lottieweb.py b/infra/bots/recipes/perf_skottiewasm_lottieweb.py
index e67486e..0176d8a 100644
--- a/infra/bots/recipes/perf_skottiewasm_lottieweb.py
+++ b/infra/bots/recipes/perf_skottiewasm_lottieweb.py
@@ -82,7 +82,7 @@
 
 def RunSteps(api):
   api.vars.setup()
-  api.flavor.setup()
+  api.flavor.setup(None)
   checkout_root = api.path['start_dir']
   buildername = api.properties['buildername']
   node_path = api.path['start_dir'].join('node', 'node', 'bin', 'node')
diff --git a/infra/bots/recipes/recreate_skps.py b/infra/bots/recipes/recreate_skps.py
index c4000ab..392cd62 100644
--- a/infra/bots/recipes/recreate_skps.py
+++ b/infra/bots/recipes/recreate_skps.py
@@ -9,7 +9,6 @@
 DEPS = [
   'checkout',
   'depot_tools/gclient',
-  'flavor',
   'infra',
   'recipe_engine/context',
   'recipe_engine/file',
@@ -46,7 +45,6 @@
       extra_gclient_env=extra_gclient_env)
 
   api.file.ensure_directory('makedirs tmp_dir', api.vars.tmp_dir)
-  api.flavor.setup()
 
   src_dir = checkout_root.join('src')
   skia_dir = checkout_root.join('skia')
diff --git a/infra/bots/recipes/skpbench.py b/infra/bots/recipes/skpbench.py
index f42d487..056d1b8 100644
--- a/infra/bots/recipes/skpbench.py
+++ b/infra/bots/recipes/skpbench.py
@@ -129,12 +129,15 @@
 def RunSteps(api):
   api.vars.setup()
   api.file.ensure_directory('makedirs tmp_dir', api.vars.tmp_dir)
-  api.flavor.setup()
+
+  # The app_name passed to api.flavor.setup() is used to determine which app
+  # to install on an attached device. That work is done in skpbench_steps, so
+  # we pass None here.
+  api.flavor.setup(None)
 
   try:
     mksp_mode = ('Mskp' in api.vars.builder_name)
-    # We install skpbench in skpbench_steps.
-    api.flavor.install(None, skps=not mksp_mode, mskps=mksp_mode)
+    api.flavor.install(skps=not mksp_mode, mskps=mksp_mode)
     skpbench_steps(api)
   finally:
     api.flavor.cleanup_steps()
diff --git a/infra/bots/recipes/skqp_test.py b/infra/bots/recipes/skqp_test.py
index 56c27f7..d7b1d51 100644
--- a/infra/bots/recipes/skqp_test.py
+++ b/infra/bots/recipes/skqp_test.py
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 # Recipe module for Skia Swarming SKQP testing.
+# TODO(borenet): This recipe seems to be unused. Can we delete it?
 
 DEPS = [
   'flavor',
@@ -30,7 +31,11 @@
 def RunSteps(api):
   api.vars.setup()
   api.file.ensure_directory('makedirs tmp_dir', api.vars.tmp_dir)
-  api.flavor.setup()
+
+  # The app_name passed to api.flavor.setup() is used to determine which app
+  # to install on an attached device. We don't need to install anything so we
+  # pass None here.
+  api.flavor.setup(None)
 
   test_firebase_steps(api)
   api.run.check_failure()
diff --git a/infra/bots/recipes/test.expected/Test-iOS-Clang-iPadPro-GPU-PowerVRGT7800-arm64-Release-All.json b/infra/bots/recipes/test.expected/Test-iOS-Clang-iPadPro-GPU-PowerVRGT7800-arm64-Release-All.json
index 0d898fc..2247949 100644
--- a/infra/bots/recipes/test.expected/Test-iOS-Clang-iPadPro-GPU-PowerVRGT7800-arm64-Release-All.json
+++ b/infra/bots/recipes/test.expected/Test-iOS-Clang-iPadPro-GPU-PowerVRGT7800-arm64-Release-All.json
@@ -140,10 +140,6 @@
       "[START_DIR]/skia/infra/bots/assets/skp/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get skp VERSION",
     "~followup_annotations": [
@@ -162,10 +158,6 @@
       "42",
       "[START_DIR]/tmp/SKP_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SKP_VERSION",
     "~followup_annotations": [
@@ -270,10 +262,6 @@
       "[START_DIR]/skia/infra/bots/assets/skimage/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get skimage VERSION",
     "~followup_annotations": [
@@ -292,10 +280,6 @@
       "42",
       "[START_DIR]/tmp/SK_IMAGE_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SK_IMAGE_VERSION",
     "~followup_annotations": [
@@ -400,10 +384,6 @@
       "[START_DIR]/skia/infra/bots/assets/svg/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get svg VERSION",
     "~followup_annotations": [
@@ -422,10 +402,6 @@
       "42",
       "[START_DIR]/tmp/SVG_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SVG_VERSION",
     "~followup_annotations": [
@@ -529,10 +505,6 @@
       "rmtree",
       "[START_DIR]/test"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "rmtree test"
   },
@@ -548,10 +520,6 @@
       "0777",
       "[START_DIR]/test"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "makedirs test"
   },
@@ -593,8 +561,6 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -654,10 +620,6 @@
       "-u",
       "import os\nprint os.environ.get('SWARMING_BOT_ID', '')\n"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "name": "get swarming bot id",
     "~followup_annotations": [
       "@@@STEP_LOG_LINE@python.inline@import os@@@",
@@ -671,10 +633,6 @@
       "-u",
       "import os\nprint os.environ.get('SWARMING_TASK_ID', '')\n"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "name": "get swarming task id",
     "~followup_annotations": [
       "@@@STEP_LOG_LINE@python.inline@import os@@@",
diff --git a/infra/bots/recipes/test.expected/Test-iOS-Clang-iPhone6-GPU-PowerVRGX6450-arm64-Release-All-Metal.json b/infra/bots/recipes/test.expected/Test-iOS-Clang-iPhone6-GPU-PowerVRGX6450-arm64-Release-All-Metal.json
index 611b483..6b5996b 100644
--- a/infra/bots/recipes/test.expected/Test-iOS-Clang-iPhone6-GPU-PowerVRGX6450-arm64-Release-All-Metal.json
+++ b/infra/bots/recipes/test.expected/Test-iOS-Clang-iPhone6-GPU-PowerVRGX6450-arm64-Release-All-Metal.json
@@ -140,10 +140,6 @@
       "[START_DIR]/skia/infra/bots/assets/skp/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get skp VERSION",
     "~followup_annotations": [
@@ -162,10 +158,6 @@
       "42",
       "[START_DIR]/tmp/SKP_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SKP_VERSION",
     "~followup_annotations": [
@@ -270,10 +262,6 @@
       "[START_DIR]/skia/infra/bots/assets/skimage/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get skimage VERSION",
     "~followup_annotations": [
@@ -292,10 +280,6 @@
       "42",
       "[START_DIR]/tmp/SK_IMAGE_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SK_IMAGE_VERSION",
     "~followup_annotations": [
@@ -400,10 +384,6 @@
       "[START_DIR]/skia/infra/bots/assets/svg/VERSION",
       "/path/to/tmp/"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "Get svg VERSION",
     "~followup_annotations": [
@@ -422,10 +402,6 @@
       "42",
       "[START_DIR]/tmp/SVG_VERSION"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "write SVG_VERSION",
     "~followup_annotations": [
@@ -529,10 +505,6 @@
       "rmtree",
       "[START_DIR]/test"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "rmtree test"
   },
@@ -548,10 +520,6 @@
       "0777",
       "[START_DIR]/test"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "infra_step": true,
     "name": "makedirs test"
   },
@@ -593,8 +561,6 @@
     ],
     "env": {
       "CHROME_HEADLESS": "1",
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice",
       "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
     },
     "infra_step": true,
@@ -654,10 +620,6 @@
       "-u",
       "import os\nprint os.environ.get('SWARMING_BOT_ID', '')\n"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "name": "get swarming bot id",
     "~followup_annotations": [
       "@@@STEP_LOG_LINE@python.inline@import os@@@",
@@ -671,10 +633,6 @@
       "-u",
       "import os\nprint os.environ.get('SWARMING_TASK_ID', '')\n"
     ],
-    "env": {
-      "IOS_BUNDLE_ID": "com.google.dm",
-      "IOS_MOUNT_POINT": "[START_DIR]/mnt_iosdevice"
-    },
     "name": "get swarming task id",
     "~followup_annotations": [
       "@@@STEP_LOG_LINE@python.inline@import os@@@",
diff --git a/infra/bots/recipes/test.py b/infra/bots/recipes/test.py
index 2d1be73..d27191a 100644
--- a/infra/bots/recipes/test.py
+++ b/infra/bots/recipes/test.py
@@ -934,23 +934,17 @@
 def RunSteps(api):
   api.vars.setup()
   api.file.ensure_directory('makedirs tmp_dir', api.vars.tmp_dir)
-  api.flavor.setup()
+  api.flavor.setup('dm')
 
-  env = {}
-  if 'iOS' in api.vars.builder_name:
-    env['IOS_BUNDLE_ID'] = 'com.google.dm'
-    env['IOS_MOUNT_POINT'] = api.vars.slave_dir.join('mnt_iosdevice')
-  with api.context(env=env):
-    try:
-      if 'Lottie' in api.vars.builder_name:
-        api.flavor.install('dm', resources=True, lotties=True)
-      else:
-        api.flavor.install('dm', skps=True, images=True, svgs=True,
-                           resources=True)
-      test_steps(api)
-    finally:
-      api.flavor.cleanup_steps()
-    api.run.check_failure()
+  try:
+    if 'Lottie' in api.vars.builder_name:
+      api.flavor.install(resources=True, lotties=True)
+    else:
+      api.flavor.install(skps=True, images=True, svgs=True, resources=True)
+    test_steps(api)
+  finally:
+    api.flavor.cleanup_steps()
+  api.run.check_failure()
 
 
 TEST_BUILDERS = [