[flutter_tools] Do not use the logcat -T flag on Android versions before Lollipop (#49327)
This commit is contained in:
parent
d9f071fd0a
commit
3f97315720
@ -10,7 +10,7 @@ import '../android/android_builder.dart';
|
|||||||
import '../android/android_sdk.dart';
|
import '../android/android_sdk.dart';
|
||||||
import '../android/android_workflow.dart';
|
import '../android/android_workflow.dart';
|
||||||
import '../application_package.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/file_system.dart';
|
||||||
import '../base/io.dart';
|
import '../base/io.dart';
|
||||||
import '../base/logger.dart';
|
import '../base/logger.dart';
|
||||||
@ -1014,29 +1014,36 @@ class _AdbLogReader extends DeviceLogReader {
|
|||||||
@override
|
@override
|
||||||
String get name => device.name;
|
String get name => device.name;
|
||||||
|
|
||||||
void _start() {
|
Future<void> _start() async {
|
||||||
final String lastTimestamp = device.lastLogcatTimestamp;
|
final String lastTimestamp = device.lastLogcatTimestamp;
|
||||||
// Start the adb logcat process and filter the most recent logs since `lastTimestamp`.
|
// Start the adb logcat process and filter the most recent logs since `lastTimestamp`.
|
||||||
final List<String> args = <String>[
|
final List<String> args = <String>[
|
||||||
'logcat',
|
'logcat',
|
||||||
'-v',
|
'-v',
|
||||||
'time',
|
'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',
|
'-T',
|
||||||
lastTimestamp ?? '', // Empty `-T` means the timestamp of the logcat command invocation.
|
lastTimestamp ?? '', // Empty `-T` means the timestamp of the logcat command invocation.
|
||||||
];
|
]);
|
||||||
processUtils.start(device.adbCommandForDevice(args)).then<void>((Process process) {
|
}
|
||||||
_process = process;
|
|
||||||
|
_process = await processUtils.start(device.adbCommandForDevice(args));
|
||||||
|
|
||||||
// We expect logcat streams to occasionally contain invalid utf-8,
|
// We expect logcat streams to occasionally contain invalid utf-8,
|
||||||
// see: https://github.com/flutter/flutter/pull/8864.
|
// see: https://github.com/flutter/flutter/pull/8864.
|
||||||
const Utf8Decoder decoder = Utf8Decoder(reportErrors: false);
|
const Utf8Decoder decoder = Utf8Decoder(reportErrors: false);
|
||||||
_process.stdout.transform<String>(decoder).transform<String>(const LineSplitter()).listen(_onLine);
|
_process.stdout.transform<String>(decoder).transform<String>(const LineSplitter()).listen(_onLine);
|
||||||
_process.stderr.transform<String>(decoder).transform<String>(const LineSplitter()).listen(_onLine);
|
_process.stderr.transform<String>(decoder).transform<String>(const LineSplitter()).listen(_onLine);
|
||||||
_process.exitCode.whenComplete(() {
|
unawaited(_process.exitCode.whenComplete(() {
|
||||||
if (_linesController.hasListener) {
|
if (_linesController.hasListener) {
|
||||||
_linesController.close();
|
_linesController.close();
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'W/ActivityManager(pid): '
|
// 'W/ActivityManager(pid): '
|
||||||
|
@ -717,21 +717,38 @@ flutter:
|
|||||||
setUp(() {
|
setUp(() {
|
||||||
mockAndroidSdk = MockAndroidSdk();
|
mockAndroidSdk = MockAndroidSdk();
|
||||||
mockProcessManager = MockProcessManager();
|
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 {
|
testUsingContext('calls adb logcat with expected flags', () async {
|
||||||
const String klastLocatcatTimestamp = '11-27 15:39:04.506';
|
const String kLastLogcatTimestamp = '11-27 15:39:04.506';
|
||||||
when(mockAndroidSdk.adbPath).thenReturn('adb');
|
when(mockAndroidSdk.adbPath).thenReturn('adb');
|
||||||
when(mockProcessManager.runSync(<String>['adb', '-s', '1234', 'shell', '-x', 'logcat', '-v', 'time', '-t', '1']))
|
when(mockProcessManager.runSync(<String>['adb', '-s', '1234', 'shell', '-x', 'logcat', '-v', 'time', '-t', '1']))
|
||||||
.thenReturn(ProcessResult(0, 0, '$klastLocatcatTimestamp I/flutter: irrelevant', ''));
|
.thenReturn(ProcessResult(0, 0, '$kLastLogcatTimestamp I/flutter: irrelevant', ''));
|
||||||
|
|
||||||
|
final Completer<void> logcatCompleter = Completer<void>();
|
||||||
when(mockProcessManager.start(argThat(contains('logcat'))))
|
when(mockProcessManager.start(argThat(contains('logcat'))))
|
||||||
.thenAnswer((_) => Future<Process>.value(createMockProcess()));
|
.thenAnswer((_) {
|
||||||
|
logcatCompleter.complete();
|
||||||
|
return Future<Process>.value(createMockProcess());
|
||||||
|
});
|
||||||
|
|
||||||
final AndroidDevice device = AndroidDevice('1234');
|
final AndroidDevice device = AndroidDevice('1234');
|
||||||
final DeviceLogReader logReader = device.getLogReader();
|
final DeviceLogReader logReader = device.getLogReader();
|
||||||
logReader.logLines.listen((_) {});
|
logReader.logLines.listen((_) {});
|
||||||
|
await logcatCompleter.future;
|
||||||
|
|
||||||
verify(mockProcessManager.start(const <String>['adb', '-s', '1234', 'logcat', '-v', 'time', '-T', klastLocatcatTimestamp]))
|
verify(mockProcessManager.start(const <String>['adb', '-s', '1234', 'logcat', '-v', 'time', '-T', kLastLogcatTimestamp]))
|
||||||
.called(1);
|
.called(1);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
AndroidSdk: () => mockAndroidSdk,
|
AndroidSdk: () => mockAndroidSdk,
|
||||||
@ -742,12 +759,18 @@ flutter:
|
|||||||
when(mockAndroidSdk.adbPath).thenReturn('adb');
|
when(mockAndroidSdk.adbPath).thenReturn('adb');
|
||||||
when(mockProcessManager.runSync(<String>['adb', '-s', '1234', 'shell', '-x', 'logcat', '-v', 'time', '-t', '1']))
|
when(mockProcessManager.runSync(<String>['adb', '-s', '1234', 'shell', '-x', 'logcat', '-v', 'time', '-t', '1']))
|
||||||
.thenReturn(ProcessResult(0, 0, '', ''));
|
.thenReturn(ProcessResult(0, 0, '', ''));
|
||||||
|
|
||||||
|
final Completer<void> logcatCompleter = Completer<void>();
|
||||||
when(mockProcessManager.start(argThat(contains('logcat'))))
|
when(mockProcessManager.start(argThat(contains('logcat'))))
|
||||||
.thenAnswer((_) => Future<Process>.value(createMockProcess()));
|
.thenAnswer((_) {
|
||||||
|
logcatCompleter.complete();
|
||||||
|
return Future<Process>.value(createMockProcess());
|
||||||
|
});
|
||||||
|
|
||||||
final AndroidDevice device = AndroidDevice('1234');
|
final AndroidDevice device = AndroidDevice('1234');
|
||||||
final DeviceLogReader logReader = device.getLogReader();
|
final DeviceLogReader logReader = device.getLogReader();
|
||||||
logReader.logLines.listen((_) {});
|
logReader.logLines.listen((_) {});
|
||||||
|
await logcatCompleter.future;
|
||||||
|
|
||||||
verify(mockProcessManager.start(const <String>['adb', '-s', '1234', 'logcat', '-v', 'time', '-T', '']))
|
verify(mockProcessManager.start(const <String>['adb', '-s', '1234', 'logcat', '-v', 'time', '-T', '']))
|
||||||
.called(1);
|
.called(1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user