Add more specific partition visibility rules
//visibility:any_system_partition, //visibility:any_vendor_partition,
etc.
Then, if a partition visibility rule is not specificed, but the module
is installed on a non-system partition via the `vendor: true` or other
properties, the visibility rule for that partition will be added by
default.
This is so that "any_partition" doesn't imply that modules could be put
on the vendor partition when they weren't designed for that, and so that
modules that do need to go on the vendor partition don't need to specify
both vendor: true and visibility:any_vendor_partition.
Eventually, the partition properties should be deprecated, and replaced
with just these visibility rules.
Bug: 321000103
Test: go tests
Change-Id: I24dba36bbc20921941f892480bf7c050e93827c6
diff --git a/android/visibility.go b/android/visibility.go
index 79a534f..89c0adc 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -58,19 +58,14 @@
var visibilityRuleRegexp = regexp.MustCompile(visibilityRulePattern)
type visibilityModuleReference struct {
- name qualifiedModuleName
- isPartitionModule bool
+ name qualifiedModuleName
+ module Module
}
-func createVisibilityModuleReference(name, dir, typ string) visibilityModuleReference {
- isPartitionModule := false
- switch typ {
- case "android_filesystem", "android_system_image":
- isPartitionModule = true
- }
+func createVisibilityModuleReference(name, dir string, module Module) visibilityModuleReference {
return visibilityModuleReference{
- name: createQualifiedModuleName(name, dir),
- isPartitionModule: isPartitionModule,
+ name: createQualifiedModuleName(name, dir),
+ module: module,
}
}
@@ -214,21 +209,37 @@
return "//visibility:private"
}
+var anyPartitionRegex = regexp.MustCompile("^any_(system|system_ext|vendor|product|data|odm)_partition$")
+
// visibilityRule for //visibility:any_partition
-type anyPartitionRule struct{}
+type anyPartitionRule struct {
+ partitionType string
+}
var _ visibilityRule = anyPartitionRule{}
+type PartitionTypeInterface interface {
+ PartitionType() string
+}
+
func (r anyPartitionRule) matches(m visibilityModuleReference) bool {
- return m.isPartitionModule
+ if m2, ok := m.module.(PartitionTypeInterface); ok {
+ return m2.PartitionType() == r.partitionType
+ }
+ return false
}
func (r anyPartitionRule) String() string {
- return "//visibility:any_partition"
+ return "//visibility:any_" + r.partitionType + "_partition"
}
var visibilityRuleMap = NewOnceKey("visibilityRuleMap")
+type visibilityRulesForModule struct {
+ rule compositeRule
+ implicitPartitionRules compositeRule
+}
+
// The map from qualifiedModuleName to visibilityRule.
func moduleToVisibilityRuleMap(config Config) *sync.Map {
return config.Once(visibilityRuleMap, func() interface{} {
@@ -304,9 +315,6 @@
if pkg == "visibility" {
switch name {
case "private", "public":
- case "any_partition":
- // any_partition can be used with another visibility fields
- continue
case "legacy_public":
ctx.PropertyErrorf(property, "//visibility:legacy_public must not be used")
continue
@@ -314,6 +322,10 @@
// This keyword does not create a rule so pretend it does not exist.
ruleCount -= 1
default:
+ if anyPartitionRegex.MatchString(name) {
+ // any_*_partition can be used with another visibility fields
+ continue
+ }
ctx.PropertyErrorf(property, "unrecognized visibility rule %q", v)
continue
}
@@ -352,15 +364,20 @@
// Parse the visibility rules that control access to the module and store them by id
// for use when enforcing the rules.
+ var rule compositeRule
primaryProperty := m.base().primaryVisibilityProperty
if primaryProperty != nil {
if visibility := primaryProperty.getStrings(); visibility != nil {
- rule := parseRules(ctx, currentPkg, primaryProperty.getName(), visibility)
- if rule != nil {
- moduleToVisibilityRuleMap(ctx.Config()).Store(qualifiedModuleId, rule)
- }
+ rule = parseRules(ctx, currentPkg, primaryProperty.getName(), visibility)
}
}
+ ipr := implicitPartitionRules(ctx)
+ if rule != nil || ipr != nil {
+ moduleToVisibilityRuleMap(ctx.Config()).Store(qualifiedModuleId, visibilityRulesForModule{
+ rule: rule,
+ implicitPartitionRules: ipr,
+ })
+ }
}
func parseRules(ctx BaseModuleContext, currentPkg, property string, visibility []string) compositeRule {
@@ -392,8 +409,13 @@
hasNonPrivateRule = false
// This does not actually create a rule so continue onto the next rule.
continue
- case "any_partition":
- r = anyPartitionRule{}
+ default:
+ match := anyPartitionRegex.FindStringSubmatch(name)
+ if match != nil {
+ r = anyPartitionRule{
+ partitionType: match[1],
+ }
+ }
}
} else {
switch name {
@@ -432,6 +454,22 @@
return rules
}
+func implicitPartitionRules(ctx BaseModuleContext) compositeRule {
+ var result compositeRule
+ if ctx.SocSpecific() {
+ result = append(result, anyPartitionRule{partitionType: "vendor"})
+ } else if ctx.ProductSpecific() {
+ result = append(result, anyPartitionRule{partitionType: "product"})
+ } else if ctx.Module().InstallInData() {
+ result = append(result, anyPartitionRule{partitionType: "data"})
+ } else if ctx.SystemExtSpecific() {
+ result = append(result, anyPartitionRule{partitionType: "system_ext"})
+ } else if ctx.DeviceSpecific() {
+ result = append(result, anyPartitionRule{partitionType: "odm"})
+ }
+ return result
+}
+
func isAllowedFromOutsideVendor(pkg string, name string) bool {
if pkg == "vendor" {
return name == "__subpackages__"
@@ -470,7 +508,7 @@
}
func visibilityRuleEnforcer(ctx TopDownMutatorContext) {
- qualified := createVisibilityModuleReference(ctx.ModuleName(), ctx.ModuleDir(), ctx.ModuleType())
+ qualified := createVisibilityModuleReference(ctx.ModuleName(), ctx.ModuleDir(), ctx.Module())
// Visit all the dependencies making sure that this module has access to them all.
ctx.VisitDirectDeps(func(dep Module) {
@@ -505,10 +543,13 @@
// which is currently //visibility:public.
func effectiveVisibilityRules(config Config, qualified qualifiedModuleName) compositeRule {
moduleToVisibilityRule := moduleToVisibilityRuleMap(config)
- value, ok := moduleToVisibilityRule.Load(qualified)
+ value := visibilityRulesForModule{}
+ if valueRaw, ok := moduleToVisibilityRule.Load(qualified); ok {
+ value = valueRaw.(visibilityRulesForModule)
+ }
var rule compositeRule
- if ok {
- rule = value.(compositeRule)
+ if value.rule != nil {
+ rule = value.rule
} else {
rule = packageDefaultVisibility(moduleToVisibilityRule, qualified)
}
@@ -518,6 +559,20 @@
if rule == nil {
rule = defaultVisibility
}
+
+ // If a partition rule wasn't specified, add implicit partition visibility
+ // rules based on the partition properties like vendor: true.
+ foundPartitionRule := false
+ for _, r := range rule {
+ if _, ok := r.(anyPartitionRule); ok {
+ foundPartitionRule = true
+ break
+ }
+ }
+ if !foundPartitionRule {
+ rule = append(rule, value.implicitPartitionRules...)
+ }
+
return rule
}
@@ -531,7 +586,7 @@
for {
value, ok := moduleToVisibilityRule.Load(packageQualifiedId)
if ok {
- return value.(compositeRule)
+ return value.(visibilityRulesForModule).rule
}
if packageQualifiedId.isRootPackage() {
@@ -605,7 +660,7 @@
rule := effectiveVisibilityRules(ctx.Config(), qualified)
- currentModule := createVisibilityModuleReference(moduleName, dir, ctx.OtherModuleType(module))
+ currentModule := createVisibilityModuleReference(moduleName, dir, module)
// Modules are implicitly visible to other modules in the same package,
// without checking the visibility rules. Here we need to add that visibility