Convert tidyPhonySingleton, jdepsGeneratorSingleton and
genNoticeBuildRules to use ModuleProxy.

Bug: 377723687
Test: Unit tests and compare the ninja and mk files generated.
Change-Id: I7507a580e3533b01f552778a7815bcc43d301e23
diff --git a/android/androidmk.go b/android/androidmk.go
index d9d78f3..2eb13ec 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -78,6 +78,12 @@
 	Entries AndroidMkEntries
 }
 
+type AndroidMkDataInfo struct {
+	Class string
+}
+
+var AndroidMkDataInfoProvider = blueprint.NewProvider[AndroidMkDataInfo]()
+
 type AndroidMkExtraFunc func(w io.Writer, outputFile Path)
 
 // Interface for modules to declare their Android.mk outputs. Note that every module needs to
diff --git a/android/gen_notice.go b/android/gen_notice.go
index 9adde9e..482b1e0 100644
--- a/android/gen_notice.go
+++ b/android/gen_notice.go
@@ -19,6 +19,7 @@
 	"path/filepath"
 	"strings"
 
+	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -35,34 +36,31 @@
 type genNoticeBuildRules struct{}
 
 func (s *genNoticeBuildRules) GenerateBuildActions(ctx SingletonContext) {
-	ctx.VisitAllModules(func(m Module) {
-		gm, ok := m.(*genNoticeModule)
+	ctx.VisitAllModuleProxies(func(m ModuleProxy) {
+		gm, ok := OtherModuleProvider(ctx, m, GenNoticeInfoProvider)
 		if !ok {
 			return
 		}
-		if len(gm.missing) > 0 {
-			missingReferencesRule(ctx, gm)
+		if len(gm.Missing) > 0 {
+			missingReferencesRule(ctx, m, &gm)
 			return
 		}
 		out := BuildNoticeTextOutputFromLicenseMetadata
-		if proptools.Bool(gm.properties.Xml) {
+		if gm.Xml {
 			out = BuildNoticeXmlOutputFromLicenseMetadata
-		} else if proptools.Bool(gm.properties.Html) {
+		} else if gm.Html {
 			out = BuildNoticeHtmlOutputFromLicenseMetadata
 		}
 		defaultName := ""
-		if len(gm.properties.For) > 0 {
-			defaultName = gm.properties.For[0]
+		if len(gm.For) > 0 {
+			defaultName = gm.For[0]
 		}
 
-		modules := make([]Module, 0)
-		for _, name := range gm.properties.For {
-			mods := ctx.ModuleVariantsFromName(gm, name)
+		modules := make([]ModuleProxy, 0)
+		for _, name := range gm.For {
+			mods := ctx.ModuleVariantsFromName(m, name)
 			for _, mod := range mods {
-				if mod == nil {
-					continue
-				}
-				if !mod.Enabled(ctx) { // don't depend on variants without build rules
+				if !OtherModuleProviderOrDefault(ctx, mod, CommonModuleInfoKey).Enabled { // don't depend on variants without build rules
 					continue
 				}
 				modules = append(modules, mod)
@@ -71,8 +69,8 @@
 		if ctx.Failed() {
 			return
 		}
-		out(ctx, gm.output, ctx.ModuleName(gm),
-			proptools.StringDefault(gm.properties.ArtifactName, defaultName),
+		out(ctx, gm.Output, ctx.ModuleName(m),
+			proptools.StringDefault(gm.ArtifactName, defaultName),
 			[]string{
 				filepath.Join(ctx.Config().OutDir(), "target", "product", ctx.Config().DeviceName()) + "/",
 				ctx.Config().OutDir() + "/",
@@ -115,6 +113,22 @@
 	missing []string
 }
 
+type GenNoticeInfo struct {
+	// For specifies the modules for which to generate a notice file.
+	For []string
+	// ArtifactName specifies the internal name to use for the notice file.
+	// It appears in the "used by:" list for targets whose entire name is stripped by --strip_prefix.
+	ArtifactName *string
+	// Html indicates an html-format file is needed. The default is text. Can be Html or Xml but not both.
+	Html bool
+	// Xml indicates an xml-format file is needed. The default is text. Can be Html or Xml but not both.
+	Xml     bool
+	Output  OutputPath
+	Missing []string
+}
+
+var GenNoticeInfoProvider = blueprint.NewProvider[GenNoticeInfo]()
+
 func (m *genNoticeModule) DepsMutator(ctx BottomUpMutatorContext) {
 	if ctx.ContainsProperty("licenses") {
 		ctx.PropertyErrorf("licenses", "not supported on \"gen_notice\" modules")
@@ -176,6 +190,15 @@
 	}
 	out := m.getStem() + m.getSuffix()
 	m.output = PathForModuleOut(ctx, out).OutputPath
+
+	SetProvider(ctx, GenNoticeInfoProvider, GenNoticeInfo{
+		For:          m.properties.For,
+		ArtifactName: m.properties.ArtifactName,
+		Xml:          proptools.Bool(m.properties.Xml),
+		Html:         proptools.Bool(m.properties.Html),
+		Output:       m.output,
+		Missing:      m.missing,
+	})
 	ctx.SetOutputFiles(Paths{m.output}, "")
 }
 
@@ -205,17 +228,17 @@
 }
 
 // missingReferencesRule emits an ErrorRule for missing module references.
-func missingReferencesRule(ctx BuilderContext, m *genNoticeModule) {
-	if len(m.missing) < 1 {
+func missingReferencesRule(ctx BuilderContext, m ModuleProxy, genInfo *GenNoticeInfo) {
+	if len(genInfo.Missing) < 1 {
 		panic(fmt.Errorf("missing references rule requested with no missing references"))
 	}
 
 	ctx.Build(pctx, BuildParams{
 		Rule:        ErrorRule,
-		Output:      m.output,
-		Description: "notice for " + proptools.StringDefault(m.properties.ArtifactName, "container"),
+		Output:      genInfo.Output,
+		Description: "notice for " + proptools.StringDefault(genInfo.ArtifactName, "container"),
 		Args: map[string]string{
-			"error": m.Name() + " references missing module(s): " + strings.Join(m.missing, ", "),
+			"error": m.Name() + " references missing module(s): " + strings.Join(genInfo.Missing, ", "),
 		},
 	})
 }
diff --git a/android/module.go b/android/module.go
index 85909b6..d2da576 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2373,8 +2373,16 @@
 		})
 	}
 
-	if v, ok := m.module.(ModuleMakeVarsProvider); m.Enabled(ctx) && ok {
-		SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx))
+	if m.Enabled(ctx) {
+		if v, ok := m.module.(ModuleMakeVarsProvider); ok {
+			SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx))
+		}
+
+		if am, ok := m.module.(AndroidMkDataProvider); ok {
+			SetProvider(ctx, AndroidMkDataInfoProvider, AndroidMkDataInfo{
+				Class: am.AndroidMk().Class,
+			})
+		}
 	}
 }
 
@@ -3163,14 +3171,6 @@
 	BaseModuleName() string
 }
 
-// Extract the base module name from the Import name.
-// Often the Import name has a prefix "prebuilt_".
-// Remove the prefix explicitly if needed
-// until we find a better solution to get the Import name.
-type IDECustomizedModuleName interface {
-	IDECustomizedModuleName() string
-}
-
 // Collect information for opening IDE project files in java/jdeps.go.
 type IdeInfo struct {
 	BaseModuleName    string   `json:"-"`
diff --git a/android/notices.go b/android/notices.go
index 3c41d92..dc2290c 100644
--- a/android/notices.go
+++ b/android/notices.go
@@ -18,9 +18,11 @@
 	"fmt"
 	"path/filepath"
 	"strings"
+
+	"github.com/google/blueprint"
 )
 
-func modulesOutputDirs(ctx BuilderContext, modules ...Module) []string {
+func modulesOutputDirs(ctx BuilderContext, modules ...ModuleProxy) []string {
 	dirs := make([]string, 0, len(modules))
 	for _, module := range modules {
 		paths, err := outputFilesForModule(ctx, module, "")
@@ -41,12 +43,12 @@
 	OtherModuleProviderContext
 }
 
-func modulesLicenseMetadata(ctx OtherModuleProviderContext, modules ...Module) Paths {
+func modulesLicenseMetadata(ctx OtherModuleProviderContext, modules ...ModuleProxy) Paths {
 	result := make(Paths, 0, len(modules))
 	mctx, isMctx := ctx.(ModuleContext)
 	for _, module := range modules {
 		var mf Path
-		if isMctx && mctx.Module() == module {
+		if isMctx && EqualModules(mctx.Module(), module) {
 			mf = mctx.LicenseMetadataFile()
 		} else {
 			mf = OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).LicenseMetadataFile
@@ -61,12 +63,12 @@
 // buildNoticeOutputFromLicenseMetadata writes out a notice file.
 func buildNoticeOutputFromLicenseMetadata(
 	ctx BuilderAndOtherModuleProviderContext, tool, ruleName string, outputFile WritablePath,
-	libraryName string, stripPrefix []string, modules ...Module) {
+	libraryName string, stripPrefix []string, modules ...ModuleProxy) {
 	depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", "."))
 	rule := NewRuleBuilder(pctx, ctx)
 	if len(modules) == 0 {
 		if mctx, ok := ctx.(ModuleContext); ok {
-			modules = []Module{mctx.Module()}
+			modules = []ModuleProxy{{blueprint.CreateModuleProxy(mctx.Module())}}
 		} else {
 			panic(fmt.Errorf("%s %q needs a module to generate the notice for", ruleName, libraryName))
 		}
@@ -97,7 +99,7 @@
 // current context module if none given.
 func BuildNoticeTextOutputFromLicenseMetadata(
 	ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
-	stripPrefix []string, modules ...Module) {
+	stripPrefix []string, modules ...ModuleProxy) {
 	buildNoticeOutputFromLicenseMetadata(ctx, "textnotice", "text_notice_"+ruleName,
 		outputFile, libraryName, stripPrefix, modules...)
 }
@@ -107,7 +109,7 @@
 // current context module if none given.
 func BuildNoticeHtmlOutputFromLicenseMetadata(
 	ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
-	stripPrefix []string, modules ...Module) {
+	stripPrefix []string, modules ...ModuleProxy) {
 	buildNoticeOutputFromLicenseMetadata(ctx, "htmlnotice", "html_notice_"+ruleName,
 		outputFile, libraryName, stripPrefix, modules...)
 }
@@ -117,7 +119,7 @@
 // current context module if none given.
 func BuildNoticeXmlOutputFromLicenseMetadata(
 	ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
-	stripPrefix []string, modules ...Module) {
+	stripPrefix []string, modules ...ModuleProxy) {
 	buildNoticeOutputFromLicenseMetadata(ctx, "xmlnotice", "xml_notice_"+ruleName,
 		outputFile, libraryName, stripPrefix, modules...)
 }
diff --git a/android/singleton.go b/android/singleton.go
index 96b1022..e5f2684 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -36,7 +36,7 @@
 
 	// ModuleVariantsFromName returns the list of module variants named `name` in the same namespace as `referer` enforcing visibility rules.
 	// Allows generating build actions for `referer` based on the metadata for `name` deferred until the singleton context.
-	ModuleVariantsFromName(referer Module, name string) []Module
+	ModuleVariantsFromName(referer ModuleProxy, name string) []ModuleProxy
 
 	otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
 
@@ -331,7 +331,7 @@
 }
 
 func (s *singletonContextAdaptor) VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) {
-	s.SingletonContext.VisitAllModuleVariantProxies(module, visitProxyAdaptor(visit))
+	s.SingletonContext.VisitAllModuleVariantProxies(getWrappedModule(module), visitProxyAdaptor(visit))
 }
 
 func (s *singletonContextAdaptor) PrimaryModule(module Module) Module {
@@ -343,32 +343,30 @@
 }
 
 func (s *singletonContextAdaptor) IsFinalModule(module Module) bool {
-	return s.SingletonContext.IsFinalModule(module)
+	return s.SingletonContext.IsFinalModule(getWrappedModule(module))
 }
 
-func (s *singletonContextAdaptor) ModuleVariantsFromName(referer Module, name string) []Module {
+func (s *singletonContextAdaptor) ModuleVariantsFromName(referer ModuleProxy, name string) []ModuleProxy {
 	// get module reference for visibility enforcement
-	qualified := createVisibilityModuleReference(s.ModuleName(referer), s.ModuleDir(referer), referer)
+	qualified := createVisibilityModuleProxyReference(s, s.ModuleName(referer), s.ModuleDir(referer), referer)
 
-	modules := s.SingletonContext.ModuleVariantsFromName(referer, name)
-	result := make([]Module, 0, len(modules))
-	for _, m := range modules {
-		if module, ok := m.(Module); ok {
-			// enforce visibility
-			depName := s.ModuleName(module)
-			depDir := s.ModuleDir(module)
-			depQualified := qualifiedModuleName{depDir, depName}
-			// Targets are always visible to other targets in their own package.
-			if depQualified.pkg != qualified.name.pkg {
-				rule := effectiveVisibilityRules(s.Config(), depQualified)
-				if !rule.matches(qualified) {
-					s.ModuleErrorf(referer, "module %q references %q which is not visible to this module\nYou may need to add %q to its visibility",
-						referer.Name(), depQualified, "//"+s.ModuleDir(referer))
-					continue
-				}
+	modules := s.SingletonContext.ModuleVariantsFromName(referer.module, name)
+	result := make([]ModuleProxy, 0, len(modules))
+	for _, module := range modules {
+		// enforce visibility
+		depName := s.ModuleName(module)
+		depDir := s.ModuleDir(module)
+		depQualified := qualifiedModuleName{depDir, depName}
+		// Targets are always visible to other targets in their own package.
+		if depQualified.pkg != qualified.name.pkg {
+			rule := effectiveVisibilityRules(s.Config(), depQualified)
+			if !rule.matches(qualified) {
+				s.ModuleErrorf(referer, "module %q references %q which is not visible to this module\nYou may need to add %q to its visibility",
+					referer.Name(), depQualified, "//"+s.ModuleDir(referer))
+				continue
 			}
-			result = append(result, module)
 		}
+		result = append(result, ModuleProxy{module})
 	}
 	return result
 }
diff --git a/android/visibility.go b/android/visibility.go
index 4837c7d..416a3f1 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -58,15 +58,29 @@
 var visibilityRuleRegexp = regexp.MustCompile(visibilityRulePattern)
 
 type visibilityModuleReference struct {
-	name   qualifiedModuleName
-	module Module
+	name          qualifiedModuleName
+	partitionType *string
 }
 
 func createVisibilityModuleReference(name, dir string, module Module) visibilityModuleReference {
-	return visibilityModuleReference{
-		name:   createQualifiedModuleName(name, dir),
-		module: module,
+	vis := visibilityModuleReference{
+		name: createQualifiedModuleName(name, dir),
 	}
+	if m, ok := module.(PartitionTypeInterface); ok {
+		pt := m.PartitionType()
+		vis.partitionType = &pt
+	}
+	return vis
+}
+
+func createVisibilityModuleProxyReference(ctx OtherModuleProviderContext, name, dir string, module ModuleProxy) visibilityModuleReference {
+	vis := visibilityModuleReference{
+		name: createQualifiedModuleName(name, dir),
+	}
+	if m, ok := OtherModuleProvider(ctx, module, PartitionTypeInfoProvider); ok {
+		vis.partitionType = &m.PartitionType
+	}
+	return vis
 }
 
 // A visibility rule is associated with a module and determines which other modules it is visible
@@ -222,9 +236,17 @@
 	PartitionType() string
 }
 
+type PartitionTypeInfo struct {
+	// Identifies which partition this is for //visibility:any_system_image (and others) visibility
+	// checks, and will be used in the future for API surface checks.
+	PartitionType string
+}
+
+var PartitionTypeInfoProvider = blueprint.NewProvider[PartitionTypeInfo]()
+
 func (r anyPartitionRule) matches(m visibilityModuleReference) bool {
-	if m2, ok := m.module.(PartitionTypeInterface); ok {
-		return m2.PartitionType() == r.partitionType
+	if m.partitionType != nil {
+		return *m.partitionType == r.partitionType
 	}
 	return false
 }
@@ -647,42 +669,6 @@
 	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) VisibilityRuleSet {
-	moduleName := ctx.OtherModuleName(module)
-	dir := ctx.OtherModuleDir(module)
-	qualified := qualifiedModuleName{dir, moduleName}
-
-	rule := effectiveVisibilityRules(ctx.Config(), qualified)
-
-	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
-	// explicitly.
-	if !rule.matches(currentModule) {
-		if len(rule) == 1 {
-			if _, ok := rule[0].(privateRule); ok {
-				// If the rule is //visibility:private we can't append another
-				// visibility to it. Semantically we need to convert it to a package
-				// visibility rule for the location where the result is used, but since
-				// modules are implicitly visible within the package we get the same
-				// result without any rule at all, so just make it an empty list to be
-				// appended below.
-				rule = nil
-			}
-		}
-		rule = append(rule, packageRule{dir})
-	}
-
-	return &visibilityRuleSet{rule.Strings()}
-}
-
 // Clear the default visibility properties so they can be replaced.
 func clearVisibilityProperties(module Module) {
 	module.base().visibilityPropertyInfo = nil
diff --git a/android/visibility_test.go b/android/visibility_test.go
index 277be0f..4acaa02 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -2112,7 +2112,10 @@
 	ctx.AddVariationDependencies(nil, dependencyTag{name: "mockdeps"}, j.properties.Deps...)
 }
 
-func (p *mockFilesystemModule) GenerateAndroidBuildActions(ModuleContext) {
+func (p *mockFilesystemModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+	SetProvider(ctx, PartitionTypeInfoProvider, PartitionTypeInfo{
+		PartitionType: p.PartitionType(),
+	})
 }
 
 func (p *mockFilesystemModule) PartitionType() string {