Build the x86 (debug) variant for virtual devices

Test LED runs:
https://ci.chromium.org/swarming/task/50fcd1beb5682210?server=chromium-swarm.appspot.com
https://ci.chromium.org/swarming/task/50fced6262722d10?server=chromium-swarm.appspot.com
https://ci.chromium.org/swarming/task/50fcedf148966010?server=chromium-swarm.appspot.com

Reland "Use more devices when doing firebase tests."

This reverts commit 58d6203d7e2fa16fc3fd761fdfa1f7f91c68cfba.

Change-Id: I7b2c32ad743b9481b2fe450e982f001371e53ce2
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/9643
Reviewed-by: Emmanuel Garcia <egarciad@google.com>
Reviewed-by: Godofredo Contreras <godofredoc@google.com>
Commit-Queue: Dan Field <dnfield@google.com>
diff --git a/recipes/firebaselab/firebaselab.expected/basic.json b/recipes/firebaselab/firebaselab.expected/basic.json
index 4af1eec..8d0353d 100644
--- a/recipes/firebaselab/firebaselab.expected/basic.json
+++ b/recipes/firebaselab/firebaselab.expected/basic.json
@@ -167,35 +167,6 @@
     ]
   },
   {
-    "cmd": [
-      "flutter",
-      "build",
-      "appbundle",
-      "--target-platform",
-      "android-arm,android-arm64"
-    ],
-    "cwd": "[START_DIR]/flutter/dev/integration_tests/the_task",
-    "env": {
-      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
-      "LUCI_BRANCH": "",
-      "LUCI_CI": "True",
-      "LUCI_PR": "",
-      "OS": "linux",
-      "PUB_CACHE": "[CACHE]/.pub-cache",
-      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter"
-    },
-    "env_prefixes": {
-      "PATH": [
-        "[START_DIR]/flutter/bin",
-        "[START_DIR]/flutter/bin/cache/dart-sdk/bin"
-      ]
-    },
-    "name": "test_execution.Build appbundle",
-    "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
-    ]
-  },
-  {
     "cmd": [],
     "name": "test_execution.ensure gcloud",
     "~followup_annotations": [
@@ -345,6 +316,35 @@
   },
   {
     "cmd": [
+      "flutter",
+      "build",
+      "appbundle",
+      "--target-platform",
+      "android-arm,android-arm64"
+    ],
+    "cwd": "[START_DIR]/flutter/dev/integration_tests/the_task",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[CACHE]/.pub-cache",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter/bin",
+        "[START_DIR]/flutter/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "name": "test_execution.Build appbundle",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
       "[START_DIR]/cipd/gcloud/bin/gcloud",
       "firebase",
       "test",
@@ -387,6 +387,89 @@
     ]
   },
   {
+    "cmd": [
+      "flutter",
+      "build",
+      "apk",
+      "--debug",
+      "--target-platform",
+      "android-x86"
+    ],
+    "cwd": "[START_DIR]/flutter/dev/integration_tests/the_task",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[CACHE]/.pub-cache",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter/bin",
+        "[START_DIR]/flutter/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "name": "test_execution.Build apk",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[START_DIR]/cipd/gcloud/bin/gcloud",
+      "firebase",
+      "test",
+      "android",
+      "run",
+      "--type",
+      "robo",
+      "--app",
+      "build/app/outputs/flutter-apk/app-debug.apk",
+      "--timeout",
+      "2m",
+      "--results-bucket=gs://flutter_firebase_testlab",
+      "--results-dir=the_task/fake-task-id",
+      "--device",
+      "model=Nexus5,version=19",
+      "--device",
+      "model=Nexus5,version=21",
+      "--device",
+      "model=Nexus5,version=22",
+      "--device",
+      "model=Nexus5,version=23",
+      "--device",
+      "model=Nexus6P,version=25",
+      "--device",
+      "model=Nexus6P,version=26",
+      "--device",
+      "model=Nexus6P,version=27",
+      "--device",
+      "model=NexusLowRes,version=30"
+    ],
+    "cwd": "[START_DIR]/flutter/dev/integration_tests/the_task",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[CACHE]/.pub-cache",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter/bin",
+        "[START_DIR]/flutter/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "name": "test_execution.gcloud firebase (2)",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [],
     "name": "test_execution.install infra/gsutil",
     "~followup_annotations": [
diff --git a/recipes/firebaselab/firebaselab.py b/recipes/firebaselab/firebaselab.py
index 6bba74d..daf7a38 100644
--- a/recipes/firebaselab/firebaselab.py
+++ b/recipes/firebaselab/firebaselab.py
@@ -36,11 +36,50 @@
   deps = api.properties.get('dependencies', [])
   api.flutter_deps.required_deps(env, env_prefixes, deps)
   task_name = api.properties.get('task_name')
-  device_flags = [
-      '--device', 'model=blueline,version=28', '--device',
-      'model=flame,version=29', '--device', 'model=griffin,version=24'
+
+  physical_devices = [
+      # Physical devices - use only highly available devices to avoid timeouts.
+      # Pixel 3
+      '--device', 'model=blueline,version=28',
+      # Pixel 4
+      '--device', 'model=flame,version=29',
+      # Moto Z XT1650
+      '--device', 'model=griffin,version=24',
   ]
 
+  virtual_devices = [
+      # Virtual devices for API level coverage.
+      '--device', 'model=Nexus5,version=19',
+      # SDK 20 not available virtually or physically.
+      '--device', 'model=Nexus5,version=21',
+      '--device', 'model=Nexus5,version=22',
+      '--device', 'model=Nexus5,version=23',
+      # SDK 24 is run on a physical griffin/Moto Z above.
+      '--device', 'model=Nexus6P,version=25',
+      '--device', 'model=Nexus6P,version=26',
+      '--device', 'model=Nexus6P,version=27',
+      # SDK 28 is run on a physical blueline/Pixel 3 above.
+      # SDK 29 is run on a physical flame/Pixel 4 above.
+      '--device', 'model=NexusLowRes,version=30',
+  ]
+
+  test_configurations = (
+      (
+          'Build appbundle',
+          ['flutter', 'build', 'appbundle', '--target-platform',
+                'android-arm,android-arm64'],
+          'build/app/outputs/bundle/release/app-release.aab',
+          physical_devices
+      ),
+      (
+          'Build apk',
+          ['flutter', 'build', 'apk', '--debug', '--target-platform',
+                'android-x86'],
+          'build/app/outputs/flutter-apk/app-debug.apk',
+          virtual_devices
+      ),
+  )
+
   with api.context(env=env, env_prefixes=env_prefixes, cwd=checkout_path):
     api.step('flutter doctor', ['flutter', 'doctor', '-v'])
     api.step('download dependencies', ['flutter', 'update-packages'])
@@ -48,22 +87,19 @@
   test_path = checkout_path.join('dev', 'integration_tests', task_name)
   with api.step.nest('test_execution') as presentation:
     with api.context(env=env, env_prefixes=env_prefixes, cwd=test_path):
-      aab = "build/app/outputs/bundle/release/app-release.aab"
-      api.step(
-          'Build appbundle', [
-              'flutter', 'build', 'appbundle', '--target-platform',
-              'android-arm,android-arm64'
-          ]
-      )
       task_id = api.swarming.task_id
       api.gcloud('--quiet', 'config', 'set', 'project', 'flutter-infra')
-      cmd = [
-          'firebase', 'test', 'android', 'run', '--type', 'robo', '--app', aab,
-          '--timeout', '2m',
-          '--results-bucket=gs://%s' % gcs_bucket,
-          '--results-dir=%s/%s' % (task_name, task_id)
-      ] + device_flags
-      api.gcloud(*cmd)
+      for step_name, build_command, binary, devices in test_configurations:
+        api.step(step_name, build_command)
+        firebase_cmd = [
+            'firebase', 'test', 'android', 'run', '--type', 'robo',
+            '--app', binary,
+            '--timeout', '2m',
+            '--results-bucket=gs://%s' % gcs_bucket,
+            '--results-dir=%s/%s' % (task_name, task_id)
+        ] + devices
+        api.gcloud(*firebase_cmd)
+
       logcat_path = '%s/%s/*/logcat' % (task_name, task_id)
       tmp_logcat = api.path['cleanup'].join('logcat')
       api.gsutil.download(gcs_bucket, logcat_path, api.path['cleanup'])