Faster auto-detection of APK's minSdkVersion
Prior to this change, when signing APKs, the build system invoked 'aapt dump badging' on each APK, to detect the value to pass into signapk as --min-sdk-version. Now that signapk uses the apksig library, it can auto-detect that value on its own, thus avoiding the need to invoke 'aapt dump badging' and thus speeding up the build process. The semantics of signapk's --min-sdk-version flag is changed by this commit from having the default value of 0 to having the default value of "auto-detect from APK". P.S. The get-package-min-sdk-version-int is not removed from core/definitions.mk in this commnit, because this function is used in another project's .mk file and thus that .mk file needs to be modified first. Test: rm -Rf out/ && make Change-Id: I0972fcf0abbde9cbf6794e6c05c743c77c8a78f9
This commit is contained in:
@@ -2621,7 +2621,6 @@ endef
|
|||||||
define sign-package-arg
|
define sign-package-arg
|
||||||
$(hide) mv $(1) $(1).unsigned
|
$(hide) mv $(1) $(1).unsigned
|
||||||
$(hide) java -Djava.library.path=$(SIGNAPK_JNI_LIBRARY_PATH) -jar $(SIGNAPK_JAR) \
|
$(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_CERTIFICATE) $(PRIVATE_PRIVATE_KEY) \
|
||||||
$(PRIVATE_ADDITIONAL_CERTIFICATES) $(1).unsigned $(1).signed
|
$(PRIVATE_ADDITIONAL_CERTIFICATES) $(1).unsigned $(1).signed
|
||||||
$(hide) mv $(1).signed $(1)
|
$(hide) mv $(1).signed $(1)
|
||||||
|
@@ -37,6 +37,7 @@ import org.conscrypt.OpenSSLProvider;
|
|||||||
import com.android.apksig.ApkSignerEngine;
|
import com.android.apksig.ApkSignerEngine;
|
||||||
import com.android.apksig.DefaultApkSignerEngine;
|
import com.android.apksig.DefaultApkSignerEngine;
|
||||||
import com.android.apksig.apk.ApkUtils;
|
import com.android.apksig.apk.ApkUtils;
|
||||||
|
import com.android.apksig.apk.MinSdkVersionException;
|
||||||
import com.android.apksig.util.DataSink;
|
import com.android.apksig.util.DataSink;
|
||||||
import com.android.apksig.util.DataSources;
|
import com.android.apksig.util.DataSources;
|
||||||
import com.android.apksig.zip.ZipFormatException;
|
import com.android.apksig.zip.ZipFormatException;
|
||||||
@@ -890,6 +891,37 @@ class SignApk {
|
|||||||
return result;
|
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() {
|
private static void usage() {
|
||||||
System.err.println("Usage: signapk [-w] " +
|
System.err.println("Usage: signapk [-w] " +
|
||||||
"[-a <alignment>] " +
|
"[-a <alignment>] " +
|
||||||
@@ -916,7 +948,7 @@ class SignApk {
|
|||||||
boolean signWholeFile = false;
|
boolean signWholeFile = false;
|
||||||
String providerClass = null;
|
String providerClass = null;
|
||||||
int alignment = 4;
|
int alignment = 4;
|
||||||
int minSdkVersion = 0;
|
Integer minSdkVersionOverride = null;
|
||||||
boolean signUsingApkSignatureSchemeV2 = true;
|
boolean signUsingApkSignatureSchemeV2 = true;
|
||||||
|
|
||||||
int argstart = 0;
|
int argstart = 0;
|
||||||
@@ -936,7 +968,7 @@ class SignApk {
|
|||||||
} else if ("--min-sdk-version".equals(args[argstart])) {
|
} else if ("--min-sdk-version".equals(args[argstart])) {
|
||||||
String minSdkVersionString = args[++argstart];
|
String minSdkVersionString = args[++argstart];
|
||||||
try {
|
try {
|
||||||
minSdkVersion = Integer.parseInt(minSdkVersionString);
|
minSdkVersionOverride = Integer.parseInt(minSdkVersionString);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"--min-sdk-version must be a decimal number: " + minSdkVersionString);
|
"--min-sdk-version must be a decimal number: " + minSdkVersionString);
|
||||||
@@ -1004,6 +1036,20 @@ class SignApk {
|
|||||||
timestamp,
|
timestamp,
|
||||||
outputFile);
|
outputFile);
|
||||||
} else {
|
} 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 =
|
try (ApkSignerEngine apkSigner =
|
||||||
new DefaultApkSignerEngine.Builder(
|
new DefaultApkSignerEngine.Builder(
|
||||||
createSignerConfigs(privateKey, publicKey), minSdkVersion)
|
createSignerConfigs(privateKey, publicKey), minSdkVersion)
|
||||||
|
Reference in New Issue
Block a user