[fuchsia_reload] Find and attach to the first instance of the named app (#8830)

diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart
index 8a5b844..bbbee28 100644
--- a/packages/flutter_tools/lib/src/vmservice.dart
+++ b/packages/flutter_tools/lib/src/vmservice.dart
@@ -170,6 +170,16 @@
   Future<VM> getVM() {
     return _vm.reload();
   }
+
+  Future<Null> waitForViews({int attempts = 5, int attemptSeconds = 1}) async {
+    await vm.refreshViews();
+    for (int i = 0; (vm.firstView == null) && (i < attempts); i++) {
+      // If the VM doesn't yet have a view, wait for one to show up.
+      printTrace('Waiting for Flutter view');
+      await new Future<Null>.delayed(new Duration(seconds: attemptSeconds));
+      await vm.refreshViews();
+    }
+  }
 }
 
 /// An error that is thrown when constructing/updating a service object.
@@ -743,9 +753,20 @@
     await vmService.vm.invokeRpc('_flutter.listViews', timeout: kLongRequestTimeout);
   }
 
-  FlutterView get mainView {
+  Iterable<FlutterView> get views => _viewCache.values;
+
+  FlutterView get firstView {
     return _viewCache.values.isEmpty ? null : _viewCache.values.first;
   }
+
+  FlutterView firstViewWithName(String isolateFilter) {
+    if (_viewCache.values.isEmpty) {
+      return null;
+    }
+    return _viewCache.values.firstWhere(
+        (FlutterView v) => v.uiIsolate.name.contains(isolateFilter),
+        orElse: () => null);
+  }
 }
 
 /// An isolate running inside the VM. Instances of the Isolate class are always