diff --git a/dev/bots/README.md b/dev/bots/README.md index 3d3fa7901c8..c6047b54198 100644 --- a/dev/bots/README.md +++ b/dev/bots/README.md @@ -102,7 +102,7 @@ Instructions to update the Android Tools version that the bots download by execu The following packages are currently installed: * Android SDK Tools * Android SDK platform-tools - * Android SDK Build-tools 24.0.3 + * Android SDK Build-tools 23.0.1 * Android 6.0 (API 23) * SDK Platform 23 * Extras diff --git a/dev/bots/VERSION_LINUX_SDK b/dev/bots/VERSION_LINUX_SDK index 9106828b337..d24f5c1f6ea 100644 --- a/dev/bots/VERSION_LINUX_SDK +++ b/dev/bots/VERSION_LINUX_SDK @@ -1 +1 @@ -efeebca78800d6855e15a22c6087a54766d1d4e9 +0d320c50b0ed188c7e1182388e2beb623a1d307d diff --git a/dev/bots/VERSION_MACOSX_SDK b/dev/bots/VERSION_MACOSX_SDK index 12fc3d7116c..2441d725226 100644 --- a/dev/bots/VERSION_MACOSX_SDK +++ b/dev/bots/VERSION_MACOSX_SDK @@ -1 +1 @@ -7eb88931c39c05a3b140da769e67c216d45db2b9 +fa5ea0ca1e0c7c2e40914f3202c7545de4dbca9c diff --git a/dev/bots/VERSION_WIN_SDK b/dev/bots/VERSION_WIN_SDK index e63ec1f1a8d..0ca540a64f7 100644 --- a/dev/bots/VERSION_WIN_SDK +++ b/dev/bots/VERSION_WIN_SDK @@ -1 +1 @@ -4b0d8fa0dcacd537330149332a28e033edfd3ca8 +e5715e2cc0d5644a241a4b3281bfada92bc145c2 diff --git a/packages/flutter_tools/lib/src/android/android_sdk.dart b/packages/flutter_tools/lib/src/android/android_sdk.dart index c703c56fd57..ac5d5d69f5d 100644 --- a/packages/flutter_tools/lib/src/android/android_sdk.dart +++ b/packages/flutter_tools/lib/src/android/android_sdk.dart @@ -24,7 +24,6 @@ const String kAndroidHome = 'ANDROID_HOME'; // $ANDROID_HOME/build-tools/22.0.1/aapt // $ANDROID_HOME/build-tools/23.0.2/aapt // $ANDROID_HOME/build-tools/24.0.0-preview/aapt -// $ANDROID_HOME/build-tools/25.0.2/apksigner // $ANDROID_HOME/platforms/android-22/android.jar // $ANDROID_HOME/platforms/android-23/android.jar @@ -226,8 +225,6 @@ class AndroidSdkVersion implements Comparable { String get zipalignPath => getBuildToolsPath('zipalign'); - String get apksignerPath => getBuildToolsPath('apksigner'); - List validateSdkWellFormed() { if (_exists(androidJarPath) != null) return [_exists(androidJarPath)]; @@ -241,9 +238,6 @@ class AndroidSdkVersion implements Comparable { if (_canRun(zipalignPath) != null) return [_canRun(zipalignPath)]; - if (_canRun(apksignerPath) != null) - return [_canRun(apksignerPath) + '\napksigner requires Android SDK Build Tools 24.0.3 or newer.']; - return []; } diff --git a/packages/flutter_tools/lib/src/android/android_workflow.dart b/packages/flutter_tools/lib/src/android/android_workflow.dart index 40210d2df3e..2ad9b4d2ec5 100644 --- a/packages/flutter_tools/lib/src/android/android_workflow.dart +++ b/packages/flutter_tools/lib/src/android/android_workflow.dart @@ -5,6 +5,7 @@ import 'dart:async'; import '../base/io.dart'; +import '../base/os.dart'; import '../base/platform.dart'; import '../base/process_manager.dart'; import '../doctor.dart'; @@ -62,11 +63,11 @@ class AndroidWorkflow extends DoctorValidator implements Workflow { } List validationResult = androidSdk.validateSdkWellFormed(); + // Empty result means SDK is well formated. if (validationResult.isEmpty) { - // Empty result means SDK is well formatted. - // The SDK also requires a valid Java JDK installation. const String _kJdkDownload = 'https://www.oracle.com/technetwork/java/javase/downloads/'; + String javaVersion; try { @@ -81,20 +82,27 @@ class AndroidWorkflow extends DoctorValidator implements Workflow { } catch (error) { } - if (javaVersion == null) { - messages.add(new ValidationMessage.error( - 'No Java Development Kit (JDK) found; you can download the JDK from $_kJdkDownload.' - )); + if (javaVersion != null) { + messages.add(new ValidationMessage(javaVersion)); + + if (os.which('jarsigner') == null) { + messages.add(new ValidationMessage.error( + 'The jarsigner utility was not found; this is used to build Android APKs. You may need to install\n' + 'or re-install the Java JDK: $_kJdkDownload.' + )); + } else { + type = ValidationType.installed; + } } else { - type = ValidationType.installed; + messages.add(new ValidationMessage.error( + 'No Java Development Kit (JDK) found; you can download the JDK from $_kJdkDownload.' + )); } } else { messages.addAll(validationResult.map((String message) { return new ValidationMessage.error(message); })); - messages.add(new ValidationMessage( - 'Try re-installing or updating your Android SDK,\n' - 'visit https://flutter.io/setup/#android-setup for detailed instructions.')); + messages.add(new ValidationMessage('Try re-installing or updating your Android SDK.')); } } diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart index cea8dc7d0ba..19b74d4c57f 100644 --- a/packages/flutter_tools/lib/src/commands/build_apk.dart +++ b/packages/flutter_tools/lib/src/commands/build_apk.dart @@ -10,6 +10,7 @@ import '../android/gradle.dart'; import '../base/common.dart'; import '../base/file_system.dart'; import '../base/logger.dart'; +import '../base/os.dart'; import '../base/process.dart'; import '../base/process_manager.dart'; import '../base/utils.dart'; @@ -67,14 +68,14 @@ class _ApkBuilder { File _aapt; File _dx; File _zipalign; - File _apksigner; + File _jarsigner; _ApkBuilder(this.sdk) { _androidJar = fs.file(sdk.androidJarPath); _aapt = fs.file(sdk.aaptPath); _dx = fs.file(sdk.dxPath); _zipalign = fs.file(sdk.zipalignPath); - _apksigner = fs.file(sdk.apksignerPath); + _jarsigner = os.which('jarsigner'); } String checkDependencies() { @@ -86,8 +87,10 @@ class _ApkBuilder { return 'Cannot find dx at ${_dx.path}'; if (!processManager.canRun(_zipalign.path)) return 'Cannot find zipalign at ${_zipalign.path}'; - if (!processManager.canRun(_apksigner.path)) - return 'Cannot find apksigner at ${_apksigner.path}'; + if (_jarsigner == null) + return 'Cannot find jarsigner in PATH.'; + if (!_jarsigner.existsSync()) + return 'Cannot find jarsigner at ${_jarsigner.path}'; return null; } @@ -120,13 +123,15 @@ class _ApkBuilder { } void sign(File keystore, String keystorePassword, String keyAlias, String keyPassword, File outputApk) { - assert(_apksigner != null); - runCheckedSync([_apksigner.path, 'sign', - '--ks', keystore.path, - '--ks-key-alias', keyAlias, - '--ks-pass', 'pass:$keystorePassword', - '--key-pass', 'pass:$keyPassword', + assert(_jarsigner != null); + runCheckedSync([_jarsigner.path, + '-keystore', keystore.path, + '-storepass', keystorePassword, + '-keypass', keyPassword, + '-digestalg', 'SHA1', + '-sigalg', 'MD5withRSA', outputApk.path, + keyAlias, ]); } @@ -366,14 +371,15 @@ int _buildApk( unalignedApk, components.manifest, assetBuilder.directory, artifactBuilder.directory, components.resources, buildMode ); + + int signResult = _signApk(builder, components, unalignedApk, keystore, buildMode); + if (signResult != 0) + return signResult; + File finalApk = fs.file(outputFile); ensureDirectoryExists(finalApk.path); builder.align(unalignedApk, finalApk); - int signResult = _signApk(builder, components, finalApk, keystore, buildMode); - if (signResult != 0) - return signResult; - printTrace('calculateSha: $outputFile'); File apkShaFile = fs.file('$outputFile.sha1'); apkShaFile.writeAsStringSync(calculateSha(finalApk));