Add prebuilt_visibility property

Some mainline modules provide an `sdk` and one or more set of
module_exports. When the snapshots are unpacked into separate prebuilts
directories (one per snapshot) then any dependencies from a member of
one snapshot to a member of another may require the latter to have
additional visibility rules.

Previously, these rules had to be added to each source module. This
change allows additional visibility rules to be specified on the
sdk/module_exports that are added to all the prebuilts in its snapshot.

Bug: 155921753
Bug: 168301990
Test: m nothing
Change-Id: Ia3eacb5749981f04770ae9872a8013e43c5c6ef1
diff --git a/android/visibility.go b/android/visibility.go
index 38f80af..51d5611 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -17,6 +17,7 @@
 import (
 	"fmt"
 	"regexp"
+	"sort"
 	"strings"
 	"sync"
 
@@ -496,13 +497,63 @@
 	}
 }
 
+type VisibilityRuleSet interface {
+	// Widen the visibility with some extra rules.
+	Widen(extra []string) error
+
+	Strings() []string
+}
+
+type visibilityRuleSet struct {
+	rules []string
+}
+
+var _ VisibilityRuleSet = (*visibilityRuleSet)(nil)
+
+func (v *visibilityRuleSet) Widen(extra []string) error {
+	// Check the extra rules first just in case they are invalid. Otherwise, if
+	// the current visibility is public then the extra rules will just be ignored.
+	if len(extra) == 1 {
+		singularRule := extra[0]
+		switch singularRule {
+		case "//visibility:public":
+			// Public overrides everything so just discard any existing rules.
+			v.rules = extra
+			return nil
+		case "//visibility:private":
+			// Extending rule with private is an error.
+			return fmt.Errorf("%q does not widen the visibility", singularRule)
+		}
+	}
+
+	if len(v.rules) == 1 {
+		switch v.rules[0] {
+		case "//visibility:public":
+			// No point in adding rules to something which is already public.
+			return nil
+		case "//visibility:private":
+			// Adding any rules to private means it is no longer private so the
+			// private can be discarded.
+			v.rules = nil
+		}
+	}
+
+	v.rules = FirstUniqueStrings(append(v.rules, extra...))
+	sort.Strings(v.rules)
+	return nil
+}
+
+func (v *visibilityRuleSet) Strings() []string {
+	return v.rules
+}
+
 // Get the effective visibility rules, i.e. the actual rules that affect the visibility of the
 // property irrespective of where they are defined.
 //
 // Includes visibility rules specified by package default_visibility and/or on defaults.
 // Short hand forms, e.g. //:__subpackages__ are replaced with their full form, e.g.
 // //package/containing/rule:__subpackages__.
-func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) []string {
+func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) VisibilityRuleSet {
 	moduleName := ctx.OtherModuleName(module)
 	dir := ctx.OtherModuleDir(module)
 	qualified := qualifiedModuleName{dir, moduleName}
@@ -527,7 +578,7 @@
 		rule = append(rule, packageRule{dir})
 	}
 
-	return rule.Strings()
+	return &visibilityRuleSet{rule.Strings()}
 }
 
 // Clear the default visibility properties so they can be replaced.