Merge "Build Go tools for arm" into main
diff --git a/aconfig/exported_java_aconfig_library.go b/aconfig/exported_java_aconfig_library.go
index 63d824a..ffb2a0c 100644
--- a/aconfig/exported_java_aconfig_library.go
+++ b/aconfig/exported_java_aconfig_library.go
@@ -15,8 +15,9 @@
 package aconfig
 
 import (
-	"android/soong/android"
 	"strconv"
+
+	"android/soong/android"
 )
 
 func ExportedJavaDeclarationsLibraryFactory() android.Singleton {
@@ -30,7 +31,7 @@
 func (this *exportedJavaDeclarationsLibrarySingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	// Find all of the aconfig_declarations modules
 	var cacheFiles android.Paths
-	ctx.VisitAllModules(func(module android.Module) {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
 		decl, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey)
 		if !ok {
 			return
diff --git a/android/all_teams.go b/android/all_teams.go
index 3b20107..8b55ade 100644
--- a/android/all_teams.go
+++ b/android/all_teams.go
@@ -78,19 +78,19 @@
 	t.teams = make(map[string]teamProperties)
 	t.teams_for_mods = make(map[string]moduleTeamAndTestInfo)
 
-	ctx.VisitAllModules(func(module Module) {
+	ctx.VisitAllModuleProxies(func(module ModuleProxy) {
 		bpFile := ctx.BlueprintFile(module)
 
 		// Package Modules and Team Modules are stored in a map so we can look them up by name for
 		// modules without a team.
-		if pack, ok := module.(*packageModule); ok {
+		if pack, ok := OtherModuleProvider(ctx, module, PackageInfoProvider); ok {
 			// Packages don't have names, use the blueprint file as the key. we can't get qualifiedModuleId in t context.
 			pkgKey := bpFile
-			t.packages[pkgKey] = pack.properties
+			t.packages[pkgKey] = pack.Properties
 			return
 		}
-		if team, ok := module.(*teamModule); ok {
-			t.teams[team.Name()] = team.properties
+		if team, ok := OtherModuleProvider(ctx, module, TeamInfoProvider); ok {
+			t.teams[module.Name()] = team.Properties
 			return
 		}
 
@@ -116,7 +116,7 @@
 			testOnly:           testModInfo.TestOnly,
 			topLevelTestTarget: testModInfo.TopLevelTarget,
 			kind:               ctx.ModuleType(module),
-			teamName:           module.base().Team(),
+			teamName:           OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).Team,
 		}
 		t.teams_for_mods[module.Name()] = entry
 
diff --git a/android/androidmk.go b/android/androidmk.go
index d9d78f3..6a1701d 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -107,8 +107,6 @@
 	SubName string
 	// If set, this value overrides the base module name. SubName is still appended.
 	OverrideName string
-	// Dist files to output
-	DistFiles TaggedDistFiles
 	// The output file for Kati to process and/or install. If absent, the module is skipped.
 	OutputFile OptionalPath
 	// If true, the module is skipped and does not appear on the final Android-<product name>.mk
@@ -351,36 +349,15 @@
 	return
 }
 
-// Compute the contributions that the module makes to the dist.
-func (a *AndroidMkEntries) getDistContributions(mod Module) *distContributions {
+// This gets the dist contributuions from the given module that were specified in the Android.bp
+// file using the dist: property. It does not include contribututions that the module's
+// implementation may have defined with ctx.DistForGoals(), for that, see DistProvider.
+func getDistContributions(ctx ConfigAndOtherModuleProviderContext, mod Module) *distContributions {
 	amod := mod.base()
 	name := amod.BaseModuleName()
 
-	// Collate the set of associated tag/paths available for copying to the dist.
-	// Start with an empty (nil) set.
-	var availableTaggedDists TaggedDistFiles
-
-	// Then merge in any that are provided explicitly by the module.
-	if a.DistFiles != nil {
-		// Merge the DistFiles into the set.
-		availableTaggedDists = availableTaggedDists.merge(a.DistFiles)
-	}
-
-	// If no paths have been provided for the DefaultDistTag and the output file is
-	// valid then add that as the default dist path.
-	if _, ok := availableTaggedDists[DefaultDistTag]; !ok && a.OutputFile.Valid() {
-		availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
-	}
-
-	info := OtherModuleProviderOrDefault(a.entryContext, mod, InstallFilesProvider)
-	// If the distFiles created by GenerateTaggedDistFiles contains paths for the
-	// DefaultDistTag then that takes priority so delete any existing paths.
-	if _, ok := info.DistFiles[DefaultDistTag]; ok {
-		delete(availableTaggedDists, DefaultDistTag)
-	}
-
-	// Finally, merge the distFiles created by GenerateTaggedDistFiles.
-	availableTaggedDists = availableTaggedDists.merge(info.DistFiles)
+	info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
+	availableTaggedDists := info.DistFiles
 
 	if len(availableTaggedDists) == 0 {
 		// Nothing dist-able for this module.
@@ -454,7 +431,7 @@
 
 			productString := ""
 			if dist.Append_artifact_with_product != nil && *dist.Append_artifact_with_product {
-				productString = fmt.Sprintf("_%s", a.entryContext.Config().DeviceProduct())
+				productString = fmt.Sprintf("_%s", ctx.Config().DeviceProduct())
 			}
 
 			if suffix != "" || productString != "" {
@@ -502,7 +479,7 @@
 // Compute the list of Make strings to declare phony goals and dist-for-goals
 // calls from the module's dist and dists properties.
 func (a *AndroidMkEntries) GetDistForGoals(mod Module) []string {
-	distContributions := a.getDistContributions(mod)
+	distContributions := getDistContributions(a.entryContext, mod)
 	if distContributions == nil {
 		return nil
 	}
@@ -911,18 +888,9 @@
 			if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
 				moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...)
 			}
-			if contribution := info.PrimaryInfo.getDistContributions(ctx, mod, &commonInfo); contribution != nil {
+			if contribution := getDistContributions(ctx, mod); contribution != nil {
 				allDistContributions = append(allDistContributions, *contribution)
 			}
-			for _, ei := range info.ExtraInfo {
-				ei.fillInEntries(ctx, mod, &commonInfo)
-				if ei.disabled() {
-					continue
-				}
-				if contribution := ei.getDistContributions(ctx, mod, &commonInfo); contribution != nil {
-					allDistContributions = append(allDistContributions, *contribution)
-				}
-			}
 		} else {
 			if x, ok := mod.(AndroidMkDataProvider); ok {
 				data := x.AndroidMk()
@@ -938,7 +906,7 @@
 				if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
 					moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...)
 				}
-				if contribution := data.Entries.getDistContributions(mod); contribution != nil {
+				if contribution := getDistContributions(ctx, mod); contribution != nil {
 					allDistContributions = append(allDistContributions, *contribution)
 				}
 			}
@@ -952,7 +920,7 @@
 					if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
 						moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...)
 					}
-					if contribution := entries.getDistContributions(mod); contribution != nil {
+					if contribution := getDistContributions(ctx, mod); contribution != nil {
 						allDistContributions = append(allDistContributions, *contribution)
 					}
 				}
@@ -1295,8 +1263,6 @@
 	SubName string
 	// If set, this value overrides the base module name. SubName is still appended.
 	OverrideName string
-	// Dist files to output
-	DistFiles TaggedDistFiles
 	// The output file for Kati to process and/or install. If absent, the module is skipped.
 	OutputFile OptionalPath
 	// If true, the module is skipped and does not appear on the final Android-<product name>.mk
@@ -1663,7 +1629,7 @@
 // TODO(b/397766191): Change the signature to take ModuleProxy
 // Please only access the module's internal data through providers.
 func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod Module, commonInfo *CommonModuleInfo) []string {
-	distContributions := a.getDistContributions(ctx, mod, commonInfo)
+	distContributions := getDistContributions(ctx, mod)
 	if distContributions == nil {
 		return nil
 	}
@@ -1671,133 +1637,6 @@
 	return generateDistContributionsForMake(distContributions)
 }
 
-// Compute the contributions that the module makes to the dist.
-// TODO(b/397766191): Change the signature to take ModuleProxy
-// Please only access the module's internal data through providers.
-func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod Module,
-	commonInfo *CommonModuleInfo) *distContributions {
-	name := commonInfo.BaseModuleName
-
-	// Collate the set of associated tag/paths available for copying to the dist.
-	// Start with an empty (nil) set.
-	var availableTaggedDists TaggedDistFiles
-
-	// Then merge in any that are provided explicitly by the module.
-	if a.DistFiles != nil {
-		// Merge the DistFiles into the set.
-		availableTaggedDists = availableTaggedDists.merge(a.DistFiles)
-	}
-
-	// If no paths have been provided for the DefaultDistTag and the output file is
-	// valid then add that as the default dist path.
-	if _, ok := availableTaggedDists[DefaultDistTag]; !ok && a.OutputFile.Valid() {
-		availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
-	}
-
-	info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
-	// If the distFiles created by GenerateTaggedDistFiles contains paths for the
-	// DefaultDistTag then that takes priority so delete any existing paths.
-	if _, ok := info.DistFiles[DefaultDistTag]; ok {
-		delete(availableTaggedDists, DefaultDistTag)
-	}
-
-	// Finally, merge the distFiles created by GenerateTaggedDistFiles.
-	availableTaggedDists = availableTaggedDists.merge(info.DistFiles)
-
-	if len(availableTaggedDists) == 0 {
-		// Nothing dist-able for this module.
-		return nil
-	}
-
-	// Collate the contributions this module makes to the dist.
-	distContributions := &distContributions{}
-
-	if !commonInfo.ExemptFromRequiredApplicableLicensesProperty {
-		distContributions.licenseMetadataFile = info.LicenseMetadataFile
-	}
-
-	// Iterate over this module's dist structs, merged from the dist and dists properties.
-	for _, dist := range commonInfo.Dists {
-		// Get the list of goals this dist should be enabled for. e.g. sdk, droidcore
-		goals := strings.Join(dist.Targets, " ")
-
-		// Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map"
-		var tag string
-		if dist.Tag == nil {
-			// If the dist struct does not specify a tag, use the default output files tag.
-			tag = DefaultDistTag
-		} else {
-			tag = *dist.Tag
-		}
-
-		// Get the paths of the output files to be dist'd, represented by the tag.
-		// Can be an empty list.
-		tagPaths := availableTaggedDists[tag]
-		if len(tagPaths) == 0 {
-			// Nothing to dist for this tag, continue to the next dist.
-			continue
-		}
-
-		if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) {
-			errorMessage := "%s: Cannot apply dest/suffix for more than one dist " +
-				"file for %q goals tag %q in module %s. The list of dist files, " +
-				"which should have a single element, is:\n%s"
-			panic(fmt.Errorf(errorMessage, mod, goals, tag, name, tagPaths))
-		}
-
-		copiesForGoals := distContributions.getCopiesForGoals(goals)
-
-		// Iterate over each path adding a copy instruction to copiesForGoals
-		for _, path := range tagPaths {
-			// It's possible that the Path is nil from errant modules. Be defensive here.
-			if path == nil {
-				tagName := "default" // for error message readability
-				if dist.Tag != nil {
-					tagName = *dist.Tag
-				}
-				panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name))
-			}
-
-			dest := filepath.Base(path.String())
-
-			if dist.Dest != nil {
-				var err error
-				if dest, err = validateSafePath(*dist.Dest); err != nil {
-					// This was checked in ModuleBase.GenerateBuildActions
-					panic(err)
-				}
-			}
-
-			ext := filepath.Ext(dest)
-			suffix := ""
-			if dist.Suffix != nil {
-				suffix = *dist.Suffix
-			}
-
-			productString := ""
-			if dist.Append_artifact_with_product != nil && *dist.Append_artifact_with_product {
-				productString = fmt.Sprintf("_%s", ctx.Config().DeviceProduct())
-			}
-
-			if suffix != "" || productString != "" {
-				dest = strings.TrimSuffix(dest, ext) + suffix + productString + ext
-			}
-
-			if dist.Dir != nil {
-				var err error
-				if dest, err = validateSafePath(*dist.Dir, dest); err != nil {
-					// This was checked in ModuleBase.GenerateBuildActions
-					panic(err)
-				}
-			}
-
-			copiesForGoals.addCopyInstruction(path, dest)
-		}
-	}
-
-	return distContributions
-}
-
 func deepCopyAndroidMkProviderInfo(providerInfo *AndroidMkProviderInfo) AndroidMkProviderInfo {
 	info := AndroidMkProviderInfo{
 		PrimaryInfo: deepCopyAndroidMkInfo(&providerInfo.PrimaryInfo),
@@ -1815,9 +1654,8 @@
 		Class:        mkinfo.Class,
 		SubName:      mkinfo.SubName,
 		OverrideName: mkinfo.OverrideName,
-		// There is no modification on DistFiles or OutputFile, so no need to
+		// There is no modification on OutputFile, so no need to
 		// make their deep copy.
-		DistFiles:       mkinfo.DistFiles,
 		OutputFile:      mkinfo.OutputFile,
 		Disabled:        mkinfo.Disabled,
 		Include:         mkinfo.Include,
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index 0a81fb8..cd61133 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -34,7 +34,6 @@
 	}
 
 	data       AndroidMkData
-	distFiles  TaggedDistFiles
 	outputFile OptionalPath
 }
 
@@ -73,7 +72,6 @@
 		path := PathForTesting("default-dist.out")
 		defaultDistPaths = Paths{path}
 		m.setOutputFiles(ctx, defaultDistPaths)
-		m.distFiles = MakeDefaultDistFiles(path)
 
 	case defaultDistFiles_Tagged:
 		// Module types that set AndroidMkEntry.DistFiles to the result of calling
@@ -84,11 +82,6 @@
 		// will be the same as empty-string-tag output.
 		defaultDistPaths = PathsForTesting("one.out")
 		m.setOutputFiles(ctx, defaultDistPaths)
-
-		// This must be called after setting defaultDistPaths/outputFile as
-		// GenerateTaggedDistFiles calls into outputFiles property which may use
-		// those fields.
-		m.distFiles = m.GenerateTaggedDistFiles(ctx)
 	}
 }
 
@@ -113,7 +106,6 @@
 	return []AndroidMkEntries{
 		{
 			Class:      "CUSTOM_MODULE",
-			DistFiles:  m.distFiles,
 			OutputFile: m.outputFile,
 		},
 	}
@@ -354,7 +346,7 @@
 			if len(entries) != 1 {
 				t.Errorf("Expected a single AndroidMk entry, got %d", len(entries))
 			}
-			distContributions := entries[0].getDistContributions(module)
+			distContributions := getDistContributions(ctx, module)
 
 			if err := compareContributions(expectedContributions, distContributions); err != nil {
 				t.Errorf("%s\nExpected Contributions\n%sActualContributions\n%s",
@@ -656,8 +648,8 @@
 				default_dist_files: "none",
 				dist_output_file: false,
 				dists: [
-					// The following is silently ignored because there is not default file
-					// in either the dist files or the output file.
+					// The following will dist one.out because there's no default dist file provided
+					// (default_dist_files: "none") and one.out is the outputfile for the "" tag.
 					{
 						targets: ["my_goal"],
 					},
@@ -672,6 +664,12 @@
 			{
 				goals: "my_goal",
 				copies: []distCopy{
+					distCopyForTest("one.out", "one.out"),
+				},
+			},
+			{
+				goals: "my_goal",
+				copies: []distCopy{
 					distCopyForTest("two.out", "two.out"),
 					distCopyForTest("three/four.out", "four.out"),
 				},
diff --git a/android/apex.go b/android/apex.go
index 91fa2c7..4e92f44 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -646,6 +646,13 @@
 	FullListPath() Path
 }
 
+type ApexBundleDepsData struct {
+	Updatable    bool
+	FlatListPath Path
+}
+
+var ApexBundleDepsDataProvider = blueprint.NewProvider[ApexBundleDepsData]()
+
 func (d *ApexBundleDepsInfo) FlatListPath() Path {
 	return d.flatListPath
 }
diff --git a/android/config.go b/android/config.go
index 54c8aac..696e772 100644
--- a/android/config.go
+++ b/android/config.go
@@ -2229,7 +2229,6 @@
 		"RELEASE_APEX_CONTRIBUTIONS_NFC":                     "com.android.nfcservices",
 		"RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION": "com.android.ondevicepersonalization",
 		"RELEASE_APEX_CONTRIBUTIONS_PERMISSION":              "com.android.permission",
-		"RELEASE_APEX_CONTRIBUTIONS_PRIMARY_LIBS":            "",
 		"RELEASE_APEX_CONTRIBUTIONS_PROFILING":               "com.android.profiling",
 		"RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING":   "com.android.rkpd",
 		"RELEASE_APEX_CONTRIBUTIONS_RESOLV":                  "com.android.resolv",
@@ -2282,10 +2281,18 @@
 }
 
 func (c *config) UseDebugArt() bool {
+	// If the ArtTargetIncludeDebugBuild product variable is set then return its value.
 	if c.productVariables.ArtTargetIncludeDebugBuild != nil {
 		return Bool(c.productVariables.ArtTargetIncludeDebugBuild)
 	}
 
+	// If the RELEASE_APEX_CONTRIBUTIONS_ART build flag is set to use a prebuilt ART apex
+	// then don't use the debug apex.
+	if val, ok := c.GetBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART"); ok && val != "" {
+		return false
+	}
+
+	// Default to the debug apex for eng builds.
 	return Bool(c.productVariables.Eng)
 }
 
diff --git a/android/filegroup.go b/android/filegroup.go
index 47102b9..4fad52a 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -131,10 +131,11 @@
 	return append(Paths{}, fg.srcs...)
 }
 
-func (fg *fileGroup) MakeVars(ctx MakeVarsModuleContext) {
+func (fg *fileGroup) MakeVars(_ MakeVarsModuleContext) []ModuleMakeVarsValue {
 	if makeVar := String(fg.properties.Export_to_make_var); makeVar != "" {
-		ctx.StrictRaw(makeVar, strings.Join(fg.srcs.Strings(), " "))
+		return []ModuleMakeVarsValue{{makeVar, strings.Join(fg.srcs.Strings(), " ")}}
 	}
+	return nil
 }
 
 // Defaults
diff --git a/android/logtags.go b/android/logtags.go
index abc37f9..88d36ec 100644
--- a/android/logtags.go
+++ b/android/logtags.go
@@ -42,8 +42,8 @@
 
 func (l *logtagsSingleton) GenerateBuildActions(ctx SingletonContext) {
 	var allLogtags Paths
-	ctx.VisitAllModules(func(module Module) {
-		if !module.ExportedToMake() {
+	ctx.VisitAllModuleProxies(func(module ModuleProxy) {
+		if !OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).ExportedToMake {
 			return
 		}
 		if logtagsInfo, ok := OtherModuleProvider(ctx, module, LogtagsProviderKey); ok {
diff --git a/android/makevars.go b/android/makevars.go
index 2931d0b..692b27e 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -84,6 +84,7 @@
 	Errorf(format string, args ...interface{})
 
 	VisitAllModules(visit func(Module))
+	VisitAllModuleProxies(visit func(proxy ModuleProxy))
 	VisitAllModulesIf(pred func(Module) bool, visit func(Module))
 
 	// Verify the make variable matches the Soong version, fail the build
@@ -108,7 +109,7 @@
 // MakeVarsModuleContext contains the set of functions available for modules
 // implementing the ModuleMakeVarsProvider interface.
 type MakeVarsModuleContext interface {
-	BaseMakeVarsContext
+	Config() Config
 }
 
 var _ PathContext = MakeVarsContext(nil)
@@ -150,14 +151,21 @@
 	return func(ctx MakeVarsContext) { singleton.MakeVars(ctx) }
 }
 
+type ModuleMakeVarsValue struct {
+	// Make variable name.
+	Name string
+	// Make variable value.
+	Value string
+}
+
 // ModuleMakeVarsProvider is a Module with an extra method to provide extra values to be exported to Make.
 type ModuleMakeVarsProvider interface {
-	Module
-
 	// MakeVars uses a MakeVarsModuleContext to provide extra values to be exported to Make.
-	MakeVars(ctx MakeVarsModuleContext)
+	MakeVars(ctx MakeVarsModuleContext) []ModuleMakeVarsValue
 }
 
+var ModuleMakeVarsInfoProvider = blueprint.NewProvider[[]ModuleMakeVarsValue]()
+
 // /////////////////////////////////////////////////////////////////////////////
 
 func makeVarsSingletonFunc() Singleton {
@@ -250,19 +258,24 @@
 	dists = append(dists, singletonDists.dists...)
 	singletonDists.lock.Unlock()
 
-	ctx.VisitAllModules(func(m Module) {
-		if provider, ok := m.(ModuleMakeVarsProvider); ok && m.Enabled(ctx) {
+	ctx.VisitAllModuleProxies(func(m ModuleProxy) {
+		commonInfo, _ := OtherModuleProvider(ctx, m, CommonModuleInfoKey)
+		if provider, ok := OtherModuleProvider(ctx, m, ModuleMakeVarsInfoProvider); ok &&
+			commonInfo.Enabled {
 			mctx := &makeVarsContext{
 				SingletonContext: ctx,
 			}
-
-			provider.MakeVars(mctx)
+			for _, val := range provider {
+				if val.Name != "" {
+					mctx.StrictRaw(val.Name, val.Value)
+				}
+			}
 
 			vars = append(vars, mctx.vars...)
 			phonies = append(phonies, mctx.phonies...)
 		}
 
-		if m.ExportedToMake() {
+		if commonInfo.ExportedToMake {
 			info := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider)
 			katiInstalls = append(katiInstalls, info.KatiInstalls...)
 			katiInitRcInstalls = append(katiInitRcInstalls, info.KatiInitRcInstalls...)
diff --git a/android/module.go b/android/module.go
index 996c64e..622399b 100644
--- a/android/module.go
+++ b/android/module.go
@@ -15,6 +15,7 @@
 package android
 
 import (
+	"errors"
 	"fmt"
 	"net/url"
 	"path/filepath"
@@ -613,17 +614,6 @@
 	return t
 }
 
-func MakeDefaultDistFiles(paths ...Path) TaggedDistFiles {
-	for _, p := range paths {
-		if p == nil {
-			panic("The path to a dist file cannot be nil.")
-		}
-	}
-
-	// The default OutputFile tag is the empty "" string.
-	return TaggedDistFiles{DefaultDistTag: paths}
-}
-
 type hostAndDeviceProperties struct {
 	// If set to true, build a variant of the module for the host.  Defaults to false.
 	Host_supported *bool
@@ -1230,6 +1220,13 @@
 		tag := proptools.StringDefault(dist.Tag, DefaultDistTag)
 
 		distFileForTagFromProvider, err := outputFilesForModuleFromProvider(ctx, m.module, tag)
+
+		// If the module doesn't define output files for the DefaultDistTag, try the files under
+		// the "" tag.
+		if tag == DefaultDistTag && errors.Is(err, ErrUnsupportedOutputTag) {
+			distFileForTagFromProvider, err = outputFilesForModuleFromProvider(ctx, m.module, "")
+		}
+
 		if err != OutputFilesProviderNotSet {
 			if err != nil && tag != DefaultDistTag {
 				ctx.PropertyErrorf("dist.tag", "%s", err.Error())
@@ -1939,6 +1936,8 @@
 	TargetRequiredModuleNames                    []string
 	VintfFragmentModuleNames                     []string
 	Dists                                        []Dist
+	ExportedToMake                               bool
+	Team                                         string
 }
 
 type ApiLevelOrPlatform struct {
@@ -2298,6 +2297,8 @@
 		TargetRequiredModuleNames:                    m.module.TargetRequiredModuleNames(),
 		VintfFragmentModuleNames:                     m.module.VintfFragmentModuleNames(ctx),
 		Dists:                                        m.Dists(),
+		ExportedToMake:                               m.ExportedToMake(),
+		Team:                                         m.Team(),
 	}
 	if mm, ok := m.module.(interface {
 		MinSdkVersion(ctx EarlyModuleContext) ApiLevel
@@ -2368,6 +2369,10 @@
 			GeneratedDeps:        s.GeneratedDeps(),
 		})
 	}
+
+	if v, ok := m.module.(ModuleMakeVarsProvider); m.Enabled(ctx) && ok {
+		SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx))
+	}
 }
 
 func SetJarJarPrefixHandler(handler func(ModuleContext)) {
@@ -2884,6 +2889,8 @@
 
 // OutputFileForModule returns the output file paths with the given tag.  On error, including if the
 // module produced zero or multiple paths, it reports errors to the ctx and returns nil.
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
 func OutputFileForModule(ctx PathContext, module Module, tag string) Path {
 	paths, err := outputFilesForModule(ctx, module, tag)
 	if err != nil {
@@ -2924,6 +2931,8 @@
 	EqualModules(m1, m2 Module) bool
 }
 
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
 func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, error) {
 	outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag)
 	if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet {
@@ -2956,14 +2965,12 @@
 // If a module doesn't have the OutputFilesProvider, nil is returned.
 func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string) (Paths, error) {
 	var outputFiles OutputFilesInfo
-	fromProperty := false
 
 	if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx {
 		if !mctx.EqualModules(mctx.Module(), module) {
 			outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
 		} else {
 			outputFiles = mctx.GetOutputFiles()
-			fromProperty = true
 		}
 	} else if cta, isCta := ctx.(*singletonContextAdaptor); isCta {
 		outputFiles, _ = OtherModuleProvider(cta, module, OutputFilesProvider)
@@ -2980,10 +2987,8 @@
 	} else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag {
 		return taggedOutputFiles, nil
 	} else {
-		if fromProperty {
-			return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag)
-		} else {
-			return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+		return nil, UnsupportedOutputTagError{
+			tag: tag,
 		}
 	}
 }
@@ -3002,8 +3007,24 @@
 
 var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]()
 
+type UnsupportedOutputTagError struct {
+	tag string
+}
+
+func (u UnsupportedOutputTagError) Error() string {
+	return fmt.Sprintf("unsupported output tag %q", u.tag)
+}
+
+func (u UnsupportedOutputTagError) Is(e error) bool {
+	_, ok := e.(UnsupportedOutputTagError)
+	return ok
+}
+
+var _ error = UnsupportedOutputTagError{}
+
 // This is used to mark the case where OutputFilesProvider is not set on some modules.
 var OutputFilesProviderNotSet = fmt.Errorf("No output files from provider")
+var ErrUnsupportedOutputTag = UnsupportedOutputTagError{}
 
 // Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to
 // specify that they can be used as a tool by a genrule module.
@@ -3069,7 +3090,7 @@
 
 	modulesInDir := make(map[string]Paths)
 
-	ctx.VisitAllModules(func(module Module) {
+	ctx.VisitAllModuleProxies(func(module ModuleProxy) {
 		info := OtherModuleProviderOrDefault(ctx, module, FinalModuleBuildTargetsProvider)
 
 		if info.CheckbuildTarget != nil {
diff --git a/android/neverallow.go b/android/neverallow.go
index 70af2ac..14dc6d2 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -298,33 +298,29 @@
 			WithoutMatcher("visibility", InAllowedList([]string{"//trusty/vendor/google/aosp/scripts", "//trusty/vendor/google/proprietary/scripts"})).Because(reason),
 		NeverAllow().
 			ModuleType("genrule").
-			// TODO: remove the 4 below targets once new targets are submitted
-			Without("name", "trusty-arm64.lk.elf.gen").
-			Without("name", "trusty-arm64-virt-test-debug.lk.elf.gen").
-			Without("name", "trusty-x86_64.lk.elf.gen").
-			Without("name", "trusty-x86_64-test.lk.elf.gen").
-			// trusty vm target names moving forward
-			Without("name", "trusty-test_vm-arm64.elf.gen").
-			Without("name", "trusty-test_vm-x86.elf.gen").
-			Without("name", "trusty-security_vm-arm64.elf.gen").
-			Without("name", "trusty-security_vm-x86.elf.gen").
-			Without("name", "trusty-widevine_vm-arm64.elf.gen").
-			Without("name", "trusty-widevine_vm-x86.elf.gen").
+			// Trusty TEE target names
+			Without("name", "trusty_tee_package_goog").
+			Without("name", "trusty_tee_package").
+			// Trusty vm target names
+			Without("name", "trusty_test_vm_arm64.bin").
+			Without("name", "trusty_test_vm_x86_64.elf").
+			Without("name", "trusty_security_vm_arm64.bin").
+			Without("name", "trusty_security_vm_x86_64.elf").
+			Without("name", "trusty_widevine_vm_arm64.bin").
+			Without("name", "trusty_widevine_vm_x86_64.elf").
 			WithMatcher("dir_srcs", isSetMatcherInstance).Because(reason),
 		NeverAllow().
 			ModuleType("genrule").
-			// TODO: remove the 4 below targets once new targets are submitted
-			Without("name", "trusty-arm64.lk.elf.gen").
-			Without("name", "trusty-arm64-virt-test-debug.lk.elf.gen").
-			Without("name", "trusty-x86_64.lk.elf.gen").
-			Without("name", "trusty-x86_64-test.lk.elf.gen").
-			// trusty vm target names moving forward
-			Without("name", "trusty-test_vm-arm64.elf.gen").
-			Without("name", "trusty-test_vm-x86.elf.gen").
-			Without("name", "trusty-security_vm-arm64.elf.gen").
-			Without("name", "trusty-security_vm-x86.elf.gen").
-			Without("name", "trusty-widevine_vm-arm64.elf.gen").
-			Without("name", "trusty-widevine_vm-x86.elf.gen").
+			// Trusty TEE target names
+			Without("name", "trusty_tee_package_goog").
+			Without("name", "trusty_tee_package").
+			// Trusty vm target names
+			Without("name", "trusty_test_vm_arm64.bin").
+			Without("name", "trusty_test_vm_x86_64.elf").
+			Without("name", "trusty_security_vm_arm64.bin").
+			Without("name", "trusty_security_vm_x86_64.elf").
+			Without("name", "trusty_widevine_vm_arm64.bin").
+			Without("name", "trusty_widevine_vm_x86_64.elf").
 			With("keep_gendir", "true").Because(reason),
 	}
 }
diff --git a/android/package.go b/android/package.go
index 385326e..42f17b1 100644
--- a/android/package.go
+++ b/android/package.go
@@ -38,6 +38,12 @@
 	Default_team                *string `android:"path"`
 }
 
+type PackageInfo struct {
+	Properties packageProperties
+}
+
+var PackageInfoProvider = blueprint.NewProvider[PackageInfo]()
+
 type packageModule struct {
 	ModuleBase
 
@@ -60,6 +66,10 @@
 		Enabled:                 true,
 		PrimaryLicensesProperty: p.primaryLicensesProperty,
 	})
+
+	ctx.SetProvider(PackageInfoProvider, PackageInfo{
+		Properties: p.properties,
+	})
 }
 
 func (p *packageModule) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName {
diff --git a/android/paths.go b/android/paths.go
index a020d8a..9c0c9a2 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -235,6 +235,8 @@
 	}
 }
 
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
 func pathContextName(ctx PathContext, module blueprint.Module) string {
 	if x, ok := ctx.(interface{ ModuleName(blueprint.Module) string }); ok {
 		return x.ModuleName(module)
diff --git a/android/phony.go b/android/phony.go
index 7bdd9d3..99ff0aa 100644
--- a/android/phony.go
+++ b/android/phony.go
@@ -55,7 +55,7 @@
 
 func (p *phonySingleton) GenerateBuildActions(ctx SingletonContext) {
 	p.phonyMap = getSingletonPhonyMap(ctx.Config())
-	ctx.VisitAllModules(func(m Module) {
+	ctx.VisitAllModuleProxies(func(m ModuleProxy) {
 		if info, ok := OtherModuleProvider(ctx, m, ModulePhonyProvider); ok {
 			for k, v := range info.Phonies {
 				p.phonyMap[k] = append(p.phonyMap[k], v...)
diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go
index 17b3230..7773bf8 100644
--- a/android/prebuilt_build_tool.go
+++ b/android/prebuilt_build_tool.go
@@ -84,13 +84,12 @@
 	t.toolPath = OptionalPathForPath(installedPath)
 }
 
-func (t *prebuiltBuildTool) MakeVars(ctx MakeVarsModuleContext) {
-	if makeVar := String(t.properties.Export_to_make_var); makeVar != "" {
-		if t.Target().Os != ctx.Config().BuildOS {
-			return
-		}
-		ctx.StrictRaw(makeVar, t.toolPath.String())
+func (t *prebuiltBuildTool) MakeVars(ctx MakeVarsModuleContext) []ModuleMakeVarsValue {
+	if makeVar := String(t.properties.Export_to_make_var); makeVar != "" &&
+		t.Target().Os == ctx.Config().BuildOS {
+		return []ModuleMakeVarsValue{{makeVar, t.toolPath.String()}}
 	}
+	return nil
 }
 
 func (t *prebuiltBuildTool) HostToolPath() OptionalPath {
diff --git a/android/provider.go b/android/provider.go
index b48fd91..d005daf 100644
--- a/android/provider.go
+++ b/android/provider.go
@@ -16,6 +16,12 @@
 var _ OtherModuleProviderContext = SingletonContext(nil)
 var _ OtherModuleProviderContext = (*TestContext)(nil)
 
+// ConfigAndOtherModuleProviderContext is OtherModuleProviderContext + ConfigContext
+type ConfigAndOtherModuleProviderContext interface {
+	OtherModuleProviderContext
+	ConfigContext
+}
+
 // OtherModuleProvider reads the provider for the given module.  If the provider has been set the value is
 // returned and the boolean is true.  If it has not been set the zero value of the provider's type  is returned
 // and the boolean is false.  The value returned may be a deep copy of the value originally passed to SetProvider.
diff --git a/android/singleton.go b/android/singleton.go
index a03ea74..96b1022 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -290,6 +290,10 @@
 	return s.SingletonContext.ModuleType(getWrappedModule(module))
 }
 
+func (s *singletonContextAdaptor) BlueprintFile(module blueprint.Module) string {
+	return s.SingletonContext.BlueprintFile(getWrappedModule(module))
+}
+
 func (s *singletonContextAdaptor) VisitAllModulesBlueprint(visit func(blueprint.Module)) {
 	s.SingletonContext.VisitAllModules(visit)
 }
diff --git a/android/team.go b/android/team.go
index c273dc6..ad37f28 100644
--- a/android/team.go
+++ b/android/team.go
@@ -32,6 +32,12 @@
 	Trendy_team_id *string `json:"trendy_team_id"`
 }
 
+type TeamInfo struct {
+	Properties teamProperties
+}
+
+var TeamInfoProvider = blueprint.NewProvider[TeamInfo]()
+
 type teamModule struct {
 	ModuleBase
 	DefaultableModuleBase
@@ -48,7 +54,11 @@
 
 // Real work is done for the module that depends on us.
 // If needed, the team can serialize the config to json/proto file as well.
-func (t *teamModule) GenerateAndroidBuildActions(ctx ModuleContext) {}
+func (t *teamModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+	SetProvider(ctx, TeamInfoProvider, TeamInfo{
+		Properties: t.properties,
+	})
+}
 
 func (t *teamModule) TrendyTeamId(ctx ModuleContext) string {
 	return *t.properties.Trendy_team_id
diff --git a/apex/apex.go b/apex/apex.go
index 6e4685b..4dd3d4c 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2258,6 +2258,11 @@
 	a.enforcePartitionTagOnApexSystemServerJar(ctx)
 
 	a.verifyNativeImplementationLibs(ctx)
+
+	android.SetProvider(ctx, android.ApexBundleDepsDataProvider, android.ApexBundleDepsData{
+		FlatListPath: a.FlatListPath(),
+		Updatable:    a.Updatable(),
+	})
 }
 
 // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index a8bd984..dabec49 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -90,11 +90,11 @@
 
 func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	updatableFlatLists := android.Paths{}
-	ctx.VisitAllModules(func(module android.Module) {
-		if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+		if binaryInfo, ok := android.OtherModuleProvider(ctx, module, android.ApexBundleDepsDataProvider); ok {
 			apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider)
-			if path := binaryInfo.FlatListPath(); path != nil {
-				if binaryInfo.Updatable() || apexInfo.Updatable {
+			if path := binaryInfo.FlatListPath; path != nil {
+				if binaryInfo.Updatable || apexInfo.Updatable {
 					if strings.HasPrefix(module.String(), "com.android.") {
 						updatableFlatLists = append(updatableFlatLists, path)
 					}
@@ -160,11 +160,11 @@
 func (a *apexPrebuiltInfo) GenerateBuildActions(ctx android.SingletonContext) {
 	prebuiltInfos := []android.PrebuiltInfo{}
 
-	ctx.VisitAllModules(func(m android.Module) {
+	ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
 		prebuiltInfo, exists := android.OtherModuleProvider(ctx, m, android.PrebuiltInfoProvider)
 		// Use prebuiltInfoProvider to filter out non apex soong modules.
 		// Use HideFromMake to filter out the unselected variants of a specific apex.
-		if exists && !m.IsHideFromMake() {
+		if exists && !android.OtherModuleProviderOrDefault(ctx, m, android.CommonModuleInfoKey).HideFromMake {
 			prebuiltInfos = append(prebuiltInfos, prebuiltInfo)
 		}
 	})
diff --git a/apex/builder.go b/apex/builder.go
index 15737f8..2fc4902 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -588,6 +588,7 @@
 			}
 			a.extraInstalledFiles = append(a.extraInstalledFiles, installedFile)
 			a.extraInstalledPairs = append(a.extraInstalledPairs, installPair{install.OutputPathOnHost, installedFile})
+			ctx.PackageFile(install.InstallDirOnDevice, install.InstallFileOnDevice, install.OutputPathOnHost)
 		}
 		if performInstalls {
 			for _, dexJar := range fi.systemServerDexJars {
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 3daa4f8..0a97027 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -245,6 +245,7 @@
 		}
 		p.extraInstalledFiles = append(p.extraInstalledFiles, installedFile)
 		p.extraInstalledPairs = append(p.extraInstalledPairs, installPair{install.OutputPathOnHost, installedFile})
+		ctx.PackageFile(install.InstallDirOnDevice, install.InstallFileOnDevice, install.OutputPathOnHost)
 	}
 
 	for _, dexJar := range p.systemServerDexJars {
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 03f229e..b016788 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -244,10 +244,6 @@
 		entries.Class = "HEADER_LIBRARIES"
 	}
 
-	if library.distFile != nil {
-		entries.DistFiles = android.MakeDefaultDistFiles(library.distFile)
-	}
-
 	library.androidMkWriteExportedFlags(entries)
 	library.androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries)
 
@@ -336,7 +332,6 @@
 	ctx.subAndroidMk(config, entries, binary.baseInstaller)
 
 	entries.Class = "EXECUTABLES"
-	entries.DistFiles = binary.distFiles
 	entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", binary.unstrippedOutputFile.String())
 	if len(binary.symlinks) > 0 {
 		entries.AddStrings("LOCAL_MODULE_SYMLINKS", binary.symlinks...)
diff --git a/cc/binary.go b/cc/binary.go
index c4791c5..627d5e5 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -104,8 +104,8 @@
 	// Output archive of gcno coverage information
 	coverageOutputFile android.OptionalPath
 
-	// Location of the files that should be copied to dist dir when requested
-	distFiles android.TaggedDistFiles
+	// Location of the file that should be copied to dist dir when no explicit tag is requested
+	defaultDistFile android.Path
 
 	// Action command lines to run directly after the binary is installed. For example,
 	// may be used to symlink runtime dependencies (such as bionic) alongside installation.
@@ -385,11 +385,11 @@
 			// When dist'ing a library or binary that has use_version_lib set, always
 			// distribute the stamped version, even for the device.
 			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
-			binary.distFiles = android.MakeDefaultDistFiles(versionedOutputFile)
+			binary.defaultDistFile = versionedOutputFile
 
 			if binary.stripper.NeedsStrip(ctx) {
 				out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
-				binary.distFiles = android.MakeDefaultDistFiles(out)
+				binary.defaultDistFile = out
 				binary.stripper.StripExecutableOrSharedLib(ctx, versionedOutputFile, out, stripFlags)
 			}
 
@@ -575,3 +575,10 @@
 		},
 	})
 }
+
+func (binary *binaryDecorator) defaultDistFiles() []android.Path {
+	if binary.defaultDistFile == nil {
+		return nil
+	}
+	return []android.Path{binary.defaultDistFile}
+}
diff --git a/cc/cc.go b/cc/cc.go
index 0e70d48..eae12b8 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -93,6 +93,9 @@
 type LibraryDecoratorInfo struct {
 	ExportIncludeDirs []string
 	InjectBsslHash    bool
+	// Location of the static library in the sysroot. Empty if the library is
+	// not included in the NDK.
+	NdkSysrootPath android.Path
 }
 
 type SnapshotInfo struct {
@@ -104,14 +107,27 @@
 }
 type BenchmarkDecoratorInfo struct{}
 
-type StubDecoratorInfo struct{}
+type StubDecoratorInfo struct {
+	AbiDumpPath  android.OutputPath
+	HasAbiDump   bool
+	AbiDiffPaths android.Paths
+	InstallPath  android.Path
+}
 
-type ObjectLinkerInfo struct{}
+type ObjectLinkerInfo struct {
+	// Location of the object in the sysroot. Empty if the object is not
+	// included in the NDK.
+	NdkSysrootPath android.Path
+}
 
 type LibraryInfo struct {
 	BuildStubs bool
 }
 
+type InstallerInfo struct {
+	StubDecoratorInfo *StubDecoratorInfo
+}
+
 // Common info about the cc module.
 type CcInfo struct {
 	IsPrebuilt             bool
@@ -122,6 +138,7 @@
 	LinkerInfo             *LinkerInfo
 	SnapshotInfo           *SnapshotInfo
 	LibraryInfo            *LibraryInfo
+	InstallerInfo          *InstallerInfo
 }
 
 var CcInfoProvider = blueprint.NewProvider[*CcInfo]()
@@ -176,6 +193,9 @@
 	// Symlinks returns a list of symlinks that should be created for this module.
 	Symlinks               []string
 	APIListCoverageXMLPath android.ModuleOutPath
+	// FuzzSharedLibraries returns the shared library dependencies for this module.
+	// Expects that IsFuzzModule returns true.
+	FuzzSharedLibraries android.RuleBuilderInstalls
 }
 
 var LinkableInfoProvider = blueprint.NewProvider[*LinkableInfo]()
@@ -754,6 +774,10 @@
 	// Get the deps that have been explicitly specified in the properties.
 	linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps
 
+	// Gets a list of files that will be disted when using the dist property without specifying
+	// an output file tag.
+	defaultDistFiles() []android.Path
+
 	moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON)
 }
 
@@ -2334,6 +2358,7 @@
 		case *libraryDecorator:
 			ccInfo.LinkerInfo.LibraryDecoratorInfo = &LibraryDecoratorInfo{
 				InjectBsslHash: Bool(c.linker.(*libraryDecorator).Properties.Inject_bssl_hash),
+				NdkSysrootPath: c.linker.(*libraryDecorator).ndkSysrootPath,
 			}
 		case *testBinary:
 			ccInfo.LinkerInfo.TestBinaryInfo = &TestBinaryInfo{
@@ -2342,7 +2367,9 @@
 		case *benchmarkDecorator:
 			ccInfo.LinkerInfo.BenchmarkDecoratorInfo = &BenchmarkDecoratorInfo{}
 		case *objectLinker:
-			ccInfo.LinkerInfo.ObjectLinkerInfo = &ObjectLinkerInfo{}
+			ccInfo.LinkerInfo.ObjectLinkerInfo = &ObjectLinkerInfo{
+				NdkSysrootPath: c.linker.(*objectLinker).ndkSysrootPath,
+			}
 		case *stubDecorator:
 			ccInfo.LinkerInfo.StubDecoratorInfo = &StubDecoratorInfo{}
 		}
@@ -2362,6 +2389,17 @@
 			BuildStubs: c.library.BuildStubs(),
 		}
 	}
+	if c.installer != nil {
+		ccInfo.InstallerInfo = &InstallerInfo{}
+		if installer, ok := c.installer.(*stubDecorator); ok {
+			ccInfo.InstallerInfo.StubDecoratorInfo = &StubDecoratorInfo{
+				HasAbiDump:   installer.hasAbiDump,
+				AbiDumpPath:  installer.abiDumpPath,
+				AbiDiffPaths: installer.abiDiffPaths,
+				InstallPath:  installer.installPath,
+			}
+		}
+	}
 	android.SetProvider(ctx, CcInfoProvider, &ccInfo)
 
 	c.setOutputFiles(ctx)
@@ -2411,6 +2449,12 @@
 		info.APIListCoverageXMLPath = vi.GetAPIListCoverageXMLPath()
 	}
 
+	if !mod.PreventInstall() && fuzz.IsValid(ctx, mod.FuzzModuleStruct()) && mod.IsFuzzModule() {
+		info.FuzzSharedLibraries = mod.FuzzSharedLibraries()
+		fm := mod.FuzzPackagedModule()
+		fuzz.SetFuzzPackagedModuleInfo(ctx, &fm)
+	}
+
 	return info
 }
 
@@ -2423,6 +2467,10 @@
 	if c.linker != nil {
 		ctx.SetOutputFiles(android.PathsIfNonNil(c.linker.unstrippedOutputFilePath()), "unstripped")
 		ctx.SetOutputFiles(android.PathsIfNonNil(c.linker.strippedAllOutputFilePath()), "stripped_all")
+		defaultDistFiles := c.linker.defaultDistFiles()
+		if len(defaultDistFiles) > 0 {
+			ctx.SetOutputFiles(defaultDistFiles, android.DefaultDistTag)
+		}
 	}
 }
 
diff --git a/cc/fuzz.go b/cc/fuzz.go
index bd3d8e4..325354b 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -470,43 +470,37 @@
 	// multiple fuzzers that depend on the same shared library.
 	sharedLibraryInstalled := make(map[string]bool)
 
-	ctx.VisitAllModules(func(module android.Module) {
-		ccModule, ok := module.(LinkableInterface)
-		if !ok || ccModule.PreventInstall() {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+		ccModule, ok := android.OtherModuleProvider(ctx, module, LinkableInfoProvider)
+		if !ok {
 			return
 		}
 		// Discard non-fuzz targets.
-		if ok := fuzz.IsValid(ctx, ccModule.FuzzModuleStruct()); !ok {
+		fuzzInfo, ok := android.OtherModuleProvider(ctx, module, fuzz.FuzzPackagedModuleInfoProvider)
+		if !ok {
 			return
 		}
 
 		sharedLibsInstallDirPrefix := "lib"
-		if ccModule.InVendor() {
+		if ccModule.InVendor {
 			sharedLibsInstallDirPrefix = "lib/vendor"
 		}
 
-		if !ccModule.IsFuzzModule() {
-			return
-		}
-
+		commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey)
+		isHost := commonInfo.Target.Os.Class == android.Host
 		hostOrTargetString := "target"
-		if ccModule.Target().HostCross {
+		if commonInfo.Target.HostCross {
 			hostOrTargetString = "host_cross"
-		} else if ccModule.Host() {
+		} else if isHost {
 			hostOrTargetString = "host"
 		}
 		if s.onlyIncludePresubmits == true {
 			hostOrTargetString = "presubmit-" + hostOrTargetString
 		}
 
-		fpm := fuzz.FuzzPackagedModule{}
-		if ok {
-			fpm = ccModule.FuzzPackagedModule()
-		}
-
 		intermediatePath := "fuzz"
 
-		archString := ccModule.Target().Arch.ArchType.String()
+		archString := commonInfo.Target.Arch.ArchType.String()
 		archDir := android.PathForIntermediates(ctx, intermediatePath, hostOrTargetString, archString)
 		archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
 
@@ -514,23 +508,24 @@
 		builder := android.NewRuleBuilder(pctx, ctx)
 
 		// Package the corpus, data, dict and config into a zipfile.
-		files = s.PackageArtifacts(ctx, module, fpm, archDir, builder)
+		files = s.PackageArtifacts(ctx, module, &fuzzInfo, archDir, builder)
 
 		// Package shared libraries
-		files = append(files, GetSharedLibsToZip(ccModule.FuzzSharedLibraries(), ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)
+		files = append(files, GetSharedLibsToZip(ccModule.FuzzSharedLibraries, isHost, ccModule.InVendor, &s.FuzzPackager,
+			archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)
 
 		// The executable.
-		files = append(files, fuzz.FileToZip{SourceFilePath: android.OutputFileForModule(ctx, ccModule, "unstripped")})
+		files = append(files, fuzz.FileToZip{SourceFilePath: android.OutputFileForModule(ctx, module, "unstripped")})
 
 		if s.onlyIncludePresubmits == true {
-			if fpm.FuzzProperties.Fuzz_config == nil {
+			if fuzzInfo.FuzzConfig == nil {
 				return
 			}
-			if !BoolDefault(fpm.FuzzProperties.Fuzz_config.Use_for_presubmit, false) {
+			if !fuzzInfo.FuzzConfig.UseForPresubmit {
 				return
 			}
 		}
-		archDirs[archOs], ok = s.BuildZipFile(ctx, module, fpm, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
+		archDirs[archOs], ok = s.BuildZipFile(ctx, module, &fuzzInfo, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
 		if !ok {
 			return
 		}
@@ -559,7 +554,8 @@
 
 // GetSharedLibsToZip finds and marks all the transiently-dependent shared libraries for
 // packaging.
-func GetSharedLibsToZip(sharedLibraries android.RuleBuilderInstalls, module LinkableInterface, s *fuzz.FuzzPackager, archString string, destinationPathPrefix string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip {
+func GetSharedLibsToZip(sharedLibraries android.RuleBuilderInstalls, isHost bool, inVendor bool, s *fuzz.FuzzPackager,
+	archString string, destinationPathPrefix string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip {
 	var files []fuzz.FileToZip
 
 	fuzzDir := "fuzz"
@@ -577,7 +573,7 @@
 		// install it to the output directory. Setup the install destination here,
 		// which will be used by $(copy-many-files) in the Make backend.
 		installDestination := SharedLibraryInstallLocation(
-			install, module.Host(), module.InVendor(), fuzzDir, archString)
+			install, isHost, inVendor, fuzzDir, archString)
 		if (*sharedLibraryInstalled)[installDestination] {
 			continue
 		}
@@ -594,8 +590,8 @@
 		// dir. Symbolized DSO's are always installed to the device when fuzzing, but
 		// we want symbolization tools (like `stack`) to be able to find the symbols
 		// in $ANDROID_PRODUCT_OUT/symbols automagically.
-		if !module.Host() {
-			symbolsInstallDestination := SharedLibrarySymbolsInstallLocation(install, module.InVendor(), fuzzDir, archString)
+		if !isHost {
+			symbolsInstallDestination := SharedLibrarySymbolsInstallLocation(install, inVendor, fuzzDir, archString)
 			symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
 			s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
 				library.String()+":"+symbolsInstallDestination)
diff --git a/cc/library.go b/cc/library.go
index 532b7e9..ee7610d 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -419,8 +419,8 @@
 	// Location of the linked, stripped library for shared libraries, strip: "all"
 	strippedAllOutputFile android.Path
 
-	// Location of the file that should be copied to dist dir when requested
-	distFile android.Path
+	// Location of the file that should be copied to dist dir when no explicit tag is requested
+	defaultDistFile android.Path
 
 	versionScriptPath android.OptionalPath
 
@@ -1066,7 +1066,7 @@
 			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
 		} else {
 			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
-			library.distFile = versionedOutputFile
+			library.defaultDistFile = versionedOutputFile
 			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
 		}
 	}
@@ -1206,11 +1206,11 @@
 			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
 		} else {
 			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
-			library.distFile = versionedOutputFile
+			library.defaultDistFile = versionedOutputFile
 
 			if library.stripper.NeedsStrip(ctx) {
 				out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
-				library.distFile = out
+				library.defaultDistFile = out
 				library.stripper.StripExecutableOrSharedLib(ctx, versionedOutputFile, out, stripFlags)
 			}
 
@@ -2090,6 +2090,13 @@
 	return library.Properties.Overrides
 }
 
+func (library *libraryDecorator) defaultDistFiles() []android.Path {
+	if library.defaultDistFile == nil {
+		return nil
+	}
+	return []android.Path{library.defaultDistFile}
+}
+
 var _ overridable = (*libraryDecorator)(nil)
 
 var versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList")
diff --git a/cc/ndk_abi.go b/cc/ndk_abi.go
index 2706261..a9f26a4 100644
--- a/cc/ndk_abi.go
+++ b/cc/ndk_abi.go
@@ -39,15 +39,15 @@
 
 func (n *ndkAbiDumpSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	var depPaths android.Paths
-	ctx.VisitAllModules(func(module android.Module) {
-		if !module.Enabled(ctx) {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
 			return
 		}
 
-		if m, ok := module.(*Module); ok {
-			if installer, ok := m.installer.(*stubDecorator); ok {
-				if installer.hasAbiDump {
-					depPaths = append(depPaths, installer.abiDumpPath)
+		if ccInfo, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok {
+			if ccInfo.InstallerInfo != nil && ccInfo.InstallerInfo.StubDecoratorInfo != nil {
+				if ccInfo.InstallerInfo.StubDecoratorInfo.HasAbiDump {
+					depPaths = append(depPaths, ccInfo.InstallerInfo.StubDecoratorInfo.AbiDumpPath)
 				}
 			}
 		}
@@ -77,14 +77,14 @@
 
 func (n *ndkAbiDiffSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	var depPaths android.Paths
-	ctx.VisitAllModules(func(module android.Module) {
-		if m, ok := module.(android.Module); ok && !m.Enabled(ctx) {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
 			return
 		}
 
-		if m, ok := module.(*Module); ok {
-			if installer, ok := m.installer.(*stubDecorator); ok {
-				depPaths = append(depPaths, installer.abiDiffPaths...)
+		if ccInfo, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok {
+			if ccInfo.InstallerInfo != nil && ccInfo.InstallerInfo.StubDecoratorInfo != nil {
+				depPaths = append(depPaths, ccInfo.InstallerInfo.StubDecoratorInfo.AbiDiffPaths...)
 			}
 		}
 	})
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index 7481954..6e26d4c 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -80,6 +80,20 @@
 	licensePath  android.Path
 }
 
+type NdkHeaderInfo struct {
+	SrcPaths     android.Paths
+	InstallPaths android.Paths
+	LicensePath  android.Path
+	// Set to true if the headers installed by this module should skip
+	// verification. This step ensures that each header is self-contained (can
+	// be #included alone) and is valid C. This should not be disabled except in
+	// rare cases. Outside bionic and external, if you're using this option
+	// you've probably made a mistake.
+	SkipVerification bool
+}
+
+var NdkHeaderInfoProvider = blueprint.NewProvider[NdkHeaderInfo]()
+
 func getHeaderInstallDir(ctx android.ModuleContext, header android.Path, from string,
 	to string) android.OutputPath {
 	// Output path is the sysroot base + "usr/include" + to directory + directory component
@@ -135,6 +149,13 @@
 	if len(m.installPaths) == 0 {
 		ctx.ModuleErrorf("srcs %q matched zero files", m.properties.Srcs)
 	}
+
+	android.SetProvider(ctx, NdkHeaderInfoProvider, NdkHeaderInfo{
+		SrcPaths:         m.srcPaths,
+		InstallPaths:     m.installPaths,
+		LicensePath:      m.licensePath,
+		SkipVerification: Bool(m.properties.Skip_verification),
+	})
 }
 
 // ndk_headers installs the sets of ndk headers defined in the srcs property
@@ -203,6 +224,8 @@
 	licensePath  android.Path
 }
 
+var NdkPreprocessedHeaderInfoProvider = blueprint.NewProvider[NdkHeaderInfo]()
+
 func (m *preprocessedHeadersModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	if String(m.properties.License) == "" {
 		ctx.PropertyErrorf("license", "field is required")
@@ -231,6 +254,13 @@
 	if len(m.installPaths) == 0 {
 		ctx.ModuleErrorf("srcs %q matched zero files", m.properties.Srcs)
 	}
+
+	android.SetProvider(ctx, NdkPreprocessedHeaderInfoProvider, NdkHeaderInfo{
+		SrcPaths:         m.srcPaths,
+		InstallPaths:     m.installPaths,
+		LicensePath:      m.licensePath,
+		SkipVerification: Bool(m.properties.Skip_verification),
+	})
 }
 
 // preprocessed_ndk_headers preprocesses all the ndk headers listed in the srcs
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 1f0fc07..c21fe56 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -560,6 +560,10 @@
 	return false
 }
 
+func (stub *stubDecorator) defaultDistFiles() []android.Path {
+	return nil
+}
+
 // Returns the install path for unversioned NDK libraries (currently only static
 // libraries).
 func getUnversionedLibraryInstallPath(ctx ModuleContext) android.OutputPath {
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index a5f014b..34f6195 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -53,11 +53,12 @@
 // TODO(danalbert): Write `ndk_static_library` rule.
 
 import (
-	"android/soong/android"
 	"fmt"
 	"path/filepath"
 	"strings"
 
+	"android/soong/android"
+
 	"github.com/google/blueprint"
 )
 
@@ -209,57 +210,61 @@
 	var headerCCompatVerificationTimestampPaths android.Paths
 	var installPaths android.Paths
 	var licensePaths android.Paths
-	ctx.VisitAllModules(func(module android.Module) {
-		if m, ok := module.(android.Module); ok && !m.Enabled(ctx) {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
 			return
 		}
 
-		if m, ok := module.(*headerModule); ok {
-			headerSrcPaths = append(headerSrcPaths, m.srcPaths...)
-			headerInstallPaths = append(headerInstallPaths, m.installPaths...)
-			if !Bool(m.properties.Skip_verification) {
-				for i, installPath := range m.installPaths {
+		if m, ok := android.OtherModuleProvider(ctx, module, NdkHeaderInfoProvider); ok {
+			headerSrcPaths = append(headerSrcPaths, m.SrcPaths...)
+			headerInstallPaths = append(headerInstallPaths, m.InstallPaths...)
+			if !m.SkipVerification {
+				for i, installPath := range m.InstallPaths {
 					headersToVerify = append(headersToVerify, srcDestPair{
-						src:  m.srcPaths[i],
+						src:  m.SrcPaths[i],
 						dest: installPath,
 					})
 				}
 			}
-			installPaths = append(installPaths, m.installPaths...)
-			licensePaths = append(licensePaths, m.licensePath)
+			installPaths = append(installPaths, m.InstallPaths...)
+			licensePaths = append(licensePaths, m.LicensePath)
 		}
 
-		if m, ok := module.(*preprocessedHeadersModule); ok {
-			headerSrcPaths = append(headerSrcPaths, m.srcPaths...)
-			headerInstallPaths = append(headerInstallPaths, m.installPaths...)
-			if !Bool(m.properties.Skip_verification) {
-				for i, installPath := range m.installPaths {
+		if m, ok := android.OtherModuleProvider(ctx, module, NdkPreprocessedHeaderInfoProvider); ok {
+			headerSrcPaths = append(headerSrcPaths, m.SrcPaths...)
+			headerInstallPaths = append(headerInstallPaths, m.InstallPaths...)
+			if !m.SkipVerification {
+				for i, installPath := range m.InstallPaths {
 					headersToVerify = append(headersToVerify, srcDestPair{
-						src:  m.srcPaths[i],
+						src:  m.SrcPaths[i],
 						dest: installPath,
 					})
 				}
 			}
-			installPaths = append(installPaths, m.installPaths...)
-			licensePaths = append(licensePaths, m.licensePath)
+			installPaths = append(installPaths, m.InstallPaths...)
+			licensePaths = append(licensePaths, m.LicensePath)
 		}
 
-		if m, ok := module.(*Module); ok {
-			if installer, ok := m.installer.(*stubDecorator); ok && m.library.BuildStubs() {
-				installPaths = append(installPaths, installer.installPath)
+		if ccInfo, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok {
+			if installer := ccInfo.InstallerInfo; installer != nil && installer.StubDecoratorInfo != nil &&
+				ccInfo.LibraryInfo != nil && ccInfo.LibraryInfo.BuildStubs {
+				installPaths = append(installPaths, installer.StubDecoratorInfo.InstallPath)
 			}
 
-			if library, ok := m.linker.(*libraryDecorator); ok {
-				if library.ndkSysrootPath != nil {
-					staticLibInstallPaths = append(
-						staticLibInstallPaths, library.ndkSysrootPath)
+			if ccInfo.LinkerInfo != nil {
+				if library := ccInfo.LinkerInfo.LibraryDecoratorInfo; library != nil {
+					if library.NdkSysrootPath != nil {
+						staticLibInstallPaths = append(
+							staticLibInstallPaths, library.NdkSysrootPath)
+					}
 				}
-			}
 
-			if object, ok := m.linker.(*objectLinker); ok {
-				if object.ndkSysrootPath != nil {
-					staticLibInstallPaths = append(
-						staticLibInstallPaths, object.ndkSysrootPath)
+				if object := ccInfo.LinkerInfo.ObjectLinkerInfo; object != nil {
+					if object.NdkSysrootPath != nil {
+						staticLibInstallPaths = append(
+							staticLibInstallPaths, object.NdkSysrootPath)
+					}
 				}
 			}
 		}
diff --git a/cc/object.go b/cc/object.go
index bbfca94..95a8beb 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -242,6 +242,10 @@
 	return Bool(object.Properties.Crt)
 }
 
+func (object *objectLinker) defaultDistFiles() []android.Path {
+	return nil
+}
+
 func (object *objectLinker) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
 	object.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON)
 	moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"}
diff --git a/cmd/symbols_map/symbols_map_proto/regen.sh b/cmd/symbols_map/symbols_map_proto/regen.sh
new file mode 100755
index 0000000..3c189d1
--- /dev/null
+++ b/cmd/symbols_map/symbols_map_proto/regen.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+aprotoc --go_out=paths=source_relative:. symbols_map.proto
+
diff --git a/cmd/symbols_map/symbols_map_proto/symbols_map.pb.go b/cmd/symbols_map/symbols_map_proto/symbols_map.pb.go
index f9c0ce5..07f4b39 100644
--- a/cmd/symbols_map/symbols_map_proto/symbols_map.pb.go
+++ b/cmd/symbols_map/symbols_map_proto/symbols_map.pb.go
@@ -14,8 +14,8 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.27.1
-// 	protoc        v3.9.1
+// 	protoc-gen-go v1.30.0
+// 	protoc        v3.21.12
 // source: symbols_map.proto
 
 package symbols_map_proto
@@ -93,6 +93,68 @@
 	return file_symbols_map_proto_rawDescGZIP(), []int{0, 0}
 }
 
+// LocationType is the place where to look for the file with the given
+// identifier.
+type Mapping_LocationType int32
+
+const (
+	// ZIP denotes the file with the given identifier is in the distribuited
+	// symbols.zip or proguard_dict.zip files, or the local disc.
+	Mapping_ZIP Mapping_LocationType = 0
+	// AB denotes the file with the given identifier is in the AB artifacts but
+	// not in a symbols.zip or proguard_dict.zip.
+	Mapping_AB Mapping_LocationType = 1
+)
+
+// Enum value maps for Mapping_LocationType.
+var (
+	Mapping_LocationType_name = map[int32]string{
+		0: "ZIP",
+		1: "AB",
+	}
+	Mapping_LocationType_value = map[string]int32{
+		"ZIP": 0,
+		"AB":  1,
+	}
+)
+
+func (x Mapping_LocationType) Enum() *Mapping_LocationType {
+	p := new(Mapping_LocationType)
+	*p = x
+	return p
+}
+
+func (x Mapping_LocationType) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Mapping_LocationType) Descriptor() protoreflect.EnumDescriptor {
+	return file_symbols_map_proto_enumTypes[1].Descriptor()
+}
+
+func (Mapping_LocationType) Type() protoreflect.EnumType {
+	return &file_symbols_map_proto_enumTypes[1]
+}
+
+func (x Mapping_LocationType) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *Mapping_LocationType) UnmarshalJSON(b []byte) error {
+	num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
+	if err != nil {
+		return err
+	}
+	*x = Mapping_LocationType(num)
+	return nil
+}
+
+// Deprecated: Use Mapping_LocationType.Descriptor instead.
+func (Mapping_LocationType) EnumDescriptor() ([]byte, []int) {
+	return file_symbols_map_proto_rawDescGZIP(), []int{0, 1}
+}
+
 type Mapping struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -107,6 +169,9 @@
 	Location *string `protobuf:"bytes,2,opt,name=location" json:"location,omitempty"`
 	// type is the type of the mapping, either ELF or R8.
 	Type *Mapping_Type `protobuf:"varint,3,opt,name=type,enum=symbols_map.Mapping_Type" json:"type,omitempty"`
+	// location_type is the Location Type that dictates where to search for the
+	// file with the given identifier. Defaults to ZIP if not present.
+	LocationType *Mapping_LocationType `protobuf:"varint,4,opt,name=location_type,json=locationType,enum=symbols_map.Mapping_LocationType" json:"location_type,omitempty"`
 }
 
 func (x *Mapping) Reset() {
@@ -162,6 +227,13 @@
 	return Mapping_ELF
 }
 
+func (x *Mapping) GetLocationType() Mapping_LocationType {
+	if x != nil && x.LocationType != nil {
+		return *x.LocationType
+	}
+	return Mapping_ZIP
+}
+
 type Mappings struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -214,23 +286,29 @@
 var file_symbols_map_proto_rawDesc = []byte{
 	0x0a, 0x11, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x5f, 0x6d, 0x61, 0x70, 0x2e, 0x70, 0x72,
 	0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x5f, 0x6d, 0x61, 0x70,
-	0x22, 0x8d, 0x01, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0a,
+	0x22, 0xf6, 0x01, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0a,
 	0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
 	0x52, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08,
 	0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
 	0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
 	0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73,
 	0x5f, 0x6d, 0x61, 0x70, 0x2e, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x79, 0x70,
-	0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x17, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12,
-	0x07, 0x0a, 0x03, 0x45, 0x4c, 0x46, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x52, 0x38, 0x10, 0x01,
-	0x22, 0x3c, 0x0a, 0x08, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x08,
-	0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14,
+	0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x46, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21,
 	0x2e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x5f, 0x6d, 0x61, 0x70, 0x2e, 0x4d, 0x61, 0x70,
-	0x70, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x31,
-	0x5a, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f,
-	0x63, 0x6d, 0x64, 0x2f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x5f, 0x6d, 0x61, 0x70, 0x2f,
-	0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x5f, 0x6d, 0x61, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x74,
-	0x6f,
+	0x70, 0x69, 0x6e, 0x67, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70,
+	0x65, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22,
+	0x17, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x45, 0x4c, 0x46, 0x10, 0x00,
+	0x12, 0x06, 0x0a, 0x02, 0x52, 0x38, 0x10, 0x01, 0x22, 0x1f, 0x0a, 0x0c, 0x4c, 0x6f, 0x63, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x5a, 0x49, 0x50, 0x10,
+	0x00, 0x12, 0x06, 0x0a, 0x02, 0x41, 0x42, 0x10, 0x01, 0x22, 0x3c, 0x0a, 0x08, 0x4d, 0x61, 0x70,
+	0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x08, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67,
+	0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c,
+	0x73, 0x5f, 0x6d, 0x61, 0x70, 0x2e, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x6d,
+	0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+	0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x73, 0x79, 0x6d,
+	0x62, 0x6f, 0x6c, 0x73, 0x5f, 0x6d, 0x61, 0x70, 0x2f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73,
+	0x5f, 0x6d, 0x61, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 }
 
 var (
@@ -245,21 +323,23 @@
 	return file_symbols_map_proto_rawDescData
 }
 
-var file_symbols_map_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_symbols_map_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
 var file_symbols_map_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
 var file_symbols_map_proto_goTypes = []interface{}{
-	(Mapping_Type)(0), // 0: symbols_map.Mapping.Type
-	(*Mapping)(nil),   // 1: symbols_map.Mapping
-	(*Mappings)(nil),  // 2: symbols_map.Mappings
+	(Mapping_Type)(0),         // 0: symbols_map.Mapping.Type
+	(Mapping_LocationType)(0), // 1: symbols_map.Mapping.LocationType
+	(*Mapping)(nil),           // 2: symbols_map.Mapping
+	(*Mappings)(nil),          // 3: symbols_map.Mappings
 }
 var file_symbols_map_proto_depIdxs = []int32{
 	0, // 0: symbols_map.Mapping.type:type_name -> symbols_map.Mapping.Type
-	1, // 1: symbols_map.Mappings.mappings:type_name -> symbols_map.Mapping
-	2, // [2:2] is the sub-list for method output_type
-	2, // [2:2] is the sub-list for method input_type
-	2, // [2:2] is the sub-list for extension type_name
-	2, // [2:2] is the sub-list for extension extendee
-	0, // [0:2] is the sub-list for field type_name
+	1, // 1: symbols_map.Mapping.location_type:type_name -> symbols_map.Mapping.LocationType
+	2, // 2: symbols_map.Mappings.mappings:type_name -> symbols_map.Mapping
+	3, // [3:3] is the sub-list for method output_type
+	3, // [3:3] is the sub-list for method input_type
+	3, // [3:3] is the sub-list for extension type_name
+	3, // [3:3] is the sub-list for extension extendee
+	0, // [0:3] is the sub-list for field type_name
 }
 
 func init() { file_symbols_map_proto_init() }
@@ -298,7 +378,7 @@
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_symbols_map_proto_rawDesc,
-			NumEnums:      1,
+			NumEnums:      2,
 			NumMessages:   2,
 			NumExtensions: 0,
 			NumServices:   0,
diff --git a/cmd/symbols_map/symbols_map_proto/symbols_map.proto b/cmd/symbols_map/symbols_map_proto/symbols_map.proto
index a76d171..a52f75c 100644
--- a/cmd/symbols_map/symbols_map_proto/symbols_map.proto
+++ b/cmd/symbols_map/symbols_map_proto/symbols_map.proto
@@ -40,7 +40,7 @@
 
   // LocationType is the place where to look for the file with the given
   // identifier.
-  Enum LocationType {
+  enum LocationType {
     // ZIP denotes the file with the given identifier is in the distribuited
     // symbols.zip or proguard_dict.zip files, or the local disc.
     ZIP = 0;
@@ -56,4 +56,4 @@
 
 message Mappings {
   repeated Mapping mappings = 4;
-}
\ No newline at end of file
+}
diff --git a/dexpreopt/Android.bp b/dexpreopt/Android.bp
index 679d066..ea3f52b 100644
--- a/dexpreopt/Android.bp
+++ b/dexpreopt/Android.bp
@@ -9,6 +9,7 @@
         "class_loader_context.go",
         "config.go",
         "dexpreopt.go",
+        "system_server_zip.go",
         "testing.go",
     ],
     testSrcs: [
diff --git a/dexpreopt/system_server_zip.go b/dexpreopt/system_server_zip.go
new file mode 100644
index 0000000..cef847b
--- /dev/null
+++ b/dexpreopt/system_server_zip.go
@@ -0,0 +1,49 @@
+package dexpreopt
+
+import "android/soong/android"
+
+func init() {
+	android.InitRegistrationContext.RegisterSingletonType("system_server_zip_singleton", systemServerZipSingletonFactory)
+}
+
+func systemServerZipSingletonFactory() android.Singleton {
+	return &systemServerZipSingleton{}
+}
+
+type systemServerZipSingleton struct{}
+
+func (s *systemServerZipSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+	global := GetGlobalConfig(ctx)
+	if global.DisablePreopt || global.OnlyPreoptArtBootImage {
+		return
+	}
+
+	systemServerDexjarsDir := android.PathForOutput(ctx, SystemServerDexjarsDir)
+
+	out := android.PathForOutput(ctx, "system_server.zip")
+	builder := android.NewRuleBuilder(pctx, ctx)
+	cmd := builder.Command().BuiltTool("soong_zip").
+		FlagWithOutput("-o ", out).
+		FlagWithArg("-C ", systemServerDexjarsDir.String())
+
+	for i := 0; i < global.SystemServerJars.Len(); i++ {
+		jar := global.SystemServerJars.Jar(i) + ".jar"
+		cmd.FlagWithInput("-f ", systemServerDexjarsDir.Join(ctx, jar))
+	}
+	for i := 0; i < global.StandaloneSystemServerJars.Len(); i++ {
+		jar := global.StandaloneSystemServerJars.Jar(i) + ".jar"
+		cmd.FlagWithInput("-f ", systemServerDexjarsDir.Join(ctx, jar))
+	}
+	for i := 0; i < global.ApexSystemServerJars.Len(); i++ {
+		jar := global.ApexSystemServerJars.Jar(i) + ".jar"
+		cmd.FlagWithInput("-f ", systemServerDexjarsDir.Join(ctx, jar))
+	}
+	for i := 0; i < global.ApexStandaloneSystemServerJars.Len(); i++ {
+		jar := global.ApexStandaloneSystemServerJars.Jar(i) + ".jar"
+		cmd.FlagWithInput("-f ", systemServerDexjarsDir.Join(ctx, jar))
+	}
+
+	builder.Build("system_server_zip", "building system_server.zip")
+
+	ctx.DistForGoal("droidcore", out)
+}
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index a440c91..fad8f07 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -61,6 +61,7 @@
 	ctx.RegisterModuleType("prebuilt_usr_keychars", PrebuiltUserKeyCharsFactory)
 	ctx.RegisterModuleType("prebuilt_usr_idc", PrebuiltUserIdcFactory)
 	ctx.RegisterModuleType("prebuilt_usr_srec", PrebuiltUserSrecFactory)
+	ctx.RegisterModuleType("prebuilt_usr_odml", PrebuiltUserOdmlFactory)
 	ctx.RegisterModuleType("prebuilt_font", PrebuiltFontFactory)
 	ctx.RegisterModuleType("prebuilt_overlay", PrebuiltOverlayFactory)
 	ctx.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory)
@@ -786,6 +787,17 @@
 	return module
 }
 
+// prebuilt_usr_odml is for a prebuilt artifact that is installed in
+// <partition>/usr/odml/<sub_dir> directory.
+func PrebuiltUserOdmlFactory() android.Module {
+	module := &PrebuiltEtc{}
+	InitPrebuiltEtcModule(module, "usr/odml")
+	// This module is device-only
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+	android.InitDefaultableModule(module)
+	return module
+}
+
 // prebuilt_font installs a font in <partition>/fonts directory.
 func PrebuiltFontFactory() android.Module {
 	module := &PrebuiltEtc{}
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index fef4aeb..31678aa 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -279,7 +279,7 @@
 
 	ret := []android.Module{}
 	ctx.WalkDepsProxy(func(mod, _ android.ModuleProxy) bool {
-		if variations, ok := allOwners[mod.Name()]; ok && android.InList(ctx.OtherModuleSubDir(mod), variations) {
+		if variations, ok := allOwners[ctx.OtherModuleName(mod)]; ok && android.InList(ctx.OtherModuleSubDir(mod), variations) {
 			ret = append(ret, mod)
 		}
 		return true
@@ -325,10 +325,11 @@
 	}
 }
 
-func (a *androidDevice) MakeVars(ctx android.MakeVarsModuleContext) {
+func (a *androidDevice) MakeVars(_ android.MakeVarsModuleContext) []android.ModuleMakeVarsValue {
 	if proptools.Bool(a.deviceProps.Main_device) {
-		ctx.StrictRaw("SOONG_ONLY_ALL_IMAGES_ZIP", a.allImagesZip.String())
+		return []android.ModuleMakeVarsValue{{"SOONG_ONLY_ALL_IMAGES_ZIP", a.allImagesZip.String()}}
 	}
+	return nil
 }
 
 func (a *androidDevice) buildProguardZips(ctx android.ModuleContext, allInstalledModules []android.Module) {
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 28eb36d..d4ea6a3 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -1525,10 +1525,11 @@
 	})
 }
 
-func (f *filesystem) MakeVars(ctx android.MakeVarsModuleContext) {
+func (f *filesystem) MakeVars(ctx android.MakeVarsModuleContext) []android.ModuleMakeVarsValue {
 	if f.Name() == ctx.Config().SoongDefinedSystemImage() {
-		ctx.StrictRaw("SOONG_DEFINED_SYSTEM_IMAGE_PATH", f.output.String())
+		return []android.ModuleMakeVarsValue{{"SOONG_DEFINED_SYSTEM_IMAGE_PATH", f.output.String()}}
 	}
+	return nil
 }
 
 func setCommonFilesystemInfo(ctx android.ModuleContext, m Filesystem) {
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index e2485a1..3d83706 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -347,11 +347,9 @@
 	superImageSubPartitions []string,
 ) {
 	baseProps := &struct {
-		Name         *string
-		Android_info *string
+		Name *string
 	}{
-		Name:         proptools.StringPtr(generatedModuleName(ctx.Config(), "device")),
-		Android_info: proptools.StringPtr(":" + generatedModuleName(ctx.Config(), "android_info.prop{.txt}")),
+		Name: proptools.StringPtr(generatedModuleName(ctx.Config(), "device")),
 	}
 
 	// Currently, only the system and system_ext partition module is created.
@@ -406,6 +404,7 @@
 		Ab_ota_partitions:         ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaPartitions,
 		Ab_ota_postinstall_config: ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaPostInstallConfig,
 		Ramdisk_node_list:         proptools.StringPtr(":ramdisk_node_list"),
+		Android_info:              proptools.StringPtr(":" + generatedModuleName(ctx.Config(), "android_info.prop{.txt}")),
 	}
 
 	if bootloader, ok := f.createBootloaderFilegroup(ctx); ok {
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index 83ccd89..f08378d 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -22,6 +22,7 @@
 	"sort"
 	"strings"
 
+	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
@@ -309,14 +310,14 @@
 	return false
 }
 
-func IsValidConfig(fuzzModule FuzzPackagedModule, moduleName string) bool {
-	var config = fuzzModule.FuzzProperties.Fuzz_config
+func IsValidConfig(fuzzModule *FuzzPackagedModuleInfo, moduleName string) bool {
+	var config = fuzzModule.FuzzConfig
 	if config != nil {
 		if !config.Vector.isValidVector() {
 			panic(fmt.Errorf("Invalid vector in fuzz config in %s", moduleName))
 		}
 
-		if !config.Service_privilege.isValidServicePrivilege() {
+		if !config.ServicePrivilege.isValidServicePrivilege() {
 			panic(fmt.Errorf("Invalid service_privilege in fuzz config in %s", moduleName))
 		}
 
@@ -324,15 +325,15 @@
 			panic(fmt.Errorf("Invalid users (user_data) in fuzz config in %s", moduleName))
 		}
 
-		if !config.Fuzzed_code_usage.isValidFuzzedCodeUsage() {
+		if !config.FuzzedCodeUsage.isValidFuzzedCodeUsage() {
 			panic(fmt.Errorf("Invalid fuzzed_code_usage in fuzz config in %s", moduleName))
 		}
 
-		if !config.Automatically_route_to.isValidAutomaticallyRouteTo() {
+		if !config.AutomaticallyRouteTo.isValidAutomaticallyRouteTo() {
 			panic(fmt.Errorf("Invalid automatically_route_to in fuzz config in %s", moduleName))
 		}
 
-		if !config.Use_platform_libs.isValidUsePlatformLibs() {
+		if !config.UsePlatformLibs.isValidUsePlatformLibs() {
 			panic(fmt.Errorf("Invalid use_platform_libs in fuzz config in %s", moduleName))
 		}
 	}
@@ -451,6 +452,62 @@
 	Data           android.Paths
 }
 
+type FuzzConfigInfo struct {
+	Vector Vector
+	// How privileged the service being fuzzed is.
+	ServicePrivilege ServicePrivilege
+	// Whether the service being fuzzed handles data from multiple users or only
+	// a single one.
+	Users UserData
+	// Specifies the use state of the code being fuzzed. This state factors into
+	// how an issue is handled.
+	FuzzedCodeUsage FuzzedCodeUsage
+	// Which team to route this to, if it should be routed automatically.
+	AutomaticallyRouteTo AutomaticallyRouteTo
+	// Specifies libs used to initialize ART (java only, 'use_none' for no initialization)
+	UsePlatformLibs UsePlatformLibs
+	// Specify whether to enable continuous fuzzing on devices. Defaults to true.
+	FuzzOnHaikuDevice bool
+	// Specify whether to enable continuous fuzzing on host. Defaults to true.
+	FuzzOnHaikuHost bool
+	// Specifies whether fuzz target should check presubmitted code changes for crashes.
+	// Defaults to false.
+	UseForPresubmit bool
+}
+type FuzzPackagedModuleInfo struct {
+	FuzzConfig *FuzzConfigInfo
+	Dictionary android.Path
+	Corpus     android.Paths
+	Config     android.Path
+	Data       android.Paths
+}
+
+var FuzzPackagedModuleInfoProvider = blueprint.NewProvider[FuzzPackagedModuleInfo]()
+
+func SetFuzzPackagedModuleInfo(ctx android.ModuleContext, fm *FuzzPackagedModule) {
+	info := FuzzPackagedModuleInfo{
+		Dictionary: fm.Dictionary,
+		Config:     fm.Config,
+		Corpus:     fm.Corpus,
+		Data:       fm.Data,
+	}
+	if fm.FuzzProperties.Fuzz_config != nil {
+		info.FuzzConfig = &FuzzConfigInfo{
+			Vector:               fm.FuzzProperties.Fuzz_config.Vector,
+			ServicePrivilege:     fm.FuzzProperties.Fuzz_config.Service_privilege,
+			Users:                fm.FuzzProperties.Fuzz_config.Users,
+			FuzzedCodeUsage:      fm.FuzzProperties.Fuzz_config.Fuzzed_code_usage,
+			AutomaticallyRouteTo: fm.FuzzProperties.Fuzz_config.Automatically_route_to,
+			FuzzOnHaikuDevice:    BoolDefault(fm.FuzzProperties.Fuzz_config.Fuzz_on_haiku_device, true),
+			FuzzOnHaikuHost:      BoolDefault(fm.FuzzProperties.Fuzz_config.Fuzz_on_haiku_host, true),
+			UsePlatformLibs:      fm.FuzzProperties.Fuzz_config.Use_platform_libs,
+			UseForPresubmit:      BoolDefault(fm.FuzzProperties.Fuzz_config.Use_for_presubmit, false),
+		}
+	}
+
+	android.SetProvider(ctx, FuzzPackagedModuleInfoProvider, info)
+}
+
 func GetFramework(ctx android.LoadHookContext, lang Lang) Framework {
 	framework := ctx.Config().Getenv("FUZZ_FRAMEWORK")
 
@@ -509,7 +566,9 @@
 	return true
 }
 
-func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip {
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
+func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.Module, fuzzModule *FuzzPackagedModuleInfo, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip {
 	// Package the corpora into a zipfile.
 	var files []FileToZip
 	if fuzzModule.Corpus != nil {
@@ -548,7 +607,9 @@
 	return files
 }
 
-func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) {
+// TODO(b/397766191): Change the signature to take ModuleProxy
+// Please only access the module's internal data through providers.
+func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module android.Module, fuzzModule *FuzzPackagedModuleInfo, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) {
 	fuzzZip := archDir.Join(ctx, module.Name()+".zip")
 
 	command := builder.Command().BuiltTool("soong_zip").
@@ -570,10 +631,10 @@
 	builder.Build("create-"+fuzzZip.String(),
 		"Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
 
-	if config := fuzzModule.FuzzProperties.Fuzz_config; config != nil {
-		if strings.Contains(hostOrTargetString, "host") && !BoolDefault(config.Fuzz_on_haiku_host, true) {
+	if config := fuzzModule.FuzzConfig; config != nil {
+		if strings.Contains(hostOrTargetString, "host") && !config.FuzzOnHaikuHost {
 			return archDirs[archOs], false
-		} else if !strings.Contains(hostOrTargetString, "host") && !BoolDefault(config.Fuzz_on_haiku_device, true) {
+		} else if !strings.Contains(hostOrTargetString, "host") && !config.FuzzOnHaikuDevice {
 			return archDirs[archOs], false
 		}
 	}
diff --git a/java/aar.go b/java/aar.go
index 976e4fc..0e27cb8 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -945,6 +945,12 @@
 
 var AndroidLibraryInfoProvider = blueprint.NewProvider[AndroidLibraryInfo]()
 
+type AARImportInfo struct {
+	// Empty for now
+}
+
+var AARImportInfoProvider = blueprint.NewProvider[AARImportInfo]()
+
 type AndroidLibrary struct {
 	Library
 	aapt
@@ -1571,6 +1577,8 @@
 		JniPackages: a.jniPackages,
 	})
 
+	android.SetProvider(ctx, AARImportInfoProvider, AARImportInfo{})
+
 	ctx.SetOutputFiles([]android.Path{a.implementationAndResourcesJarFile}, "")
 	ctx.SetOutputFiles([]android.Path{a.aarPath}, ".aar")
 
diff --git a/java/app.go b/java/app.go
index 17548e7..827b235 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1124,6 +1124,11 @@
 		android.SetProvider(ctx, JavaInfoProvider, javaInfo)
 	}
 
+	android.SetProvider(ctx, android.ApexBundleDepsDataProvider, android.ApexBundleDepsData{
+		FlatListPath: a.FlatListPath(),
+		Updatable:    a.Updatable(),
+	})
+
 	moduleInfoJSON := ctx.ModuleInfoJSON()
 	moduleInfoJSON.Class = []string{"APPS"}
 	if !a.embeddedJniLibs {
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 313d8c7..2287043 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -675,6 +675,139 @@
 			installs: artBootImageHostInstalls,
 		},
 	)
+
+	d.buildBootZip(ctx)
+}
+
+// Build the boot.zip which contains the boot jars and their compilation output
+// We can do this only if preopt is enabled and if the product uses libart config (which sets the
+// default properties for preopting).
+// Origionally, this was only for ART Cloud.
+func (d *dexpreoptBootJars) buildBootZip(ctx android.ModuleContext) {
+	image := d.defaultBootImage
+	if image == nil || SkipDexpreoptBootJars(ctx) {
+		return
+	}
+	global := dexpreopt.GetGlobalConfig(ctx)
+	globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
+	if global.DisablePreopt || global.OnlyPreoptArtBootImage {
+		return
+	}
+
+	bootclasspathDexFiles, bootclassPathLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp)
+	if len(bootclasspathDexFiles) == 0 {
+		return
+	}
+
+	systemServerDexjarsDir := android.PathForOutput(ctx, dexpreopt.SystemServerDexjarsDir)
+
+	bootZipMetadataTmp := android.PathForModuleOut(ctx, "boot_zip", "METADATA.txt.tmp")
+	bootZipMetadata := android.PathForModuleOut(ctx, "boot_zip", "METADATA.txt")
+	newlineFile := android.PathForModuleOut(ctx, "boot_zip", "newline.txt")
+	android.WriteFileRule(ctx, newlineFile, "")
+
+	dexPreoptRootDir := filepath.Dir(filepath.Dir(bootclasspathDexFiles[0].String()))
+
+	var sb strings.Builder
+	sb.WriteString("bootclasspath = ")
+	for i, bootclasspathJar := range bootclasspathDexFiles {
+		if i > 0 {
+			sb.WriteString(":")
+		}
+		rel, err := filepath.Rel(dexPreoptRootDir, bootclasspathJar.String())
+		if err != nil {
+			ctx.ModuleErrorf("All dexpreopt jars should be under the same rootdir %q, but %q wasn't.", dexPreoptRootDir, bootclasspathJar)
+		} else {
+			sb.WriteString(rel)
+		}
+	}
+	sb.WriteString("\nbootclasspath-locations = ")
+	for i, bootclasspathLocation := range bootclassPathLocations {
+		if i > 0 {
+			sb.WriteString(":")
+		}
+		sb.WriteString(bootclasspathLocation)
+	}
+	sb.WriteString("\nboot-image = ")
+
+	// Infix can be 'art' (ART image for testing), 'boot' (primary), or 'mainline' (mainline
+	// extension). Soong creates a set of variables for Make, one or each boot image. The only
+	// reason why the ART image is exposed to Make is testing (art gtests) and benchmarking (art
+	// golem benchmarks). Install rules that use those variables are in dex_preopt_libart.mk. Here
+	// for dexpreopt purposes the infix is always 'boot' or 'mainline'.
+	dexpreoptInfix := "boot"
+	if global.PreoptWithUpdatableBcp {
+		dexpreoptInfix = "mainline"
+	}
+
+	var dexPreoptImageZipBoot android.Path
+	var dexPreoptImageZipArt android.Path
+	var dexPreoptImageZipMainline android.Path
+	for _, current := range append(d.otherImages, image) {
+		if current.name == dexpreoptInfix {
+			_, imageLocationsOnDevice := current.getAnyAndroidVariant().imageLocations()
+			for i, location := range imageLocationsOnDevice {
+				imageLocationsOnDevice[i] = strings.TrimPrefix(location, "/")
+			}
+			sb.WriteString(strings.Join(imageLocationsOnDevice, ":"))
+		}
+		switch current.name {
+		case "boot":
+			dexPreoptImageZipBoot = current.zip
+		case "art":
+			dexPreoptImageZipArt = current.zip
+		case "mainline":
+			dexPreoptImageZipMainline = current.zip
+		}
+	}
+	sb.WriteString("\nextra-args = ")
+	android.WriteFileRuleVerbatim(ctx, bootZipMetadataTmp, sb.String())
+	ctx.Build(pctx, android.BuildParams{
+		Rule: android.Cat,
+		Inputs: []android.Path{
+			bootZipMetadataTmp,
+			globalSoong.UffdGcFlag,
+			newlineFile,
+		},
+		Output: bootZipMetadata,
+	})
+
+	bootZipFirstPart := android.PathForModuleOut(ctx, "boot_zip", "boot_first_part.zip")
+	bootZip := android.PathForModuleOut(ctx, "boot_zip", "boot.zip")
+	builder := android.NewRuleBuilder(pctx, ctx)
+	cmd := builder.Command().BuiltTool("soong_zip").
+		FlagWithOutput("-o ", bootZipFirstPart).
+		FlagWithArg("-C ", filepath.Dir(filepath.Dir(bootclasspathDexFiles[0].String())))
+	for _, bootclasspathJar := range bootclasspathDexFiles {
+		cmd.FlagWithInput("-f ", bootclasspathJar)
+	}
+	for i := range global.SystemServerJars.Len() {
+		// Use "/system" path for JARs with "platform:" prefix. These JARs counterintuitively use
+		// "platform" prefix but they will be actually installed to /system partition.
+		// For the remaining system server JARs use the partition signified by the prefix.
+		// For example, prefix "system_ext:" will use "/system_ext" path.
+		dir := global.SystemServerJars.Apex(i)
+		if dir == "platform" {
+			dir = "system"
+		}
+		jar := global.SystemServerJars.Jar(i) + ".jar"
+		cmd.FlagWithArg("-e ", dir+"/framework/"+jar)
+		cmd.FlagWithInput("-f ", systemServerDexjarsDir.Join(ctx, jar))
+	}
+	cmd.Flag("-j")
+	cmd.FlagWithInput("-f ", bootZipMetadata)
+
+	builder.Command().BuiltTool("merge_zips").
+		Output(bootZip).
+		Input(bootZipFirstPart).
+		Input(dexPreoptImageZipBoot).
+		Input(dexPreoptImageZipArt).
+		Input(dexPreoptImageZipMainline)
+
+	builder.Build("boot_zip", "build boot.zip")
+
+	ctx.DistForGoal("droidcore", bootZipMetadata)
+	ctx.DistForGoal("droidcore", bootZip)
 }
 
 // GenerateSingletonBuildActions generates build rules for the dexpreopt config for Make.
diff --git a/java/fuzz.go b/java/fuzz.go
index 5973957..0e239f0 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -132,6 +132,8 @@
 	}
 
 	j.Test.GenerateAndroidBuildActions(ctx)
+
+	fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule)
 }
 
 type javaFuzzPackager struct {
@@ -153,6 +155,10 @@
 		if !ok {
 			return
 		}
+		fuzzInfo, ok := android.OtherModuleProvider(ctx, module, fuzz.FuzzPackagedModuleInfoProvider)
+		if !ok {
+			return
+		}
 
 		hostOrTargetString := "target"
 		if javaFuzzModule.Target().HostCross {
@@ -179,7 +185,7 @@
 		builder := android.NewRuleBuilder(pctx, ctx)
 
 		// Package the artifacts (data, corpus, config and dictionary) into a zipfile.
-		files = s.PackageArtifacts(ctx, module, javaFuzzModule.fuzzPackagedModule, archDir, builder)
+		files = s.PackageArtifacts(ctx, module, &fuzzInfo, archDir, builder)
 
 		// Add .jar
 		if !javaFuzzModule.Host() {
@@ -193,7 +199,7 @@
 			files = append(files, fuzz.FileToZip{SourceFilePath: fPath})
 		}
 
-		archDirs[archOs], ok = s.BuildZipFile(ctx, module, javaFuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
+		archDirs[archOs], ok = s.BuildZipFile(ctx, module, &fuzzInfo, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
 		if !ok {
 			return
 		}
diff --git a/java/java.go b/java/java.go
index b18c561..38361bf 100644
--- a/java/java.go
+++ b/java/java.go
@@ -432,6 +432,9 @@
 	DexJarBuildPath OptionalDexJarPath
 
 	DexpreopterInfo *DexpreopterInfo
+
+	XrefJavaFiles   android.Paths
+	XrefKotlinFiles android.Paths
 }
 
 var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]()
@@ -3649,10 +3652,10 @@
 func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	var xrefTargets android.Paths
 	var xrefKotlinTargets android.Paths
-	ctx.VisitAllModules(func(module android.Module) {
-		if javaModule, ok := module.(xref); ok {
-			xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...)
-			xrefKotlinTargets = append(xrefKotlinTargets, javaModule.XrefKotlinFiles()...)
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+		if javaInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
+			xrefTargets = append(xrefTargets, javaInfo.XrefJavaFiles...)
+			xrefKotlinTargets = append(xrefKotlinTargets, javaInfo.XrefKotlinFiles...)
 		}
 	})
 	// TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
@@ -3853,4 +3856,9 @@
 			ApexSystemServerDexJars:           di.ApexSystemServerDexJars(),
 		}
 	}
+
+	if xr, ok := module.(xref); ok {
+		javaInfo.XrefJavaFiles = xr.XrefJavaFiles()
+		javaInfo.XrefKotlinFiles = xr.XrefKotlinFiles()
+	}
 }
diff --git a/java/lint.go b/java/lint.go
index 66f7f85..c31dfd0 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -595,12 +595,12 @@
 	l.copyLintDependencies(ctx)
 }
 
-func findModuleOrErr(ctx android.SingletonContext, moduleName string) android.Module {
-	var res android.Module
-	ctx.VisitAllModules(func(m android.Module) {
+func findModuleOrErr(ctx android.SingletonContext, moduleName string) *android.ModuleProxy {
+	var res *android.ModuleProxy
+	ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
 		if ctx.ModuleName(m) == moduleName {
 			if res == nil {
-				res = m
+				res = &m
 			} else {
 				ctx.Errorf("lint: multiple %s modules found: %s and %s", moduleName,
 					ctx.ModuleSubDir(m), ctx.ModuleSubDir(res))
@@ -635,13 +635,13 @@
 
 		ctx.Build(pctx, android.BuildParams{
 			Rule:   android.CpIfChanged,
-			Input:  android.OutputFileForModule(ctx, sdkAnnotations, ""),
+			Input:  android.OutputFileForModule(ctx, *sdkAnnotations, ""),
 			Output: copiedLintDatabaseFilesPath(ctx, files.annotationCopiedName),
 		})
 
 		ctx.Build(pctx, android.BuildParams{
 			Rule:   android.CpIfChanged,
-			Input:  android.OutputFileForModule(ctx, apiVersionsDb, ".api_versions.xml"),
+			Input:  android.OutputFileForModule(ctx, *apiVersionsDb, ".api_versions.xml"),
 			Output: copiedLintDatabaseFilesPath(ctx, files.apiVersionsCopiedName),
 		})
 	}
@@ -658,12 +658,13 @@
 
 	var outputs []*LintInfo
 	var dirs []string
-	ctx.VisitAllModules(func(m android.Module) {
-		if ctx.Config().KatiEnabled() && !m.ExportedToMake() {
+	ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
+		commonInfo, _ := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoKey)
+		if ctx.Config().KatiEnabled() && !commonInfo.ExportedToMake {
 			return
 		}
 
-		if apex, ok := m.(android.ApexModule); ok && apex.NotAvailableForPlatform() {
+		if commonInfo.IsApexModule && commonInfo.NotAvailableForPlatform {
 			apexInfo, _ := android.OtherModuleProvider(ctx, m, android.ApexInfoProvider)
 			if apexInfo.IsForPlatform() {
 				// There are stray platform variants of modules in apexes that are not available for
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 363521a..ab4f8f8 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -99,6 +99,14 @@
 	includeInMergedXml() bool
 }
 
+type PlatformCompatConfigMetadataInfo struct {
+	CompatConfigMetadata android.Path
+	// Whether to include it in the "merged" XML (merged_compat_config.xml) or not.
+	IncludeInMergedXml bool
+}
+
+var PlatformCompatConfigMetadataInfoProvider = blueprint.NewProvider[PlatformCompatConfigMetadataInfo]()
+
 type PlatformCompatConfigIntf interface {
 	android.Module
 
@@ -136,6 +144,11 @@
 		CompatConfig: p.CompatConfig(),
 		SubDir:       p.SubDir(),
 	})
+
+	android.SetProvider(ctx, PlatformCompatConfigMetadataInfoProvider, PlatformCompatConfigMetadataInfo{
+		CompatConfigMetadata: p.compatConfigMetadata(),
+		IncludeInMergedXml:   p.includeInMergedXml(),
+	})
 }
 
 func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries {
@@ -238,6 +251,11 @@
 
 func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	module.metadataFile = module.prebuilt.SingleSourcePath(ctx)
+
+	android.SetProvider(ctx, PlatformCompatConfigMetadataInfoProvider, PlatformCompatConfigMetadataInfo{
+		CompatConfigMetadata: module.compatConfigMetadata(),
+		IncludeInMergedXml:   module.includeInMergedXml(),
+	})
 }
 
 // A prebuilt version of platform_compat_config that provides the metadata.
@@ -258,18 +276,18 @@
 
 	var compatConfigMetadata android.Paths
 
-	ctx.VisitAllModules(func(module android.Module) {
-		if !module.Enabled(ctx) {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
 			return
 		}
-		if c, ok := module.(platformCompatConfigMetadataProvider); ok {
-			if !android.IsModulePreferred(module) {
+		if c, ok := android.OtherModuleProvider(ctx, module, PlatformCompatConfigMetadataInfoProvider); ok {
+			if !android.IsModulePreferredProxy(ctx, module) {
 				return
 			}
-			if !c.includeInMergedXml() {
+			if !c.IncludeInMergedXml {
 				return
 			}
-			metadata := c.compatConfigMetadata()
+			metadata := c.CompatConfigMetadata
 			compatConfigMetadata = append(compatConfigMetadata, metadata)
 		}
 	})
diff --git a/java/sdk.go b/java/sdk.go
index 8510959..ab1c653 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -274,7 +274,7 @@
 func createFrameworkAidl(stubsModules []string, path android.WritablePath, ctx android.SingletonContext) *android.RuleBuilder {
 	stubsJars := make([]android.Paths, len(stubsModules))
 
-	ctx.VisitAllModules(func(module android.Module) {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
 		// Collect dex jar paths for the modules listed above.
 		if j, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
 			name := ctx.ModuleName(module)
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 431bbac..6d27e54 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -494,7 +494,7 @@
 		PrepareForTestWithJavaSdkLibraryFiles,
 		FixtureWithLastReleaseApis("foo"),
 	).
-		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported module reference tag ".public.annotations.zip"`)).
+		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported output tag ".public.annotations.zip"`)).
 		RunTestWithBp(t, `
 		java_sdk_library {
 			name: "foo",
@@ -520,7 +520,7 @@
 		PrepareForTestWithJavaSdkLibraryFiles,
 		FixtureWithLastReleaseApis("foo"),
 	).
-		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported module reference tag ".system.stubs.source"`)).
+		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported output tag ".system.stubs.source"`)).
 		RunTestWithBp(t, `
 		java_sdk_library {
 			name: "foo",
diff --git a/java/support_libraries.go b/java/support_libraries.go
index c483fc1..f76eb11 100644
--- a/java/support_libraries.go
+++ b/java/support_libraries.go
@@ -28,7 +28,7 @@
 func supportLibrariesMakeVarsProvider(ctx android.MakeVarsContext) {
 	var supportAars, supportJars []string
 
-	ctx.VisitAllModules(func(module android.Module) {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
 		dir := ctx.ModuleDir(module)
 		switch {
 		case strings.HasPrefix(dir, "prebuilts/sdk/current/extras"),
@@ -47,11 +47,16 @@
 			return
 		}
 
-		switch module.(type) {
-		case *AndroidLibrary, *AARImport:
+		_, isAndroidLibrary := android.OtherModuleProvider(ctx, module, AndroidLibraryInfoProvider)
+		_, isAARImport := android.OtherModuleProvider(ctx, module, AARImportInfoProvider)
+		if isAndroidLibrary || isAARImport {
 			supportAars = append(supportAars, name)
-		case *Library, *Import:
-			supportJars = append(supportJars, name)
+		} else {
+			_, isJavaLibrary := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider)
+			_, isJavaPlugin := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider)
+			if isJavaLibrary && !isJavaPlugin {
+				supportJars = append(supportJars, name)
+			}
 		}
 	})
 
diff --git a/rust/rust.go b/rust/rust.go
index 4eebda3..d8a0444 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -60,6 +60,7 @@
 	CompilerInfo                  *CompilerInfo
 	SnapshotInfo                  *cc.SnapshotInfo
 	SourceProviderInfo            *SourceProviderInfo
+	XrefRustFiles                 android.Paths
 }
 
 var RustInfoProvider = blueprint.NewProvider[*RustInfo]()
@@ -1171,6 +1172,7 @@
 		AndroidMkSuffix:               mod.AndroidMkSuffix(),
 		RustSubName:                   mod.Properties.RustSubName,
 		TransitiveAndroidMkSharedLibs: mod.transitiveAndroidMkSharedLibs,
+		XrefRustFiles:                 mod.XrefRustFiles(),
 	}
 	if mod.compiler != nil {
 		rustInfo.CompilerInfo = &CompilerInfo{
@@ -2236,9 +2238,9 @@
 
 func (k kytheExtractRustSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	var xrefTargets android.Paths
-	ctx.VisitAllModules(func(module android.Module) {
-		if rustModule, ok := module.(xref); ok {
-			xrefTargets = append(xrefTargets, rustModule.XrefRustFiles()...)
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+		if rustModule, ok := android.OtherModuleProvider(ctx, module, RustInfoProvider); ok {
+			xrefTargets = append(xrefTargets, rustModule.XrefRustFiles...)
 		}
 	})
 	if len(xrefTargets) > 0 {
diff --git a/sdk/sdk.go b/sdk/sdk.go
index aa82abb..ab50659 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -178,22 +178,24 @@
 		s.buildSnapshot(ctx, sdkVariants)
 	}
 
+	if s.snapshotFile.Valid() != s.infoFile.Valid() {
+		panic(fmt.Sprintf("Snapshot (%q) and info file (%q) should both be set or neither should be set.", s.snapshotFile, s.infoFile))
+	}
+
 	if s.snapshotFile.Valid() {
 		ctx.SetOutputFiles([]android.Path{s.snapshotFile.Path()}, "")
+		ctx.SetOutputFiles([]android.Path{s.snapshotFile.Path(), s.infoFile.Path()}, android.DefaultDistTag)
 	}
 }
 
 func (s *sdk) AndroidMkEntries() []android.AndroidMkEntries {
-	if !s.snapshotFile.Valid() != !s.infoFile.Valid() {
-		panic("Snapshot (%q) and info file (%q) should both be set or neither should be set.")
-	} else if !s.snapshotFile.Valid() {
+	if !s.snapshotFile.Valid() {
 		return []android.AndroidMkEntries{}
 	}
 
 	return []android.AndroidMkEntries{android.AndroidMkEntries{
 		Class:      "FAKE",
 		OutputFile: s.snapshotFile,
-		DistFiles:  android.MakeDefaultDistFiles(s.snapshotFile.Path(), s.infoFile.Path()),
 		Include:    "$(BUILD_PHONY_PACKAGE)",
 		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
 			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go
index 640a82d..cd49ec8 100644
--- a/ui/build/androidmk_denylist.go
+++ b/ui/build/androidmk_denylist.go
@@ -70,8 +70,8 @@
 	}
 }
 
-// The Android.mk files in these directories are for NDK build system.
-var external_ndk_androidmks []string = []string{
+var external_androidmks []string = []string{
+	// The Android.mk files in these directories are for NDK build system.
 	"external/fmtlib/",
 	"external/google-breakpad/",
 	"external/googletest/",
@@ -83,6 +83,9 @@
 	"external/vulkan-validation-layers/",
 	"external/walt/",
 	"external/webp/",
+	// These directories hold the published Android SDK, used in Unbundled Gradle builds.
+	"prebuilts/fullsdk-darwin",
+	"prebuilts/fullsdk-linux",
 }
 
 var art_androidmks = []string{
@@ -90,8 +93,8 @@
 }
 
 func ignoreSomeAndroidMks(androidMks []string) (filtered []string) {
-	ignore_androidmks := make([]string, 0, len(external_ndk_androidmks)+len(art_androidmks))
-	ignore_androidmks = append(ignore_androidmks, external_ndk_androidmks...)
+	ignore_androidmks := make([]string, 0, len(external_androidmks)+len(art_androidmks))
+	ignore_androidmks = append(ignore_androidmks, external_androidmks...)
 	ignore_androidmks = append(ignore_androidmks, art_androidmks...)
 
 	shouldKeep := func(androidmk string) bool {