Unverified Commit 2466ca5b authored by Emmanuel Garcia's avatar Emmanuel Garcia Committed by GitHub

Copy Flutter assets before merging the rest of resources (#41333)

parent 2b138fd7
......@@ -20,7 +20,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
...flutterAssets,
'classes.dex',
'assets/flutter_assets/isolate_snapshot_data',
'assets/flutter_assets/kernel_blob.bin',
......@@ -47,7 +47,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
...flutterAssets,
'classes.dex',
'lib/arm64-v8a/libflutter.so',
'lib/arm64-v8a/libapp.so',
......@@ -70,7 +70,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
...flutterAssets,
'classes.dex',
'lib/armeabi-v7a/libflutter.so',
'lib/armeabi-v7a/libapp.so',
......@@ -94,7 +94,7 @@ Future<void> main() async {
final Iterable<String> armApkFiles = await getFilesInApk(pluginProject.releaseArmApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
...flutterAssets,
'classes.dex',
'lib/armeabi-v7a/libflutter.so',
'lib/armeabi-v7a/libapp.so',
......@@ -109,7 +109,7 @@ Future<void> main() async {
final Iterable<String> arm64ApkFiles = await getFilesInApk(pluginProject.releaseArm64ApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
...flutterAssets,
'classes.dex',
'lib/arm64-v8a/libflutter.so',
'lib/arm64-v8a/libapp.so',
......@@ -134,13 +134,14 @@ Future<void> main() async {
];
for (final String targetPlatform in targetPlatforms) {
final String androidArmSnapshotPath = path.join(
project.rootPath,
'build',
'app',
'intermediates',
'flutter',
'release',
targetPlatform);
project.rootPath,
'build',
'app',
'intermediates',
'flutter',
'release',
targetPlatform,
);
final String sharedLibrary = path.join(androidArmSnapshotPath, 'app.so');
if (!File(sharedLibrary).existsSync()) {
......
......@@ -20,7 +20,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
...flutterAssets,
'classes.dex',
'assets/flutter_assets/isolate_snapshot_data',
'assets/flutter_assets/kernel_blob.bin',
......@@ -47,7 +47,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
...flutterAssets,
'classes.dex',
'assets/flutter_assets/isolate_snapshot_data',
'assets/flutter_assets/kernel_blob.bin',
......@@ -73,7 +73,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.debugApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
...flutterAssets,
'classes.dex',
'assets/flutter_assets/isolate_snapshot_data',
'assets/flutter_assets/kernel_blob.bin',
......@@ -98,7 +98,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
...flutterAssets,
'classes.dex',
'lib/armeabi-v7a/libflutter.so',
'lib/armeabi-v7a/libapp.so',
......@@ -121,7 +121,7 @@ Future<void> main() async {
final Iterable<String> apkFiles = await getFilesInApk(pluginProject.releaseApkPath);
checkItContains<String>(<String>[
'AndroidManifest.xml',
...flutterAssets,
'classes.dex',
'lib/arm64-v8a/libflutter.so',
'lib/arm64-v8a/libapp.so',
......
......@@ -65,14 +65,30 @@ Future<void> main() async {
Directory(path.join(hostAppDir.path, 'gradle', 'wrapper')),
);
final Function clean = () async {
section('Clean');
await inDirectory(hostAppDir, () async {
await exec(gradlewExecutable,
<String>['clean'],
environment: <String, String>{
'JAVA_HOME': javaHome,
},
);
});
};
if (!Platform.isWindows) {
section('Make $gradlewExecutable executable');
await inDirectory(hostAppDir, () async {
await exec('chmod', <String>['+x', gradlewExecutable]);
});
}
section('Build debug APKs');
section('Run app:assembleDemoDebug');
await inDirectory(hostAppDir, () async {
if (!Platform.isWindows) {
await exec('chmod', <String>['+x', 'gradlew']);
}
await exec(gradlewExecutable,
<String>['app:assembleDemoDebug'],
environment: <String, String>{
......@@ -98,31 +114,63 @@ Future<void> main() async {
section('Verify snapshots in app-demo-debug.apk');
final Iterable<String> demoDebugFiles = await getFilesInApk(demoDebugApk);
checkItContains<String>(<String>[
...flutterAssets,
'assets/flutter_assets/isolate_snapshot_data',
'assets/flutter_assets/kernel_blob.bin',
'assets/flutter_assets/vm_snapshot_data',
], demoDebugFiles);
], await getFilesInApk(demoDebugApk));
await clean();
section('Clean');
// Change the order of the task and ensure that flutter_assets are in the APK.
// https://github.com/flutter/flutter/pull/41333
section('Run app:assembleDemoDebug - Merge assets before processing manifest');
await inDirectory(hostAppDir, () async {
await exec(gradlewExecutable,
<String>['clean'],
<String>[
// Normally, `app:processDemoDebugManifest` runs before `app:mergeDemoDebugAssets`.
// In this case, we run `app:mergeDemoDebugAssets` first.
'app:mergeDemoDebugAssets',
'app:processDemoDebugManifest',
'app:assembleDemoDebug',
],
environment: <String, String>{
'JAVA_HOME': javaHome,
},
);
});
final String demoDebugApk2 = path.join(
hostAppDir.path,
'app',
'build',
'outputs',
'apk',
'demo',
'debug',
'app-demo-debug.apk',
);
if (!exists(File(demoDebugApk2))) {
return TaskResult.failure('Failed to build app-demo-debug.apk');
}
section('Verify snapshots in app-demo-debug.apk');
checkItContains<String>(<String>[
...flutterAssets,
'assets/flutter_assets/isolate_snapshot_data',
'assets/flutter_assets/kernel_blob.bin',
'assets/flutter_assets/vm_snapshot_data',
], await getFilesInApk(demoDebugApk2));
await clean();
section('Run app:assembleDemoStaging');
await inDirectory(hostAppDir, () async {
if (!Platform.isWindows) {
await exec('chmod', <String>['+x', 'gradlew']);
}
await inDirectory(hostAppDir, () async {
await exec(gradlewExecutable,
<String>['app:assembleDemoStaging'],
environment: <String, String>{
......@@ -148,33 +196,20 @@ Future<void> main() async {
section('Verify snapshots in app-demo-staging.apk');
final Iterable<String> demoStagingFiles = await getFilesInApk(demoStagingApk);
checkItContains<String>(<String>[
...flutterAssets,
'assets/flutter_assets/isolate_snapshot_data',
'assets/flutter_assets/kernel_blob.bin',
'assets/flutter_assets/vm_snapshot_data',
], demoStagingFiles);
], await getFilesInApk(demoStagingApk));
section('Clean');
await inDirectory(hostAppDir, () async {
await exec(gradlewExecutable,
<String>['clean'],
environment: <String, String>{
'JAVA_HOME': javaHome,
},
);
});
await clean();
section('Build release APKs');
section('Run app:assembleDemoRelease');
await inDirectory(hostAppDir, () async {
if (!Platform.isWindows) {
await exec('chmod', <String>['+x', 'gradlew']);
}
await exec(gradlewExecutable,
<String>['app:assembleDemoRelease'],
environment: <String, String>{
......@@ -200,32 +235,19 @@ Future<void> main() async {
section('Verify AOT blobs in app-demo-release-unsigned.apk');
final Iterable<String> demoReleaseFiles = await getFilesInApk(demoReleaseApk);
checkItContains<String>(<String>[
...flutterAssets,
'lib/arm64-v8a/libapp.so',
'lib/arm64-v8a/libflutter.so',
'lib/armeabi-v7a/libapp.so',
'lib/armeabi-v7a/libflutter.so',
], demoReleaseFiles);
section('Clean');
], await getFilesInApk(demoReleaseApk));
await inDirectory(hostAppDir, () async {
await exec(gradlewExecutable,
<String>['clean'],
environment: <String, String>{
'JAVA_HOME': javaHome,
},
);
});
await clean();
section('Run app:assembleDemoProd');
await inDirectory(hostAppDir, () async {
if (!Platform.isWindows) {
await exec('chmod', <String>['+x', 'gradlew']);
}
await exec(gradlewExecutable,
<String>['app:assembleDemoProd'],
environment: <String, String>{
......@@ -251,14 +273,13 @@ Future<void> main() async {
section('Verify AOT blobs in app-demo-prod-unsigned.apk');
final Iterable<String> demoProdFiles = await getFilesInApk(demoProdApk);
checkItContains<String>(<String>[
...flutterAssets,
'lib/arm64-v8a/libapp.so',
'lib/arm64-v8a/libflutter.so',
'lib/armeabi-v7a/libapp.so',
'lib/armeabi-v7a/libflutter.so',
], demoProdFiles);
...flutterAssets,
'lib/arm64-v8a/libapp.so',
'lib/arm64-v8a/libflutter.so',
'lib/armeabi-v7a/libapp.so',
'lib/armeabi-v7a/libflutter.so',
], await getFilesInApk(demoProdApk));
return TaskResult.success(null);
} on TaskResult catch (taskResult) {
......
......@@ -576,12 +576,13 @@ class FlutterPlugin implements Plugin<Project> {
}
}
}
def compileTasks = targetPlatforms.collect { targetArch ->
String variantBuildMode = buildModeFor(variant.buildType)
List<FlutterTask> compileTasks = targetPlatforms.collect { targetArch ->
String taskName = toCammelCase(["compile", FLUTTER_BUILD_PREFIX, variant.name, targetArch.replace('android-', '')])
project.tasks.create(name: taskName, type: FlutterTask) {
flutterRoot this.flutterRoot
flutterExecutable this.flutterExecutable
buildMode buildModeFor(variant.buildType)
buildMode variantBuildMode
localEngine this.localEngine
localEngineSrcPath this.localEngineSrcPath
abi PLATFORM_ARCH_MAP[targetArch]
......@@ -601,7 +602,7 @@ class FlutterPlugin implements Plugin<Project> {
extraGenSnapshotOptions extraGenSnapshotOptionsValue
}
}
def libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar")
File libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar")
Task packFlutterAppAotTask = project.tasks.create(name: "packLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}", type: Jar) {
destinationDir libJar.parentFile
archiveName libJar.name
......@@ -619,33 +620,70 @@ class FlutterPlugin implements Plugin<Project> {
addApiDependencies(project, variant.name, project.files {
packFlutterAppAotTask
})
// We know that the flutter app is a subproject in another Android app when these tasks exist.
Task packageAssets = project.tasks.findByPath(":flutter:package${variant.name.capitalize()}Assets")
Task cleanPackageAssets = project.tasks.findByPath(":flutter:cleanPackage${variant.name.capitalize()}Assets")
// In add to app scenarios, :flutter is a subproject of another Android app.
// We know that :flutter is used as a subproject when these tasks exist.
boolean isUsedAsSubproject = packageAssets && cleanPackageAssets
Task copyFlutterAssetsTask = project.tasks.create(name: "copyFlutterAssets${variant.name.capitalize()}", type: Copy) {
dependsOn compileTasks
if (packageAssets && cleanPackageAssets) {
compileTasks.each { flutterTask ->
// Add flutter_assets.
with flutterTask.assets
}
if (isUsedAsSubproject) {
dependsOn packageAssets
dependsOn cleanPackageAssets
into packageAssets.outputDir
} else {
// `variant.mergeAssets` will be removed at the end of 2019.
def mergeAssets = variant.hasProperty("mergeAssetsProvider") ?
variant.mergeAssetsProvider.get() : variant.mergeAssets
dependsOn mergeAssets
dependsOn "clean${mergeAssets.name.capitalize()}"
mergeAssets.mustRunAfter("clean${mergeAssets.name.capitalize()}")
into mergeAssets.outputDir
return
}
compileTasks.each { flutterTask ->
with flutterTask.assets
// `variant.mergeAssets` will be removed at the end of 2019.
def mergeAssets = variant.hasProperty("mergeAssetsProvider") ?
variant.mergeAssetsProvider.get() : variant.mergeAssets
dependsOn mergeAssets
dependsOn "clean${mergeAssets.name.capitalize()}"
mergeAssets.mustRunAfter("clean${mergeAssets.name.capitalize()}")
into mergeAssets.outputDir
}
if (!isUsedAsSubproject) {
variant.mergeResources.dependsOn(copyFlutterAssetsTask)
return
}
// Flutter module included as a subproject in add to app.
Project appProject = project.rootProject.findProject(':app')
assert appProject != null
appProject.afterEvaluate {
assert appProject.android != null
appProject.android.applicationVariants.all { appProjectVariant ->
// Find a compatible application variant in the host app.
//
// For example, consider a host app that defines the following variants:
// | ----------------- | ----------------------------- |
// | Build Variant | Flutter Equivalent Variant |
// | ----------------- | ----------------------------- |
// | freeRelease | relese |
// | freeDebug | debug |
// | freeDevelop | debug |
// | profile | profile |
// | ----------------- | ----------------------------- |
//
// This mapping is based on the following rules:
// 1. If the host app build variant name is `profile` then the equivalent
// Flutter variant is `profile`.
// 2. If the host app build variant is debuggable
// (e.g. `buildType.debuggable = true`), then the equivalent Flutter
// variant is `debug`.
// 3. Otherwise, the equivalent Flutter variant is `release`.
if (buildModeFor(appProjectVariant.buildType) != variantBuildMode) {
return
}
Task mergeAssets = project
.tasks
.findByPath(":app:merge${appProjectVariant.name.capitalize()}Assets")
assert mergeAssets
mergeAssets.dependsOn(copyFlutterAssetsTask)
}
}
def variantOutput = variant.outputs.first()
// `variantOutput.processResources` will be removed at the end of 2019.
def processResources = variantOutput.hasProperty("processResourcesProvider") ?
variantOutput.processResourcesProvider.get() : variantOutput.processResources
processResources.dependsOn(copyFlutterAssetsTask)
}
if (project.android.hasProperty("applicationVariants")) {
project.android.applicationVariants.all addFlutterDeps
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment