1 /* 2 * Copyright 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.baselineprofile.gradle.utils 18 19 import com.android.build.api.AndroidPluginVersion 20 import com.android.build.api.variant.Variant 21 import org.gradle.api.DefaultTask 22 import org.gradle.api.Project 23 import org.gradle.api.file.DirectoryProperty 24 import org.gradle.api.provider.Property 25 import org.gradle.api.tasks.Input 26 import org.gradle.api.tasks.OutputDirectory 27 import org.gradle.api.tasks.TaskAction 28 import org.gradle.work.DisableCachingByDefault 29 30 internal class R8Utils(private val project: Project) { 31 32 companion object { 33 private const val PROPERTY_R8_REWRITE_BASELINE_PROFILE_RULES = 34 "android.experimental.art-profile-r8-rewriting" 35 private const val PROPERTY_R8_DEX_LAYOUT_OPTIMIZATION = 36 "android.experimental.r8.dex-startup-optimization" 37 } 38 39 @Suppress("UnstableApiUsage") setRulesRewriteForVariantEnablednull40 fun setRulesRewriteForVariantEnabled(variant: Variant, value: Boolean) { 41 42 // Checks the AGP min version to support this. 43 if (project.agpVersion() < AndroidPluginVersion(8, 1, 0).alpha(8)) { 44 if (!project.isGradleSyncRunning()) { 45 throw IllegalStateException( 46 """ 47 Unable to set baseline profile rules rewrite property in module `${project.path}` 48 due to minimum AGP version requirement not met. This functionality requires at 49 least AGP version 8.1.0. Please check your module build.gradle file and ensure 50 the property `baselineProfileRulesRewrite` is not set. 51 """ 52 .trimIndent() 53 ) 54 } 55 return 56 } 57 58 // TODO: Note that currently there needs to be at least a baseline profile, 59 // even if empty. For this reason we always add a src set that points to 60 // an empty file. This can removed after b/271158087 is fixed. 61 if (value) GenerateDummyBaselineProfileTask.setupForVariant(project, variant) 62 63 // Sets the experimental property 64 variant.experimentalProperties.put(PROPERTY_R8_REWRITE_BASELINE_PROFILE_RULES, value) 65 } 66 67 @Suppress("UnstableApiUsage") setDexLayoutOptimizationEnablednull68 fun setDexLayoutOptimizationEnabled(variant: Variant, value: Boolean) { 69 70 // Checks the AGP min version to support this. 71 if (project.agpVersion() < AndroidPluginVersion(8, 1, 0).alpha(11)) { 72 if (!project.isGradleSyncRunning()) { 73 throw IllegalStateException( 74 """ 75 Unable to set dex layout optimization property in module `${project.path}` due to 76 minimum AGP version requirement not met. This functionality requires at least AGP 77 version 8.1.0. Please check your module build.gradle file and ensure the property 78 `dexLayoutOptimization` is not set. 79 """ 80 .trimIndent() 81 ) 82 } 83 } 84 85 // Sets the experimental property 86 variant.experimentalProperties.put(PROPERTY_R8_DEX_LAYOUT_OPTIMIZATION, value) 87 } 88 } 89 90 @DisableCachingByDefault(because = "Not worth caching.") 91 abstract class GenerateDummyBaselineProfileTask : DefaultTask() { 92 93 companion object { setupForVariantnull94 internal fun setupForVariant(project: Project, variant: Variant) { 95 val taskProvider = 96 project.tasks.maybeRegister<GenerateDummyBaselineProfileTask>( 97 "generate", 98 variant.name, 99 "profileForR8RuleRewrite" 100 ) { 101 it.outputDir.set( 102 project.layout.buildDirectory.dir( 103 "$INTERMEDIATES_BASE_FOLDER/${variant.name}/empty/" 104 ) 105 ) 106 it.variantName.set(variant.name) 107 } 108 @Suppress("UnstableApiUsage") 109 variant.sources.baselineProfiles?.addGeneratedSourceDirectory( 110 taskProvider, 111 GenerateDummyBaselineProfileTask::outputDir 112 ) 113 } 114 } 115 116 @get:OutputDirectory abstract val outputDir: DirectoryProperty 117 118 @get:Input abstract val variantName: Property<String> 119 120 @TaskAction execnull121 fun exec() { 122 outputDir.file("empty-baseline-prof.txt").get().asFile.writeText("Lignore/This;") 123 } 124 } 125