Clean up pre-existing DevFS during creation (#10843)

diff --git a/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart b/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart
index 4af62da..e439d37 100644
--- a/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart
+++ b/packages/flutter_tools/lib/src/commands/fuchsia_reload.dart
@@ -143,9 +143,24 @@
     return _vmServiceCache[port];
   }
 
+  Future<bool> _checkPort(int port) async {
+    bool connected = true;
+    Socket s;
+    try {
+      s = await Socket.connect("$_address", port);
+    } catch (_) {
+      connected = false;
+    }
+    if (s != null)
+      await s.close();
+    return connected;
+  }
+
   Future<List<FlutterView>> _getViews(List<int> ports) async {
     final List<FlutterView> views = <FlutterView>[];
     for (int port in ports) {
+      if (!await _checkPort(port))
+        continue;
       final VMService vmService = _getVMService(port);
       await vmService.getVM();
       await vmService.waitForViews();
diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart
index 2657e92..39b9766 100644
--- a/packages/flutter_tools/lib/src/devfs.dart
+++ b/packages/flutter_tools/lib/src/devfs.dart
@@ -5,6 +5,8 @@
 import 'dart:async';
 import 'dart:convert' show BASE64, UTF8;
 
+import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
+
 import 'asset.dart';
 import 'base/context.dart';
 import 'base/file_system.dart';
@@ -185,10 +187,7 @@
 
   @override
   Future<dynamic> destroy(String fsName) async {
-    await vmService.vm.invokeRpcRaw(
-      '_deleteDevFS',
-      params: <String, dynamic> { 'fsName': fsName },
-    );
+    await vmService.vm.deleteDevFS(fsName);
   }
 
   @override
@@ -352,7 +351,16 @@
 
   Future<Uri> create() async {
     printTrace('DevFS: Creating new filesystem on the device ($_baseUri)');
-    _baseUri = await _operations.create(fsName);
+    try {
+      _baseUri = await _operations.create(fsName);
+    } on rpc.RpcException catch (rpcException) {
+      // 1001 is kFileSystemAlreadyExists in //dart/runtime/vm/json_stream.h
+      if (rpcException.code != 1001)
+        rethrow;
+      printTrace('DevFS: Creating failed. Destroying and trying again');
+      await destroy();
+      _baseUri = await _operations.create(fsName);
+    }
     printTrace('DevFS: Created new filesystem on the device ($_baseUri)');
     return _baseUri;
   }
diff --git a/packages/flutter_tools/test/devfs_test.dart b/packages/flutter_tools/test/devfs_test.dart
index 34030cc..f931e9b 100644
--- a/packages/flutter_tools/test/devfs_test.dart
+++ b/packages/flutter_tools/test/devfs_test.dart
@@ -13,6 +13,7 @@
 import 'package:flutter_tools/src/build_info.dart';
 import 'package:flutter_tools/src/devfs.dart';
 import 'package:flutter_tools/src/vmservice.dart';
+import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
 import 'package:test/test.dart';
 
 import 'src/common.dart';
@@ -335,7 +336,34 @@
     testUsingContext('delete dev file system', () async {
       expect(vmService.messages, isEmpty, reason: 'prior test timeout');
       await devFS.destroy();
-      vmService.expectMessages(<String>['_deleteDevFS {fsName: test}']);
+      vmService.expectMessages(<String>['destroy test']);
+      expect(devFS.assetPathsToEvict, isEmpty);
+    }, overrides: <Type, Generator>{
+      FileSystem: () => fs,
+    });
+
+    testUsingContext('cleanup preexisting file system', () async {
+      // simulate workspace
+      final File file = fs.file(fs.path.join(basePath, filePath));
+      await file.parent.create(recursive: true);
+      file.writeAsBytesSync(<int>[1, 2, 3]);
+
+      // simulate package
+      await _createPackage(fs, 'somepkg', 'somefile.txt');
+
+      devFS = new DevFS(vmService, 'test', tempDir);
+      await devFS.create();
+      vmService.expectMessages(<String>['create test']);
+      expect(devFS.assetPathsToEvict, isEmpty);
+
+      // Try to create again.
+      await devFS.create();
+      vmService.expectMessages(<String>['create test', 'destroy test', 'create test']);
+      expect(devFS.assetPathsToEvict, isEmpty);
+
+      // Really destroy.
+      await devFS.destroy();
+      vmService.expectMessages(<String>['destroy test']);
       expect(devFS.assetPathsToEvict, isEmpty);
     }, overrides: <Type, Generator>{
       FileSystem: () => fs,
@@ -390,16 +418,30 @@
 class MockVM implements VM {
   final MockVMService _service;
   final Uri _baseUri = Uri.parse('file:///tmp/devfs/test');
+  bool _devFSExists = false;
+
+  static const int kFileSystemAlreadyExists = 1001;
 
   MockVM(this._service);
 
   @override
   Future<Map<String, dynamic>> createDevFS(String fsName) async {
     _service.messages.add('create $fsName');
+    if (_devFSExists) {
+      throw new rpc.RpcException(kFileSystemAlreadyExists, 'File system already exists');
+    }
+    _devFSExists = true;
     return <String, dynamic>{'uri': '$_baseUri'};
   }
 
   @override
+  Future<Map<String, dynamic>> deleteDevFS(String fsName) async {
+    _service.messages.add('destroy $fsName');
+    _devFSExists = false;
+    return <String, dynamic>{'type': 'Success'};
+  }
+
+  @override
   Future<Map<String, dynamic>> invokeRpcRaw(String method, {
     Map<String, dynamic> params: const <String, dynamic>{},
     Duration timeout,