Merge "record-finalized-flags: pass in list of finalized flags" into main
diff --git a/android/container.go b/android/container.go
index 882535e..eb2fc18 100644
--- a/android/container.go
+++ b/android/container.go
@@ -198,7 +198,7 @@
 	unstableModule := module.Name() == "framework-minus-apex"
 	if installable, ok := module.(InstallableModule); ok {
 		for _, staticDepTag := range installable.StaticDependencyTags() {
-			mctx.VisitDirectDepsWithTag(staticDepTag, func(dep Module) {
+			mctx.VisitDirectDepsProxyWithTag(staticDepTag, func(dep ModuleProxy) {
 				if unstableInfo, ok := OtherModuleProvider(mctx, dep, unstableInfoProvider); ok {
 					unstableModule = unstableModule || unstableInfo.ContainsPlatformPrivateApis
 				}
diff --git a/android/module_context.go b/android/module_context.go
index fd804d0..e63c672 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -24,6 +24,7 @@
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/depset"
 	"github.com/google/blueprint/proptools"
+	"github.com/google/blueprint/uniquelist"
 )
 
 // BuildParameters describes the set of potential parameters to build a Ninja rule.
@@ -589,8 +590,8 @@
 	return m.packageFile(fullInstallPath, srcPath, false)
 }
 
-func (m *moduleContext) getAconfigPaths() *Paths {
-	return &m.aconfigFilePaths
+func (m *moduleContext) getAconfigPaths() Paths {
+	return m.aconfigFilePaths
 }
 
 func (m *moduleContext) setAconfigPaths(paths Paths) {
@@ -618,13 +619,13 @@
 		srcPath:               srcPath,
 		symlinkTarget:         "",
 		executable:            executable,
-		effectiveLicenseFiles: &licenseFiles,
+		effectiveLicenseFiles: uniquelist.Make(licenseFiles),
 		partition:             fullInstallPath.partition,
 		skipInstall:           m.skipInstall(),
-		aconfigPaths:          m.getAconfigPaths(),
+		aconfigPaths:          uniquelist.Make(m.getAconfigPaths()),
 		archType:              m.target.Arch.ArchType,
-		overrides:             &overrides,
-		owner:                 owner,
+        overrides:             uniquelist.Make(overrides),
+        owner:                 owner,
 	}
 	m.packagingSpecs = append(m.packagingSpecs, spec)
 	return spec
@@ -756,10 +757,10 @@
 		executable:       false,
 		partition:        fullInstallPath.partition,
 		skipInstall:      m.skipInstall(),
-		aconfigPaths:     m.getAconfigPaths(),
+		aconfigPaths:     uniquelist.Make(m.getAconfigPaths()),
 		archType:         m.target.Arch.ArchType,
-		overrides:        &overrides,
-		owner:            owner,
+        overrides:        uniquelist.Make(overrides),
+        owner:            owner,
 	})
 
 	return fullInstallPath
@@ -804,10 +805,10 @@
 		executable:       false,
 		partition:        fullInstallPath.partition,
 		skipInstall:      m.skipInstall(),
-		aconfigPaths:     m.getAconfigPaths(),
+		aconfigPaths:     uniquelist.Make(m.getAconfigPaths()),
 		archType:         m.target.Arch.ArchType,
-		overrides:        &overrides,
-		owner:            owner,
+        overrides:        uniquelist.Make(overrides),
+        owner:            owner,
 	})
 
 	return fullInstallPath
diff --git a/android/packaging.go b/android/packaging.go
index d96cccd..738f215 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -22,6 +22,7 @@
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/gobtools"
 	"github.com/google/blueprint/proptools"
+	"github.com/google/blueprint/uniquelist"
 )
 
 // PackagingSpec abstracts a request to place a built artifact at a certain path in a package. A
@@ -42,7 +43,7 @@
 	// Whether relPathInPackage should be marked as executable or not
 	executable bool
 
-	effectiveLicenseFiles *Paths
+	effectiveLicenseFiles uniquelist.UniqueList[Path]
 
 	partition string
 
