Do not use logcat -T on pre-lollipop Android

diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart
index 22dbcd9..f222c1d 100644
--- a/packages/flutter_tools/lib/src/android/android_device.dart
+++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -10,7 +10,7 @@
 import '../android/android_sdk.dart';
 import '../android/android_workflow.dart';
 import '../application_package.dart';
-import '../base/common.dart' show throwToolExit;
+import '../base/common.dart' show throwToolExit, unawaited;
 import '../base/file_system.dart';
 import '../base/io.dart';
 import '../base/logger.dart';
@@ -854,22 +854,36 @@
   @override
   String get name => device.name;
 
-  void _start() {
+  Future<void> _start() async {
+    final String lastTimestamp = device.lastLogcatTimestamp;
     // Start the adb logcat process and filter logs by the "flutter" tag.
-    final List<String> args = <String>['shell', '-x', 'logcat', '-v', 'time', '-s', 'flutter'];
-    processUtils.start(device.adbCommandForDevice(args)).then<void>((Process process) {
-      _process = process;
-      // We expect logcat streams to occasionally contain invalid utf-8,
-      // see: https://github.com/flutter/flutter/pull/8864.
-      const Utf8Decoder decoder = Utf8Decoder(reportErrors: false);
-      _process.stdout.transform<String>(decoder).transform<String>(const LineSplitter()).listen(_onLine);
-      _process.stderr.transform<String>(decoder).transform<String>(const LineSplitter()).listen(_onLine);
-      _process.exitCode.whenComplete(() {
-        if (_linesController.hasListener) {
-          _linesController.close();
-        }
-      });
-    });
+    final List<String> args = <String>[
+      'logcat',
+      '-v',
+      'time',
+    ];
+    // logcat -T is not supported on Android releases before Lollipop.
+    const int kLollipopVersionCode = 21;
+    final int apiVersion = int.tryParse(await device._apiVersion);
+    if (apiVersion != null && apiVersion >= kLollipopVersionCode) {
+      args.addAll(<String>[
+        '-T',
+        lastTimestamp ?? '', // Empty `-T` means the timestamp of the logcat command invocation.
+      ]);
+    }
+
+    _process = await processUtils.start(device.adbCommandForDevice(args));
+
+    // We expect logcat streams to occasionally contain invalid utf-8,
+    // see: https://github.com/flutter/flutter/pull/8864.
+    const Utf8Decoder decoder = Utf8Decoder(reportErrors: false);
+    _process.stdout.transform<String>(decoder).transform<String>(const LineSplitter()).listen(_onLine);
+    _process.stderr.transform<String>(decoder).transform<String>(const LineSplitter()).listen(_onLine);
+    unawaited(_process.exitCode.whenComplete(() {
+      if (_linesController.hasListener) {
+        _linesController.close();
+      }
+    }));
   }
 
   // 'W/ActivityManager(pid): '
diff --git a/packages/flutter_tools/test/general.shard/android/android_device_test.dart b/packages/flutter_tools/test/general.shard/android/android_device_test.dart
index a765a5b..c33089c 100644
--- a/packages/flutter_tools/test/general.shard/android/android_device_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/android_device_test.dart
@@ -679,6 +679,76 @@
       ProcessManager: () => mockProcessManager,
     });
   });
+
+  group('logReader', () {
+    ProcessManager mockProcessManager;
+    AndroidSdk mockAndroidSdk;
+
+    setUp(() {
+      mockAndroidSdk = MockAndroidSdk();
+      mockProcessManager = MockProcessManager();
+
+      when(mockProcessManager.run(
+        argThat(contains('getprop')),
+        stderrEncoding: anyNamed('stderrEncoding'),
+        stdoutEncoding: anyNamed('stdoutEncoding'),
+      )).thenAnswer((_) {
+        final StringBuffer buf = StringBuffer()
+          ..writeln('[ro.build.version.sdk]: [28]');
+        final ProcessResult result = ProcessResult(1, 0, buf.toString(), '');
+        return Future<ProcessResult>.value(result);
+      });
+    });
+
+    testUsingContext('calls adb logcat with expected flags', () async {
+      const String kLastLogcatTimestamp = '11-27 15:39:04.506';
+      when(mockAndroidSdk.adbPath).thenReturn('adb');
+      when(mockProcessManager.runSync(<String>['adb', '-s', '1234', 'shell', '-x', 'logcat', '-v', 'time', '-t', '1']))
+        .thenReturn(ProcessResult(0, 0, '$kLastLogcatTimestamp I/flutter: irrelevant', ''));
+
+      final Completer<void> logcatCompleter = Completer<void>();
+      when(mockProcessManager.start(argThat(contains('logcat'))))
+        .thenAnswer((_) {
+          logcatCompleter.complete();
+          return Future<Process>.value(createMockProcess());
+        });
+
+      final AndroidDevice device = AndroidDevice('1234');
+      final DeviceLogReader logReader = device.getLogReader();
+      logReader.logLines.listen((_) {});
+      await logcatCompleter.future;
+
+      verify(mockProcessManager.start(const <String>['adb', '-s', '1234', 'logcat', '-v', 'time', '-T', kLastLogcatTimestamp]))
+        .called(1);
+    }, overrides: <Type, Generator>{
+      AndroidSdk: () => mockAndroidSdk,
+      ProcessManager: () => mockProcessManager,
+    });
+
+    testUsingContext('calls adb logcat with expected flags when the device logs are empty', () async {
+      when(mockAndroidSdk.adbPath).thenReturn('adb');
+      when(mockProcessManager.runSync(<String>['adb', '-s', '1234', 'shell', '-x', 'logcat', '-v', 'time', '-t', '1']))
+        .thenReturn(ProcessResult(0, 0, '', ''));
+
+      final Completer<void> logcatCompleter = Completer<void>();
+      when(mockProcessManager.start(argThat(contains('logcat'))))
+        .thenAnswer((_) {
+          logcatCompleter.complete();
+          return Future<Process>.value(createMockProcess());
+        });
+
+      final AndroidDevice device = AndroidDevice('1234');
+      final DeviceLogReader logReader = device.getLogReader();
+      logReader.logLines.listen((_) {});
+      await logcatCompleter.future;
+
+      verify(mockProcessManager.start(const <String>['adb', '-s', '1234', 'logcat', '-v', 'time', '-T', '']))
+        .called(1);
+    }, overrides: <Type, Generator>{
+      AndroidSdk: () => mockAndroidSdk,
+      ProcessManager: () => mockProcessManager,
+    });
+  });
 }
 
 class MockProcessManager extends Mock implements ProcessManager {}