Merge "Faster auto-detection of APK's minSdkVersion"
diff --git a/core/definitions.mk b/core/definitions.mk
index 969260b..e07d911 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2621,7 +2621,6 @@
define sign-package-arg
$(hide) mv $(1) $(1).unsigned
$(hide) java -Djava.library.path=$(SIGNAPK_JNI_LIBRARY_PATH) -jar $(SIGNAPK_JAR) \
- --min-sdk-version $(call get-package-min-sdk-version-int,$@.unsigned) \
$(PRIVATE_CERTIFICATE) $(PRIVATE_PRIVATE_KEY) \
$(PRIVATE_ADDITIONAL_CERTIFICATES) $(1).unsigned $(1).signed
$(hide) mv $(1).signed $(1)
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index 10e220c..3b00599 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -37,6 +37,7 @@
import com.android.apksig.ApkSignerEngine;
import com.android.apksig.DefaultApkSignerEngine;
import com.android.apksig.apk.ApkUtils;
+import com.android.apksig.apk.MinSdkVersionException;
import com.android.apksig.util.DataSink;
import com.android.apksig.util.DataSources;
import com.android.apksig.zip.ZipFormatException;
@@ -890,6 +891,37 @@
return result;
}
+ /**
+ * Returns the API Level corresponding to the APK's minSdkVersion.
+ *
+ * @throws MinSdkVersionException if the API Level cannot be determined from the APK.
+ */
+ private static final int getMinSdkVersion(JarFile apk) throws MinSdkVersionException {
+ JarEntry manifestEntry = apk.getJarEntry("AndroidManifest.xml");
+ if (manifestEntry == null) {
+ throw new MinSdkVersionException("No AndroidManifest.xml in APK");
+ }
+ byte[] manifestBytes;
+ try {
+ try (InputStream manifestIn = apk.getInputStream(manifestEntry)) {
+ manifestBytes = toByteArray(manifestIn);
+ }
+ } catch (IOException e) {
+ throw new MinSdkVersionException("Failed to read AndroidManifest.xml", e);
+ }
+ return ApkUtils.getMinSdkVersionFromBinaryAndroidManifest(ByteBuffer.wrap(manifestBytes));
+ }
+
+ private static byte[] toByteArray(InputStream in) throws IOException {
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
+ byte[] buf = new byte[65536];
+ int chunkSize;
+ while ((chunkSize = in.read(buf)) != -1) {
+ result.write(buf, 0, chunkSize);
+ }
+ return result.toByteArray();
+ }
+
private static void usage() {
System.err.println("Usage: signapk [-w] " +
"[-a <alignment>] " +
@@ -916,7 +948,7 @@
boolean signWholeFile = false;
String providerClass = null;
int alignment = 4;
- int minSdkVersion = 0;
+ Integer minSdkVersionOverride = null;
boolean signUsingApkSignatureSchemeV2 = true;
int argstart = 0;
@@ -936,7 +968,7 @@
} else if ("--min-sdk-version".equals(args[argstart])) {
String minSdkVersionString = args[++argstart];
try {
- minSdkVersion = Integer.parseInt(minSdkVersionString);
+ minSdkVersionOverride = Integer.parseInt(minSdkVersionString);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
"--min-sdk-version must be a decimal number: " + minSdkVersionString);
@@ -1004,6 +1036,20 @@
timestamp,
outputFile);
} else {
+ // Determine the value to use as minSdkVersion of the APK being signed
+ int minSdkVersion;
+ if (minSdkVersionOverride != null) {
+ minSdkVersion = minSdkVersionOverride;
+ } else {
+ try {
+ minSdkVersion = getMinSdkVersion(inputJar);
+ } catch (MinSdkVersionException e) {
+ throw new IllegalArgumentException(
+ "Cannot detect minSdkVersion. Use --min-sdk-version to override",
+ e);
+ }
+ }
+
try (ApkSignerEngine apkSigner =
new DefaultApkSignerEngine.Builder(
createSignerConfigs(privateKey, publicKey), minSdkVersion)