@@ -52,13 +53,13 @@
 	skipInstall bool
 
 	// Paths of aconfig files for the built artifact
-	aconfigPaths *Paths
+	aconfigPaths uniquelist.UniqueList[Path]
 
 	// ArchType of the module which produced this packaging spec
 	archType ArchType
 
 	// List of module names that this packaging spec overrides
-	overrides *[]string
+	overrides uniquelist.UniqueList[string]
 
 	// Name of the module where this packaging spec is output of
 	owner string
@@ -69,12 +70,12 @@
 	SrcPath               Path
 	SymlinkTarget         string
 	Executable            bool
-	EffectiveLicenseFiles *Paths
+	EffectiveLicenseFiles Paths
 	Partition             string
 	SkipInstall           bool
-	AconfigPaths          *Paths
+	AconfigPaths          Paths
 	ArchType              ArchType
-	Overrides             *[]string
+	Overrides             []string
 	Owner                 string
 }
 
@@ -84,12 +85,12 @@
 		SrcPath:               p.srcPath,
 		SymlinkTarget:         p.symlinkTarget,
 		Executable:            p.executable,
-		EffectiveLicenseFiles: p.effectiveLicenseFiles,
+		EffectiveLicenseFiles: p.effectiveLicenseFiles.ToSlice(),
 		Partition:             p.partition,
 		SkipInstall:           p.skipInstall,
-		AconfigPaths:          p.aconfigPaths,
+		AconfigPaths:          p.aconfigPaths.ToSlice(),
 		ArchType:              p.archType,
-		Overrides:             p.overrides,
+		Overrides:             p.overrides.ToSlice(),
 		Owner:                 p.owner,
 	}
 }
@@ -99,12 +100,12 @@
 	p.srcPath = data.SrcPath
 	p.symlinkTarget = data.SymlinkTarget
 	p.executable = data.Executable
-	p.effectiveLicenseFiles = data.EffectiveLicenseFiles
+	p.effectiveLicenseFiles = uniquelist.Make(data.EffectiveLicenseFiles)
 	p.partition = data.Partition
 	p.skipInstall = data.SkipInstall
-	p.aconfigPaths = data.AconfigPaths
+	p.aconfigPaths = uniquelist.Make(data.AconfigPaths)
 	p.archType = data.ArchType
-	p.overrides = data.Overrides
+	p.overrides = uniquelist.Make(data.Overrides)
 	p.owner = data.Owner
 }
 
@@ -154,10 +155,7 @@
 }
 
 func (p *PackagingSpec) EffectiveLicenseFiles() Paths {
-	if p.effectiveLicenseFiles == nil {
-		return Paths{}
-	}
-	return *p.effectiveLicenseFiles
+	return p.effectiveLicenseFiles.ToSlice()
 }
 
 func (p *PackagingSpec) Partition() string {
@@ -174,7 +172,7 @@
 
 // Paths of aconfig files for the built artifact
 func (p *PackagingSpec) GetAconfigPaths() Paths {
-	return *p.aconfigPaths
+	return p.aconfigPaths.ToSlice()
 }
 
 type PackageModule interface {
@@ -507,9 +505,7 @@
 			}
 
 			depNames = append(depNames, child.Name())
-			if ps.overrides != nil {
-				overridden = append(overridden, *ps.overrides...)
-			}
+			overridden = append(overridden, ps.overrides.ToSlice()...)
 		}
 	})
 
diff --git a/cc/cc.go b/cc/cc.go
index b51d74d..0279928 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -2419,7 +2419,7 @@
 		staticDepNames = append(staticDepNames, dep.Name())
 	}
 	// Process CrtBegin and CrtEnd as static libs
-	ctx.VisitDirectDeps(func(dep android.Module) {
+	ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
 		depName := ctx.OtherModuleName(dep)
 		depTag := ctx.OtherModuleDependencyTag(dep)
 		switch depTag {
diff --git a/rust/afdo.go b/rust/afdo.go
index 6bd4bae..1bec709 100644
--- a/rust/afdo.go
+++ b/rust/afdo.go
@@ -66,7 +66,7 @@
 		return flags, deps
 	}
 
-	ctx.VisitDirectDepsWithTag(cc.FdoProfileTag, func(m android.Module) {
+	ctx.VisitDirectDepsProxyWithTag(cc.FdoProfileTag, func(m android.ModuleProxy) {
 		if info, ok := android.OtherModuleProvider(ctx, m, cc.FdoProfileProvider); ok {
 			path := info.Path
 			profileUseFlag := fmt.Sprintf(afdoFlagFormat, path.String())
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 898e792..8accd03 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -309,7 +309,8 @@
 
 	var cmd, cmdDesc string
 	if b.Properties.Custom_bindgen != "" {
-		cmd = ctx.GetDirectDepWithTag(b.Properties.Custom_bindgen, customBindgenDepTag).(android.HostToolProvider).HostToolPath().String()
+		m := ctx.GetDirectDepProxyWithTag(b.Properties.Custom_bindgen, customBindgenDepTag)
+		cmd = android.OtherModuleProviderOrDefault(ctx, m, android.HostToolProviderInfoProvider).HostToolPath.String()
 		cmdDesc = b.Properties.Custom_bindgen
 	} else {
 		cmd = "$bindgenCmd"
diff --git a/rust/coverage.go b/rust/coverage.go
index 381fcf1..ae95e46 100644
--- a/rust/coverage.go
+++ b/rust/coverage.go
@@ -15,6 +15,7 @@
 package rust
 
 import (
+	"android/soong/android"
 	"github.com/google/blueprint"
 
 	"android/soong/cc"
@@ -65,16 +66,18 @@
 		flags.RustFlags = append(flags.RustFlags,
 			"-C instrument-coverage", "-g")
 		if ctx.Device() {
-			coverage := ctx.GetDirectDepWithTag(CovLibraryName, cc.CoverageDepTag).(cc.LinkableInterface)
+			m := ctx.GetDirectDepProxyWithTag(CovLibraryName, cc.CoverageDepTag)
+			coverage := android.OtherModuleProviderOrDefault(ctx, m, cc.LinkableInfoProvider)
 			flags.LinkFlags = append(flags.LinkFlags,
-				profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open")
-			deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path())
+				profileInstrFlag, "-g", coverage.OutputFile.Path().String(), "-Wl,--wrap,open")
+			deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile.Path())
 		}
 
 		// no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency.
 		if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() {
-			profiler_builtins := ctx.GetDirectDepWithTag(ProfilerBuiltins, rlibDepTag).(*Module)
-			deps.RLibs = append(deps.RLibs, RustLibrary{Path: profiler_builtins.OutputFile().Path(), CrateName: profiler_builtins.CrateName()})
+			m := ctx.GetDirectDepProxyWithTag(ProfilerBuiltins, rlibDepTag)
+			profiler_builtins := android.OtherModuleProviderOrDefault(ctx, m, cc.LinkableInfoProvider)
+			deps.RLibs = append(deps.RLibs, RustLibrary{Path: profiler_builtins.OutputFile.Path(), CrateName: profiler_builtins.CrateName})
 		}
 
 		if cc.EnableContinuousCoverage(ctx) {
diff --git a/rust/rust.go b/rust/rust.go
index 5e9b7af..c0df9f3 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -49,6 +49,7 @@
 type ProtobufDecoratorInfo struct{}
 
 type SourceProviderInfo struct {
+	Srcs                  android.Paths
 	ProtobufDecoratorInfo *ProtobufDecoratorInfo
 }
 
@@ -1065,9 +1066,9 @@
 			mod.sourceProvider.GenerateSource(ctx, deps)
 			mod.sourceProvider.setSubName(ctx.ModuleSubDir())
 		} else {
-			sourceMod := actx.GetDirectDepWithTag(mod.Name(), sourceDepTag)
-			sourceLib := sourceMod.(*Module).compiler.(*libraryDecorator)
-			mod.sourceProvider.setOutputFiles(sourceLib.sourceProvider.Srcs())
+			sourceMod := actx.GetDirectDepProxyWithTag(mod.Name(), sourceDepTag)
+			sourceLib := android.OtherModuleProviderOrDefault(ctx, sourceMod, RustInfoProvider).SourceProviderInfo
+			mod.sourceProvider.setOutputFiles(sourceLib.Srcs)
 		}
 		ctx.CheckbuildFile(mod.sourceProvider.Srcs()...)
 	}
@@ -1155,10 +1156,11 @@
 		}
 	}
 	if mod.sourceProvider != nil {
+		rustInfo.SourceProviderInfo = &SourceProviderInfo{
+			Srcs: mod.sourceProvider.Srcs(),
+		}
 		if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
-			rustInfo.SourceProviderInfo = &SourceProviderInfo{
-				ProtobufDecoratorInfo: &ProtobufDecoratorInfo{},
-			}
+			rustInfo.SourceProviderInfo.ProtobufDecoratorInfo = &ProtobufDecoratorInfo{}
 		}
 	}
 	android.SetProvider(ctx, RustInfoProvider, rustInfo)
@@ -1203,12 +1205,12 @@
 	metadataInfo.SetStringValue(android.ComplianceMetadataProp.BUILT_FILES, mod.outputFile.String())
 
 	// Static libs
-	staticDeps := ctx.GetDirectDepsWithTag(rlibDepTag)
+	staticDeps := ctx.GetDirectDepsProxyWithTag(rlibDepTag)
 	staticDepNames := make([]string, 0, len(staticDeps))
 	for _, dep := range staticDeps {
 		staticDepNames = append(staticDepNames, dep.Name())
 	}
-	ccStaticDeps := ctx.GetDirectDepsWithTag(cc.StaticDepTag(false))
+	ccStaticDeps := ctx.GetDirectDepsProxyWithTag(cc.StaticDepTag(false))
 	for _, dep := range ccStaticDeps {
 		staticDepNames = append(staticDepNames, dep.Name())
 	}
@@ -1226,7 +1228,7 @@
 	metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.FirstUniqueStrings(staticDepPaths))
 
 	// C Whole static libs
-	ccWholeStaticDeps := ctx.GetDirectDepsWithTag(cc.StaticDepTag(true))
+	ccWholeStaticDeps := ctx.GetDirectDepsProxyWithTag(cc.StaticDepTag(true))
 	wholeStaticDepNames := make([]string, 0, len(ccWholeStaticDeps))
 	for _, dep := range ccStaticDeps {
 		wholeStaticDepNames = append(wholeStaticDepNames, dep.Name())
diff --git a/rust/test.go b/rust/test.go
index dce5e03..4fd1da0 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -148,35 +148,36 @@
 	dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
 	dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_common_data)...)
 
-	ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) {
+	ctx.VisitDirectDepsProxyWithTag(dataLibDepTag, func(dep android.ModuleProxy) {
 		depName := ctx.OtherModuleName(dep)
-		linkableDep, ok := dep.(cc.LinkableInterface)
+		linkableDep, ok := android.OtherModuleProvider(ctx, dep, cc.LinkableInfoProvider)
 		if !ok {
 			ctx.ModuleErrorf("data_lib %q is not a linkable module", depName)
 		}
-		if linkableDep.OutputFile().Valid() {
+		if linkableDep.OutputFile.Valid() {
 			// Copy the output in "lib[64]" so that it's compatible with
 			// the default rpath values.
+			commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey)
 			libDir := "lib"
-			if linkableDep.Target().Arch.ArchType.Multilib == "lib64" {
+			if commonInfo.Target.Arch.ArchType.Multilib == "lib64" {
 				libDir = "lib64"
 			}
 			test.data = append(test.data,
-				android.DataPath{SrcPath: linkableDep.OutputFile().Path(),
-					RelativeInstallPath: filepath.Join(libDir, linkableDep.RelativeInstallPath())})
+				android.DataPath{SrcPath: linkableDep.OutputFile.Path(),
+					RelativeInstallPath: filepath.Join(libDir, linkableDep.RelativeInstallPath)})
 		}
 	})
 
-	ctx.VisitDirectDepsWithTag(dataBinDepTag, func(dep android.Module) {
+	ctx.VisitDirectDepsProxyWithTag(dataBinDepTag, func(dep android.ModuleProxy) {
 		depName := ctx.OtherModuleName(dep)
-		linkableDep, ok := dep.(cc.LinkableInterface)
+		linkableDep, ok := android.OtherModuleProvider(ctx, dep, cc.LinkableInfoProvider)
 		if !ok {
 			ctx.ModuleErrorf("data_bin %q is not a linkable module", depName)
 		}
-		if linkableDep.OutputFile().Valid() {
+		if linkableDep.OutputFile.Valid() {
 			test.data = append(test.data,
-				android.DataPath{SrcPath: linkableDep.OutputFile().Path(),
-					RelativeInstallPath: linkableDep.RelativeInstallPath()})
+				android.DataPath{SrcPath: linkableDep.OutputFile.Path(),
+					RelativeInstallPath: linkableDep.RelativeInstallPath})
 		}
 	})
 
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 60c5317..d753d24 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -423,7 +423,7 @@
 	expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_common_data)...)
 	expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_first_data)...)
 	// Emulate the data property for java_data dependencies.
