Propagate owners info in filesystem provider

Owners contain information about the name and the variants of the
modules that are installed in the partition. This information can be
used to determine whether the dependency module is installed or not.

Utilization of this information will be done in a follow up change.

Test: m nothing
Bug: 395989947
Change-Id: I8c63ed5765a3f582ff0d2ce98f63e6e0fc6edad8
diff --git a/android/module_context.go b/android/module_context.go
index f279fd9..fb62e67 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -655,6 +655,7 @@
 		owner:                 owner,
 		requiresFullInstall:   requiresFullInstall,
 		fullInstallPath:       fullInstallPath,
+		variation:             m.ModuleSubDir(),
 	}
 	m.packagingSpecs = append(m.packagingSpecs, spec)
 	return spec
@@ -806,6 +807,7 @@
 		owner:               owner,
 		requiresFullInstall: m.requiresFullInstall(),
 		fullInstallPath:     fullInstallPath,
+		variation:           m.ModuleSubDir(),
 	})
 
 	return fullInstallPath
@@ -856,6 +858,7 @@
 		owner:               owner,
 		requiresFullInstall: m.requiresFullInstall(),
 		fullInstallPath:     fullInstallPath,
+		variation:           m.ModuleSubDir(),
 	})
 
 	return fullInstallPath
diff --git a/android/packaging.go b/android/packaging.go
index 551fd4c..73cc7c7 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -72,6 +72,9 @@
 	// tools that want to interact with these files outside of the build. You should not use it
 	// inside of the build. Will be nil if this module doesn't require a "full install".
 	fullInstallPath InstallPath
+
+	// String representation of the variation of the module where this packaging spec is output of
+	variation string
 }
 
 type packagingSpecGob struct {
@@ -86,6 +89,15 @@
 	ArchType              ArchType
 	Overrides             []string
 	Owner                 string
+	Variation             string
+}
+
+func (p *PackagingSpec) Owner() string {
+	return p.owner
+}
+
+func (p *PackagingSpec) Variation() string {
+	return p.variation
 }
 
 func (p *PackagingSpec) ToGob() *packagingSpecGob {
@@ -101,6 +113,7 @@
 		ArchType:              p.archType,
 		Overrides:             p.overrides.ToSlice(),
 		Owner:                 p.owner,
+		Variation:             p.variation,
 	}
 }
 
@@ -116,6 +129,7 @@
 	p.archType = data.ArchType
 	p.overrides = uniquelist.Make(data.Overrides)
 	p.owner = data.Owner
+	p.variation = data.Variation
 }
 
 func (p *PackagingSpec) GobEncode() ([]byte, error) {
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 8d7f92f..6d65217 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -15,7 +15,9 @@
 package filesystem
 
 import (
+	"cmp"
 	"fmt"
+	"slices"
 	"strings"
 	"sync/atomic"
 
@@ -247,6 +249,38 @@
 	a.distFiles(ctx)
 }
 
+// Returns a list of modules that are installed, which are collected from the dependency
+// filesystem and super_image modules.
+func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android.Module {
+	fsInfoMap := a.getFsInfos(ctx)
+	allOwners := make(map[string][]string)
+	for _, partition := range android.SortedKeys(fsInfoMap) {
+		fsInfo := fsInfoMap[partition]
+		for _, owner := range fsInfo.Owners {
+			allOwners[owner.Name] = append(allOwners[owner.Name], owner.Variation)
+		}
+	}
+
+	ret := []android.Module{}
+	ctx.WalkDepsProxy(func(mod, _ android.ModuleProxy) bool {
+		if variations, ok := allOwners[mod.Name()]; ok && android.InList(ctx.OtherModuleSubDir(mod), variations) {
+			ret = append(ret, mod)
+		}
+		return true
+	})
+
+	// Remove duplicates
+	ret = android.FirstUniqueFunc(ret, func(a, b android.Module) bool {
+		return a.String() == b.String()
+	})
+
+	// Sort the modules by their names and variants
+	slices.SortFunc(ret, func(a, b android.Module) int {
+		return cmp.Compare(a.String(), b.String())
+	})
+	return ret
+}
+
 func (a *androidDevice) distFiles(ctx android.ModuleContext) {
 	if !ctx.Config().KatiEnabled() {
 		if proptools.Bool(a.deviceProps.Main_device) {
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index f84993d..aadb762 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -384,6 +384,11 @@
 	Json android.Path
 }
 
+type InstalledModuleInfo struct {
+	Name      string
+	Variation string
+}
+
 type FilesystemInfo struct {
 	// The built filesystem image
 	Output android.Path
@@ -428,6 +433,8 @@
 	SelinuxFc android.Path
 
 	FilesystemConfig android.Path
+
+	Owners []InstalledModuleInfo
 }
 
 // FullInstallPathInfo contains information about the "full install" paths of all the files
@@ -673,6 +680,7 @@
 		ErofsCompressHints: erofsCompressHints,
 		SelinuxFc:          f.selinuxFc,
 		FilesystemConfig:   f.generateFilesystemConfig(ctx, rootDir, rebasedDir),
+		Owners:             f.gatherOwners(specs),
 	}
 
 	android.SetProvider(ctx, FilesystemProvider, fsInfo)
@@ -1326,6 +1334,18 @@
 	return f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, f.filesystemBuilder.FilterPackagingSpec, f.filesystemBuilder.ModifyPackagingSpec)
 }
 
+func (f *filesystem) gatherOwners(specs map[string]android.PackagingSpec) []InstalledModuleInfo {
+	var owners []InstalledModuleInfo
+	for _, p := range android.SortedKeys(specs) {
+		spec := specs[p]
+		owners = append(owners, InstalledModuleInfo{
+			Name:      spec.Owner(),
+			Variation: spec.Variation(),
+		})
+	}
+	return owners
+}
+
 // Dexpreopt files are installed to system_other. Collect the packaingSpecs for the dexpreopt files
 // from this partition to export to the system_other partition later.
 func (f *filesystem) systemOtherFiles(ctx android.ModuleContext) map[string]android.PackagingSpec {