<lambda>null1import com.android.build.api.variant.AndroidComponentsExtension 2 import com.android.build.api.variant.ComponentIdentity 3 import com.android.build.gradle.tasks.MergeResources 4 import org.gradle.api.Plugin 5 import org.gradle.api.Project 6 import org.gradle.api.artifacts.component.ProjectComponentIdentifier 7 import org.gradle.configurationcache.extensions.capitalized 8 9 /** 10 * Plugin that verifies that correct order is used for Google and AOSP SystemUI resources. When 11 * there are multiple modules with the same resource, AGP will use the order of the dependencies 12 * declaration. 13 * 14 * See https://developer.android.com/build/dependencies#dependency-order for more details 15 */ 16 abstract class VerifySystemUiResourceOrderPlugin : Plugin<Project> { 17 18 override fun apply(project: Project) { 19 project.extensions.configure(AndroidComponentsExtension::class.java) { 20 onVariants { variant -> 21 project.afterEvaluate { 22 val capitalizedVariantName = variant.name.capitalized() 23 val mergeTask = 24 project.tasks.named( 25 "merge${capitalizedVariantName}Resources", 26 MergeResources::class.java 27 ) 28 29 mergeTask.configure { doLast { verifyOrder(variant) } } 30 } 31 } 32 } 33 } 34 35 private fun MergeResources.verifyOrder(variant: ComponentIdentity) { 36 val projectPaths = librariesProjectPaths 37 38 // The lower the index, the higher is the priority 39 val googleResourcesPriority = projectPaths.indexOf(GOOGLE_RESOURCES_PROJECT) 40 val aospResourcesPriority = projectPaths.indexOf(AOSP_RESOURCES_PROJECT) 41 42 if (variant.isGoogleSpecific()) { 43 if (googleResourcesPriority == INDEX_NOT_FOUND) { 44 throw IllegalArgumentException( 45 "Project ${projectPath.get()} doesn't have $GOOGLE_RESOURCES_PROJECT dependency" 46 ) 47 } 48 if (aospResourcesPriority == INDEX_NOT_FOUND) { 49 throw IllegalArgumentException( 50 "Project ${projectPath.get()} doesn't have $AOSP_RESOURCES_PROJECT dependency" 51 ) 52 } 53 54 if (googleResourcesPriority > aospResourcesPriority) { 55 val prioritiesDescription = 56 "'$GOOGLE_RESOURCES_PROJECT' index: $googleResourcesPriority, " + 57 "'$AOSP_RESOURCES_PROJECT' index: $aospResourcesPriority" 58 59 throw IllegalArgumentException( 60 "Invalid resource dependencies order, expected Google resources " + 61 "($GOOGLE_RESOURCES_PROJECT) to have higher priority " + 62 "(earlier in the list) than AOSP resources " + 63 "($AOSP_RESOURCES_PROJECT) for task ${this.name}.\n\n" + 64 prioritiesDescription 65 ) 66 } 67 } 68 } 69 70 private val MergeResources.librariesProjectPaths: List<String> 71 get() = 72 resourcesComputer.libraries 73 .get() 74 .map { it.id.componentIdentifier } 75 .filterIsInstance<ProjectComponentIdentifier>() 76 .map { it.projectPath } 77 78 private fun ComponentIdentity.isGoogleSpecific(): Boolean = 79 name.contains("google", ignoreCase = true) || name.contains("titan", ignoreCase = true) 80 81 private companion object { 82 private const val GOOGLE_RESOURCES_PROJECT = ":sysuig-resources" 83 private const val AOSP_RESOURCES_PROJECT = ":SystemUI-res" 84 private const val INDEX_NOT_FOUND = -1 85 } 86 } 87