Android: Fix signing of APKs that are generated when an AAB is also built
To simplify matters, this removes the support for signing APKs with just jarsigner. apksigner is always used for APKs, and jarsigner is used for AABs. I consider that to be just fine, you _have_ to start using apksigner eventually, and the time for that is long past. Pick-to: 6.4 6.2 5.15 Task-number: QTBUG-91255 Change-Id: I211ae796db0f2619265deb1f30ab3cc5d1ecfbc9 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
parent
528b03d6b6
commit
b82c5f9b7f
@ -93,7 +93,6 @@ struct Options
|
||||
, internalSf(false)
|
||||
, sectionsOnly(false)
|
||||
, protectedAuthenticationPath(false)
|
||||
, jarSigner(false)
|
||||
, installApk(false)
|
||||
, uninstallApk(false)
|
||||
, qmlImportScannerBinaryPath()
|
||||
@ -191,7 +190,6 @@ struct Options
|
||||
bool internalSf;
|
||||
bool sectionsOnly;
|
||||
bool protectedAuthenticationPath;
|
||||
bool jarSigner;
|
||||
QString apkPath;
|
||||
|
||||
// Installation information
|
||||
@ -366,7 +364,6 @@ Options parseOptions()
|
||||
} else if (argument.compare("--aab"_L1, Qt::CaseInsensitive) == 0) {
|
||||
options.buildAAB = true;
|
||||
options.build = true;
|
||||
options.jarSigner = true;
|
||||
} else if (!options.buildAAB && argument.compare("--no-build"_L1, Qt::CaseInsensitive) == 0) {
|
||||
options.build = false;
|
||||
} else if (argument.compare("--install"_L1, Qt::CaseInsensitive) == 0) {
|
||||
@ -501,8 +498,6 @@ Options parseOptions()
|
||||
options.sectionsOnly = true;
|
||||
} else if (argument.compare("--protected"_L1, Qt::CaseInsensitive) == 0) {
|
||||
options.protectedAuthenticationPath = true;
|
||||
} else if (argument.compare("--jarsigner"_L1, Qt::CaseInsensitive) == 0) {
|
||||
options.jarSigner = true;
|
||||
} else if (argument.compare("--aux-mode"_L1, Qt::CaseInsensitive) == 0) {
|
||||
options.auxMode = true;
|
||||
} else if (argument.compare("--qml-importscanner-binary"_L1, Qt::CaseInsensitive) == 0) {
|
||||
@ -594,8 +589,7 @@ void printHelp()
|
||||
" --internalsf: Include the .SF file inside the signature block.\n"
|
||||
" --sectionsonly: Don't compute hash of entire manifest.\n"
|
||||
" --protected: Keystore has protected authentication path.\n"
|
||||
" --jarsigner: Force jarsigner usage, otherwise apksigner will be\n"
|
||||
" used if available.\n"
|
||||
" --jarsigner: Deprecated, ignored.\n"
|
||||
"\n"
|
||||
" NOTE: To conceal the keystore information, the environment variables\n"
|
||||
" QT_ANDROID_KEYSTORE_PATH, and QT_ANDROID_KEYSTORE_ALIAS are used to\n"
|
||||
@ -2846,7 +2840,7 @@ static QString zipalignPath(const Options &options, bool *ok)
|
||||
return zipAlignTool;
|
||||
}
|
||||
|
||||
bool jarSignerSignPackage(const Options &options)
|
||||
bool signAAB(const Options &options)
|
||||
{
|
||||
if (options.verbose)
|
||||
fprintf(stdout, "Signing Android package.\n");
|
||||
@ -2900,7 +2894,7 @@ bool jarSignerSignPackage(const Options &options)
|
||||
if (options.protectedAuthenticationPath)
|
||||
jarSignerTool += " -protected"_L1;
|
||||
|
||||
auto signPackage = [&](const QString &file) {
|
||||
auto jarSignPackage = [&](const QString &file) {
|
||||
fprintf(stdout, "Signing file %s\n", qPrintable(file));
|
||||
fflush(stdout);
|
||||
QString command = jarSignerTool + " %1 %2"_L1.arg(shellQuote(file))
|
||||
@ -2928,49 +2922,15 @@ bool jarSignerSignPackage(const Options &options)
|
||||
return true;
|
||||
};
|
||||
|
||||
if (!signPackage(packagePath(options, UnsignedAPK)))
|
||||
if (options.buildAAB && !jarSignPackage(packagePath(options, AAB)))
|
||||
return false;
|
||||
if (options.buildAAB && !signPackage(packagePath(options, AAB)))
|
||||
return false;
|
||||
|
||||
bool ok;
|
||||
QString zipAlignTool = zipalignPath(options, &ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
zipAlignTool = "%1%2 -f 4 %3 %4"_L1.arg(shellQuote(zipAlignTool),
|
||||
options.verbose ? " -v"_L1 : QLatin1StringView(),
|
||||
shellQuote(packagePath(options, UnsignedAPK)),
|
||||
shellQuote(packagePath(options, SignedAPK)));
|
||||
|
||||
FILE *zipAlignCommand = openProcess(zipAlignTool);
|
||||
if (zipAlignCommand == 0) {
|
||||
fprintf(stderr, "Couldn't run zipalign.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
while (fgets(buffer, sizeof(buffer), zipAlignCommand) != 0)
|
||||
fprintf(stdout, "%s", buffer);
|
||||
|
||||
int errorCode = pclose(zipAlignCommand);
|
||||
if (errorCode != 0) {
|
||||
fprintf(stderr, "zipalign command failed.\n");
|
||||
if (!options.verbose)
|
||||
fprintf(stderr, " -- Run with --verbose for more information.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return QFile::remove(packagePath(options, UnsignedAPK));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool signPackage(const Options &options)
|
||||
{
|
||||
const QString apksignerTool = batSuffixAppended(options.sdkPath + "/build-tools/"_L1 +
|
||||
options.sdkBuildToolsVersion + "/apksigner"_L1);
|
||||
if (options.jarSigner || !QFile::exists(apksignerTool))
|
||||
return jarSignerSignPackage(options);
|
||||
|
||||
// APKs signed with apksigner must not be changed after they're signed,
|
||||
// therefore we need to zipalign it before we sign it.
|
||||
|
||||
@ -3075,6 +3035,9 @@ bool signPackage(const Options &options)
|
||||
"%1 verify --verbose %2"_L1
|
||||
.arg(shellQuote(apksignerTool), shellQuote(packagePath(options, SignedAPK)));
|
||||
|
||||
if (options.buildAAB && !signAAB(options))
|
||||
return false;
|
||||
|
||||
// Verify the package and remove the unsigned apk
|
||||
return apkSignerRunner(apkVerifyCommand, true) && QFile::remove(packagePath(options, UnsignedAPK));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user