blob: 6000833e4e640617e70c731443058cdb18ee9f6a [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.build.gradle.integration.bundle
import com.android.build.gradle.integration.common.fixture.GradleTestProject
import com.android.build.gradle.integration.common.fixture.app.MinimalSubProject
import com.android.build.gradle.integration.common.fixture.app.MultiModuleTestProject
import com.android.build.gradle.integration.common.utils.getOutputByName
import com.android.build.gradle.integration.common.utils.getVariantByName
import com.android.build.gradle.options.StringOption
import com.android.builder.model.AppBundleProjectBuildOutput
import com.android.builder.model.AppBundleVariantBuildOutput
import com.android.testutils.apk.Zip
import com.android.testutils.truth.PathSubject.assertThat
import com.android.testutils.truth.PathSubject.assertThat
import com.google.common.truth.Truth
import org.junit.Rule
import org.junit.Test
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.test.fail
class TextureTargetedAssetPackTest {
private val textureTargetedAssetPackTestApp = MultiModuleTestProject.builder().apply {
val app = MinimalSubProject.app("com.example.texturetargetedassetpacktestapp")
.appendToBuild(
"""android.assetPacks = [':level1']"""
)
.appendToBuild(
"""android.bundle.texture.enableSplit = true;
|android.bundle.texture.defaultFormat = "etc2";""".trimMargin()
)
val level1 = MinimalSubProject.assetPack()
.appendToBuild(
"""assetPack {
| packName = "level1"
| dynamicDelivery {
| deliveryType = "install-time"
| }
|}""".trimMargin()
)
.withFile(
"src/main/assets/commonFile.txt",
"""This is an asset file for level 1."""
)
.withFile(
"src/main/assets/textures#tcf_astc/astc.txt",
"""ASTC texture"""
)
.withFile(
"src/main/assets/textures#tcf_etc2/etc2.txt",
"""ETC2 texture"""
)
subproject(":app", app)
subproject(":level1", level1)
}
.build()
@get:Rule
val project: GradleTestProject = GradleTestProject.builder()
.fromTestApp(textureTargetedAssetPackTestApp)
.create()
@Test
fun buildDebugApksForRecentAstcDevice() {
val apkFromBundleTaskName = getApkFromBundleTaskName("debug")
var jsonFile = getJsonFile(27, true)
project
.executor()
.with(StringOption.IDE_APK_SELECT_CONFIG, jsonFile.toString())
.run("app:$apkFromBundleTaskName")
// Fetch the build output model.
var apkFolder = getApkFolderOutput("debug").apkFolder
assertThat(apkFolder).isDirectory()
// Verify the installed apks.
var apkFileArray = apkFolder.list() ?: fail("No Files at $apkFolder")
Truth.assertThat(apkFileArray.toList()).named("APK List")
.containsExactly(
"level1-master.apk",
"level1-astc.apk",
"base-master.apk",
"base-xxhdpi.apk"
)
// Verify the content of the asset-pack apks.
val level1MasterApk = File(apkFolder, "level1-master.apk")
Zip(level1MasterApk).use {
Truth.assertThat(it.entries.map { it.toString() })
.contains("/assets/commonFile.txt")
}
val level1AstcApk = File(apkFolder, "level1-astc.apk")
Zip(level1AstcApk).use {
Truth.assertThat(it.entries.map { it.toString() })
.contains("/assets/textures/astc.txt")
}
}
@Test
fun buildDebugApksForRecentEtc2Device() {
val apkFromBundleTaskName = getApkFromBundleTaskName("debug")
var jsonFile = getJsonFile(27, false)
project
.executor()
.with(StringOption.IDE_APK_SELECT_CONFIG, jsonFile.toString())
.run("app:$apkFromBundleTaskName")
// Fetch the build output model.
var apkFolder = getApkFolderOutput("debug").apkFolder
assertThat(apkFolder).isDirectory()
// Verify the installed apks.
var apkFileArray = apkFolder.list() ?: fail("No Files at $apkFolder")
Truth.assertThat(apkFileArray.toList()).named("APK List")
.containsExactly(
"level1-master.apk",
"level1-etc2.apk",
"base-master.apk",
"base-xxhdpi.apk"
)
// Verify the content of the asset-pack apks.
val level1MasterApk = File(apkFolder, "level1-master.apk")
Zip(level1MasterApk).use {
Truth.assertThat(it.entries.map { it.toString() })
.contains("/assets/commonFile.txt")
}
val level1Etc2Apk = File(apkFolder, "level1-etc2.apk")
Zip(level1Etc2Apk).use {
Truth.assertThat(it.entries.map { it.toString() })
.contains("/assets/textures/etc2.txt")
}
}
@Test
fun buildStandaloneDebugApksForPreLDevice() {
val apkFromBundleTaskName = getApkFromBundleTaskName("debug")
var jsonFile = getJsonFile(18, false)
project
.executor()
.with(StringOption.IDE_APK_SELECT_CONFIG, jsonFile.toString())
.run("app:$apkFromBundleTaskName")
// Fetch the build output model.
var apkFolder = getApkFolderOutput("debug").apkFolder
assertThat(apkFolder).isDirectory()
// Verify the installed standalone apk.
var apkFileArray = apkFolder.list() ?: fail("No Files at $apkFolder")
Truth.assertThat(apkFileArray.toList()).named("APK List")
.containsExactly("standalone-etc2.apk")
val standaloneEtc2Apk = File(apkFolder, "standalone-etc2.apk")
Zip(standaloneEtc2Apk).use {
Truth.assertThat(it.entries.map { it.toString() })
.containsAllOf(
"/assets/commonFile.txt",
"/assets/textures/etc2.txt"
)
}
}
private fun getApkFromBundleTaskName(name: String): String {
// Query the model to get the task name.
val syncModels = project.model()
.fetchAndroidProjects()
val appModel =
syncModels.rootBuildModelMap[":app"] ?: fail("Failed to get sync model for :app module")
val debugArtifact = appModel.getVariantByName(name).mainArtifact
return debugArtifact.apkFromBundleTaskName
?: fail("Module App does not have apkFromBundle task name")
}
private fun getApkFolderOutput(variantName: String): AppBundleVariantBuildOutput {
val outputModels = project.model()
.fetchContainer(AppBundleProjectBuildOutput::class.java)
val outputAppModel = outputModels.rootBuildModelMap[":app"]
?: fail("Failed to get output model for :app module")
return outputAppModel.getOutputByName(variantName)
}
private fun getJsonFile(api: Int, supportsAstc: Boolean): Path {
val tempFile = Files.createTempFile("", "texture-target-asset-pack-app-test")
val glExtension = if (supportsAstc) "GL_KHR_texture_compression_astc_ldr" else ""
Files.write(
tempFile, listOf(
"""{ "supportedAbis": [ "X86", "ARMEABI_V7A" ],
| "supportedLocales": [ "en", "fr" ],
| "screenDensity": 480,
| "deviceFeatures": ["reqGlEsVersion=0x30000"],
| "glExtensions": ["$glExtension", "GL_EXT_debug_marker"],
| "sdkVersion": $api
| }""".trimMargin()
)
)
return tempFile
}
}