Filter Android logs by the pid of the remote process (#9293)

Fixes https://github.com/flutter/flutter/issues/6849
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart
index 40ab664..1df0b0d 100644
--- a/packages/flutter_tools/lib/src/android/android_device.dart
+++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -621,8 +621,8 @@
     });
   }
 
-  // 'W/ActivityManager: '
-  static final RegExp _logFormat = new RegExp(r'^[VDIWEF]\/.{8,}:\s');
+  // 'W/ActivityManager(pid): '
+  static final RegExp _logFormat = new RegExp(r'^[VDIWEF]\/.*?\(\s*(\d+)\):\s');
 
   static final List<RegExp> _whitelistedTags = <RegExp>[
     new RegExp(r'^[VDIWEF]\/flutter[^:]*:\s+', caseSensitive: false),
@@ -657,14 +657,19 @@
     }
     // Chop off the time.
     line = line.substring(timeMatch.end + 1);
-    if (_logFormat.hasMatch(line)) {
-      // Filter on approved names and levels.
-      for (RegExp regex in _whitelistedTags) {
-        if (regex.hasMatch(line)) {
-          _acceptedLastLine = true;
-          _linesController.add(line);
-          return;
-        }
+    final Match logMatch = _logFormat.firstMatch(line);
+    if (logMatch != null) {
+      bool acceptLine = false;
+      if (appPid != null && int.parse(logMatch.group(1)) == appPid) {
+        acceptLine = true;
+      } else {
+        // Filter on approved names and levels.
+        acceptLine = _whitelistedTags.any((RegExp re) => re.hasMatch(line));
+      }
+      if (acceptLine) {
+        _acceptedLastLine = true;
+        _linesController.add(line);
+        return;
       }
       _acceptedLastLine = false;
     } else if (line == '--------- beginning of system' ||
diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart
index 6ad3b4b..a69951e 100644
--- a/packages/flutter_tools/lib/src/device.dart
+++ b/packages/flutter_tools/lib/src/device.dart
@@ -374,6 +374,9 @@
 
   @override
   String toString() => name;
+
+  /// Process ID of the app on the deivce.
+  int appPid;
 }
 
 /// Describes an app running on the device.
diff --git a/packages/flutter_tools/lib/src/run_cold.dart b/packages/flutter_tools/lib/src/run_cold.dart
index fa2e88c..7bd6ced 100644
--- a/packages/flutter_tools/lib/src/run_cold.dart
+++ b/packages/flutter_tools/lib/src/run_cold.dart
@@ -114,6 +114,7 @@
     printTrace('Application running.');
 
     if (vmService != null) {
+      device.getLogReader(app: package).appPid = vmService.vm.pid;
       await vmService.vm.refreshViews();
       printTrace('Connected to ${vmService.vm.firstView}\.');
     }
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart
index d2704c1..312c357 100644
--- a/packages/flutter_tools/lib/src/run_hot.dart
+++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -101,6 +101,8 @@
       return 2;
     }
 
+    device.getLogReader(app: package).appPid = vmService.vm.pid;
+
     try {
       final Uri baseUri = await _initDevFS();
       if (connectionInfoCompleter != null) {
diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart
index d9afbfd..7b9f1ac 100644
--- a/packages/flutter_tools/lib/src/vmservice.dart
+++ b/packages/flutter_tools/lib/src/vmservice.dart
@@ -507,6 +507,7 @@
     _loaded = true;
 
     // TODO(johnmccutchan): Extract any properties we care about here.
+    _pid = map['pid'];
 
     // Remove any isolates which are now dead from the isolate cache.
     _removeDeadIsolates(map['isolates']);
@@ -521,6 +522,11 @@
   /// The set of live views.
   final Map<String, FlutterView> _viewCache = <String, FlutterView>{};
 
+  /// The pid of the VM's process.
+  int _pid;
+
+  int get pid => _pid;
+
   int _compareIsolates(Isolate a, Isolate b) {
     final DateTime aStart = a.startTime;
     final DateTime bStart = b.startTime;