From c724504142d18eb09edb3898cf69e25d92c0791e Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 19 Nov 2019 19:04:17 -0800 Subject: [PATCH] Update Android CPU device detection (#45139) --- AUTHORS | 1 + .../lib/src/android/android_device.dart | 11 ++- .../android/android_device_test.dart | 71 +++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 10d164d99b..156501f5ed 100644 --- a/AUTHORS +++ b/AUTHORS @@ -45,3 +45,4 @@ Sarbagya Dhaubanjar Rody Davis Jr Robin Jespersen Jefferson Quesado +Mark Diener diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index f0e493ed61..a47581d360 100644 --- a/packages/flutter_tools/lib/src/android/android_device.dart +++ b/packages/flutter_tools/lib/src/android/android_device.dart @@ -192,7 +192,16 @@ class AndroidDevice extends Device { // http://developer.android.com/ndk/guides/abis.html (x86, armeabi-v7a, ...) switch (await _getProperty('ro.product.cpu.abi')) { case 'arm64-v8a': - _platform = TargetPlatform.android_arm64; + // Perform additional verification for 64 bit ABI. Some devices, + // like the Kindle Fire 8, misreport the abilist. We might not + // be able to retrieve this property, in which case we fall back + // to assuming 64 bit. + final String abilist = await _getProperty('ro.product.cpu.abilist'); + if (abilist == null || abilist.contains('arm64-v8a')) { + _platform = TargetPlatform.android_arm64; + } else { + _platform = TargetPlatform.android_arm; + } break; case 'x86_64': _platform = TargetPlatform.android_x64; 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 7cd19f355a..45ccaf0692 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 @@ -318,6 +318,77 @@ Use the 'android' tool to install them: }); }); + group('ABI detection', () { + ProcessManager mockProcessManager; + String cpu; + String abilist; + + setUp(() { + mockProcessManager = MockProcessManager(); + cpu = 'unknown'; + abilist = 'unknown'; + when(mockProcessManager.run( + argThat(contains('getprop')), + stderrEncoding: anyNamed('stderrEncoding'), + stdoutEncoding: anyNamed('stdoutEncoding'), + )).thenAnswer((_) { + final StringBuffer buf = StringBuffer() + ..writeln('[ro.product.cpu.abi]: [$cpu]') + ..writeln('[ro.product.cpu.abilist]: [$abilist]'); + final ProcessResult result = ProcessResult(1, 0, buf.toString(), ''); + return Future.value(result); + }); + }); + + testUsingContext('detects x64', () async { + cpu = 'x86_64'; + final AndroidDevice device = AndroidDevice('test'); + + expect(await device.targetPlatform, TargetPlatform.android_x64); + }, overrides: { + ProcessManager: () => mockProcessManager + }); + + testUsingContext('detects x86', () async { + cpu = 'x86'; + final AndroidDevice device = AndroidDevice('test'); + + expect(await device.targetPlatform, TargetPlatform.android_x86); + }, overrides: { + ProcessManager: () => mockProcessManager + }); + + testUsingContext('unknown device defaults to 32bit arm', () async { + cpu = '???'; + final AndroidDevice device = AndroidDevice('test'); + + expect(await device.targetPlatform, TargetPlatform.android_arm); + }, overrides: { + ProcessManager: () => mockProcessManager + }); + + testUsingContext('detects 64 bit arm', () async { + cpu = 'arm64-v8a'; + abilist = 'arm64-v8a,'; + final AndroidDevice device = AndroidDevice('test'); + + // If both abi properties agree, we are 64 bit. + expect(await device.targetPlatform, TargetPlatform.android_arm64); + }, overrides: { + ProcessManager: () => mockProcessManager + }); + + testUsingContext('detects kind fire ABI', () async { + cpu = 'arm64-v8a'; + abilist = 'arm'; + final AndroidDevice device = AndroidDevice('test'); + + // If one does not contain arm64, assume 32 bit. + expect(await device.targetPlatform, TargetPlatform.android_arm); + }, overrides: { + ProcessManager: () => mockProcessManager + }); + }); group('isLocalEmulator', () { final ProcessManager mockProcessManager = MockProcessManager();