Merge changes Ia0e1b307,I63c7c33e into main am: a5289ac9ef

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/3216639

Change-Id: I5de31ae329756b4fd028e58e1bf9299eb3ad8347
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2024-08-17 04:43:09 +00:00
committed by Automerger Merge Worker
5 changed files with 229 additions and 19 deletions

View File

@@ -43,16 +43,86 @@ var depIsStubsModule exceptionHandleFunc = func(_ ModuleContext, _, dep Module)
return false return false
} }
// Returns true if the dependency module belongs to any of the apexes.
var depIsApexModule exceptionHandleFunc = func(mctx ModuleContext, _, dep Module) bool {
depContainersInfo, _ := getContainerModuleInfo(mctx, dep)
return InList(ApexContainer, depContainersInfo.belongingContainers)
}
// Returns true if the module and the dependent module belongs to common apexes.
var belongsToCommonApexes exceptionHandleFunc = func(mctx ModuleContext, m, dep Module) bool {
mContainersInfo, _ := getContainerModuleInfo(mctx, m)
depContainersInfo, _ := getContainerModuleInfo(mctx, dep)
return HasIntersection(mContainersInfo.ApexNames(), depContainersInfo.ApexNames())
}
// Returns true when all apexes that the module belongs to are non updatable.
// For an apex module to be allowed to depend on a non-apex partition module,
// all apexes that the module belong to must be non updatable.
var belongsToNonUpdatableApex exceptionHandleFunc = func(mctx ModuleContext, m, _ Module) bool {
mContainersInfo, _ := getContainerModuleInfo(mctx, m)
return !mContainersInfo.UpdatableApex()
}
// Returns true if the dependency is added via dependency tags that are not used to tag dynamic
// dependency tags.
var depIsNotDynamicDepTag exceptionHandleFunc = func(ctx ModuleContext, m, dep Module) bool {
mInstallable, _ := m.(InstallableModule)
depTag := ctx.OtherModuleDependencyTag(dep)
return !InList(depTag, mInstallable.DynamicDependencyTags())
}
// Returns true if the dependency is added via dependency tags that are not used to tag static
// or dynamic dependency tags. These dependencies do not affect the module in compile time or in
// runtime, thus are not significant enough to raise an error.
var depIsNotStaticOrDynamicDepTag exceptionHandleFunc = func(ctx ModuleContext, m, dep Module) bool {
mInstallable, _ := m.(InstallableModule)
depTag := ctx.OtherModuleDependencyTag(dep)
return !InList(depTag, append(mInstallable.StaticDependencyTags(), mInstallable.DynamicDependencyTags()...))
}
var globallyAllowlistedDependencies = []string{
// Modules that provide annotations used within the platform and apexes.
"aconfig-annotations-lib",
"framework-annotations-lib",
"unsupportedappusage",
// framework-res provides core resources essential for building apps and system UI.
// This module is implicitly added as a dependency for java modules even when the
// dependency specifies sdk_version.
"framework-res",
}
// Returns true when the dependency is globally allowlisted for inter-container dependency
var depIsGloballyAllowlisted exceptionHandleFunc = func(_ ModuleContext, _, dep Module) bool {
return InList(dep.Name(), globallyAllowlistedDependencies)
}
// Labels of exception functions, which are used to determine special dependencies that allow // Labels of exception functions, which are used to determine special dependencies that allow
// otherwise restricted inter-container dependencies // otherwise restricted inter-container dependencies
type exceptionHandleFuncLabel int type exceptionHandleFuncLabel int
const ( const (
checkStubs exceptionHandleFuncLabel = iota checkStubs exceptionHandleFuncLabel = iota
checkApexModule
checkInCommonApexes
checkApexIsNonUpdatable
checkNotDynamicDepTag
checkNotStaticOrDynamicDepTag
checkGlobalAllowlistedDep
) )
// Map of [exceptionHandleFuncLabel] to the [exceptionHandleFunc]
var exceptionHandleFunctionsTable = map[exceptionHandleFuncLabel]exceptionHandleFunc{ var exceptionHandleFunctionsTable = map[exceptionHandleFuncLabel]exceptionHandleFunc{
checkStubs: depIsStubsModule, checkStubs: depIsStubsModule,
checkApexModule: depIsApexModule,
checkInCommonApexes: belongsToCommonApexes,
checkApexIsNonUpdatable: belongsToNonUpdatableApex,
checkNotDynamicDepTag: depIsNotDynamicDepTag,
checkNotStaticOrDynamicDepTag: depIsNotStaticOrDynamicDepTag,
checkGlobalAllowlistedDep: depIsGloballyAllowlisted,
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -108,13 +178,40 @@ var ctsContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bo
return false return false
} }
type unstableInfo struct {
// Determines if the module contains the private APIs of the platform.
ContainsPlatformPrivateApis bool
}
var unstableInfoProvider = blueprint.NewProvider[unstableInfo]()
func determineUnstableModule(mctx ModuleContext) bool {
module := mctx.Module()
unstableModule := module.Name() == "framework-minus-apex"
if installable, ok := module.(InstallableModule); ok {
for _, staticDepTag := range installable.StaticDependencyTags() {
mctx.VisitDirectDepsWithTag(staticDepTag, func(dep Module) {
if unstableInfo, ok := OtherModuleProvider(mctx, dep, unstableInfoProvider); ok {
unstableModule = unstableModule || unstableInfo.ContainsPlatformPrivateApis
}
})
}
}
return unstableModule
}
var unstableContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bool {
return determineUnstableModule(mctx)
}
// Map of [*container] to the [containerBoundaryFunc] // Map of [*container] to the [containerBoundaryFunc]
var containerBoundaryFunctionsTable = map[*container]containerBoundaryFunc{ var containerBoundaryFunctionsTable = map[*container]containerBoundaryFunc{
VendorContainer: vendorContainerBoundaryFunc, VendorContainer: vendorContainerBoundaryFunc,
SystemContainer: systemContainerBoundaryFunc, SystemContainer: systemContainerBoundaryFunc,
ProductContainer: productContainerBoundaryFunc, ProductContainer: productContainerBoundaryFunc,
ApexContainer: apexContainerBoundaryFunc, ApexContainer: apexContainerBoundaryFunc,
CtsContainer: ctsContainerBoundaryFunc, CtsContainer: ctsContainerBoundaryFunc,
UnstableContainer: unstableContainerBoundaryFunc,
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -122,7 +219,9 @@ var containerBoundaryFunctionsTable = map[*container]containerBoundaryFunc{
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
type InstallableModule interface { type InstallableModule interface {
EnforceApiContainerChecks() bool ContainersInfo() ContainersInfo
StaticDependencyTags() []blueprint.DependencyTag
DynamicDependencyTags() []blueprint.DependencyTag
} }
type restriction struct { type restriction struct {
@@ -160,7 +259,11 @@ var (
"not allowed to depend on the vendor partition module, in order to support " + "not allowed to depend on the vendor partition module, in order to support " +
"independent development/update cycles and to support the Generic System " + "independent development/update cycles and to support the Generic System " +
"Image. Try depending on HALs, VNDK or AIDL instead.", "Image. Try depending on HALs, VNDK or AIDL instead.",
allowedExceptions: []exceptionHandleFuncLabel{}, allowedExceptions: []exceptionHandleFuncLabel{
checkStubs,
checkNotDynamicDepTag,
checkGlobalAllowlistedDep,
},
}, },
}, },
} }
@@ -173,7 +276,11 @@ var (
errorMessage: "Module belonging to the product partition is not allowed to " + errorMessage: "Module belonging to the product partition is not allowed to " +
"depend on the vendor partition module, as this may lead to security " + "depend on the vendor partition module, as this may lead to security " +
"vulnerabilities. Try depending on the HALs or utilize AIDL instead.", "vulnerabilities. Try depending on the HALs or utilize AIDL instead.",
allowedExceptions: []exceptionHandleFuncLabel{}, allowedExceptions: []exceptionHandleFuncLabel{
checkStubs,
checkNotDynamicDepTag,
checkGlobalAllowlistedDep,
},
}, },
}, },
} }
@@ -184,22 +291,34 @@ var (
name: "cts", name: "cts",
restricted: []restriction{ restricted: []restriction{
{ {
dependency: SystemContainer, dependency: UnstableContainer,
errorMessage: "CTS module should not depend on the modules belonging to the " + errorMessage: "CTS module should not depend on the modules that contain the " +
"system partition, including \"framework\". Depending on the system " + "platform implementation details, including \"framework\". Depending on these " +
"partition may lead to disclosure of implementation details and regression " + "modules may lead to disclosure of implementation details and regression " +
"due to API changes across platform versions. Try depending on the stubs instead.", "due to API changes across platform versions. Try depending on the stubs instead " +
allowedExceptions: []exceptionHandleFuncLabel{checkStubs}, "and ensure that the module sets an appropriate 'sdk_version'.",
allowedExceptions: []exceptionHandleFuncLabel{
checkStubs,
checkNotStaticOrDynamicDepTag,
checkGlobalAllowlistedDep,
},
}, },
}, },
} }
// Container signifying that the module contains unstable platform private APIs
UnstableContainer = &container{
name: "unstable",
restricted: nil,
}
allContainers = []*container{ allContainers = []*container{
VendorContainer, VendorContainer,
SystemContainer, SystemContainer,
ProductContainer, ProductContainer,
ApexContainer, ApexContainer,
CtsContainer, CtsContainer,
UnstableContainer,
} }
) )
@@ -213,7 +332,14 @@ func initializeApexContainer() *container {
"modules belonging to the system partition. Either statically depend on the " + "modules belonging to the system partition. Either statically depend on the " +
"module or convert the depending module to java_sdk_library and depend on " + "module or convert the depending module to java_sdk_library and depend on " +
"the stubs.", "the stubs.",
allowedExceptions: []exceptionHandleFuncLabel{checkStubs}, allowedExceptions: []exceptionHandleFuncLabel{
checkStubs,
checkApexModule,
checkInCommonApexes,
checkApexIsNonUpdatable,
checkNotStaticOrDynamicDepTag,
checkGlobalAllowlistedDep,
},
}, },
}, },
} }
@@ -224,7 +350,12 @@ func initializeApexContainer() *container {
"modules belonging to other Apex(es). Either include the depending " + "modules belonging to other Apex(es). Either include the depending " +
"module in the Apex or convert the depending module to java_sdk_library " + "module in the Apex or convert the depending module to java_sdk_library " +
"and depend on its stubs.", "and depend on its stubs.",
allowedExceptions: []exceptionHandleFuncLabel{checkStubs}, allowedExceptions: []exceptionHandleFuncLabel{
checkStubs,
checkInCommonApexes,
checkNotStaticOrDynamicDepTag,
checkGlobalAllowlistedDep,
},
}) })
return apexContainer return apexContainer
@@ -280,9 +411,24 @@ func generateContainerInfo(ctx ModuleContext) ContainersInfo {
} }
} }
func getContainerModuleInfo(ctx ModuleContext, module Module) (ContainersInfo, bool) {
if ctx.Module() == module {
return module.ContainersInfo(), true
}
return OtherModuleProvider(ctx, module, ContainersInfoProvider)
}
func setContainerInfo(ctx ModuleContext) { func setContainerInfo(ctx ModuleContext) {
// Required to determine the unstable container. This provider is set here instead of the
// unstableContainerBoundaryFunc in order to prevent setting the provider multiple times.
SetProvider(ctx, unstableInfoProvider, unstableInfo{
ContainsPlatformPrivateApis: determineUnstableModule(ctx),
})
if _, ok := ctx.Module().(InstallableModule); ok { if _, ok := ctx.Module().(InstallableModule); ok {
containersInfo := generateContainerInfo(ctx) containersInfo := generateContainerInfo(ctx)
ctx.Module().base().containersInfo = containersInfo
SetProvider(ctx, ContainersInfoProvider, containersInfo) SetProvider(ctx, ContainersInfoProvider, containersInfo)
} }
} }

View File

@@ -118,6 +118,9 @@ type Module interface {
TransitivePackagingSpecs() []PackagingSpec TransitivePackagingSpecs() []PackagingSpec
ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator
// Get the information about the containers this module belongs to.
ContainersInfo() ContainersInfo
} }
// Qualified id for a module // Qualified id for a module
@@ -885,6 +888,10 @@ type ModuleBase struct {
// complianceMetadataInfo is for different module types to dump metadata. // complianceMetadataInfo is for different module types to dump metadata.
// See android.ModuleContext interface. // See android.ModuleContext interface.
complianceMetadataInfo *ComplianceMetadataInfo complianceMetadataInfo *ComplianceMetadataInfo
// containersInfo stores the information about the containers and the information of the
// apexes the module belongs to.
containersInfo ContainersInfo
} }
func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
@@ -2091,6 +2098,10 @@ func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string {
return variant return variant
} }
func (m *ModuleBase) ContainersInfo() ContainersInfo {
return m.containersInfo
}
// Check the supplied dist structure to make sure that it is valid. // Check the supplied dist structure to make sure that it is valid.
// //
// property - the base property, e.g. dist or dists[1], which is combined with the // property - the base property, e.g. dist or dists[1], which is combined with the

View File

@@ -571,8 +571,14 @@ type Module struct {
var _ android.InstallableModule = (*Module)(nil) var _ android.InstallableModule = (*Module)(nil)
// To satisfy the InstallableModule interface // To satisfy the InstallableModule interface
func (j *Module) EnforceApiContainerChecks() bool { func (j *Module) StaticDependencyTags() []blueprint.DependencyTag {
return true return []blueprint.DependencyTag{staticLibTag}
}
// To satisfy the InstallableModule interface
func (j *Module) DynamicDependencyTags() []blueprint.DependencyTag {
return []blueprint.DependencyTag{libTag, sdkLibTag, bootClasspathTag, systemModulesTag,
instrumentationForTag, java9LibTag}
} }
// Overrides android.ModuleBase.InstallInProduct() // Overrides android.ModuleBase.InstallInProduct()

View File

@@ -65,6 +65,18 @@ func TestJavaContainersModuleProperties(t *testing.T) {
"general-tests", "general-tests",
], ],
} }
java_library {
name: "bar",
static_libs: [
"framework-minus-apex",
],
}
java_library {
name: "baz",
static_libs: [
"bar",
],
}
`) `)
testcases := []struct { testcases := []struct {
@@ -73,6 +85,7 @@ func TestJavaContainersModuleProperties(t *testing.T) {
isVendorContainer bool isVendorContainer bool
isProductContainer bool isProductContainer bool
isCts bool isCts bool
isUnstable bool
}{ }{
{ {
moduleName: "foo", moduleName: "foo",
@@ -80,6 +93,7 @@ func TestJavaContainersModuleProperties(t *testing.T) {
isVendorContainer: false, isVendorContainer: false,
isProductContainer: false, isProductContainer: false,
isCts: false, isCts: false,
isUnstable: false,
}, },
{ {
moduleName: "foo_vendor", moduleName: "foo_vendor",
@@ -87,6 +101,7 @@ func TestJavaContainersModuleProperties(t *testing.T) {
isVendorContainer: true, isVendorContainer: true,
isProductContainer: false, isProductContainer: false,
isCts: false, isCts: false,
isUnstable: false,
}, },
{ {
moduleName: "foo_soc_specific", moduleName: "foo_soc_specific",
@@ -94,6 +109,7 @@ func TestJavaContainersModuleProperties(t *testing.T) {
isVendorContainer: true, isVendorContainer: true,
isProductContainer: false, isProductContainer: false,
isCts: false, isCts: false,
isUnstable: false,
}, },
{ {
moduleName: "foo_product_specific", moduleName: "foo_product_specific",
@@ -101,6 +117,7 @@ func TestJavaContainersModuleProperties(t *testing.T) {
isVendorContainer: false, isVendorContainer: false,
isProductContainer: true, isProductContainer: true,
isCts: false, isCts: false,
isUnstable: false,
}, },
{ {
moduleName: "foo_cts_test", moduleName: "foo_cts_test",
@@ -108,6 +125,7 @@ func TestJavaContainersModuleProperties(t *testing.T) {
isVendorContainer: false, isVendorContainer: false,
isProductContainer: false, isProductContainer: false,
isCts: true, isCts: true,
isUnstable: false,
}, },
{ {
moduleName: "foo_non_cts_test", moduleName: "foo_non_cts_test",
@@ -115,6 +133,23 @@ func TestJavaContainersModuleProperties(t *testing.T) {
isVendorContainer: false, isVendorContainer: false,
isProductContainer: false, isProductContainer: false,
isCts: false, isCts: false,
isUnstable: false,
},
{
moduleName: "bar",
isSystemContainer: true,
isVendorContainer: false,
isProductContainer: false,
isCts: false,
isUnstable: true,
},
{
moduleName: "baz",
isSystemContainer: true,
isVendorContainer: false,
isProductContainer: false,
isCts: false,
isUnstable: true,
}, },
} }
@@ -125,5 +160,7 @@ func TestJavaContainersModuleProperties(t *testing.T) {
checkContainerMatch(t, c.moduleName, "system", c.isSystemContainer, android.InList(android.SystemContainer, belongingContainers)) checkContainerMatch(t, c.moduleName, "system", c.isSystemContainer, android.InList(android.SystemContainer, belongingContainers))
checkContainerMatch(t, c.moduleName, "vendor", c.isVendorContainer, android.InList(android.VendorContainer, belongingContainers)) checkContainerMatch(t, c.moduleName, "vendor", c.isVendorContainer, android.InList(android.VendorContainer, belongingContainers))
checkContainerMatch(t, c.moduleName, "product", c.isProductContainer, android.InList(android.ProductContainer, belongingContainers)) checkContainerMatch(t, c.moduleName, "product", c.isProductContainer, android.InList(android.ProductContainer, belongingContainers))
checkContainerMatch(t, c.moduleName, "cts", c.isCts, android.InList(android.CtsContainer, belongingContainers))
checkContainerMatch(t, c.moduleName, "unstable", c.isUnstable, android.InList(android.UnstableContainer, belongingContainers))
} }
} }

View File

@@ -542,6 +542,16 @@ func gatherRequiredDepsForTest() string {
}, },
compile_dex: true, compile_dex: true,
} }
java_library {
name: "framework-minus-apex",
srcs: ["a.java"],
sdk_version: "none",
system_modules: "stable-core-platform-api-stubs-system-modules",
aidl: {
export_include_dirs: ["framework/aidl"],
},
compile_dex: true,
}
android_app { android_app {
name: "framework-res", name: "framework-res",