summaryrefslogtreecommitdiff
path: root/android/container.go
diff options
context:
space:
mode:
author Jihoon Kang <jihoonkang@google.com> 2024-07-01 17:04:46 +0000
committer Jihoon Kang <jihoonkang@google.com> 2024-08-28 18:01:25 +0000
commit2a88491afc72707c21a125b81f7dcd252d2fc5f1 (patch)
tree49f62c495320605e5f5792d702ea368adc8dc7f7 /android/container.go
parenta1527e5e23a517911891074a6b83dfe02823aef3 (diff)
Revert^2 "Implement detecting container violations."
This change introduces a method to detect violating inter-container dependencies between modules. The method is run in `ModuleBase.GenerateBuildActions`, after the container info provider is set. Given that the provider of the direct dependencies would have been set at this time, the method utilizes this information to determine the violations, which are introduced in https://r.android.com/3141104. Note that this enforcement does not turn all inter-container dependencies as errors. Instead, it will only turn dependencies that matches the pre-defined violations into errors. Even if the dependency matches the violation, an error will not be thrown if the dependency satisfies any of the exception functions (e.g. the dependent module is stubs, or the two modules belong to the same apexes). Test: m nothing --no-skip-soong-tests Bug: 338660802 Change-Id: Ia693c4a53369c757a3e96656a769405c759b111c
Diffstat (limited to 'android/container.go')
-rw-r--r--android/container.go65
1 files changed, 65 insertions, 0 deletions
diff --git a/android/container.go b/android/container.go
index 43dccf635..63fb362ad 100644
--- a/android/container.go
+++ b/android/container.go
@@ -15,8 +15,10 @@
package android
import (
+ "fmt"
"reflect"
"slices"
+ "strings"
"github.com/google/blueprint"
)
@@ -395,6 +397,40 @@ func (c *ContainersInfo) UpdatableApex() bool {
var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]()
+func satisfyAllowedExceptions(ctx ModuleContext, allowedExceptionLabels []exceptionHandleFuncLabel, m, dep Module) bool {
+ for _, label := range allowedExceptionLabels {
+ if exceptionHandleFunctionsTable[label](ctx, m, dep) {
+ return true
+ }
+ }
+ return false
+}
+
+func (c *ContainersInfo) GetViolations(mctx ModuleContext, m, dep Module, depInfo ContainersInfo) []string {
+ var violations []string
+
+ // Any containers that the module belongs to but the dependency does not belong to must be examined.
+ _, containersUniqueToModule, _ := ListSetDifference(c.belongingContainers, depInfo.belongingContainers)
+
+ // Apex container should be examined even if both the module and the dependency belong to
+ // the apex container to check that the two modules belong to the same apex.
+ if InList(ApexContainer, c.belongingContainers) && !InList(ApexContainer, containersUniqueToModule) {
+ containersUniqueToModule = append(containersUniqueToModule, ApexContainer)
+ }
+
+ for _, containerUniqueToModule := range containersUniqueToModule {
+ for _, restriction := range containerUniqueToModule.restricted {
+ if InList(restriction.dependency, depInfo.belongingContainers) {
+ if !satisfyAllowedExceptions(mctx, restriction.allowedExceptions, m, dep) {
+ violations = append(violations, restriction.errorMessage)
+ }
+ }
+ }
+ }
+
+ return violations
+}
+
func generateContainerInfo(ctx ModuleContext) ContainersInfo {
var containers []*container
@@ -436,3 +472,32 @@ func setContainerInfo(ctx ModuleContext) {
SetProvider(ctx, ContainersInfoProvider, containersInfo)
}
}
+
+func checkContainerViolations(ctx ModuleContext) {
+ if _, ok := ctx.Module().(InstallableModule); ok {
+ containersInfo, _ := getContainerModuleInfo(ctx, ctx.Module())
+ ctx.VisitDirectDepsIgnoreBlueprint(func(dep Module) {
+ if !dep.Enabled(ctx) {
+ return
+ }
+
+ // Pre-existing violating dependencies are tracked in containerDependencyViolationAllowlist.
+ // If this dependency is allowlisted, do not check for violation.
+ // If not, check if this dependency matches any restricted dependency and
+ // satisfies any exception functions, which allows bypassing the
+ // restriction. If all of the exceptions are not satisfied, throw an error.
+ if depContainersInfo, ok := getContainerModuleInfo(ctx, dep); ok {
+ if allowedViolations, ok := ContainerDependencyViolationAllowlist[ctx.ModuleName()]; ok && InList(dep.Name(), allowedViolations) {
+ return
+ } else {
+ violations := containersInfo.GetViolations(ctx, ctx.Module(), dep, depContainersInfo)
+ if len(violations) > 0 {
+ errorMessage := fmt.Sprintf("%s cannot depend on %s. ", ctx.ModuleName(), dep.Name())
+ errorMessage += strings.Join(violations, " ")
+ ctx.ModuleErrorf(errorMessage)
+ }
+ }
+ }
+ })
+ }
+}