Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
diff --git a/android/apex.go b/android/apex.go
index 99b13ab..557febf 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -78,12 +78,23 @@
// Return the no_apex property
NoApex() bool
+
+ // Tests if this module is available for the specified APEX or ":platform"
+ AvailableFor(what string) bool
}
type ApexProperties struct {
// Whether this module should not be part of any APEX. Default is false.
+ // TODO(b/128708192): remove this as this is equal to apex_available: [":platform"]
No_apex *bool
+ // Availability of this module in APEXes. Only the listed APEXes can include this module.
+ // "//apex_available:anyapex" is a pseudo APEX name that matches to any APEX.
+ // "//apex_available:platform" refers to non-APEX partitions like "system.img".
+ // Default is ["//apex_available:platform", "//apex_available:anyapex"].
+ // TODO(b/128708192) change the default to ["//apex_available:platform"]
+ Apex_available []string
+
// Name of the apex variant that this module is mutated into
ApexName string `blueprint:"mutated"`
}
@@ -136,15 +147,46 @@
return proptools.Bool(m.ApexProperties.No_apex)
}
+const (
+ availableToPlatform = "//apex_available:platform"
+ availableToAnyApex = "//apex_available:anyapex"
+)
+
+func (m *ApexModuleBase) AvailableFor(what string) bool {
+ if len(m.ApexProperties.Apex_available) == 0 {
+ // apex_available defaults to ["//apex_available:platform", "//apex_available:anyapex"],
+ // which means 'available to everybody'.
+ return true
+ }
+ return InList(what, m.ApexProperties.Apex_available) ||
+ (what != availableToPlatform && InList(availableToAnyApex, m.ApexProperties.Apex_available))
+}
+
+func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) {
+ for _, n := range m.ApexProperties.Apex_available {
+ if n == availableToPlatform || n == availableToAnyApex {
+ continue
+ }
+ if !mctx.OtherModuleExists(n) {
+ mctx.PropertyErrorf("apex_available", "%q is not a valid module name", n)
+ }
+ }
+}
+
func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []blueprint.Module {
if len(m.apexVariations) > 0 {
+ m.checkApexAvailableProperty(mctx)
sort.Strings(m.apexVariations)
- variations := []string{""} // Original variation for platform
+ variations := []string{}
+ availableForPlatform := m.AvailableFor(availableToPlatform)
+ if availableForPlatform {
+ variations = append(variations, "") // Original variation for platform
+ }
variations = append(variations, m.apexVariations...)
modules := mctx.CreateVariations(variations...)
for i, m := range modules {
- if i == 0 {
+ if availableForPlatform && i == 0 {
continue
}
m.(ApexModule).setApexName(variations[i])