-	for _, javaData := range ctx.GetDirectDepsWithTag(shTestJavaDataTag) {
+	for _, javaData := range ctx.GetDirectDepsProxyWithTag(shTestJavaDataTag) {
 		expandedData = append(expandedData, android.OutputFilesForModule(ctx, javaData, "")...)
 	}
 	for _, d := range expandedData {
@@ -476,21 +476,24 @@
 
 	s.extraTestConfigs = android.PathsForModuleSrc(ctx, s.testProperties.Extra_test_configs)
 	s.dataModules = make(map[string]android.Path)
-	ctx.VisitDirectDeps(func(dep android.Module) {
+	ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
 		depTag := ctx.OtherModuleDependencyTag(dep)
 		switch depTag {
 		case shTestDataBinsTag, shTestDataDeviceBinsTag:
 			path := android.OutputFileForModule(ctx, dep, "")
 			s.addToDataModules(ctx, path.Base(), path)
 		case shTestDataLibsTag, shTestDataDeviceLibsTag:
-			if cc, isCc := dep.(*cc.Module); isCc {
+			if _, isCc := android.OtherModuleProvider(ctx, dep, cc.CcInfoProvider); isCc {
 				// Copy to an intermediate output directory to append "lib[64]" to the path,
 				// so that it's compatible with the default rpath values.
 				var relPath string
-				if cc.Arch().ArchType.Multilib == "lib64" {
-					relPath = filepath.Join("lib64", cc.OutputFile().Path().Base())
+				linkableInfo := android.OtherModuleProviderOrDefault(ctx, dep, cc.LinkableInfoProvider)
+				commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey)
+
+				if commonInfo.Target.Arch.ArchType.Multilib == "lib64" {
+					relPath = filepath.Join("lib64", linkableInfo.OutputFile.Path().Base())
 				} else {
-					relPath = filepath.Join("lib", cc.OutputFile().Path().Base())
+					relPath = filepath.Join("lib", linkableInfo.OutputFile.Path().Base())
 				}
 				if _, exist := s.dataModules[relPath]; exist {
 					return
@@ -498,7 +501,7 @@
 				relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath)
 				ctx.Build(pctx, android.BuildParams{
 					Rule:   android.Cp,
-					Input:  cc.OutputFile().Path(),
+					Input:  linkableInfo.OutputFile.Path(),
 					Output: relocatedLib,
 				})
 				s.addToDataModules(ctx, relPath, relocatedLib)