Handle new observatory url (#7061)

* reapply handle new Observatory URL changes
Fixes https://github.com/flutter/flutter/issues/6843

* allow non numeric IPv4 addresses
Fixes https://github.com/flutter/flutter/issues/7051
diff --git a/packages/flutter_tools/lib/src/protocol_discovery.dart b/packages/flutter_tools/lib/src/protocol_discovery.dart
index 7c27b13..470d527 100644
--- a/packages/flutter_tools/lib/src/protocol_discovery.dart
+++ b/packages/flutter_tools/lib/src/protocol_discovery.dart
@@ -21,37 +21,37 @@
   final DeviceLogReader _logReader;
   final String _serviceName;
 
-  Completer<int> _completer = new Completer<int>();
+  Completer<Uri> _completer = new Completer<Uri>();
   StreamSubscription<String> _subscription;
 
   /// The [Future] returned by this function will complete when the next service
-  /// protocol port is found.
-  Future<int> nextPort() => _completer.future;
+  /// Uri is found.
+  Future<Uri> nextUri() => _completer.future;
 
   void cancel() {
     _subscription.cancel();
   }
 
   void _onLine(String line) {
-    int portNumber = 0;
-    if (line.contains('$_serviceName listening on http://')) {
+    Uri uri;
+    String prefix = '$_serviceName listening on ';
+    int index = line.indexOf(prefix + 'http://');
+    if (index >= 0) {
       try {
-        RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)");
-        String port = portExp.firstMatch(line).group(1);
-        portNumber = int.parse(port);
+        uri = Uri.parse(line.substring(index + prefix.length));
       } catch (_) {
         // Ignore errors.
       }
     }
-    if (portNumber != 0)
-      _located(portNumber);
+    if (uri != null)
+      _located(uri);
   }
 
-  void _located(int port) {
+  void _located(Uri uri) {
     assert(_completer != null);
     assert(!_completer.isCompleted);
 
-    _completer.complete(port);
-    _completer = new Completer<int>();
+    _completer.complete(uri);
+    _completer = new Completer<Uri>();
   }
 }