Allow default visibility to be set per package

Adds a package module type with a default_visibility property. The
package module type can only be specified once per package.

Bug: 133290645
Test: m droid
Change-Id: Ibb2fb499c9ea88ecaa662d3cd2cbde478e4b9a4b
diff --git a/android/module.go b/android/module.go
index 66822f0..b912726 100644
--- a/android/module.go
+++ b/android/module.go
@@ -202,6 +202,42 @@
 	BuildParamsForTests() []BuildParams
 	RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
 	VariablesForTests() map[string]string
+
+	// Get the qualified module id for this module.
+	qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName
+
+	// Get information about the properties that can contain visibility rules.
+	visibilityProperties() []visibilityProperty
+}
+
+// Qualified id for a module
+type qualifiedModuleName struct {
+	// The package (i.e. directory) in which the module is defined, without trailing /
+	pkg string
+
+	// The name of the module, empty string if package.
+	name string
+}
+
+func (q qualifiedModuleName) String() string {
+	if q.name == "" {
+		return "//" + q.pkg
+	}
+	return "//" + q.pkg + ":" + q.name
+}
+
+// Get the id for the package containing this module.
+func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName {
+	pkg := q.pkg
+	if q.name == "" {
+		panic(fmt.Errorf("Cannot get containing package id of package module %s", pkg))
+	}
+	return newPackageId(pkg)
+}
+
+func newPackageId(pkg string) qualifiedModuleName {
+	// A qualified id for a package module has no name.
+	return qualifiedModuleName{pkg: pkg, name: ""}
 }
 
 type nameProperties struct {
@@ -236,6 +272,13 @@
 	//      //packages/apps/Settings:__subpackages__.
 	//  ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public
 	//      for now. It is an error if it is used in a module.
+	//
+	// If a module does not specify the `visibility` property then it uses the
+	// `default_visibility` property of the `package` module in the module's package.
+	//
+	// If the `default_visibility` property is not set for the module's package then
+	// the module uses `//visibility:legacy_public`.
+	//
 	// See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for
 	// more details.
 	Visibility []string
@@ -571,6 +614,18 @@
 	return m
 }
 
+func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
+	return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()}
+}
+
+func (m *ModuleBase) visibilityProperties() []visibilityProperty {
+	return []visibilityProperty{
+		newVisibilityProperty("visibility", func() []string {
+			return m.base().commonProperties.Visibility
+		}),
+	}
+}
+
 func (m *ModuleBase) SetTarget(target Target, multiTargets []Target, primary bool) {
 	m.commonProperties.CompileTarget = target
 	m.commonProperties.CompileMultiTargets = multiTargets