1/**
2 * This file was created using the `create_project.py` script located in the
3 * `<AndroidX root>/development/project-creator` directory.
4 *
5 * Please use that script when creating a new project, rather than copying an existing project and
6 * modifying its settings.
7 */
8import com.google.common.io.Files
9import org.apache.commons.compress.utils.IOUtils
10
11import java.util.zip.ZipEntry
12import java.util.zip.ZipFile
13
14/*
15 * Copyright (C) 2022 The Android Open Source Project
16 *
17 * Licensed under the Apache License, Version 2.0 (the "License");
18 * you may not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
20 *
21 *      http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS,
25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
28 */
29plugins {
30    id("AndroidXPlugin")
31    id("com.android.library")
32    id("org.jetbrains.kotlin.android")
33}
34
35// This task copies the apks provided by the `apkAssets` configuration and places them in the
36// assets folder. It also extracts the profiles to make them available to the test app.
37// This allows a build time generation of the sample apps.
38abstract class PrepareAssetsTask extends DefaultTask {
39
40    @InputFiles
41    @PathSensitive(PathSensitivity.NONE)
42    abstract ConfigurableFileCollection getApkAssetsFolders()
43
44    @OutputDirectory
45    abstract DirectoryProperty getOutputDir()
46
47    @TaskAction
48    void exec() {
49        for (File folder : apkAssetsFolders.files) {
50            for (File file : folder.listFiles()) {
51
52                // Consider only apk files (skip json metadata)
53                if (!file.name.endsWith(".apk")) {
54                    continue
55                }
56
57                // Copies the apk in the output dir
58                Files.copy(file, outputDir.file(file.name).get().asFile)
59
60                // Extract the profile in the apk and places it in the assets
61                if (file.getName().endsWith("-release.apk")) {
62                    ZipFile zipFile = new ZipFile(file)
63                    extractZipEntry(zipFile, "assets/dexopt/baseline.prof", "${file.name}_baseline.prof")
64                    extractZipEntry(zipFile, "assets/dexopt/baseline.profm", "${file.name}_baseline.profm")
65                }
66            }
67        }
68    }
69
70    private void extractZipEntry(ZipFile zipFile, String zipEntryName, String outputFileName) {
71        ZipEntry entry = zipFile.entries().find { it.name == zipEntryName }
72        File outputFile = outputDir.file(outputFileName).get().asFile
73        try (FileOutputStream os = new FileOutputStream(outputFile)) {
74            IOUtils.copy(zipFile.getInputStream(entry), os)
75        }
76    }
77}
78
79def prepareAssetsTaskProvider = tasks.register("prepareAssets", PrepareAssetsTask) {
80    description = "Copies the apks and profiles provided by profile-verification-sample projects into the assets."
81    apkAssetsFolders.from(configurations.getByName("apkAssets").incoming.artifactView {}.files)
82    outputDir.set(layout.buildDirectory.dir("intermediates/profile-verification-assets"))
83}
84
85androidx {
86    deviceTests {
87        enableAlsoRunningOnPhysicalDevices = true
88    }
89}
90
91android {
92    compileSdk = 35
93    defaultConfig {
94        minSdk = 23
95    }
96    sourceSets.androidTest.assets.srcDir(prepareAssetsTaskProvider.map { it.outputDir })
97    namespace = "androidx.profileinstaller.integration.profileverification"
98}
99
100// Define a configuration that can be resolved. This project is the consumer of test apks, i.e. it
101// contains the integration tests.
102configurations {
103    apkAssets {
104        canBeConsumed = false
105        canBeResolved = true
106        attributes {
107            attribute(
108                    LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
109                    objects.named(LibraryElements, 'profileverification-apkAssets')
110            )
111        }
112    }
113}
114
115dependencies {
116    androidTestImplementation(project(":profileinstaller:profileinstaller"))
117    androidTestImplementation(libs.testRules)
118    androidTestImplementation(libs.testExtJunit)
119    androidTestImplementation(libs.testCore)
120    androidTestImplementation(libs.testRunner)
121    androidTestImplementation(libs.testUiautomator)
122    androidTestImplementation(libs.testExtTruth)
123    androidTestImplementation("androidx.core:core:1.15.0")
124    apkAssets(project(":profileinstaller:integration-tests:profile-verification-sample"))
125    apkAssets(project(":profileinstaller:integration-tests:profile-verification-sample-no-initializer"))
126    apkAssets(project(":benchmark:integration-tests:baselineprofile-consumer"))
127}
128
129// It makes sure that the apks are generated before the assets are packed.
130afterEvaluate {
131    tasks.named("generateReleaseAndroidTestAssets").configure { it.dependsOn(prepareAssetsTaskProvider) }
132}
133