Unverified Commit ef62d532 authored by Zachary Anderson's avatar Zachary Anderson Committed by GitHub

[flutter_tools] Fix crash on null Android apiVersion (#50029)

parent abf4e161
...@@ -1040,7 +1040,11 @@ class _AdbLogReader extends DeviceLogReader { ...@@ -1040,7 +1040,11 @@ class _AdbLogReader extends DeviceLogReader {
]; ];
// logcat -T is not supported on Android releases before Lollipop. // logcat -T is not supported on Android releases before Lollipop.
const int kLollipopVersionCode = 21; const int kLollipopVersionCode = 21;
final int apiVersion = int.tryParse(await device._apiVersion); final int apiVersion = (String v) {
// If the API version string isn't found, conservatively assume that the
// version is less recent than the one we're looking for.
return v == null ? kLollipopVersionCode - 1 : int.tryParse(v);
}(await device._apiVersion);
if (apiVersion != null && apiVersion >= kLollipopVersionCode) { if (apiVersion != null && apiVersion >= kLollipopVersionCode) {
args.addAll(<String>[ args.addAll(<String>[
'-T', '-T',
......
...@@ -698,23 +698,31 @@ flutter: ...@@ -698,23 +698,31 @@ flutter:
setUp(() { setUp(() {
mockAndroidSdk = MockAndroidSdk(); mockAndroidSdk = MockAndroidSdk();
mockProcessManager = MockProcessManager(); mockProcessManager = MockProcessManager();
});
void setupGetprop({int apiVersion}) {
when(mockProcessManager.run( when(mockProcessManager.run(
argThat(contains('getprop')), argThat(contains('getprop')),
stderrEncoding: anyNamed('stderrEncoding'), stderrEncoding: anyNamed('stderrEncoding'),
stdoutEncoding: anyNamed('stdoutEncoding'), stdoutEncoding: anyNamed('stdoutEncoding'),
)).thenAnswer((_) { )).thenAnswer((_) {
final StringBuffer buf = StringBuffer() final String buf = apiVersion == null
..writeln('[ro.build.version.sdk]: [28]'); ? ''
final ProcessResult result = ProcessResult(1, 0, buf.toString(), ''); : '[ro.build.version.sdk]: [$apiVersion]\n';
final ProcessResult result = ProcessResult(1, 0, buf, '');
return Future<ProcessResult>.value(result); return Future<ProcessResult>.value(result);
}); });
}); }
testUsingContext('calls adb logcat with expected flags', () async { const int kLollipopVersionCode = 21;
void callsAdbLogcatCorrectly({int apiVersion}) {
testUsingContext('calls adb logcat with expected flags, apiVersion=$apiVersion', () async {
const String kLastLogcatTimestamp = '11-27 15:39:04.506'; const String kLastLogcatTimestamp = '11-27 15:39:04.506';
setupGetprop(apiVersion: apiVersion);
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, '$kLastLogcatTimestamp I/flutter: irrelevant', '')); .thenReturn(ProcessResult(0, 0, '$kLastLogcatTimestamp I/flutter: irrelevant', ''));
final Completer<void> logcatCompleter = Completer<void>(); final Completer<void> logcatCompleter = Completer<void>();
...@@ -729,17 +737,22 @@ flutter: ...@@ -729,17 +737,22 @@ flutter:
logReader.logLines.listen((_) {}); logReader.logLines.listen((_) {});
await logcatCompleter.future; await logcatCompleter.future;
verify(mockProcessManager.start(const <String>['adb', '-s', '1234', 'logcat', '-v', 'time', '-T', kLastLogcatTimestamp])) verify(mockProcessManager.start(<String>[
.called(1); 'adb', '-s', '1234', 'logcat', '-v', 'time',
if (apiVersion != null && apiVersion >= kLollipopVersionCode)
...<String>['-T', kLastLogcatTimestamp],
])).called(1);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk, AndroidSdk: () => mockAndroidSdk,
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
}); });
testUsingContext('calls adb logcat with expected flags when the device logs are empty', () async { testUsingContext('calls adb logcat with expected flags when the device logs are empty, apiVersion=$apiVersion', () async {
setupGetprop(apiVersion: apiVersion);
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>[
.thenReturn(ProcessResult(0, 0, '', '')); 'adb', '-s', '1234', 'shell', '-x', 'logcat', '-v', 'time', '-t', '1',
])).thenReturn(ProcessResult(0, 0, '', ''));
final Completer<void> logcatCompleter = Completer<void>(); final Completer<void> logcatCompleter = Completer<void>();
when(mockProcessManager.start(argThat(contains('logcat')))) when(mockProcessManager.start(argThat(contains('logcat'))))
...@@ -753,12 +766,20 @@ flutter: ...@@ -753,12 +766,20 @@ flutter:
logReader.logLines.listen((_) {}); logReader.logLines.listen((_) {});
await logcatCompleter.future; await logcatCompleter.future;
verify(mockProcessManager.start(const <String>['adb', '-s', '1234', 'logcat', '-v', 'time', '-T', ''])) verify(mockProcessManager.start(<String>[
.called(1); 'adb', '-s', '1234', 'logcat', '-v', 'time',
if (apiVersion != null && apiVersion >= kLollipopVersionCode)
...<String>['-T', ''],
])).called(1);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk, AndroidSdk: () => mockAndroidSdk,
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
}); });
}
callsAdbLogcatCorrectly(apiVersion: kLollipopVersionCode);
callsAdbLogcatCorrectly(apiVersion: kLollipopVersionCode - 1);
callsAdbLogcatCorrectly();
}); });
test('Can parse adb shell dumpsys info', () { test('Can parse adb shell dumpsys info', () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment