aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml11
-rw-r--r--doc/reference/items/convenience/application.qdoc5
-rw-r--r--doc/reference/modules/android-sdk-module.qdoc9
-rw-r--r--docker-compose.yml4
-rw-r--r--docker/bionic/test-android.Dockerfile4
-rw-r--r--share/qbs/imports/qbs/base/AndroidApk.qbs2
-rw-r--r--share/qbs/imports/qbs/base/Application.qbs2
-rw-r--r--share/qbs/module-providers/Qt/templates/android_support.qbs6
-rw-r--r--share/qbs/modules/Android/sdk/sdk.qbs65
-rw-r--r--share/qbs/modules/Android/sdk/utils.js90
-rw-r--r--src/lib/corelib/api/project.cpp5
-rw-r--r--src/lib/corelib/api/projectdata.cpp6
-rw-r--r--src/lib/corelib/api/projectdata_p.h4
-rw-r--r--tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml1
-rw-r--r--tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml1
-rw-r--r--tests/auto/blackbox/tst_blackboxandroid.cpp609
16 files changed, 562 insertions, 262 deletions
diff --git a/.travis.yml b/.travis.yml
index ef86db701..e5a73e9f2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -64,14 +64,21 @@ jobs:
- docker-compose run --rm bionic scripts/run-analyzer.sh
- <<: *build-on-bionic
- name: With Qbs and with Qt for Android
+ name: With Qbs and with Qt 5.13 for Android
before_install:
- docker-compose pull bionic
- docker-compose pull bionic-android-513
- - docker-compose pull bionic-android-514
script:
- docker-compose run bionic qbs build modules.cpp.compilerWrapper:ccache modules.qbsbuildconfig.enableBundledQt:true config:release
- docker-compose run bionic-android-513 scripts/test-qt-for-android.sh release/install-root/usr/local/bin
+
+ - <<: *build-on-bionic
+ name: With Qbs and with Qt 5.14 for Android
+ before_install:
+ - docker-compose pull bionic
+ - docker-compose pull bionic-android-514
+ script:
+ - docker-compose run bionic qbs build modules.cpp.compilerWrapper:ccache modules.qbsbuildconfig.enableBundledQt:true config:release
- docker-compose run bionic-android-514 scripts/test-qt-for-android.sh release/install-root/usr/local/bin
- &build-on-macos
diff --git a/doc/reference/items/convenience/application.qdoc b/doc/reference/items/convenience/application.qdoc
index e92247f5f..ca77e153c 100644
--- a/doc/reference/items/convenience/application.qdoc
+++ b/doc/reference/items/convenience/application.qdoc
@@ -41,8 +41,9 @@
The target artifact of this type of product is usually an executable binary
tagged \c "application".
However, on Android, unless you set \l{Product::}{consoleApplication} to \c true,
- the application target will be an APK package tagged \c "android.apk", and a
- dependency to the \l{Android.sdk} module is automatically added to the product.
+ the application target will be an APK or an AAB package tagged \c "android.package"
+ according to the \l{Android.sdk}{packageType} property. A dependency to the \l{Android.sdk}
+ module is automatically added to the product.
*/
/*!
diff --git a/doc/reference/modules/android-sdk-module.qdoc b/doc/reference/modules/android-sdk-module.qdoc
index 74599d0ba..676eaa825 100644
--- a/doc/reference/modules/android-sdk-module.qdoc
+++ b/doc/reference/modules/android-sdk-module.qdoc
@@ -241,3 +241,12 @@
\defaultvalue \c "aapt"
*/
+
+/*!
+ \qmlproperty string Android.sdk::packageType
+
+ Type of the package. Allowed options: "apk" and "aab".
+ Type "apk" generates a runnable package whereas "aab" generates a package for Google Play.
+
+ \defaultvalue \c "apk"
+*/
diff --git a/docker-compose.yml b/docker-compose.yml
index ac9ba433f..b8b4528c9 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -26,7 +26,7 @@ services:
bionic-android-513:
<< : *linux
hostname: bionic-android
- image: ${DOCKER_USER:-qbsbuild}/qbsdev:bionic-android-5.13.2-2
+ image: ${DOCKER_USER:-qbsbuild}/qbsdev:bionic-android-5.13.2-3
build:
dockerfile: docker/bionic/test-android.Dockerfile
context: .
@@ -36,7 +36,7 @@ services:
bionic-android-514:
<< : *linux
hostname: bionic-android
- image: ${DOCKER_USER:-qbsbuild}/qbsdev:bionic-android-5.14.0-2
+ image: ${DOCKER_USER:-qbsbuild}/qbsdev:bionic-android-5.14.0-3
build:
dockerfile: docker/bionic/test-android.Dockerfile
context: .
diff --git a/docker/bionic/test-android.Dockerfile b/docker/bionic/test-android.Dockerfile
index 56bb0b9e6..3ec8b4808 100644
--- a/docker/bionic/test-android.Dockerfile
+++ b/docker/bionic/test-android.Dockerfile
@@ -89,6 +89,10 @@ RUN mkdir ${ANDROID_SDK_ROOT}/samples && \
rm -v master.zip && \
mv android-BasicMediaDecoder-master android-BasicMediaDecoder
+# Download buildtool to generate aab packages in ${ANDROID_SDK_ROOT}
+RUN cd ${ANDROID_SDK_ROOT} && \
+ curl -sLO https://github.com/google/bundletool/releases/download/0.15.0/bundletool-all-0.15.0.jar
+
USER root
#
diff --git a/share/qbs/imports/qbs/base/AndroidApk.qbs b/share/qbs/imports/qbs/base/AndroidApk.qbs
index 5f86d8457..70cf6aa93 100644
--- a/share/qbs/imports/qbs/base/AndroidApk.qbs
+++ b/share/qbs/imports/qbs/base/AndroidApk.qbs
@@ -32,7 +32,7 @@ import qbs.File
import qbs.FileInfo
Product {
- type: ["android.apk"]
+ type: ["android.package"]
qbs.targetPlatform: "android"
Depends { name: "Android.sdk" }
}
diff --git a/share/qbs/imports/qbs/base/Application.qbs b/share/qbs/imports/qbs/base/Application.qbs
index 63ffc6283..1e4f805a8 100644
--- a/share/qbs/imports/qbs/base/Application.qbs
+++ b/share/qbs/imports/qbs/base/Application.qbs
@@ -29,7 +29,7 @@
****************************************************************************/
NativeBinary {
- type: isForAndroid && !consoleApplication ? ["android.apk"] : ["application"]
+ type: isForAndroid && !consoleApplication ? ["android.package"] : ["application"]
property bool usesNativeCode
diff --git a/share/qbs/module-providers/Qt/templates/android_support.qbs b/share/qbs/module-providers/Qt/templates/android_support.qbs
index 342018321..2835a9336 100644
--- a/share/qbs/module-providers/Qt/templates/android_support.qbs
+++ b/share/qbs/module-providers/Qt/templates/android_support.qbs
@@ -18,7 +18,7 @@ Module {
property string _androidDeployQtFilePath: FileInfo.joinPaths(_qtInstallDir, "bin",
"androiddeployqt")
property string _qtInstallDir
- property bool _enableSdkSupport: product.type && product.type.contains("android.apk")
+ property bool _enableSdkSupport: product.type && product.type.contains("android.package")
&& !consoleApplication
property bool _enableNdkSupport: !product.aggregate || product.multiplexConfigurationId
property string _templatesBaseDir: FileInfo.joinPaths(_qtInstallDir, "src", "android")
@@ -312,7 +312,7 @@ Module {
File.move(product.Qt.android_support._deployQtOutDir + "/AndroidManifest.xml",
outputs["android.manifest_final"][0].filePath);
var libsDir = product.Qt.android_support._deployQtOutDir + "/libs";
- var libDir = product.Android.sdk.apkContentsDir + "/lib";
+ var libDir = product.Android.sdk.packageContentsDir + "/lib";
var listFilePath = outputs["android.deployqt_list"][0].filePath;
var oldLibs = [];
try {
@@ -364,7 +364,7 @@ Module {
for (var i in inputs["android.nativelibrary"])
architectures.push(inputs["android.nativelibrary"][i].Android.ndk.abi);
for (var i in architectures) {
- var abiDirPath = FileInfo.joinPaths(product.Android.sdk.apkContentsDir,
+ var abiDirPath = FileInfo.joinPaths(product.Android.sdk.packageContentsDir,
"lib", architectures[i]);
var files = File.directoryEntries(abiDirPath, File.Files);
for (var i = 0; i < files.length; ++i) {
diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs
index 681b3da94..31f3ed465 100644
--- a/share/qbs/modules/Android/sdk/sdk.qbs
+++ b/share/qbs/modules/Android/sdk/sdk.qbs
@@ -50,6 +50,14 @@ Module {
environmentPaths: (ndkDir ? [ndkDir] : []).concat(base)
}
+ Probes.PathProbe {
+ id: bundletoolProbe
+ platformSearchPaths: [Android.sdk.sdkDir]
+ names: ["bundletool-all"]
+ nameSuffixes: ["-0.11.0.jar", "-0.12.0.jar", "-0.13.0.jar", "-0.13.3.jar", "-0.13.4.jar",
+ "-0.14.0.jar", "-0.15.0.jar"]
+ }
+
property path sdkDir: sdkProbe.path
property path ndkDir: ndkProbe.path
property path ndkSamplesDir: ndkProbe.samplesDir
@@ -60,6 +68,8 @@ Module {
property int buildToolsVersionPatch: buildToolsVersionParts[2]
property string platform: sdkProbe.platform
+ property path bundletoolFilePath: bundletoolProbe.filePath
+
// Product-specific properties and files
property string packageName: {
var idx = product.name.indexOf(".")
@@ -146,6 +156,12 @@ Module {
}
property path aaptFilePath: FileInfo.joinPaths(buildToolsDir, aaptName)
readonly property bool _enableAapt2: aaptName === "aapt2"
+ property string packageType: "apk"
+ PropertyOptions {
+ name: "packageType"
+ allowedValues: ["apk", "aab"]
+ }
+ readonly property bool _generateAab: packageType == "aab"
property path apksignerFilePath: FileInfo.joinPaths(buildToolsDir, "apksigner")
property path aidlFilePath: FileInfo.joinPaths(buildToolsDir, "aidl")
@@ -160,7 +176,7 @@ Module {
(packageName || "").split('.').join('/'))
property path compiledResourcesDir: FileInfo.joinPaths(product.buildDirectory,
"compiled_resources")
- property string apkContentsDir: FileInfo.joinPaths(product.buildDirectory, "bin")
+ property string packageContentsDir: FileInfo.joinPaths(product.buildDirectory, packageType)
property string debugKeyStorePath: FileInfo.joinPaths(
Environment.getEnv(qbs.hostOS.contains("windows")
? "USERPROFILE" : "HOME"),
@@ -186,6 +202,14 @@ Module {
+ "ANDROID_HOME environment variable to a valid "
+ "Android SDK location.");
}
+ if (!bundletoolFilePath && _generateAab) {
+ throw ModUtils.ModuleError("Could not find Android bundletool at the following "
+ + "location:\n\t" + Android.sdk.sdkDir
+ + "\nInstall the Android bundletool to the above location, "
+ + "or set the Android.sdk.bundletoolFilePath property.\n"
+ + "Android bundletool can be downloaded from "
+ + "https://github.com/google/bundletool");
+ }
}
FileTagger {
@@ -366,12 +390,13 @@ Module {
condition: _enableRules && _enableAapt2
multiplex: true
inputs: ["android.resources_compiled", "android.assets", "android.manifest_final"]
- outputFileTags: ["java.java", "android.apk_base"]
+ outputFileTags: ["java.java", "android.apk_resources"]
outputArtifacts: {
var artifacts = [];
artifacts.push({
- filePath: product.Android.sdk.apkBaseName + ".apk_base",
- fileTags: ["android.apk_base"]
+ filePath: product.Android.sdk.apkBaseName + (product.Android.sdk._generateAab ?
+ ".apk_aab" : ".apk_apk"),
+ fileTags: ["android.apk_resources"]
});
var resources = inputs["android.resources_compiled"];
if (resources && resources.length) {
@@ -419,7 +444,10 @@ Module {
inputs: ["java.class"]
inputsFromDependencies: ["java.jar"]
Artifact {
- filePath: FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "classes.dex")
+ filePath: product.Android.sdk._generateAab ?
+ FileInfo.joinPaths(product.Android.sdk.packageContentsDir, "dex",
+ "classes.dex") :
+ FileInfo.joinPaths(product.Android.sdk.packageContentsDir, "classes.dex")
fileTags: ["android.dex"]
}
prepare: SdkUtils.prepareDex.apply(SdkUtils, arguments)
@@ -431,7 +459,7 @@ Module {
inputsFromDependencies: inputTags
inputs: product.aggregate ? [] : inputTags
Artifact {
- filePath: FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "lib",
+ filePath: FileInfo.joinPaths(product.Android.sdk.packageContentsDir, "lib",
input.Android.ndk.abi, input.fileName)
fileTags: "android.nativelibrary_deployed"
}
@@ -475,7 +503,7 @@ Module {
}
Rule {
- condition: _enableRules && !_enableAapt2
+ condition: _enableRules && !_enableAapt2 && !_generateAab
multiplex: true
inputs: [
"android.resources", "android.assets", "android.manifest_final",
@@ -484,23 +512,38 @@ Module {
]
Artifact {
filePath: product.Android.sdk.apkBaseName + ".apk"
- fileTags: "android.apk"
+ fileTags: "android.package"
}
prepare: SdkUtils.prepareAaptPackage.apply(SdkUtils, arguments)
}
Rule {
- condition: _enableRules && _enableAapt2
+ condition: _enableRules && _enableAapt2 && !_generateAab
multiplex: true
inputs: [
- "android.apk_base", "android.manifest_final",
+ "android.apk_resources", "android.manifest_final",
"android.dex", "android.stl_deployed",
"android.nativelibrary_deployed", "android.keystore"
]
Artifact {
filePath: product.Android.sdk.apkBaseName + ".apk"
- fileTags: "android.apk"
+ fileTags: "android.package"
}
prepare: SdkUtils.prepareApkPackage.apply(SdkUtils, arguments)
}
+
+ Rule {
+ condition: _enableRules && _enableAapt2 && _generateAab
+ multiplex: true
+ inputs: [
+ "android.apk_resources", "android.manifest_final",
+ "android.dex", "android.stl_deployed",
+ "android.nativelibrary_deployed"
+ ]
+ Artifact {
+ filePath: product.Android.sdk.apkBaseName + ".aab"
+ fileTags: "android.package"
+ }
+ prepare: SdkUtils.prepareBundletoolPackage.apply(SdkUtils, arguments)
+ }
}
diff --git a/share/qbs/modules/Android/sdk/utils.js b/share/qbs/modules/Android/sdk/utils.js
index b1c929e68..63bf1f5c4 100644
--- a/share/qbs/modules/Android/sdk/utils.js
+++ b/share/qbs/modules/Android/sdk/utils.js
@@ -79,7 +79,7 @@ function prepareDex(project, product, inputs, outputs, input, output, explicitly
args = args.concat(jarFiles);
var cmd = new Command(dxFilePath, args);
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
return [cmd];
}
@@ -183,13 +183,12 @@ function prepareAapt2CompileResource(project, product, inputs, outputs, input, o
function prepareAapt2Link(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var cmds = [];
+ var baseOutputFilePath = outputs["android.apk_resources"][0].filePath;
var manifestFilePath = inputs["android.manifest_final"][0].filePath;
var compilesResourcesDir = product.Android.sdk.compiledResourcesDir;
- var apkOutputFilePath = outputs["android.apk_base"][0].filePath;
var compiledResources = inputs["android.resources_compiled"];
- var args = ["link", "-o", apkOutputFilePath, "-I", product.Android.sdk.androidJarFilePath];
- //For aab: args.push("link", "--proto-format");
+ var args = ["link", "-o", baseOutputFilePath, "-I", product.Android.sdk.androidJarFilePath];
var i = 0;
if (compiledResources) {
for (i = 0; i < compiledResources.length; ++i)
@@ -217,9 +216,10 @@ function prepareAapt2Link(project, product, inputs, outputs, input, output, expl
args.push("-A", assetDirs[i]);
if (product.qbs.buildVariant === "debug")
args.push("-v");
-
+ if (product.Android.sdk._generateAab)
+ args.push("--proto-format");
var cmd = new Command(product.Android.sdk.aaptFilePath, args);
- cmd.description = "Linking resources";
+ cmd.description = "linking resources";
cmd.workingDirectory = product.buildDirectory;
cmds.push(cmd);
@@ -234,18 +234,18 @@ function prepareAaptGenerate(project, product, inputs, outputs, input, output,
if (resources && resources.length)
args.push("-J", ModUtils.moduleProperty(product, "generatedJavaFilesBaseDir"));
var cmd = new Command(product.Android.sdk.aaptFilePath, args);
- cmd.description = "Processing resources";
+ cmd.description = "processing resources";
return [cmd];
}
function prepareAaptPackage(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var cmds = [];
- var apkOutput = outputs["android.apk"][0];
+ var apkOutput = outputs["android.package"][0];
var args = commonAaptPackageArgs.apply(this, arguments);
args.push("-F", apkOutput.filePath + ".unaligned");
- args.push(product.Android.sdk.apkContentsDir);
+ args.push(product.Android.sdk.packageContentsDir);
var cmd = new Command(product.Android.sdk.aaptFilePath, args);
- cmd.description = "Generating " + apkOutput.filePath;
+ cmd.description = "generating " + apkOutput.fileName;
cmds.push(cmd);
if (!product.Android.sdk.useApksigner) {
@@ -255,7 +255,7 @@ function prepareAaptPackage(project, product, inputs, outputs, input, output, ex
apkOutput.filePath + ".unaligned",
"androiddebugkey"];
cmd = new Command(product.java.jarsignerFilePath, args);
- cmd.description = "Signing " + apkOutput.fileName;
+ cmd.description = "signing " + apkOutput.fileName;
cmds.push(cmd);
}
@@ -277,7 +277,7 @@ function prepareAaptPackage(project, product, inputs, outputs, input, output, ex
"--ks-pass", "pass:android",
apkOutput.filePath];
cmd = new Command(product.Android.sdk.apksignerFilePath, args);
- cmd.description = "Signing " + apkOutput.fileName;
+ cmd.description = "signing " + apkOutput.fileName;
cmds.push(cmd);
}
@@ -286,9 +286,9 @@ function prepareAaptPackage(project, product, inputs, outputs, input, output, ex
function prepareApkPackage(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
var cmds = [];
- var apkInputFilePath = inputs["android.apk_base"][0].filePath;
- var apkOutput = outputs["android.apk"][0];
- var apkOutputFilePathUnaligned = outputs["android.apk"][0].filePath + ".unaligned";
+ var apkInputFilePath = inputs["android.apk_resources"][0].filePath;
+ var apkOutput = outputs["android.package"][0];
+ var apkOutputFilePathUnaligned = outputs["android.package"][0].filePath + ".unaligned";
var dexFilePath = inputs["android.dex"][0].filePath;
var copyCmd = new JavaScriptCommand();
@@ -301,7 +301,7 @@ function prepareApkPackage(project, product, inputs, outputs, input, output, exp
cmds.push(copyCmd);
var jarArgs = ["-uvf", apkOutputFilePathUnaligned, "."];
- var libPath = FileInfo.joinPaths(product.Android.sdk.apkContentsDir);
+ var libPath = FileInfo.joinPaths(product.Android.sdk.packageContentsDir);
var jarCmd = new Command(product.java.jarFilePath, jarArgs);
jarCmd.description = "packaging files";
jarCmd.workingDirectory = libPath;
@@ -314,7 +314,7 @@ function prepareApkPackage(project, product, inputs, outputs, input, output, exp
apkOutputFilePathUnaligned,
"androiddebugkey"];
cmd = new Command(product.java.jarsignerFilePath, args);
- cmd.description = "Signing " + apkOutput.fileName;
+ cmd.description = "signing " + apkOutput.fileName;
cmds.push(cmd);
}
@@ -336,13 +336,65 @@ function prepareApkPackage(project, product, inputs, outputs, input, output, exp
"--ks-pass", "pass:android",
apkOutput.filePath];
cmd = new Command(product.Android.sdk.apksignerFilePath, args);
- cmd.description = "Signing " + apkOutput.fileName;
+ cmd.description = "signing " + apkOutput.fileName;
cmds.push(cmd);
}
return cmds;
}
+function prepareBundletoolPackage(project, product, inputs, outputs, input, output,
+ explicitlyDependsOn) {
+ var cmds = [];
+ var baseModuleDir = product.Android.sdk.packageContentsDir;
+ var manifestDirName = FileInfo.joinPaths(baseModuleDir, "manifest");
+ var pkgBaseFileName = inputs["android.apk_resources"][0].filePath;
+
+ var jarResourcesArgs = ["xf", pkgBaseFileName];
+ var jarResourcesCmd = new Command(product.java.jarFilePath, jarResourcesArgs);
+ jarResourcesCmd.description = "extracting resources apk";
+ jarResourcesCmd.workingDirectory = baseModuleDir;
+ cmds.push(jarResourcesCmd);
+
+ var moveManifestCmd = new JavaScriptCommand();
+ moveManifestCmd.description = "moving manifest in manifest directory";
+ moveManifestCmd.path = manifestDirName;
+ moveManifestCmd.manifestFilePath = baseModuleDir + "/AndroidManifest.xml";
+ moveManifestCmd.sourceCode = function() {
+ if (!File.exists(path))
+ File.makePath(path);
+ if (File.exists(manifestFilePath))
+ File.move(manifestFilePath, path + "/AndroidManifest.xml");
+ }
+ cmds.push(moveManifestCmd);
+
+ var baseFilePath = FileInfo.joinPaths(product.buildDirectory, "base.zip");
+ var jarBaseArgs = ["cfM", baseFilePath, "."];
+ var jarBaseCmd = new Command(product.java.jarFilePath, jarBaseArgs);
+ jarBaseCmd.description = "compressing base module";
+ jarBaseCmd.workingDirectory = baseModuleDir;
+ cmds.push(jarBaseCmd);
+
+ var aabFilePath = outputs["android.package"][0].filePath;
+ var removeCmd = new JavaScriptCommand();
+ removeCmd.description = "removing previous aab";
+ removeCmd.filePath = aabFilePath;
+ removeCmd.sourceCode = function() {
+ if (File.exists(filePath))
+ File.remove(filePath);
+ }
+ cmds.push(removeCmd);
+
+ var args = ["-jar", product.Android.sdk.bundletoolFilePath, "build-bundle"];
+ args.push("--modules=" + baseFilePath);
+ args.push("--output=" + aabFilePath);
+ var cmd = new Command(product.java.interpreterFilePath, args);
+ cmd.description = "generating " + outputs["android.package"][0].fileName;
+ cmds.push(cmd);
+
+ return cmds;
+}
+
function createDebugKeyStoreCommandString(keytoolFilePath, keystoreFilePath) {
var args = ["-genkey", "-keystore", keystoreFilePath, "-alias", "androiddebugkey",
"-storepass", "android", "-keypass", "android", "-keyalg", "RSA",
@@ -365,7 +417,7 @@ function stlDeploymentData(product, inputs, type)
uniqueFilePaths.push(currentInput.filePath);
data.uniqueInputs.push(currentInput);
var outputFileName = currentInput.fileName;
- data.outputFilePaths.push(FileInfo.joinPaths(product.Android.sdk.apkContentsDir, "lib",
+ data.outputFilePaths.push(FileInfo.joinPaths(product.Android.sdk.packageContentsDir, "lib",
currentInput.Android.ndk.abi,
outputFileName));
}
diff --git a/src/lib/corelib/api/project.cpp b/src/lib/corelib/api/project.cpp
index 378b13dfe..f7a9eca09 100644
--- a/src/lib/corelib/api/project.cpp
+++ b/src/lib/corelib/api/project.cpp
@@ -635,7 +635,10 @@ static bool productIsRunnable(const ResolvedProductConstPtr &product)
{
const bool isBundle = product->moduleProperties->moduleProperty(
QStringLiteral("bundle"), QStringLiteral("isBundle")).toBool();
- return isRunnableArtifact(product->fileTags, isBundle);
+ const QString androidSdkPackageType = product->moduleProperties->moduleProperty(
+ QStringLiteral("Android.sdk"), QStringLiteral("packageType")).toString();
+ const bool isAndroidApk = androidSdkPackageType == QStringLiteral("apk");
+ return isRunnableArtifact(product->fileTags, isBundle, isAndroidApk);
}
static bool productIsMultiplexed(const ResolvedProductConstPtr &product)
diff --git a/src/lib/corelib/api/projectdata.cpp b/src/lib/corelib/api/projectdata.cpp
index cb7d12b98..c378fbea4 100644
--- a/src/lib/corelib/api/projectdata.cpp
+++ b/src/lib/corelib/api/projectdata.cpp
@@ -323,8 +323,10 @@ bool ArtifactData::isExecutable() const
{
const bool isBundle = d->properties.getModuleProperty(
QStringLiteral("bundle"), QStringLiteral("isBundle")).toBool();
- return isRunnableArtifact(
- FileTags::fromStringList(d->fileTags), isBundle);
+ const QString androidSdkPackageType = d->properties.getModuleProperty(
+ QStringLiteral("Android.sdk"), QStringLiteral("packageType")).toString();
+ const bool isAndroidApk = androidSdkPackageType == QStringLiteral("apk");
+ return isRunnableArtifact(FileTags::fromStringList(d->fileTags), isBundle, isAndroidApk);
}
/*!
diff --git a/src/lib/corelib/api/projectdata_p.h b/src/lib/corelib/api/projectdata_p.h
index 834aeec23..e241ea92c 100644
--- a/src/lib/corelib/api/projectdata_p.h
+++ b/src/lib/corelib/api/projectdata_p.h
@@ -123,11 +123,11 @@ public:
QString buildDir;
};
-inline bool isRunnableArtifact(const FileTags &fileTags, bool isBundle)
+inline bool isRunnableArtifact(const FileTags &fileTags, bool isBundle, bool isAndroidApk)
{
return (fileTags.contains("application") && (!isBundle || fileTags.contains("bundle.content")))
|| fileTags.contains("bundle.application-executable")
- || fileTags.contains("android.apk")
+ || (fileTags.contains("android.package") && isAndroidApk)
|| fileTags.contains("msi");
}
diff --git a/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml
index e8a950847..1d27681ac 100644
--- a/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml
+++ b/tests/auto/blackbox/testdata-android/aidl/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:versionName="1.0" android:versionCode="1"
package="io.qbs.aidltest">
<application android:label="AidlTest">
<activity android:name="MainActivity">
diff --git a/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml b/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml
index 575e95e8d..f61dc9850 100644
--- a/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml
+++ b/tests/auto/blackbox/testdata-android/minimal-native/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:versionName="1.0" android:versionCode="1"
package="somedefault">
<application android:label="MinimalNative">
<activity android:name="MainActivity">
diff --git a/tests/auto/blackbox/tst_blackboxandroid.cpp b/tests/auto/blackbox/tst_blackboxandroid.cpp
index e8d44188c..5e850874e 100644
--- a/tests/auto/blackbox/tst_blackboxandroid.cpp
+++ b/tests/auto/blackbox/tst_blackboxandroid.cpp
@@ -81,6 +81,8 @@ void TestBlackboxAndroid::android()
QFETCH(QList<QByteArrayList>, expectedFilesLists);
QFETCH(QStringList, qmlAppCustomProperties);
QFETCH(bool, enableAapt2);
+ QFETCH(bool, generateAab);
+ QFETCH(bool, isIncrementalBuild);
const SettingsPtr s = settings();
Profile p(theProfileName(projectDir == "qml-app"), s.get());
@@ -104,7 +106,7 @@ void TestBlackboxAndroid::android()
&& ndkSamplesDirs.contains(projectDir))
QSKIP("NDK samples directory not present");
- const QString aaptVersion = enableAapt2 ? "aapt2" : "aapt";
+ const QString buildSubDir = enableAapt2 ? (generateAab ? "aab" : "aapt2") : "aapt";
QDir::setCurrent(testDataDir + "/" + projectDir);
static const QStringList configNames { "debug", "release" };
@@ -112,29 +114,29 @@ void TestBlackboxAndroid::android()
auto currentExpectedFilesLists = expectedFilesLists;
const QString configArgument = "config:" + configName;
QbsRunParameters resolveParams("resolve");
- resolveParams.buildDirectory = aaptVersion;
+ resolveParams.buildDirectory = buildSubDir;
resolveParams.arguments << configArgument << qmlAppCustomProperties;
resolveParams.profile = p.name();
QCOMPARE(runQbs(resolveParams), 0);
QbsRunParameters buildParams(QStringList{"--command-echo-mode", "command-line",
configArgument});
- buildParams.buildDirectory = aaptVersion;
+ buildParams.buildDirectory = buildSubDir;
buildParams.profile = p.name();
QCOMPARE(runQbs(buildParams), 0);
for (const QString &productName : qAsConst(productNames)) {
const QByteArray tag(QTest::currentDataTag());
- const bool isIncrementalBuild = tag.startsWith("qml app") && tag != "qml app";
QCOMPARE(m_qbsStdout.count("Generating BuildConfig.java"),
isIncrementalBuild ? 0 : productNames.size());
- QVERIFY(m_qbsStdout.contains(productName.toLocal8Bit() + ".apk"));
- const QString apkFilePath = aaptVersion + "/" + relativeProductBuildDir(productName,
- configName)
- + '/' + productName + ".apk";
- QVERIFY2(regularFileExists(apkFilePath), qPrintable(apkFilePath));
+ const QString packageName = productName + (generateAab ? ".aab" : ".apk");
+ QVERIFY(m_qbsStdout.contains(packageName.toLocal8Bit()));
+ const QString packageFilePath = buildSubDir + "/" + relativeProductBuildDir(productName,
+ configName)
+ + '/' + packageName;
+ QVERIFY2(regularFileExists(packageFilePath), qPrintable(packageFilePath));
const QString jarFilePath = androidPaths["jar"];
QVERIFY(!jarFilePath.isEmpty());
QProcess jar;
- jar.start(jarFilePath, QStringList() << "-tf" << apkFilePath);
+ jar.start(jarFilePath, QStringList() << "-tf" << packageFilePath);
QVERIFY2(jar.waitForStarted(), qPrintable(jar.errorString()));
QVERIFY2(jar.waitForFinished(), qPrintable(jar.errorString()));
QVERIFY2(jar.exitCode() == 0, qPrintable(jar.readAllStandardError().constData()));
@@ -209,7 +211,8 @@ void TestBlackboxAndroid::android_data()
const auto cxxLibPath = [&p, &pQt](const QByteArray &oldcxxLib, bool forQt) {
const bool usesClang = (forQt ? pQt : p).value(QStringLiteral("qbs.toolchainType"))
.toString() == "clang";
- return QByteArray("lib/${ARCH}/") + (usesClang ? "libc++_shared.so" : oldcxxLib);
+ const QByteArray path = "lib/${ARCH}/";
+ return path + (usesClang ? "libc++_shared.so" : oldcxxLib);
};
bool usingOldQt = true;
QStringList qmakeFilePaths = pQt.value(QStringLiteral("moduleProviders.Qt.qmakeFilePaths")).
@@ -246,129 +249,229 @@ void TestBlackboxAndroid::android_data()
.replace("arm64", "arm64-v8a");
});
- auto expandArchs = [] (const QByteArrayList &archs, const QByteArrayList &lst) {
+ auto expandArchs = [] (const QByteArrayList &archs, const QByteArrayList &lst, bool aabPackage) {
const QByteArray &archPlaceHolder = "${ARCH}";
QByteArrayList result;
+ QByteArray base( aabPackage ? "base/" : QByteArray());
for (const QByteArray &entry : lst) {
if (entry.contains(archPlaceHolder)) {
for (const QByteArray &arch : qAsConst(archs))
- result << QByteArray(entry).replace(archPlaceHolder, arch);
+ result << (base + QByteArray(entry).replace(archPlaceHolder, arch));
} else {
- result << entry;
+ result << (base + entry);
}
}
return result;
};
- const QByteArrayList commonFiles = expandArchs(archs, {
- "AndroidManifest.xml", "META-INF/ANDROIDD.RSA", "META-INF/ANDROIDD.SF",
- "META-INF/MANIFEST.MF", "classes.dex"
- });
+ auto commonFiles = [](bool generateAab) {
+ if (generateAab)
+ return (QByteArrayList()
+ << "base/manifest/AndroidManifest.xml" << "base/dex/classes.dex"
+ << "BundleConfig.pb");
+ return (QByteArrayList()
+ << "AndroidManifest.xml" << "META-INF/ANDROIDD.RSA" << "META-INF/ANDROIDD.SF"
+ << "META-INF/MANIFEST.MF" << "classes.dex");
+ };
QTest::addColumn<QString>("projectDir");
QTest::addColumn<QStringList>("productNames");
QTest::addColumn<QList<QByteArrayList>>("expectedFilesLists");
QTest::addColumn<QStringList>("qmlAppCustomProperties");
QTest::addColumn<bool>("enableAapt2");
+ QTest::addColumn<bool>("generateAab");
+ QTest::addColumn<bool>("isIncrementalBuild");
const auto aaptVersion = [](bool enableAapt2) {
return QString("modules.Android.sdk.aaptName:") + (enableAapt2 ? "aapt2" : "aapt");
};
bool enableAapt2 = false;
- QByteArrayList teaPotAppExpectedFiles;
- teaPotAppExpectedFiles << commonFiles + expandArchs(archs, {
- "resources.arsc",
- "assets/Shaders/ShaderPlain.fsh",
- "assets/Shaders/VS_ShaderPlain.vsh",
- cxxLibPath("libgnustl_shared.so", false),
- "lib/${ARCH}/libTeapotNativeActivity.so",
- "res/layout/widgets.xml",
- "res/mipmap-hdpi-v4/ic_launcher.png",
- "res/mipmap-mdpi-v4/ic_launcher.png",
- "res/mipmap-xhdpi-v4/ic_launcher.png",
- "res/mipmap-xxhdpi-v4/ic_launcher.png"});
+ const auto packageType = [](bool generateAab) {
+ return QString("modules.Android.sdk.packageType:") + (generateAab ? "aab" : "apk");
+ };
+ bool generateAab = false;
+ bool isIncrementalBuild = false;
+
+ auto teaPotAppExpectedFiles = [&](const QByteArrayList &archs, bool generateAab) {
+ QByteArrayList expectedFile;
+ expectedFile << commonFiles(generateAab) + expandArchs(archs, {
+ "assets/Shaders/ShaderPlain.fsh",
+ "assets/Shaders/VS_ShaderPlain.vsh",
+ cxxLibPath("libgnustl_shared.so", false),
+ "lib/${ARCH}/libTeapotNativeActivity.so",
+ "res/layout/widgets.xml",
+ "res/mipmap-hdpi-v4/ic_launcher.png",
+ "res/mipmap-mdpi-v4/ic_launcher.png",
+ "res/mipmap-xhdpi-v4/ic_launcher.png",
+ "res/mipmap-xxhdpi-v4/ic_launcher.png"}, generateAab);
+ if (generateAab)
+ expectedFile << "base/resources.pb" << "base/assets.pb" << "base/native.pb";
+ else
+ expectedFile << "resources.arsc";
+ return expectedFile;
+ };
+
QTest::newRow("teapot")
<< "teapot" << QStringList("TeapotNativeActivity")
- << (QList<QByteArrayList>() << teaPotAppExpectedFiles)
- << QStringList{aaptVersion(enableAapt2)} << enableAapt2;
+ << (QList<QByteArrayList>() << teaPotAppExpectedFiles(archs, generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = true;
- QTest::newRow("teapot")
+ QTest::newRow("teapot aapt2")
+ << "teapot" << QStringList("TeapotNativeActivity")
+ << (QList<QByteArrayList>() << teaPotAppExpectedFiles(archs, generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ generateAab = true;
+ QTest::newRow("teapot aapt2 aab")
<< "teapot" << QStringList("TeapotNativeActivity")
- << (QList<QByteArrayList>() << teaPotAppExpectedFiles)
- << QStringList{aaptVersion(enableAapt2)} << enableAapt2;
+ << (QList<QByteArrayList>() << teaPotAppExpectedFiles(archs, generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = false;
+ generateAab = false;
QTest::newRow("minimal-native")
<< "minimal-native" << QStringList("minimalnative")
- << (QList<QByteArrayList>() << commonFiles + expandArchs({archs.first()}, {
+ << (QList<QByteArrayList>() << commonFiles(generateAab) + expandArchs({archs.first()}, {
"lib/${ARCH}/libminimalnative.so",
cxxLibPath("libstlport_shared.so", false),
- "lib/${ARCH}/libdependency.so"}))
+ "lib/${ARCH}/libdependency.so"}, generateAab))
<< QStringList{"products.minimalnative.multiplexByQbsProperties:[]",
"modules.qbs.architecture:" + archsStringList.first(),
aaptVersion(enableAapt2)}
- << enableAapt2;
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = true;
- QTest::newRow("minimal-native")
+ QTest::newRow("minimal-native aapt2")
<< "minimal-native" << QStringList("minimalnative")
- << (QList<QByteArrayList>() << commonFiles + expandArchs({archs.first()}, {
- "resources.arsc",
+ << (QList<QByteArrayList>() << commonFiles(generateAab) +
+ (QByteArrayList() << "resources.arsc") + expandArchs({archs.first()}, {
"lib/${ARCH}/libminimalnative.so",
cxxLibPath("libstlport_shared.so", false),
- "lib/${ARCH}/libdependency.so"}))
+ "lib/${ARCH}/libdependency.so"}, generateAab))
<< QStringList{"products.minimalnative.multiplexByQbsProperties:[]",
"modules.qbs.architecture:" + archsStringList.first(),
- aaptVersion(enableAapt2)}
- << enableAapt2;
- QByteArrayList qmlAppExpectedFiles;
- QByteArrayList qmlAppMinistroExpectedFiles;
- QByteArrayList qmlAppCustomMetaDataExpectedFiles;
- QStringList qmlAppCustomProperties;
- if (usingOldQt) {
- qmlAppExpectedFiles << commonFiles + expandArchs(ndkArchsForQt, {
- "resources.arsc",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/plugins.qmltypes",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/qmldir",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/plugins.qmltypes",
- "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/qmldir",
- "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list",
- cxxLibPath("libgnustl_shared.so", true),
- "lib/${ARCH}/libplugins_bearer_libqandroidbearer.so",
- "lib/${ARCH}/libplugins_imageformats_libqgif.so",
- "lib/${ARCH}/libplugins_imageformats_libqicns.so",
- "lib/${ARCH}/libplugins_imageformats_libqico.so",
- "lib/${ARCH}/libplugins_imageformats_libqjpeg.so",
- "lib/${ARCH}/libplugins_imageformats_libqtga.so",
- "lib/${ARCH}/libplugins_imageformats_libqtiff.so",
- "lib/${ARCH}/libplugins_imageformats_libqwbmp.so",
- "lib/${ARCH}/libplugins_imageformats_libqwebp.so",
- "lib/${ARCH}/libplugins_platforms_android_libqtforandroid.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_debugger.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_inspector.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_local.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_messages.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_native.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_nativedebugger.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_profiler.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_preview.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_quickprofiler.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_server.so",
- "lib/${ARCH}/libplugins_qmltooling_libqmldbg_tcp.so",
- "lib/${ARCH}/libqml_QtQuick.2_libqtquick2plugin.so",
- "lib/${ARCH}/libqml_QtQuick_Window.2_libwindowplugin.so",
- "lib/${ARCH}/libQt5Core.so",
- "lib/${ARCH}/libQt5Gui.so",
- "lib/${ARCH}/libQt5Network.so",
- "lib/${ARCH}/libQt5Qml.so",
- "lib/${ARCH}/libQt5QuickParticles.so",
- "lib/${ARCH}/libQt5Quick.so",
- "lib/${ARCH}/libqmlapp.so"});
- qmlAppMinistroExpectedFiles << commonFiles + expandArchs(ndkArchsForQt, {
- "resources.arsc",
+ aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ generateAab = true;
+ QTest::newRow("minimal-native aapt2 aab")
+ << "minimal-native" << QStringList("minimalnative")
+ << (QList<QByteArrayList>() << commonFiles(generateAab) +
+ (QByteArrayList() << "base/resources.pb" << "base/native.pb") +
+ expandArchs({archs.first()}, {
+ "lib/${ARCH}/libminimalnative.so",
+ cxxLibPath("libstlport_shared.so", false),
+ "lib/${ARCH}/libdependency.so"}, generateAab))
+ << QStringList{"products.minimalnative.multiplexByQbsProperties:[]",
+ "modules.qbs.architecture:" + archsStringList.first(),
+ aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ auto qmlAppExpectedFiles = [&](bool generateAab) {
+ QByteArrayList expectedFile;
+ if (usingOldQt) {
+ expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/plugins.qmltypes",
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick.2/qmldir",
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/plugins.qmltypes",
+ "assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/qmldir",
+ "assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list",
+ cxxLibPath("libgnustl_shared.so", true),
+ "lib/${ARCH}/libplugins_bearer_libqandroidbearer.so",
+ "lib/${ARCH}/libplugins_imageformats_libqgif.so",
+ "lib/${ARCH}/libplugins_imageformats_libqicns.so",
+ "lib/${ARCH}/libplugins_imageformats_libqico.so",
+ "lib/${ARCH}/libplugins_imageformats_libqjpeg.so",
+ "lib/${ARCH}/libplugins_imageformats_libqtga.so",
+ "lib/${ARCH}/libplugins_imageformats_libqtiff.so",
+ "lib/${ARCH}/libplugins_imageformats_libqwbmp.so",
+ "lib/${ARCH}/libplugins_imageformats_libqwebp.so",
+ "lib/${ARCH}/libplugins_platforms_android_libqtforandroid.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_debugger.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_inspector.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_local.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_messages.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_native.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_nativedebugger.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_profiler.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_preview.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_quickprofiler.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_server.so",
+ "lib/${ARCH}/libplugins_qmltooling_libqmldbg_tcp.so",
+ "lib/${ARCH}/libqml_QtQuick.2_libqtquick2plugin.so",
+ "lib/${ARCH}/libqml_QtQuick_Window.2_libwindowplugin.so",
+ "lib/${ARCH}/libQt5Core.so",
+ "lib/${ARCH}/libQt5Gui.so",
+ "lib/${ARCH}/libQt5Network.so",
+ "lib/${ARCH}/libQt5Qml.so",
+ "lib/${ARCH}/libQt5QuickParticles.so",
+ "lib/${ARCH}/libQt5Quick.so",
+ "lib/${ARCH}/libqmlapp.so"}, generateAab);
+ } else {
+ expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
+ "assets/android_rcc_bundle.rcc",
+ cxxLibPath("libgnustl_shared.so", true),
+ "lib/${ARCH}/libplugins_bearer_qandroidbearer_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qgif_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qicns_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qico_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qjpeg_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qtga_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qtiff_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qwbmp_${ARCH}.so",
+ "lib/${ARCH}/libplugins_imageformats_qwebp_${ARCH}.so",
+ "lib/${ARCH}/libplugins_platforms_qtforandroid_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_debugger_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_inspector_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_local_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_messages_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_native_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_nativedebugger_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_profiler_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_preview_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_quickprofiler_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_server_${ARCH}.so",
+ "lib/${ARCH}/libplugins_qmltooling_qmldbg_tcp_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick.2_qtquick2plugin_${ARCH}.so",
+ "lib/${ARCH}/libqml_QtQuick_Window.2_windowplugin_${ARCH}.so",
+ "lib/${ARCH}/libQt5Core_${ARCH}.so",
+ "lib/${ARCH}/libQt5Gui_${ARCH}.so",
+ "lib/${ARCH}/libQt5Network_${ARCH}.so",
+ "lib/${ARCH}/libQt5Qml_${ARCH}.so",
+ "lib/${ARCH}/libQt5QuickParticles_${ARCH}.so",
+ "lib/${ARCH}/libQt5Quick_${ARCH}.so",
+ "lib/${ARCH}/libQt5QmlModels_${ARCH}.so",
+ "lib/${ARCH}/libQt5QmlWorkerScript_${ARCH}.so",
+ "lib/${ARCH}/libqmlapp_${ARCH}.so"}, generateAab);
+ }
+ if (generateAab)
+ expectedFile << "base/resources.pb" << "base/assets.pb" << "base/native.pb";
+ else
+ expectedFile << "resources.arsc";
+ return expectedFile;
+ };
+
+ auto qmlAppMinistroExpectedFiles = [&](bool generateAab) {
+ QByteArrayList expectedFile;
+ if (usingOldQt) {
+ expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
"assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list",
cxxLibPath("libgnustl_shared.so", true),
- "lib/${ARCH}/libqmlapp.so"});
- qmlAppCustomMetaDataExpectedFiles << commonFiles + expandArchs(ndkArchsForQt, {
- "resources.arsc",
+ "lib/${ARCH}/libqmlapp.so"}, generateAab);
+ } else {
+ expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
+ "assets/android_rcc_bundle.rcc",
+ cxxLibPath("libgnustl_shared.so", true),
+ "lib/${ARCH}/libqmlapp_${ARCH}.so"}, generateAab);
+ }
+ if (generateAab)
+ expectedFile << "base/resources.pb" << "base/assets.pb" << "base/native.pb";
+ else
+ expectedFile << "resources.arsc";
+ return expectedFile;
+ };
+ auto qmlAppCustomMetaDataExpectedFiles = [&](bool generateAab) {
+ QByteArrayList expectedFile;
+ if (usingOldQt) {
+ expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
"assets/--Added-by-androiddeployqt--/qml/QtQuick.2/plugins.qmltypes",
"assets/--Added-by-androiddeployqt--/qml/QtQuick.2/qmldir",
"assets/--Added-by-androiddeployqt--/qml/QtQuick/Window.2/plugins.qmltypes",
@@ -405,53 +508,9 @@ void TestBlackboxAndroid::android_data()
"lib/${ARCH}/libQt5Qml.so",
"lib/${ARCH}/libQt5QuickParticles.so",
"lib/${ARCH}/libQt5Quick.so",
- "lib/${ARCH}/libqmlapp.so"});
- qmlAppCustomProperties = QStringList{"modules.Android.sdk.automaticSources:false",
- "modules.qbs.architecture:" + archsForQt.first()};
- } else {
- qmlAppExpectedFiles << commonFiles + expandArchs(ndkArchsForQt, {
- "resources.arsc",
- "assets/android_rcc_bundle.rcc",
- cxxLibPath("libgnustl_shared.so", true),
- "lib/${ARCH}/libplugins_bearer_qandroidbearer_${ARCH}.so",
- "lib/${ARCH}/libplugins_imageformats_qgif_${ARCH}.so",
- "lib/${ARCH}/libplugins_imageformats_qicns_${ARCH}.so",
- "lib/${ARCH}/libplugins_imageformats_qico_${ARCH}.so",
- "lib/${ARCH}/libplugins_imageformats_qjpeg_${ARCH}.so",
- "lib/${ARCH}/libplugins_imageformats_qtga_${ARCH}.so",
- "lib/${ARCH}/libplugins_imageformats_qtiff_${ARCH}.so",
- "lib/${ARCH}/libplugins_imageformats_qwbmp_${ARCH}.so",
- "lib/${ARCH}/libplugins_imageformats_qwebp_${ARCH}.so",
- "lib/${ARCH}/libplugins_platforms_qtforandroid_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_debugger_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_inspector_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_local_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_messages_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_native_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_nativedebugger_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_profiler_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_preview_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_quickprofiler_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_server_${ARCH}.so",
- "lib/${ARCH}/libplugins_qmltooling_qmldbg_tcp_${ARCH}.so",
- "lib/${ARCH}/libqml_QtQuick.2_qtquick2plugin_${ARCH}.so",
- "lib/${ARCH}/libqml_QtQuick_Window.2_windowplugin_${ARCH}.so",
- "lib/${ARCH}/libQt5Core_${ARCH}.so",
- "lib/${ARCH}/libQt5Gui_${ARCH}.so",
- "lib/${ARCH}/libQt5Network_${ARCH}.so",
- "lib/${ARCH}/libQt5Qml_${ARCH}.so",
- "lib/${ARCH}/libQt5QuickParticles_${ARCH}.so",
- "lib/${ARCH}/libQt5Quick_${ARCH}.so",
- "lib/${ARCH}/libQt5QmlModels_${ARCH}.so",
- "lib/${ARCH}/libQt5QmlWorkerScript_${ARCH}.so",
- "lib/${ARCH}/libqmlapp_${ARCH}.so"});
- qmlAppMinistroExpectedFiles << commonFiles + expandArchs(ndkArchsForQt, {
- "resources.arsc",
- "assets/android_rcc_bundle.rcc",
- cxxLibPath("libgnustl_shared.so", true),
- "lib/${ARCH}/libqmlapp_${ARCH}.so"});
- qmlAppCustomMetaDataExpectedFiles << commonFiles + expandArchs(ndkArchsForQt, {
- "resources.arsc",
+ "lib/${ARCH}/libqmlapp.so"}, generateAab);
+ } else {
+ expectedFile << commonFiles(generateAab) + expandArchs(ndkArchsForQt, {
"assets/android_rcc_bundle.rcc",
"assets/dummyasset.txt",
cxxLibPath("libgnustl_shared.so", true),
@@ -486,61 +545,115 @@ void TestBlackboxAndroid::android_data()
"lib/${ARCH}/libQt5Quick_${ARCH}.so",
"lib/${ARCH}/libQt5QmlModels_${ARCH}.so",
"lib/${ARCH}/libQt5QmlWorkerScript_${ARCH}.so",
- "lib/${ARCH}/libqmlapp_${ARCH}.so"});
+ "lib/${ARCH}/libqmlapp_${ARCH}.so"}, generateAab);
+ }
+ if (generateAab)
+ expectedFile << "base/resources.pb" << "base/assets.pb" << "base/native.pb";
+ else
+ expectedFile << "resources.arsc";
+ return expectedFile;
+ };
+ QStringList qmlAppCustomProperties;
+ if (usingOldQt) {
+ qmlAppCustomProperties = QStringList{"modules.Android.sdk.automaticSources:false",
+ "modules.qbs.architecture:" + archsForQt.first()};
+ } else {
qmlAppCustomProperties = QStringList{"modules.Android.sdk.automaticSources:false"};
}
+
// aapt tool for the resources works with a directory option pointing to the parent directory
// of the resources (res).
// The Qt.android_support module adds res/values/libs.xml (from Qt install dir). So the res from
// Qt install res directory is added to aapt. This results in adding res/layout/splash.xml to
// the package eventhough the file is not needed.
// On the other hand aapt2 requires giving all the resources files.
- // Also when enabling aapt2 the resources.arsc is always created, eventhough no resources is
+ // Also when enabling aapt2 the resources.arsc is always created, eventhough no resources are
// declared.
enableAapt2 = false;
+ generateAab = false;
QTest::newRow("qml app")
<< "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << (QByteArrayList() << qmlAppExpectedFiles
+ << (QList<QByteArrayList>() << (QByteArrayList() << qmlAppExpectedFiles(generateAab)
<< "res/layout/splash.xml"))
- << (QStringList() << qmlAppCustomProperties << aaptVersion(enableAapt2)) << enableAapt2;
+ << (QStringList() << qmlAppCustomProperties << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild;
+
enableAapt2 = true;
- QTest::newRow("qml app")
+ QTest::newRow("qml app aapt2")
+ << "qml-app" << QStringList("qmlapp")
+ << (QList<QByteArrayList>() << qmlAppExpectedFiles(generateAab))
+ << (QStringList() << qmlAppCustomProperties << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ generateAab = true;
+ QTest::newRow("qml app aab")
<< "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << qmlAppExpectedFiles)
- << (QStringList() << qmlAppCustomProperties << aaptVersion(enableAapt2)) << enableAapt2;
+ << (QList<QByteArrayList>() << qmlAppExpectedFiles(generateAab))
+ << (QStringList() << qmlAppCustomProperties << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = false;
+ generateAab = false;
+ isIncrementalBuild = true;
QTest::newRow("qml app using Ministro")
<< "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << (QByteArrayList() << qmlAppMinistroExpectedFiles
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << qmlAppMinistroExpectedFiles(generateAab)
<< "res/layout/splash.xml"))
- << QStringList{"modules.Qt.android_support.useMinistro:true",
- "modules.Android.sdk.automaticSources:false",
- aaptVersion(enableAapt2)} << enableAapt2;
+ << (QStringList() << "modules.Qt.android_support.useMinistro:true"
+ << "modules.Android.sdk.automaticSources:false" << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = true;
- QTest::newRow("qml app using Ministro")
+ QTest::newRow("qml app using Ministro aapt2")
+ << "qml-app" << QStringList("qmlapp")
+ << (QList<QByteArrayList>() << qmlAppMinistroExpectedFiles(generateAab))
+ << (QStringList() << "modules.Qt.android_support.useMinistro:true"
+ << "modules.Android.sdk.automaticSources:false" << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ generateAab = true;
+ QTest::newRow("qml app using Ministro aab")
<< "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << qmlAppMinistroExpectedFiles)
- << QStringList{"modules.Qt.android_support.useMinistro:true",
- "modules.Android.sdk.automaticSources:false",
- aaptVersion(enableAapt2)} << enableAapt2;
+ << (QList<QByteArrayList>() << qmlAppMinistroExpectedFiles(generateAab))
+ << (QStringList() << "modules.Qt.android_support.useMinistro:true"
+ << "modules.Android.sdk.automaticSources:false" << aaptVersion(enableAapt2)
+ << packageType(generateAab))
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = false;
+ generateAab = false;
QTest::newRow("qml app with custom metadata")
<< "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << (QByteArrayList() << qmlAppCustomMetaDataExpectedFiles
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << qmlAppCustomMetaDataExpectedFiles(generateAab)
<< "res/layout/splash.xml"))
<< QStringList{"modules.Android.sdk.automaticSources:true",
- aaptVersion(enableAapt2)} << enableAapt2;
+ aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = true;
- QTest::newRow("qml app with custom metadata")
+ QTest::newRow("qml app with custom metadata aapt2")
<< "qml-app" << QStringList("qmlapp")
- << (QList<QByteArrayList>() << qmlAppCustomMetaDataExpectedFiles)
- << QStringList{"modules.Android.sdk.automaticSources:true",
- aaptVersion(enableAapt2)} << enableAapt2;
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << qmlAppCustomMetaDataExpectedFiles(generateAab)))
+ << QStringList{"modules.Android.sdk.automaticSources:true", aaptVersion(enableAapt2),
+ packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ generateAab = true;
+ QTest::newRow("qml app with custom metadata aab")
+ << "qml-app" << QStringList("qmlapp")
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << qmlAppCustomMetaDataExpectedFiles(generateAab)))
+ << QStringList{"modules.Android.sdk.automaticSources:true", aaptVersion(enableAapt2),
+ packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ isIncrementalBuild = false;
enableAapt2 = false;
+ generateAab = false;
QTest::newRow("no native")
<< "no-native"
<< QStringList("com.example.android.basicmediadecoder")
- << (QList<QByteArrayList>() << commonFiles + expandArchs(archs, {
+ << (QList<QByteArrayList>() << commonFiles(generateAab) + expandArchs(archs, {
"resources.arsc",
"res/drawable-hdpi-v4/ic_action_play_disabled.png",
"res/drawable-hdpi-v4/ic_action_play.png",
@@ -557,87 +670,151 @@ void TestBlackboxAndroid::android_data()
"res/layout/sample_main.xml",
"res/menu/action_menu.xml",
"res/menu-v11/action_menu.xml",
- "res/raw/vid_bigbuckbunny.mp4"}))
- << QStringList(aaptVersion(enableAapt2)) << enableAapt2;
+ "res/raw/vid_bigbuckbunny.mp4"}, generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = true;
- QTest::newRow("no native")
+ auto noNativeExpectedFiles = [&](bool generateAab) {
+ QByteArrayList expectedFile;
+ expectedFile << commonFiles(generateAab) + expandArchs(archs, {
+ "res/drawable-hdpi-v4/ic_action_play_disabled.png",
+ "res/drawable-hdpi-v4/ic_action_play.png",
+ "res/drawable-hdpi-v4/ic_launcher.png",
+ "res/drawable-hdpi-v4/tile.9.png",
+ "res/drawable-mdpi-v4/ic_action_play_disabled.png",
+ "res/drawable-mdpi-v4/ic_action_play.png",
+ "res/drawable-mdpi-v4/ic_launcher.png",
+ "res/drawable/selector_play.xml",
+ "res/drawable-xhdpi-v4/ic_action_play_disabled.png",
+ "res/drawable-xhdpi-v4/ic_action_play.png",
+ "res/drawable-xhdpi-v4/ic_launcher.png",
+ "res/drawable-xxhdpi-v4/ic_launcher.png",
+ "res/layout/sample_main.xml",
+ "res/menu/action_menu.xml",
+ // I have no idea why this file is generated with aapt and not with aapt2
+ //"res/menu-v11/action_menu.xml",
+ "res/raw/vid_bigbuckbunny.mp4"}, generateAab);
+ if (generateAab)
+ expectedFile << "base/resources.pb";
+ else
+ expectedFile << "resources.arsc";
+ return expectedFile;
+ };
+ QTest::newRow("no native aapt2")
<< "no-native"
<< QStringList("com.example.android.basicmediadecoder")
- << (QList<QByteArrayList>() << commonFiles + expandArchs(archs, {
- "resources.arsc",
- "res/drawable-hdpi-v4/ic_action_play_disabled.png",
- "res/drawable-hdpi-v4/ic_action_play.png",
- "res/drawable-hdpi-v4/ic_launcher.png",
- "res/drawable-hdpi-v4/tile.9.png",
- "res/drawable-mdpi-v4/ic_action_play_disabled.png",
- "res/drawable-mdpi-v4/ic_action_play.png",
- "res/drawable-mdpi-v4/ic_launcher.png",
- "res/drawable/selector_play.xml",
- "res/drawable-xhdpi-v4/ic_action_play_disabled.png",
- "res/drawable-xhdpi-v4/ic_action_play.png",
- "res/drawable-xhdpi-v4/ic_launcher.png",
- "res/drawable-xxhdpi-v4/ic_launcher.png",
- "res/layout/sample_main.xml",
- "res/menu/action_menu.xml",
- // I have no idea why this file is generated with aapt and not with aapt2
- //"res/menu-v11/action_menu.xml",
- "res/raw/vid_bigbuckbunny.mp4"}))
- << QStringList(aaptVersion(enableAapt2)) << enableAapt2;
+ << (QList<QByteArrayList>() << noNativeExpectedFiles(generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ generateAab = true;
+ QTest::newRow("no native aab")
+ << "no-native"
+ << QStringList("com.example.android.basicmediadecoder")
+ << (QList<QByteArrayList>() << noNativeExpectedFiles(generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = false;
+ generateAab = false;
QTest::newRow("aidl") << "aidl" << QStringList("io.qbs.aidltest")
- << (QList<QByteArrayList>() << (QByteArrayList() << commonFiles))
- << QStringList(aaptVersion(enableAapt2)) << enableAapt2;
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << commonFiles(generateAab)))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = true;
QTest::newRow("aidl") << "aidl" << QStringList("io.qbs.aidltest")
- << (QList<QByteArrayList>() << (QByteArrayList() << commonFiles
- << "resources.arsc"))
- << QStringList(aaptVersion(enableAapt2)) << enableAapt2;
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << commonFiles(generateAab)
+ << "resources.arsc"))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ generateAab = true;
+ QTest::newRow("aidl") << "aidl" << QStringList("io.qbs.aidltest")
+ << (QList<QByteArrayList>() << (QByteArrayList()
+ << commonFiles(generateAab)
+ << "base/resources.pb"))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = false;
+ generateAab = false;
QTest::newRow("multiple libs")
<< "multiple-libs-per-apk"
<< QStringList("twolibs")
- << (QList<QByteArrayList>() << commonFiles + expandArchs(archs, {
+ << (QList<QByteArrayList>() << commonFiles(generateAab) + expandArchs(archs, {
"resources.arsc",
"lib/${ARCH}/liblib1.so",
"lib/${ARCH}/liblib2.so",
- cxxLibPath("libstlport_shared.so", false)}))
- << QStringList(aaptVersion(enableAapt2)) << enableAapt2;
+ cxxLibPath("libstlport_shared.so", false)}, generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = true;
- QTest::newRow("multiple libs")
+ QTest::newRow("multiple libs aapt2")
<< "multiple-libs-per-apk"
<< QStringList("twolibs")
- << (QList<QByteArrayList>() << commonFiles + expandArchs(archs, {
+ << (QList<QByteArrayList>() << commonFiles(generateAab) + expandArchs(archs, {
"resources.arsc",
"lib/${ARCH}/liblib1.so",
"lib/${ARCH}/liblib2.so",
- cxxLibPath("libstlport_shared.so", false)}))
- << QStringList(aaptVersion(enableAapt2)) << enableAapt2;
- QByteArrayList expectedFiles1 = qbs::toList(qbs::toSet(commonFiles
- + expandArchs(QByteArrayList{"armeabi-v7a", "x86"}, {
- "resources.arsc",
- "lib/${ARCH}/libp1lib1.so",
- cxxLibPath("libstlport_shared.so", false)})
- + expandArchs(QByteArrayList{archs}, {
- "resources.arsc",
- "lib/${ARCH}/libp1lib2.so",
- cxxLibPath("libstlport_shared.so", false)})));
- QByteArrayList expectedFiles2 = commonFiles + expandArchs(archs, {
- "lib/${ARCH}/libp2lib1.so",
- "lib/${ARCH}/libp2lib2.so",
- cxxLibPath("libstlport_shared.so", false)});
+ cxxLibPath("libstlport_shared.so", false)}, generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ generateAab = true;
+ QTest::newRow("multiple libs aab")
+ << "multiple-libs-per-apk"
+ << QStringList("twolibs")
+ << (QList<QByteArrayList>() << commonFiles(generateAab) + expandArchs(archs, {
+ "resources.pb", "native.pb",
+ "lib/${ARCH}/liblib1.so",
+ "lib/${ARCH}/liblib2.so",
+ cxxLibPath("libstlport_shared.so", false)}, generateAab))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = false;
+ generateAab = false;
+ auto expectedFiles1 = [&](bool generateAab) {
+ QByteArrayList expectedFile = qbs::toList(qbs::toSet(commonFiles(generateAab)
+ + expandArchs(QByteArrayList{"armeabi-v7a", "x86"}, {
+ "lib/${ARCH}/libp1lib1.so",
+ cxxLibPath("libstlport_shared.so", false)}, generateAab)
+ + expandArchs(QByteArrayList{archs}, {
+ "lib/${ARCH}/libp1lib2.so",
+ cxxLibPath("libstlport_shared.so", false)}, generateAab)));
+ if (generateAab)
+ expectedFile << "base/resources.pb" << "base/native.pb";
+ else
+ expectedFile << "resources.arsc";
+ return expectedFile;
+ };
+ auto expectedFiles2 = [&](bool generateAab) {
+ QByteArrayList expectedFile = commonFiles(generateAab) + expandArchs(archs, {
+ "lib/${ARCH}/libp2lib1.so",
+ "lib/${ARCH}/libp2lib2.so",
+ cxxLibPath("libstlport_shared.so", false)}, generateAab);
+ return expectedFile;
+ };
+
QTest::newRow("multiple apks")
<< "multiple-apks-per-project"
<< (QStringList() << "twolibs1" << "twolibs2")
- << QList<QByteArrayList>{expectedFiles1, expectedFiles2}
- << QStringList(aaptVersion(enableAapt2)) << enableAapt2;
+ << QList<QByteArrayList>{expectedFiles1(generateAab), expectedFiles2(generateAab)}
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
enableAapt2 = true;
- expectedFiles2 << "resources.arsc";
- QTest::newRow("multiple apks")
+ QTest::newRow("multiple apks aapt2")
+ << "multiple-apks-per-project"
+ << (QStringList() << "twolibs1" << "twolibs2")
+ << (QList<QByteArrayList>() << expectedFiles1(generateAab)
+ << (QByteArrayList() << expectedFiles2(generateAab) << "resources.arsc"))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
+ generateAab = true;
+ QTest::newRow("multiple apks aab")
<< "multiple-apks-per-project"
<< (QStringList() << "twolibs1" << "twolibs2")
- << QList<QByteArrayList>{expectedFiles1, expectedFiles2}
- << QStringList(aaptVersion(enableAapt2)) << enableAapt2;
+ << (QList<QByteArrayList>() << expectedFiles1(generateAab)
+ << (QByteArrayList() << expectedFiles2(generateAab) << "base/resources.pb"
+ << "base/native.pb"))
+ << QStringList{aaptVersion(enableAapt2), packageType(generateAab)}
+ << enableAapt2 << generateAab << isIncrementalBuild;
}
QTEST_MAIN(TestBlackboxAndroid)