Build tool support for Android x86 targets in 32- or 64-bit modes (#3761)
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart
index b5e37eb..0712fde 100644
--- a/packages/flutter_tools/lib/src/android/android_device.dart
+++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -49,23 +49,49 @@
final String modelID;
final String deviceCodeName;
+ Map<String, String> _properties;
bool _isLocalEmulator;
+ TargetPlatform _platform;
+
+ String _getProperty(String name) {
+ if (_properties == null) {
+ String getpropOutput = runCheckedSync(adbCommandForDevice(<String>['shell', 'getprop']));
+ RegExp propertyExp = new RegExp(r'\[(.*?)\]: \[(.*?)\]');
+ _properties = <String, String>{};
+ for (Match m in propertyExp.allMatches(getpropOutput)) {
+ _properties[m.group(1)] = m.group(2);
+ }
+ }
+ return _properties[name];
+ }
@override
bool get isLocalEmulator {
if (_isLocalEmulator == null) {
+ String characteristics = _getProperty('ro.build.characteristics');
+ _isLocalEmulator = characteristics != null && characteristics.contains('emulator');
+ }
+ return _isLocalEmulator;
+ }
+
+ @override
+ TargetPlatform get platform {
+ if (_platform == null) {
// http://developer.android.com/ndk/guides/abis.html (x86, armeabi-v7a, ...)
- try {
- String value = runCheckedSync(adbCommandForDevice(
- <String>['shell', 'getprop', 'ro.product.cpu.abi']
- ));
- _isLocalEmulator = value.startsWith('x86');
- } catch (error) {
- _isLocalEmulator = false;
+ switch (_getProperty('ro.product.cpu.abi')) {
+ case 'x86_64':
+ _platform = TargetPlatform.android_x64;
+ break;
+ case 'x86':
+ _platform = TargetPlatform.android_x86;
+ break;
+ default:
+ _platform = TargetPlatform.android_arm;
+ break;
}
}
- return _isLocalEmulator;
+ return _platform;
}
_AdbLogReader _logReader;
@@ -123,9 +149,7 @@
runCheckedSync(<String>[androidSdk.adbPath, 'start-server']);
// Sample output: '22'
- String sdkVersion = runCheckedSync(
- adbCommandForDevice(<String>['shell', 'getprop', 'ro.build.version.sdk'])
- ).trimRight();
+ String sdkVersion = _getProperty('ro.build.version.sdk');
int sdkVersionParsed = int.parse(sdkVersion, onError: (String source) => null);
if (sdkVersionParsed == null) {
@@ -334,9 +358,6 @@
}
@override
- TargetPlatform get platform => isLocalEmulator ? TargetPlatform.android_x64 : TargetPlatform.android_arm;
-
- @override
void clearLogs() {
runSync(adbCommandForDevice(<String>['logcat', '-c']));
}
diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart
index 07a9318..f4154eb 100644
--- a/packages/flutter_tools/lib/src/application_package.dart
+++ b/packages/flutter_tools/lib/src/application_package.dart
@@ -103,6 +103,7 @@
switch (platform) {
case TargetPlatform.android_arm:
case TargetPlatform.android_x64:
+ case TargetPlatform.android_x86:
return new AndroidApk.fromCurrentDirectory();
case TargetPlatform.ios:
return new IOSApp.fromCurrentDirectory();
@@ -122,6 +123,7 @@
switch (platform) {
case TargetPlatform.android_arm:
case TargetPlatform.android_x64:
+ case TargetPlatform.android_x86:
android ??= new AndroidApk.fromCurrentDirectory();
return android;
case TargetPlatform.ios:
diff --git a/packages/flutter_tools/lib/src/build_configuration.dart b/packages/flutter_tools/lib/src/build_configuration.dart
index a70e691..e4e992c 100644
--- a/packages/flutter_tools/lib/src/build_configuration.dart
+++ b/packages/flutter_tools/lib/src/build_configuration.dart
@@ -41,6 +41,7 @@
enum TargetPlatform {
android_arm,
android_x64,
+ android_x86,
ios,
darwin_x64,
linux_x64
diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart
index 892657b..ebb7369 100644
--- a/packages/flutter_tools/lib/src/cache.dart
+++ b/packages/flutter_tools/lib/src/cache.dart
@@ -192,7 +192,8 @@
'android-arm',
'android-arm-profile',
'android-arm-release',
- 'android-x64'
+ 'android-x64',
+ 'android-x86',
];
if (Platform.isMacOS)
diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart
index 6004bff..0029062 100644
--- a/packages/flutter_tools/lib/src/commands/build_apk.dart
+++ b/packages/flutter_tools/lib/src/commands/build_apk.dart
@@ -261,6 +261,21 @@
}
}
+// Return the directory name within the APK that is used for native code libraries
+// on the given platform.
+String getAbiDirectory(TargetPlatform platform) {
+ switch (platform) {
+ case TargetPlatform.android_arm:
+ return 'armeabi-v7a';
+ case TargetPlatform.android_x64:
+ return 'x86_64';
+ case TargetPlatform.android_x86:
+ return 'x86';
+ default:
+ throw new Exception('Unsupported platform.');
+ }
+}
+
Future<_ApkComponents> _findApkComponents(
TargetPlatform platform,
BuildMode buildMode,
@@ -274,7 +289,7 @@
components.extraFiles = extraFiles != null ? extraFiles : <String, File>{};
if (tools.isLocalEngine) {
- String abiDir = platform == TargetPlatform.android_arm ? 'armeabi-v7a' : 'x86_64';
+ String abiDir = getAbiDirectory(platform);
String enginePath = tools.engineSrcPath;
String buildDir = tools.getEngineArtifactsDirectory(platform, buildMode).path;
@@ -348,7 +363,7 @@
_AssetBuilder artifactBuilder = new _AssetBuilder(tempDir, 'artifacts');
artifactBuilder.add(classesDex, 'classes.dex');
- String abiDir = platform == TargetPlatform.android_arm ? 'armeabi-v7a' : 'x86_64';
+ String abiDir = getAbiDirectory(platform);
artifactBuilder.add(components.libSkyShell, 'lib/$abiDir/libsky_shell.so');
for (String relativePath in components.extraFiles.keys)
diff --git a/packages/flutter_tools/lib/src/toolchain.dart b/packages/flutter_tools/lib/src/toolchain.dart
index 7c87656..3c3dd97 100644
--- a/packages/flutter_tools/lib/src/toolchain.dart
+++ b/packages/flutter_tools/lib/src/toolchain.dart
@@ -144,10 +144,9 @@
switch (platform) {
case TargetPlatform.android_arm:
- type = 'android';
- break;
case TargetPlatform.android_x64:
- type = 'android_sim';
+ case TargetPlatform.android_x86:
+ type = 'android';
break;
// TODO(devoncarew): We will need an ios vs ios_x86 target (for ios vs. ios_sim).
@@ -166,6 +165,18 @@
if (isAotBuildMode(mode))
buildOutputPath += '_Deploy';
+ // Add a suffix for the target architecture.
+ switch (platform) {
+ case TargetPlatform.android_x64:
+ buildOutputPath += '_x64';
+ break;
+ case TargetPlatform.android_x86:
+ buildOutputPath += '_x86';
+ break;
+ default:
+ break;
+ }
+
return new Directory(path.join(engineSrcPath, buildOutputPath));
} else {
String suffix = mode != BuildMode.debug ? '-${getModeName(mode)}' : '';