Merge "android: neverallow.go: add trusty test_vm_os genrule targets" into main
diff --git a/android/androidmk.go b/android/androidmk.go
index 6a1701d..e4366fa 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -78,6 +78,12 @@
 	Entries AndroidMkEntries
 }
 
+type AndroidMkDataInfo struct {
+	Class string
+}
+
+var AndroidMkDataInfoProvider = blueprint.NewProvider[AndroidMkDataInfo]()
+
 type AndroidMkExtraFunc func(w io.Writer, outputFile Path)
 
 // Interface for modules to declare their Android.mk outputs. Note that every module needs to
diff --git a/android/apex.go b/android/apex.go
index 4e92f44..39de6de 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -196,7 +196,7 @@
 		return false
 	}
 
-	if !ctx.EqualModules(ctx.Module(), module) {
+	if !EqualModules(ctx.Module(), module) {
 		if moduleInfo, ok := OtherModuleProvider(ctx, module, DepInSameApexInfoProvider); ok {
 			if !moduleInfo.Checker.OutgoingDepIsInSameApex(depTag) {
 				return false
diff --git a/android/base_module_context.go b/android/base_module_context.go
index 5e05f54..d2404fd 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -34,8 +34,6 @@
 
 	blueprintBaseModuleContext() blueprint.BaseModuleContext
 
-	EqualModules(m1, m2 Module) bool
-
 	// OtherModuleName returns the name of another Module.  See BaseModuleContext.ModuleName for more information.
 	// It is intended for use inside the visit functions of Visit* and WalkDeps.
 	OtherModuleName(m blueprint.Module) string
@@ -271,8 +269,8 @@
 	return module
 }
 
-func (b *baseModuleContext) EqualModules(m1, m2 Module) bool {
-	return b.bp.EqualModules(getWrappedModule(m1), getWrappedModule(m2))
+func EqualModules(m1, m2 Module) bool {
+	return blueprint.EqualModules(getWrappedModule(m1), getWrappedModule(m2))
 }
 
 func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string {
diff --git a/android/container.go b/android/container.go
index 5dc97d3..a5aab79 100644
--- a/android/container.go
+++ b/android/container.go
@@ -449,7 +449,7 @@
 }
 
 func getContainerModuleInfo(ctx ModuleContext, module Module) (ContainersInfo, bool) {
-	if ctx.EqualModules(ctx.Module(), module) {
+	if EqualModules(ctx.Module(), module) {
 		return ctx.getContainersInfo(), true
 	}
 
diff --git a/android/gen_notice.go b/android/gen_notice.go
index 9adde9e..482b1e0 100644
--- a/android/gen_notice.go
+++ b/android/gen_notice.go
@@ -19,6 +19,7 @@
 	"path/filepath"
 	"strings"
 
+	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -35,34 +36,31 @@
 type genNoticeBuildRules struct{}
 
 func (s *genNoticeBuildRules) GenerateBuildActions(ctx SingletonContext) {
-	ctx.VisitAllModules(func(m Module) {
-		gm, ok := m.(*genNoticeModule)
+	ctx.VisitAllModuleProxies(func(m ModuleProxy) {
+		gm, ok := OtherModuleProvider(ctx, m, GenNoticeInfoProvider)
 		if !ok {
 			return
 		}
-		if len(gm.missing) > 0 {
-			missingReferencesRule(ctx, gm)
+		if len(gm.Missing) > 0 {
+			missingReferencesRule(ctx, m, &gm)
 			return
 		}
 		out := BuildNoticeTextOutputFromLicenseMetadata
-		if proptools.Bool(gm.properties.Xml) {
+		if gm.Xml {
 			out = BuildNoticeXmlOutputFromLicenseMetadata
-		} else if proptools.Bool(gm.properties.Html) {
+		} else if gm.Html {
 			out = BuildNoticeHtmlOutputFromLicenseMetadata
 		}
 		defaultName := ""
-		if len(gm.properties.For) > 0 {
-			defaultName = gm.properties.For[0]
+		if len(gm.For) > 0 {
+			defaultName = gm.For[0]
 		}
 
-		modules := make([]Module, 0)
-		for _, name := range gm.properties.For {
-			mods := ctx.ModuleVariantsFromName(gm, name)
+		modules := make([]ModuleProxy, 0)
+		for _, name := range gm.For {
+			mods := ctx.ModuleVariantsFromName(m, name)
 			for _, mod := range mods {
-				if mod == nil {
-					continue
-				}
-				if !mod.Enabled(ctx) { // don't depend on variants without build rules
+				if !OtherModuleProviderOrDefault(ctx, mod, CommonModuleInfoKey).Enabled { // don't depend on variants without build rules
 					continue
 				}
 				modules = append(modules, mod)
@@ -71,8 +69,8 @@
 		if ctx.Failed() {
 			return
 		}
-		out(ctx, gm.output, ctx.ModuleName(gm),
-			proptools.StringDefault(gm.properties.ArtifactName, defaultName),
+		out(ctx, gm.Output, ctx.ModuleName(m),
+			proptools.StringDefault(gm.ArtifactName, defaultName),
 			[]string{
 				filepath.Join(ctx.Config().OutDir(), "target", "product", ctx.Config().DeviceName()) + "/",
 				ctx.Config().OutDir() + "/",
@@ -115,6 +113,22 @@
 	missing []string
 }
 
+type GenNoticeInfo struct {
+	// For specifies the modules for which to generate a notice file.
+	For []string
+	// ArtifactName specifies the internal name to use for the notice file.
+	// It appears in the "used by:" list for targets whose entire name is stripped by --strip_prefix.
+	ArtifactName *string
+	// Html indicates an html-format file is needed. The default is text. Can be Html or Xml but not both.
+	Html bool
+	// Xml indicates an xml-format file is needed. The default is text. Can be Html or Xml but not both.
+	Xml     bool
+	Output  OutputPath
+	Missing []string
+}
+
+var GenNoticeInfoProvider = blueprint.NewProvider[GenNoticeInfo]()
+
 func (m *genNoticeModule) DepsMutator(ctx BottomUpMutatorContext) {
 	if ctx.ContainsProperty("licenses") {
 		ctx.PropertyErrorf("licenses", "not supported on \"gen_notice\" modules")
@@ -176,6 +190,15 @@
 	}
 	out := m.getStem() + m.getSuffix()
 	m.output = PathForModuleOut(ctx, out).OutputPath
+
+	SetProvider(ctx, GenNoticeInfoProvider, GenNoticeInfo{
+		For:          m.properties.For,
+		ArtifactName: m.properties.ArtifactName,
+		Xml:          proptools.Bool(m.properties.Xml),
+		Html:         proptools.Bool(m.properties.Html),
+		Output:       m.output,
+		Missing:      m.missing,
+	})
 	ctx.SetOutputFiles(Paths{m.output}, "")
 }
 
@@ -205,17 +228,17 @@
 }
 
 // missingReferencesRule emits an ErrorRule for missing module references.
-func missingReferencesRule(ctx BuilderContext, m *genNoticeModule) {
-	if len(m.missing) < 1 {
+func missingReferencesRule(ctx BuilderContext, m ModuleProxy, genInfo *GenNoticeInfo) {
+	if len(genInfo.Missing) < 1 {
 		panic(fmt.Errorf("missing references rule requested with no missing references"))
 	}
 
 	ctx.Build(pctx, BuildParams{
 		Rule:        ErrorRule,
-		Output:      m.output,
-		Description: "notice for " + proptools.StringDefault(m.properties.ArtifactName, "container"),
+		Output:      genInfo.Output,
+		Description: "notice for " + proptools.StringDefault(genInfo.ArtifactName, "container"),
 		Args: map[string]string{
-			"error": m.Name() + " references missing module(s): " + strings.Join(m.missing, ", "),
+			"error": m.Name() + " references missing module(s): " + strings.Join(genInfo.Missing, ", "),
 		},
 	})
 }
diff --git a/android/module.go b/android/module.go
index 622399b..405573c 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1662,7 +1662,7 @@
 		var checkbuildTarget Path
 		var uncheckedModule bool
 		var skipAndroidMkProcessing bool
-		if ctx.EqualModules(m.module, module) {
+		if EqualModules(m.module, module) {
 			allInstalledFiles = append(allInstalledFiles, ctx.installFiles...)
 			checkbuildTarget = ctx.checkbuildTarget
 			uncheckedModule = ctx.uncheckedModule
@@ -2370,8 +2370,16 @@
 		})
 	}
 
-	if v, ok := m.module.(ModuleMakeVarsProvider); m.Enabled(ctx) && ok {
-		SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx))
+	if m.Enabled(ctx) {
+		if v, ok := m.module.(ModuleMakeVarsProvider); ok {
+			SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx))
+		}
+
+		if am, ok := m.module.(AndroidMkDataProvider); ok {
+			SetProvider(ctx, AndroidMkDataInfoProvider, AndroidMkDataInfo{
+				Class: am.AndroidMk().Class,
+			})
+		}
 	}
 }
 
@@ -2928,7 +2936,6 @@
 	OtherModuleProviderContext
 	Module() Module
 	GetOutputFiles() OutputFilesInfo
-	EqualModules(m1, m2 Module) bool
 }
 
 // TODO(b/397766191): Change the signature to take ModuleProxy
@@ -2940,7 +2947,7 @@
 	}
 
 	if octx, ok := ctx.(OutputFilesProviderModuleContext); ok {
-		if octx.EqualModules(octx.Module(), module) {
+		if EqualModules(octx.Module(), module) {
 			// It is the current module, we can access the srcs through interface
 			if sourceFileProducer, ok := module.(SourceFileProducer); ok {
 				return sourceFileProducer.Srcs(), nil
@@ -2967,7 +2974,7 @@
 	var outputFiles OutputFilesInfo
 
 	if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx {
-		if !mctx.EqualModules(mctx.Module(), module) {
+		if !EqualModules(mctx.Module(), module) {
 			outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
 		} else {
 			outputFiles = mctx.GetOutputFiles()
@@ -3173,14 +3180,6 @@
 	BaseModuleName() string
 }
 
-// Extract the base module name from the Import name.
-// Often the Import name has a prefix "prebuilt_".
-// Remove the prefix explicitly if needed
-// until we find a better solution to get the Import name.
-type IDECustomizedModuleName interface {
-	IDECustomizedModuleName() string
-}
-
 // Collect information for opening IDE project files in java/jdeps.go.
 type IdeInfo struct {
 	BaseModuleName    string   `json:"-"`
diff --git a/android/notices.go b/android/notices.go
index 3c41d92..dc2290c 100644
--- a/android/notices.go
+++ b/android/notices.go
@@ -18,9 +18,11 @@
 	"fmt"
 	"path/filepath"
 	"strings"
+
+	"github.com/google/blueprint"
 )
 
-func modulesOutputDirs(ctx BuilderContext, modules ...Module) []string {
+func modulesOutputDirs(ctx BuilderContext, modules ...ModuleProxy) []string {
 	dirs := make([]string, 0, len(modules))
 	for _, module := range modules {
 		paths, err := outputFilesForModule(ctx, module, "")
@@ -41,12 +43,12 @@
 	OtherModuleProviderContext
 }
 
-func modulesLicenseMetadata(ctx OtherModuleProviderContext, modules ...Module) Paths {
+func modulesLicenseMetadata(ctx OtherModuleProviderContext, modules ...ModuleProxy) Paths {
 	result := make(Paths, 0, len(modules))
 	mctx, isMctx := ctx.(ModuleContext)
 	for _, module := range modules {
 		var mf Path
-		if isMctx && mctx.Module() == module {
+		if isMctx && EqualModules(mctx.Module(), module) {
 			mf = mctx.LicenseMetadataFile()
 		} else {
 			mf = OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).LicenseMetadataFile
@@ -61,12 +63,12 @@
 // buildNoticeOutputFromLicenseMetadata writes out a notice file.
 func buildNoticeOutputFromLicenseMetadata(
 	ctx BuilderAndOtherModuleProviderContext, tool, ruleName string, outputFile WritablePath,
-	libraryName string, stripPrefix []string, modules ...Module) {
+	libraryName string, stripPrefix []string, modules ...ModuleProxy) {
 	depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", "."))
 	rule := NewRuleBuilder(pctx, ctx)
 	if len(modules) == 0 {
 		if mctx, ok := ctx.(ModuleContext); ok {
-			modules = []Module{mctx.Module()}
+			modules = []ModuleProxy{{blueprint.CreateModuleProxy(mctx.Module())}}
 		} else {
 			panic(fmt.Errorf("%s %q needs a module to generate the notice for", ruleName, libraryName))
 		}
@@ -97,7 +99,7 @@
 // current context module if none given.
 func BuildNoticeTextOutputFromLicenseMetadata(
 	ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
-	stripPrefix []string, modules ...Module) {
+	stripPrefix []string, modules ...ModuleProxy) {
 	buildNoticeOutputFromLicenseMetadata(ctx, "textnotice", "text_notice_"+ruleName,
 		outputFile, libraryName, stripPrefix, modules...)
 }
@@ -107,7 +109,7 @@
 // current context module if none given.
 func BuildNoticeHtmlOutputFromLicenseMetadata(
 	ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
-	stripPrefix []string, modules ...Module) {
+	stripPrefix []string, modules ...ModuleProxy) {
 	buildNoticeOutputFromLicenseMetadata(ctx, "htmlnotice", "html_notice_"+ruleName,
 		outputFile, libraryName, stripPrefix, modules...)
 }
@@ -117,7 +119,7 @@
 // current context module if none given.
 func BuildNoticeXmlOutputFromLicenseMetadata(
 	ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
-	stripPrefix []string, modules ...Module) {
+	stripPrefix []string, modules ...ModuleProxy) {
 	buildNoticeOutputFromLicenseMetadata(ctx, "xmlnotice", "xml_notice_"+ruleName,
 		outputFile, libraryName, stripPrefix, modules...)
 }
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 7273599..4a94c0b 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -412,7 +412,7 @@
 		if prebuiltMod != nil {
 			return false
 		}
-		if ctx.EqualModules(parent, ctx.Module()) {
+		if EqualModules(parent, ctx.Module()) {
 			// First level: Only recurse if the module is found as a direct dependency.
 			sourceModDepFound = child == module
 			return sourceModDepFound
diff --git a/android/singleton.go b/android/singleton.go
index 96b1022..e5f2684 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -36,7 +36,7 @@
 
 	// ModuleVariantsFromName returns the list of module variants named `name` in the same namespace as `referer` enforcing visibility rules.
 	// Allows generating build actions for `referer` based on the metadata for `name` deferred until the singleton context.
-	ModuleVariantsFromName(referer Module, name string) []Module
+	ModuleVariantsFromName(referer ModuleProxy, name string) []ModuleProxy
 
 	otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
 
@@ -331,7 +331,7 @@
 }
 
 func (s *singletonContextAdaptor) VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) {
-	s.SingletonContext.VisitAllModuleVariantProxies(module, visitProxyAdaptor(visit))
+	s.SingletonContext.VisitAllModuleVariantProxies(getWrappedModule(module), visitProxyAdaptor(visit))
 }
 
 func (s *singletonContextAdaptor) PrimaryModule(module Module) Module {
@@ -343,32 +343,30 @@
 }
 
 func (s *singletonContextAdaptor) IsFinalModule(module Module) bool {
-	return s.SingletonContext.IsFinalModule(module)
+	return s.SingletonContext.IsFinalModule(getWrappedModule(module))
 }
 
-func (s *singletonContextAdaptor) ModuleVariantsFromName(referer Module, name string) []Module {
+func (s *singletonContextAdaptor) ModuleVariantsFromName(referer ModuleProxy, name string) []ModuleProxy {
 	// get module reference for visibility enforcement
-	qualified := createVisibilityModuleReference(s.ModuleName(referer), s.ModuleDir(referer), referer)
+	qualified := createVisibilityModuleProxyReference(s, s.ModuleName(referer), s.ModuleDir(referer), referer)
 
-	modules := s.SingletonContext.ModuleVariantsFromName(referer, name)
-	result := make([]Module, 0, len(modules))
-	for _, m := range modules {
-		if module, ok := m.(Module); ok {
-			// enforce visibility
-			depName := s.ModuleName(module)
-			depDir := s.ModuleDir(module)
-			depQualified := qualifiedModuleName{depDir, depName}
-			// Targets are always visible to other targets in their own package.
-			if depQualified.pkg != qualified.name.pkg {
-				rule := effectiveVisibilityRules(s.Config(), depQualified)
-				if !rule.matches(qualified) {
-					s.ModuleErrorf(referer, "module %q references %q which is not visible to this module\nYou may need to add %q to its visibility",
-						referer.Name(), depQualified, "//"+s.ModuleDir(referer))
-					continue
-				}
+	modules := s.SingletonContext.ModuleVariantsFromName(referer.module, name)
+	result := make([]ModuleProxy, 0, len(modules))
+	for _, module := range modules {
+		// enforce visibility
+		depName := s.ModuleName(module)
+		depDir := s.ModuleDir(module)
+		depQualified := qualifiedModuleName{depDir, depName}
+		// Targets are always visible to other targets in their own package.
+		if depQualified.pkg != qualified.name.pkg {
+			rule := effectiveVisibilityRules(s.Config(), depQualified)
+			if !rule.matches(qualified) {
+				s.ModuleErrorf(referer, "module %q references %q which is not visible to this module\nYou may need to add %q to its visibility",
+					referer.Name(), depQualified, "//"+s.ModuleDir(referer))
+				continue
 			}
-			result = append(result, module)
 		}
+		result = append(result, ModuleProxy{module})
 	}
 	return result
 }
diff --git a/android/variable.go b/android/variable.go
index 81999f3..5bc0b29 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -667,6 +667,7 @@
 	AbOtaPartitions                   []string                                 `json:",omitempty"`
 	AbOtaKeys                         []string                                 `json:",omitempty"`
 	AbOtaPostInstallConfig            []string                                 `json:",omitempty"`
+	BoardSuperImageInUpdatePackage    bool                                     `json:",omitempty"`
 
 	// Avb (android verified boot) stuff
 	BoardAvbEnable          bool                                `json:",omitempty"`
@@ -715,6 +716,8 @@
 	ProductFsCompression string `json:",omitempty"`
 
 	ReleaseToolsExtensionDir string `json:",omitempty"`
+
+	BoardFastbootInfoFile string `json:",omitempty"`
 }
 
 func boolPtr(v bool) *bool {
diff --git a/android/visibility.go b/android/visibility.go
index 4837c7d..416a3f1 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -58,15 +58,29 @@
 var visibilityRuleRegexp = regexp.MustCompile(visibilityRulePattern)
 
 type visibilityModuleReference struct {
-	name   qualifiedModuleName
-	module Module
+	name          qualifiedModuleName
+	partitionType *string
 }
 
 func createVisibilityModuleReference(name, dir string, module Module) visibilityModuleReference {
-	return visibilityModuleReference{
-		name:   createQualifiedModuleName(name, dir),
-		module: module,
+	vis := visibilityModuleReference{
+		name: createQualifiedModuleName(name, dir),
 	}
+	if m, ok := module.(PartitionTypeInterface); ok {
+		pt := m.PartitionType()
+		vis.partitionType = &pt
+	}
+	return vis
+}
+
+func createVisibilityModuleProxyReference(ctx OtherModuleProviderContext, name, dir string, module ModuleProxy) visibilityModuleReference {
+	vis := visibilityModuleReference{
+		name: createQualifiedModuleName(name, dir),
+	}
+	if m, ok := OtherModuleProvider(ctx, module, PartitionTypeInfoProvider); ok {
+		vis.partitionType = &m.PartitionType
+	}
+	return vis
 }
 
 // A visibility rule is associated with a module and determines which other modules it is visible
@@ -222,9 +236,17 @@
 	PartitionType() string
 }
 
+type PartitionTypeInfo struct {
+	// Identifies which partition this is for //visibility:any_system_image (and others) visibility
+	// checks, and will be used in the future for API surface checks.
+	PartitionType string
+}
+
+var PartitionTypeInfoProvider = blueprint.NewProvider[PartitionTypeInfo]()
+
 func (r anyPartitionRule) matches(m visibilityModuleReference) bool {
-	if m2, ok := m.module.(PartitionTypeInterface); ok {
-		return m2.PartitionType() == r.partitionType
+	if m.partitionType != nil {
+		return *m.partitionType == r.partitionType
 	}
 	return false
 }
@@ -647,42 +669,6 @@
 	return v.rules
 }
 
-// Get the effective visibility rules, i.e. the actual rules that affect the visibility of the
-// property irrespective of where they are defined.
-//
-// Includes visibility rules specified by package default_visibility and/or on defaults.
-// Short hand forms, e.g. //:__subpackages__ are replaced with their full form, e.g.
-// //package/containing/rule:__subpackages__.
-func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) VisibilityRuleSet {
-	moduleName := ctx.OtherModuleName(module)
-	dir := ctx.OtherModuleDir(module)
-	qualified := qualifiedModuleName{dir, moduleName}
-
-	rule := effectiveVisibilityRules(ctx.Config(), qualified)
-
-	currentModule := createVisibilityModuleReference(moduleName, dir, module)
-
-	// Modules are implicitly visible to other modules in the same package,
-	// without checking the visibility rules. Here we need to add that visibility
-	// explicitly.
-	if !rule.matches(currentModule) {
-		if len(rule) == 1 {
-			if _, ok := rule[0].(privateRule); ok {
-				// If the rule is //visibility:private we can't append another
-				// visibility to it. Semantically we need to convert it to a package
-				// visibility rule for the location where the result is used, but since
-				// modules are implicitly visible within the package we get the same
-				// result without any rule at all, so just make it an empty list to be
-				// appended below.
-				rule = nil
-			}
-		}
-		rule = append(rule, packageRule{dir})
-	}
-
-	return &visibilityRuleSet{rule.Strings()}
-}
-
 // Clear the default visibility properties so they can be replaced.
 func clearVisibilityProperties(module Module) {
 	module.base().visibilityPropertyInfo = nil
diff --git a/android/visibility_test.go b/android/visibility_test.go
index 277be0f..4acaa02 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -2112,7 +2112,10 @@
 	ctx.AddVariationDependencies(nil, dependencyTag{name: "mockdeps"}, j.properties.Deps...)
 }
 
-func (p *mockFilesystemModule) GenerateAndroidBuildActions(ModuleContext) {
+func (p *mockFilesystemModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+	SetProvider(ctx, PartitionTypeInfoProvider, PartitionTypeInfo{
+		PartitionType: p.PartitionType(),
+	})
 }
 
 func (p *mockFilesystemModule) PartitionType() string {
diff --git a/apex/apex.go b/apex/apex.go
index bda5f2f..f700768 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1849,7 +1849,7 @@
 		return false
 	}
 	depName := ctx.OtherModuleName(child)
-	if ctx.EqualModules(parent, ctx.Module()) {
+	if android.EqualModules(parent, ctx.Module()) {
 		switch depTag {
 		case sharedLibTag, jniLibTag:
 			isJniLib := depTag == jniLibTag
@@ -2893,7 +2893,7 @@
 
 				tag := ctx.OtherModuleDependencyTag(child)
 
-				if ctx.EqualModules(parent, ctx.Module()) {
+				if android.EqualModules(parent, ctx.Module()) {
 					if !checkApexTag(tag) {
 						return false
 					}
diff --git a/cc/cc.go b/cc/cc.go
index eae12b8..4da1103 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3713,7 +3713,7 @@
 func ShouldUseStubForApex(ctx android.ModuleContext, parent android.Module, dep android.ModuleProxy) bool {
 	inVendorOrProduct := false
 	bootstrap := false
-	if ctx.EqualModules(ctx.Module(), parent) {
+	if android.EqualModules(ctx.Module(), parent) {
 		if linkable, ok := parent.(LinkableInterface); !ok {
 			ctx.ModuleErrorf("Not a Linkable module: %q", ctx.ModuleName())
 		} else {
diff --git a/cc/library.go b/cc/library.go
index ee7610d..8a2b6bd 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -220,6 +220,7 @@
 
 func RegisterLibraryBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("cc_library_static", LibraryStaticFactory)
+	ctx.RegisterModuleType("cc_rustlibs_for_make", LibraryMakeRustlibsFactory)
 	ctx.RegisterModuleType("cc_library_shared", LibrarySharedFactory)
 	ctx.RegisterModuleType("cc_library", LibraryFactory)
 	ctx.RegisterModuleType("cc_library_host_static", LibraryHostStaticFactory)
@@ -249,6 +250,19 @@
 	return module.Init()
 }
 
+// cc_rustlibs_for_make creates a static library which bundles together rust_ffi_static
+// deps for Make. This should not be depended on in Soong, and is probably not the
+// module you need unless you are sure of what you're doing. These should only
+// be declared as dependencies in Make. To ensure inclusion, rust_ffi_static modules
+// should be declared in the whole_static_libs property.
+func LibraryMakeRustlibsFactory() android.Module {
+	module, library := NewLibrary(android.HostAndDeviceSupported)
+	library.BuildOnlyStatic()
+	library.wideStaticlibForMake = true
+	module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType}
+	return module.Init()
+}
+
 // cc_library_shared creates a shared library for a device and/or host.
 func LibrarySharedFactory() android.Module {
 	module, library := NewLibrary(android.HostAndDeviceSupported)
@@ -437,6 +451,10 @@
 
 	// Path to the file containing the APIs exported by this library
 	stubsSymbolFilePath android.Path
+
+	// Forces production of the generated Rust staticlib for cc_library_static.
+	// Intended to be used to provide these generated staticlibs for Make.
+	wideStaticlibForMake bool
 }
 
 // linkerProps returns the list of properties structs relevant for this library. (For example, if
@@ -1055,6 +1073,16 @@
 	library.objects = library.objects.Append(objs)
 	library.wholeStaticLibsFromPrebuilts = android.CopyOfPaths(deps.WholeStaticLibsFromPrebuilts)
 
+	if library.wideStaticlibForMake {
+		if generatedLib := GenerateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil {
+			// WholeStaticLibsFromPrebuilts are .a files that get included whole into the resulting staticlib
+			// so reuse that here for our Rust staticlibs because we don't have individual object files for
+			// these.
+			deps.WholeStaticLibsFromPrebuilts = append(deps.WholeStaticLibsFromPrebuilts, generatedLib)
+		}
+
+	}
+
 	fileName := ctx.ModuleName() + staticLibraryExtension
 	outputFile := android.PathForModuleOut(ctx, fileName)
 	builderFlags := flagsToBuilderFlags(flags)
diff --git a/cc/tidy.go b/cc/tidy.go
index 2373658..8e7f899 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -211,7 +211,7 @@
 type tidyPhonySingleton struct{}
 
 // Given a final module, add its tidy/obj phony targets to tidy/objModulesInDirGroup.
-func collectTidyObjModuleTargets(ctx android.SingletonContext, module android.Module,
+func collectTidyObjModuleTargets(ctx android.SingletonContext, module android.ModuleProxy,
 	tidyModulesInDirGroup, objModulesInDirGroup map[string]map[string]android.Paths) {
 	allObjFileGroups := make(map[string]android.Paths)     // variant group name => obj file Paths
 	allTidyFileGroups := make(map[string]android.Paths)    // variant group name => tidy file Paths
@@ -253,7 +253,7 @@
 	objModulesInDirGroup := make(map[string]map[string]android.Paths)
 
 	// Collect tidy/obj targets from the 'final' modules.
-	ctx.VisitAllModules(func(module android.Module) {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
 		if ctx.IsFinalModule(module) {
 			collectTidyObjModuleTargets(ctx, module, tidyModulesInDirGroup, objModulesInDirGroup)
 		}
@@ -268,7 +268,7 @@
 }
 
 // The name for an obj/tidy module variant group phony target is Name_group-obj/tidy,
-func objTidyModuleGroupName(module android.Module, group string, suffix string) string {
+func objTidyModuleGroupName(module android.ModuleProxy, group string, suffix string) string {
 	if group == "" {
 		return module.Name() + "-" + suffix
 	}
@@ -327,7 +327,7 @@
 }
 
 // Add an all-OS group, with groupName, to include all os-specific phony targets.
-func addAllOSGroup(ctx android.SingletonContext, module android.Module, phonyTargetGroups map[string]android.Paths, groupName string, objTidyName string) {
+func addAllOSGroup(ctx android.SingletonContext, module android.ModuleProxy, phonyTargetGroups map[string]android.Paths, groupName string, objTidyName string) {
 	if len(phonyTargetGroups) > 0 {
 		var targets android.Paths
 		for group, _ := range phonyTargetGroups {
@@ -338,7 +338,7 @@
 }
 
 // Create one phony targets for each group and add them to the targetGroups.
-func genObjTidyPhonyTargets(ctx android.SingletonContext, module android.Module, objTidyName string, fileGroups map[string]android.Paths, targetGroups map[string]android.Path) {
+func genObjTidyPhonyTargets(ctx android.SingletonContext, module android.ModuleProxy, objTidyName string, fileGroups map[string]android.Paths, targetGroups map[string]android.Path) {
 	for group, files := range fileGroups {
 		groupName := objTidyModuleGroupName(module, group, objTidyName)
 		ctx.Phony(groupName, files...)
diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go
index acfa8e0..0db3f9f 100644
--- a/ci_tests/ci_test_package_zip.go
+++ b/ci_tests/ci_test_package_zip.go
@@ -148,9 +148,9 @@
 	ctx.SetOutputFiles(android.Paths{p.output}, "")
 
 	// dist the test output
-	if ctx.ModuleName() == "platform_tests_soong" {
+	if ctx.ModuleName() == "platform_tests" {
 		distedName := ctx.Config().Getenv("TARGET_PRODUCT") + "-tests-" + ctx.Config().BuildId() + ".zip"
-		ctx.DistForGoalsWithFilename([]string{"droid", "platform_tests"}, p.output, distedName)
+		ctx.DistForGoalWithFilename("platform_tests", p.output, distedName)
 	}
 }
 
@@ -165,52 +165,17 @@
 	builder.Command().Text("rm").Flag("-rf").Text(stagingDir.String())
 	builder.Command().Text("mkdir").Flag("-p").Output(stagingDir)
 	builder.Temporary(stagingDir)
-	ctx.VisitDirectDepsWithTag(testPackageZipDepTag, func(m android.Module) {
-		info, ok := android.OtherModuleProvider(ctx, m, android.ModuleInfoJSONProvider)
-		if !ok {
-			ctx.OtherModuleErrorf(m, "doesn't set ModuleInfoJSON provider")
-		} else if len(info) != 1 {
-			ctx.OtherModuleErrorf(m, "doesn't provide exactly one ModuleInfoJSON")
-		}
-
-		classes := info[0].GetClass()
-		if len(info[0].Class) != 1 {
-			ctx.OtherModuleErrorf(m, "doesn't have exactly one class in its ModuleInfoJSON")
-		}
-		class := strings.ToLower(classes[0])
-		if class == "apps" {
-			class = "app"
-		} else if class == "java_libraries" {
-			class = "framework"
-		}
-
-		installedFilesInfo, ok := android.OtherModuleProvider(ctx, m, android.InstallFilesProvider)
-		if !ok {
-			ctx.ModuleErrorf("Module %s doesn't set InstallFilesProvider", m.Name())
-		}
-
-		for _, installedFile := range installedFilesInfo.InstallFiles {
-			// there are additional installed files for some app-class modules, we only need the .apk files in the test package
-			if class == "app" && installedFile.Ext() != ".apk" {
-				continue
-			}
-			name := removeFileExtension(installedFile.Base())
-			f := strings.TrimPrefix(installedFile.String(), productOut+"/")
-			if strings.HasPrefix(f, "out") {
-				continue
-			}
-			f = strings.ReplaceAll(f, "system/", "DATA/")
-			f = strings.ReplaceAll(f, filepath.Join("testcases", name, arch), filepath.Join("DATA", class, name))
-			f = strings.ReplaceAll(f, filepath.Join("testcases", name, secondArch), filepath.Join("DATA", class, name))
-			f = strings.ReplaceAll(f, "testcases", filepath.Join("DATA", class))
-			f = strings.ReplaceAll(f, "data/", "DATA/")
-			f = strings.ReplaceAll(f, "DATA_other", "system_other")
-			f = strings.ReplaceAll(f, "system_other/DATA", "system_other/system")
-			dir := filepath.Dir(f)
-			tempOut := android.PathForModuleOut(ctx, "STAGING", f)
-			builder.Command().Text("mkdir").Flag("-p").Text(filepath.Join(stagingDir.String(), dir))
-			builder.Command().Text("cp").Flag("-Rf").Input(installedFile).Output(tempOut)
-			builder.Temporary(tempOut)
+	ctx.WalkDeps(func(child, parent android.Module) bool {
+		if android.EqualModules(parent, ctx.Module()) && ctx.OtherModuleDependencyTag(child) == testPackageZipDepTag {
+			// handle direct deps
+			extendBuilderCommand(ctx, child, builder, stagingDir, productOut, arch, secondArch)
+			return true
+		} else if !android.EqualModules(parent, ctx.Module()) && ctx.OtherModuleDependencyTag(child) == android.RequiredDepTag {
+			// handle the "required" from deps
+			extendBuilderCommand(ctx, child, builder, stagingDir, productOut, arch, secondArch)
+			return true
+		} else {
+			return false
 		}
 	})
 
@@ -225,6 +190,73 @@
 	return output
 }
 
+func extendBuilderCommand(ctx android.ModuleContext, m android.Module, builder *android.RuleBuilder, stagingDir android.ModuleOutPath, productOut, arch, secondArch string) {
+	info, ok := android.OtherModuleProvider(ctx, m, android.ModuleInfoJSONProvider)
+	if !ok {
+		ctx.OtherModuleErrorf(m, "doesn't set ModuleInfoJSON provider")
+	} else if len(info) != 1 {
+		ctx.OtherModuleErrorf(m, "doesn't provide exactly one ModuleInfoJSON")
+	}
+
+	classes := info[0].GetClass()
+	if len(info[0].Class) != 1 {
+		ctx.OtherModuleErrorf(m, "doesn't have exactly one class in its ModuleInfoJSON")
+	}
+	class := strings.ToLower(classes[0])
+	if class == "apps" {
+		class = "app"
+	} else if class == "java_libraries" {
+		class = "framework"
+	}
+
+	installedFilesInfo, ok := android.OtherModuleProvider(ctx, m, android.InstallFilesProvider)
+	if !ok {
+		ctx.ModuleErrorf("Module %s doesn't set InstallFilesProvider", m.Name())
+	}
+
+	for _, installedFile := range installedFilesInfo.InstallFiles {
+		ext := installedFile.Ext()
+		// there are additional installed files for some app-class modules, we only need the .apk, .odex and .vdex files in the test package
+		excludeInstalledFile := ext != ".apk" && ext != ".odex" && ext != ".vdex"
+		if class == "app" && excludeInstalledFile {
+			continue
+		}
+		// only .jar files should be included for a framework dep
+		if class == "framework" && ext != ".jar" {
+			continue
+		}
+		name := removeFileExtension(installedFile.Base())
+		// some apks have other apk as installed files, these additional files shouldn't be included
+		isAppOrFramework := class == "app" || class == "framework"
+		if isAppOrFramework && name != ctx.OtherModuleName(m) {
+			continue
+		}
+
+		f := strings.TrimPrefix(installedFile.String(), productOut+"/")
+		if strings.HasPrefix(f, "out") {
+			continue
+		}
+		f = strings.ReplaceAll(f, "system/", "DATA/")
+		f = strings.ReplaceAll(f, filepath.Join("testcases", name, arch), filepath.Join("DATA", class, name))
+		f = strings.ReplaceAll(f, filepath.Join("testcases", name, secondArch), filepath.Join("DATA", class, name))
+		f = strings.ReplaceAll(f, "testcases", filepath.Join("DATA", class))
+		f = strings.ReplaceAll(f, "data/", "DATA/")
+		f = strings.ReplaceAll(f, "DATA_other", "system_other")
+		f = strings.ReplaceAll(f, "system_other/DATA", "system_other/system")
+		dir := filepath.Dir(f)
+
+		// ignore the additional installed files from test
+		if strings.Contains(dir, "DATA/native_tests") || strings.Count(dir, "DATA") > 1 {
+			continue
+		}
+
+		tempOut := android.PathForModuleOut(ctx, "STAGING", f)
+		builder.Command().Text("mkdir").Flag("-p").Text(filepath.Join(stagingDir.String(), dir))
+		builder.Command().Text("cp").Flag("-Rf").Input(installedFile).Output(tempOut)
+		builder.Temporary(tempOut)
+	}
+}
+
 func removeFileExtension(filename string) string {
 	return strings.TrimSuffix(filename, filepath.Ext(filename))
 }
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index c5cafb1..655ee9b 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -510,7 +510,7 @@
 	var dex2oatModule android.ModuleProxy
 	ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
 		prebuiltInfo, isPrebuilt := android.OtherModuleProvider(ctx, child, android.PrebuiltModuleInfoProvider)
-		if ctx.EqualModules(parent, ctx.Module()) && ctx.OtherModuleDependencyTag(child) == Dex2oatDepTag {
+		if android.EqualModules(parent, ctx.Module()) && ctx.OtherModuleDependencyTag(child) == Dex2oatDepTag {
 			// Found the source module, or prebuilt module that has replaced the source.
 			dex2oatModule = child
 			if isPrebuilt {
@@ -519,7 +519,7 @@
 				return true // Recurse to check if the source has a prebuilt dependency.
 			}
 		}
-		if ctx.EqualModules(parent, dex2oatModule) && ctx.OtherModuleDependencyTag(child) == android.PrebuiltDepTag {
+		if android.EqualModules(parent, dex2oatModule) && ctx.OtherModuleDependencyTag(child) == android.PrebuiltDepTag {
 			if isPrebuilt && prebuiltInfo.UsePrebuilt {
 				dex2oatModule = child // Found a prebuilt that should be used.
 			}
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index a2fa0f0..c0f0676 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -87,6 +87,7 @@
 
 	Ramdisk_node_list      *string `android:"path"`
 	Releasetools_extension *string `android:"path"`
+	FastbootInfo           *string `android:"path"`
 }
 
 type androidDevice struct {
@@ -621,6 +622,23 @@
 	}
 	installedApexKeys = android.SortedUniquePaths(installedApexKeys) // Sort by keypath to match make
 	builder.Command().Text("cat").Inputs(installedApexKeys).Textf(" >> %s/META/apexkeys.txt", targetFilesDir.String())
+	// Copy fastboot-info.txt
+	if fastbootInfo := android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.FastbootInfo)); fastbootInfo != nil {
+		// TODO (b/399788523): Autogenerate fastboot-info.txt if there is no source fastboot-info.txt
+		// https://cs.android.com/android/_/android/platform/build/+/80b9546f8f69e78b8fe1870e0e745d70fc18dfcd:core/Makefile;l=5831-5893;drc=077490384423dff9eac954da5c001c6f0be3fa6e;bpv=0;bpt=0
+		builder.Command().Textf("cp").Input(fastbootInfo).Textf(" %s/META/fastboot-info.txt", targetFilesDir.String())
+	}
+
+	if a.partitionProps.Super_partition_name != nil {
+		superPartition := ctx.GetDirectDepProxyWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag)
+		if info, ok := android.OtherModuleProvider(ctx, superPartition, SuperImageProvider); ok {
+			// dynamic_partitions_info.txt
+			// TODO (b/390192334): Add `building_super_empty_partition=true`
+			builder.Command().Text("cp").Input(info.DynamicPartitionsInfo).Textf(" %s/META/", targetFilesDir.String())
+		} else {
+			ctx.ModuleErrorf("Super partition %s does set SuperImageProvider\n", superPartition.Name())
+		}
+	}
 
 }
 
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index d4ea6a3..7257868 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -474,11 +474,7 @@
 
 var FilesystemProvider = blueprint.NewProvider[FilesystemInfo]()
 
-type FilesystemDefaultsInfo struct {
-	// Identifies which partition this is for //visibility:any_system_image (and others) visibility
-	// checks, and will be used in the future for API surface checks.
-	PartitionType string
-}
+type FilesystemDefaultsInfo struct{}
 
 var FilesystemDefaultsInfoProvider = blueprint.NewProvider[FilesystemDefaultsInfo]()
 
@@ -696,6 +692,10 @@
 
 	android.SetProvider(ctx, FilesystemProvider, fsInfo)
 
+	android.SetProvider(ctx, android.PartitionTypeInfoProvider, android.PartitionTypeInfo{
+		PartitionType: f.PartitionType(),
+	})
+
 	f.fileListFile = fileListFile
 
 	if proptools.Bool(f.properties.Unchecked_module) {
@@ -822,11 +822,12 @@
 	}
 
 	ctx.VisitDirectDepsProxyWithTag(android.DefaultsDepTag, func(m android.ModuleProxy) {
-		if fdm, ok := android.OtherModuleProvider(ctx, m, FilesystemDefaultsInfoProvider); ok {
-			if p.PartitionType() != fdm.PartitionType {
+		if _, ok := android.OtherModuleProvider(ctx, m, FilesystemDefaultsInfoProvider); ok {
+			partitionInfo := android.OtherModuleProviderOrDefault(ctx, m, android.PartitionTypeInfoProvider)
+			if p.PartitionType() != partitionInfo.PartitionType {
 				ctx.PropertyErrorf("partition_type",
 					"%s doesn't match with the partition type %s of the filesystem default module %s",
-					p.PartitionType(), fdm.PartitionType, m.Name())
+					p.PartitionType(), partitionInfo.PartitionType, m.Name())
 			}
 		}
 	})
@@ -1413,7 +1414,8 @@
 
 func (f *filesystemDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	validatePartitionType(ctx, f)
-	android.SetProvider(ctx, FilesystemDefaultsInfoProvider, FilesystemDefaultsInfo{
+	android.SetProvider(ctx, FilesystemDefaultsInfoProvider, FilesystemDefaultsInfo{})
+	android.SetProvider(ctx, android.PartitionTypeInfoProvider, android.PartitionTypeInfo{
 		PartitionType: f.PartitionType(),
 	})
 }
diff --git a/filesystem/super_image.go b/filesystem/super_image.go
index 58c938a..5e62fa7 100644
--- a/filesystem/super_image.go
+++ b/filesystem/super_image.go
@@ -78,6 +78,8 @@
 		// specified we default to COW version 2 in update_engine for backwards compatibility
 		Cow_version *int64
 	}
+	// Whether the super image will be disted in the update package
+	Super_image_in_update_package *bool
 }
 
 type PartitionGroupsInfo struct {
@@ -114,6 +116,8 @@
 	// Mapping from the sub-partition type to its re-exported FileSystemInfo providers from the
 	// sub-partitions.
 	SubImageInfo map[string]FilesystemInfo
+
+	DynamicPartitionsInfo android.Path
 }
 
 var SuperImageProvider = blueprint.NewProvider[SuperImageInfo]()
@@ -173,8 +177,9 @@
 		Output(output)
 	builder.Build("build_super_image", fmt.Sprintf("Creating super image %s", s.BaseModuleName()))
 	android.SetProvider(ctx, SuperImageProvider, SuperImageInfo{
-		SuperImage:   output,
-		SubImageInfo: subImageInfos,
+		SuperImage:            output,
+		SubImageInfo:          subImageInfos,
+		DynamicPartitionsInfo: s.generateDynamicPartitionsInfo(ctx),
 	})
 	ctx.SetOutputFiles([]android.Path{output}, "")
 	ctx.CheckbuildFile(output)
@@ -186,6 +191,7 @@
 
 func (s *superImage) buildMiscInfo(ctx android.ModuleContext) (android.Path, android.Paths, map[string]FilesystemInfo) {
 	var miscInfoString strings.Builder
+	partitionList := s.dumpDynamicPartitionInfo(ctx, &miscInfoString)
 	addStr := func(name string, value string) {
 		miscInfoString.WriteString(name)
 		miscInfoString.WriteRune('=')
@@ -193,71 +199,6 @@
 		miscInfoString.WriteRune('\n')
 	}
 
-	addStr("build_super_partition", "true")
-	addStr("use_dynamic_partitions", strconv.FormatBool(proptools.Bool(s.properties.Use_dynamic_partitions)))
-	if proptools.Bool(s.properties.Retrofit) {
-		addStr("dynamic_partition_retrofit", "true")
-	}
-	addStr("lpmake", "lpmake")
-	addStr("super_metadata_device", proptools.String(s.properties.Metadata_device))
-	if len(s.properties.Block_devices) > 0 {
-		addStr("super_block_devices", strings.Join(s.properties.Block_devices, " "))
-	}
-	addStr("super_partition_size", strconv.Itoa(proptools.Int(s.properties.Size)))
-	// TODO: In make, there's more complicated logic than just this surrounding super_*_device_size
-	addStr("super_super_device_size", strconv.Itoa(proptools.Int(s.properties.Size)))
-	var groups, partitionList []string
-	for _, groupInfo := range s.properties.Partition_groups {
-		groups = append(groups, groupInfo.Name)
-		partitionList = append(partitionList, groupInfo.PartitionList...)
-		addStr("super_"+groupInfo.Name+"_group_size", groupInfo.GroupSize)
-		addStr("super_"+groupInfo.Name+"_partition_list", strings.Join(groupInfo.PartitionList, " "))
-	}
-	initialPartitionListLen := len(partitionList)
-	partitionList = android.SortedUniqueStrings(partitionList)
-	if len(partitionList) != initialPartitionListLen {
-		ctx.ModuleErrorf("Duplicate partitions found in the partition_groups property")
-	}
-	addStr("super_partition_groups", strings.Join(groups, " "))
-	addStr("dynamic_partition_list", strings.Join(partitionList, " "))
-
-	addStr("ab_update", strconv.FormatBool(proptools.Bool(s.properties.Ab_update)))
-
-	if proptools.Bool(s.properties.Virtual_ab.Enable) {
-		addStr("virtual_ab", "true")
-		if proptools.Bool(s.properties.Virtual_ab.Retrofit) {
-			addStr("virtual_ab_retrofit", "true")
-		}
-		addStr("virtual_ab_compression", strconv.FormatBool(proptools.Bool(s.properties.Virtual_ab.Compression)))
-		if s.properties.Virtual_ab.Compression_method != nil {
-			matched, _ := regexp.MatchString("^[a-zA-Z0-9_-]+$", *s.properties.Virtual_ab.Compression_method)
-			if !matched {
-				ctx.PropertyErrorf("virtual_ab.compression_method", "compression_method cannot have special characters")
-			}
-			addStr("virtual_ab_compression_method", *s.properties.Virtual_ab.Compression_method)
-		}
-		if s.properties.Virtual_ab.Compression_factor != nil {
-			addStr("virtual_ab_compression_factor", strconv.FormatInt(*s.properties.Virtual_ab.Compression_factor, 10))
-		}
-		if s.properties.Virtual_ab.Cow_version != nil {
-			addStr("virtual_ab_cow_version", strconv.FormatInt(*s.properties.Virtual_ab.Cow_version, 10))
-		}
-
-	} else {
-		if s.properties.Virtual_ab.Retrofit != nil {
-			ctx.PropertyErrorf("virtual_ab.retrofit", "This property cannot be set when virtual_ab is disabled")
-		}
-		if s.properties.Virtual_ab.Compression != nil {
-			ctx.PropertyErrorf("virtual_ab.compression", "This property cannot be set when virtual_ab is disabled")
-		}
-		if s.properties.Virtual_ab.Compression_method != nil {
-			ctx.PropertyErrorf("virtual_ab.compression_method", "This property cannot be set when virtual_ab is disabled")
-		}
-		if s.properties.Virtual_ab.Compression_factor != nil {
-			ctx.PropertyErrorf("virtual_ab.compression_factor", "This property cannot be set when virtual_ab is disabled")
-		}
-	}
-
 	subImageInfo := make(map[string]FilesystemInfo)
 	var deps android.Paths
 
@@ -346,3 +287,90 @@
 	android.WriteFileRule(ctx, miscInfo, miscInfoString.String(), missingPartitionErrorMessageFile)
 	return miscInfo, deps, subImageInfo
 }
+
+func (s *superImage) dumpDynamicPartitionInfo(ctx android.ModuleContext, sb *strings.Builder) []string {
+	addStr := func(name string, value string) {
+		sb.WriteString(name)
+		sb.WriteRune('=')
+		sb.WriteString(value)
+		sb.WriteRune('\n')
+	}
+
+	addStr("build_super_partition", "true")
+	addStr("use_dynamic_partitions", strconv.FormatBool(proptools.Bool(s.properties.Use_dynamic_partitions)))
+	if proptools.Bool(s.properties.Retrofit) {
+		addStr("dynamic_partition_retrofit", "true")
+	}
+	addStr("lpmake", "lpmake")
+	addStr("super_metadata_device", proptools.String(s.properties.Metadata_device))
+	if len(s.properties.Block_devices) > 0 {
+		addStr("super_block_devices", strings.Join(s.properties.Block_devices, " "))
+	}
+	if proptools.Bool(s.properties.Super_image_in_update_package) {
+		addStr("super_image_in_update_package", "true")
+	}
+	addStr("super_partition_size", strconv.Itoa(proptools.Int(s.properties.Size)))
+	// TODO: In make, there's more complicated logic than just this surrounding super_*_device_size
+	addStr("super_super_device_size", strconv.Itoa(proptools.Int(s.properties.Size)))
+	var groups, partitionList []string
+	for _, groupInfo := range s.properties.Partition_groups {
+		groups = append(groups, groupInfo.Name)
+		partitionList = append(partitionList, groupInfo.PartitionList...)
+		addStr("super_"+groupInfo.Name+"_group_size", groupInfo.GroupSize)
+		addStr("super_"+groupInfo.Name+"_partition_list", strings.Join(groupInfo.PartitionList, " "))
+	}
+	initialPartitionListLen := len(partitionList)
+	partitionList = android.SortedUniqueStrings(partitionList)
+	if len(partitionList) != initialPartitionListLen {
+		ctx.ModuleErrorf("Duplicate partitions found in the partition_groups property")
+	}
+	addStr("super_partition_groups", strings.Join(groups, " "))
+	addStr("dynamic_partition_list", strings.Join(partitionList, " "))
+
+	addStr("ab_update", strconv.FormatBool(proptools.Bool(s.properties.Ab_update)))
+
+	if proptools.Bool(s.properties.Virtual_ab.Enable) {
+		addStr("virtual_ab", "true")
+		if proptools.Bool(s.properties.Virtual_ab.Retrofit) {
+			addStr("virtual_ab_retrofit", "true")
+		}
+		addStr("virtual_ab_compression", strconv.FormatBool(proptools.Bool(s.properties.Virtual_ab.Compression)))
+		if s.properties.Virtual_ab.Compression_method != nil {
+			matched, _ := regexp.MatchString("^[a-zA-Z0-9_-]+$", *s.properties.Virtual_ab.Compression_method)
+			if !matched {
+				ctx.PropertyErrorf("virtual_ab.compression_method", "compression_method cannot have special characters")
+			}
+			addStr("virtual_ab_compression_method", *s.properties.Virtual_ab.Compression_method)
+		}
+		if s.properties.Virtual_ab.Compression_factor != nil {
+			addStr("virtual_ab_compression_factor", strconv.FormatInt(*s.properties.Virtual_ab.Compression_factor, 10))
+		}
+		if s.properties.Virtual_ab.Cow_version != nil {
+			addStr("virtual_ab_cow_version", strconv.FormatInt(*s.properties.Virtual_ab.Cow_version, 10))
+		}
+
+	} else {
+		if s.properties.Virtual_ab.Retrofit != nil {
+			ctx.PropertyErrorf("virtual_ab.retrofit", "This property cannot be set when virtual_ab is disabled")
+		}
+		if s.properties.Virtual_ab.Compression != nil {
+			ctx.PropertyErrorf("virtual_ab.compression", "This property cannot be set when virtual_ab is disabled")
+		}
+		if s.properties.Virtual_ab.Compression_method != nil {
+			ctx.PropertyErrorf("virtual_ab.compression_method", "This property cannot be set when virtual_ab is disabled")
+		}
+		if s.properties.Virtual_ab.Compression_factor != nil {
+			ctx.PropertyErrorf("virtual_ab.compression_factor", "This property cannot be set when virtual_ab is disabled")
+		}
+	}
+
+	return partitionList
+}
+
+func (s *superImage) generateDynamicPartitionsInfo(ctx android.ModuleContext) android.Path {
+	var contents strings.Builder
+	s.dumpDynamicPartitionInfo(ctx, &contents)
+	dynamicPartitionsInfo := android.PathForModuleOut(ctx, "dynamic_partitions_info.txt")
+	android.WriteFileRule(ctx, dynamicPartitionsInfo, contents.String())
+	return dynamicPartitionsInfo
+}
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index 3d83706..d286c66 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -340,6 +340,26 @@
 	return releaseToolsFilegroupName, true
 }
 
+func (f *filesystemCreator) createFastbootInfoFilegroup(ctx android.LoadHookContext) (string, bool) {
+	fastbootInfoFile := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BoardFastbootInfoFile
+	if fastbootInfoFile == "" {
+		return "", false
+	}
+
+	fastbootInfoFilegroupName := generatedModuleName(ctx.Config(), "fastboot")
+	filegroupProps := &struct {
+		Name       *string
+		Srcs       []string
+		Visibility []string
+	}{
+		Name:       proptools.StringPtr(fastbootInfoFilegroupName),
+		Srcs:       []string{fastbootInfoFile},
+		Visibility: []string{"//visibility:public"},
+	}
+	ctx.CreateModuleInDirectory(android.FileGroupFactory, ".", filegroupProps)
+	return fastbootInfoFilegroupName, true
+}
+
 func (f *filesystemCreator) createDeviceModule(
 	ctx android.LoadHookContext,
 	partitions allGeneratedPartitionData,
@@ -413,6 +433,9 @@
 	if releaseTools, ok := f.createReleaseToolsFilegroup(ctx); ok {
 		deviceProps.Releasetools_extension = proptools.StringPtr(":" + releaseTools)
 	}
+	if fastbootInfo, ok := f.createFastbootInfoFilegroup(ctx); ok {
+		deviceProps.FastbootInfo = proptools.StringPtr(":" + fastbootInfo)
+	}
 
 	ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps, deviceProps)
 }
diff --git a/fsgen/super_img.go b/fsgen/super_img.go
index 569f780..f564636 100644
--- a/fsgen/super_img.go
+++ b/fsgen/super_img.go
@@ -40,11 +40,12 @@
 	}
 
 	superImageProps := &filesystem.SuperImageProperties{
-		Metadata_device:        proptools.StringPtr(partitionVars.BoardSuperPartitionMetadataDevice),
-		Block_devices:          partitionVars.BoardSuperPartitionBlockDevices,
-		Ab_update:              proptools.BoolPtr(partitionVars.AbOtaUpdater),
-		Retrofit:               proptools.BoolPtr(partitionVars.ProductRetrofitDynamicPartitions),
-		Use_dynamic_partitions: proptools.BoolPtr(partitionVars.ProductUseDynamicPartitions),
+		Metadata_device:               proptools.StringPtr(partitionVars.BoardSuperPartitionMetadataDevice),
+		Block_devices:                 partitionVars.BoardSuperPartitionBlockDevices,
+		Ab_update:                     proptools.BoolPtr(partitionVars.AbOtaUpdater),
+		Retrofit:                      proptools.BoolPtr(partitionVars.ProductRetrofitDynamicPartitions),
+		Use_dynamic_partitions:        proptools.BoolPtr(partitionVars.ProductUseDynamicPartitions),
+		Super_image_in_update_package: proptools.BoolPtr(partitionVars.BoardSuperImageInUpdatePackage),
 	}
 	if partitionVars.ProductVirtualAbOta {
 		superImageProps.Virtual_ab.Enable = proptools.BoolPtr(true)
diff --git a/java/app.go b/java/app.go
index 827b235..c2aa8a4 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1175,7 +1175,7 @@
 			apkInApex := ctx.Module().(android.ApexModule).NotInPlatform()
 			childLinkable, _ := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider)
 			parentIsLinkable := false
-			if ctx.EqualModules(ctx.Module(), parent) {
+			if android.EqualModules(ctx.Module(), parent) {
 				parentLinkable, _ := ctx.Module().(cc.LinkableInterface)
 				parentIsLinkable = parentLinkable != nil
 			} else {
diff --git a/java/java.go b/java/java.go
index 38361bf..c1e4f8c 100644
--- a/java/java.go
+++ b/java/java.go
@@ -3363,21 +3363,12 @@
 
 // Add compile time check for interface implementation
 var _ android.IDEInfo = (*Import)(nil)
-var _ android.IDECustomizedModuleName = (*Import)(nil)
 
 // Collect information for opening IDE project files in java/jdeps.go.
-
 func (j *Import) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
 	dpInfo.Jars = append(dpInfo.Jars, j.combinedImplementationFile.String())
 }
 
-func (j *Import) IDECustomizedModuleName() string {
-	// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
-	// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
-	// solution to get the Import name.
-	return android.RemoveOptionalPrebuiltPrefix(j.Name())
-}
-
 var _ android.PrebuiltInterface = (*Import)(nil)
 
 func (j *Import) IsInstallable() bool {
diff --git a/java/jdeps.go b/java/jdeps.go
index 07f8c43..4711dc1 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -45,13 +45,13 @@
 	// (b/204397180) Generate module_bp_java_deps.json by default.
 	moduleInfos := make(map[string]android.IdeInfo)
 
-	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
 		}
 
 		// Prevent including both prebuilts and matching source modules when one replaces the other.
-		if !android.IsModulePreferred(module) {
+		if !android.IsModulePreferredProxy(ctx, module) {
 			return
 		}
 
@@ -60,9 +60,11 @@
 			return
 		}
 		name := ideInfoProvider.BaseModuleName
-		ideModuleNameProvider, ok := module.(android.IDECustomizedModuleName)
-		if ok {
-			name = ideModuleNameProvider.IDECustomizedModuleName()
+		if info, ok := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider); ok && info.Prebuilt {
+			// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
+			// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
+			// solution to get the Import name.
+			name = android.RemoveOptionalPrebuiltPrefix(module.Name())
 		}
 
 		dpInfo := moduleInfos[name]
@@ -70,13 +72,12 @@
 		dpInfo.Paths = []string{ctx.ModuleDir(module)}
 		moduleInfos[name] = dpInfo
 
-		mkProvider, ok := module.(android.AndroidMkDataProvider)
+		mkProvider, ok := android.OtherModuleProvider(ctx, module, android.AndroidMkDataInfoProvider)
 		if !ok {
 			return
 		}
-		data := mkProvider.AndroidMk()
-		if data.Class != "" {
-			dpInfo.Classes = append(dpInfo.Classes, data.Class)
+		if mkProvider.Class != "" {
+			dpInfo.Classes = append(dpInfo.Classes, mkProvider.Class)
 		}
 
 		if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 7944bb2..0fee529 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1580,7 +1580,9 @@
 		setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo)
 	}
 
-	javaInfo := &JavaInfo{}
+	javaInfo := &JavaInfo{
+		JacocoReportClassesFile: module.jacocoReportClassesFile,
+	}
 	setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
 	android.SetProvider(ctx, JavaInfoProvider, javaInfo)
 
@@ -2240,6 +2242,10 @@
 	}
 
 	javaInfo := &JavaInfo{}
+	if module.implLibraryInfo != nil {
+		javaInfo.JacocoReportClassesFile = module.implLibraryInfo.JacocoReportClassesFile
+	}
+
 	setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
 	android.SetProvider(ctx, JavaInfoProvider, javaInfo)
 
diff --git a/provenance/provenance_metadata_proto/Android.bp b/provenance/provenance_metadata_proto/Android.bp
index 7fc47a9..b4176a5 100644
--- a/provenance/provenance_metadata_proto/Android.bp
+++ b/provenance/provenance_metadata_proto/Android.bp
@@ -20,11 +20,6 @@
 
 python_library_host {
     name: "provenance_metadata_proto",
-    version: {
-        py3: {
-            enabled: true,
-        },
-    },
     srcs: [
         "provenance_metadata.proto",
     ],
diff --git a/rust/config/OWNERS b/rust/config/OWNERS
index dfff873..e4bf5e6 100644
--- a/rust/config/OWNERS
+++ b/rust/config/OWNERS
@@ -1,2 +1,2 @@
-per-file global.go = srhines@google.com, chh@google.com, pirama@google.com, yikong@google.com
+per-file global.go = srhines@google.com, pirama@google.com, yikong@google.com
 
diff --git a/rust/library_test.go b/rust/library_test.go
index 6db9525..6cc4f25 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -426,6 +426,45 @@
 	android.AssertStringDoesContain(t, "cFlags for lib module", libfooStatic.Args["cFlags"], " -Irust_includes ")
 }
 
+// Make sure cc_rustlibs_for_make has the expected behavior, and that
+// cc_library_static does as well.
+// This is here instead of cc/library_test.go because the test needs to
+// define a rust_ffi module which can't be done in soong-cc to avoid the
+// circular dependency.
+func TestCCRustlibsForMake(t *testing.T) {
+	t.Parallel()
+	result := testRust(t, `
+		rust_ffi_static {
+			name: "libbar",
+			srcs: ["foo.rs"],
+			crate_name: "bar",
+			export_include_dirs: ["rust_includes"],
+			host_supported: true,
+		}
+
+		cc_rustlibs_for_make {
+			name: "libmakerustlibs",
+			whole_static_libs: ["libbar"],
+		}
+
+		cc_library_static {
+			name: "libccstatic",
+			whole_static_libs: ["libbar"],
+		}
+	`)
+
+	libmakerustlibs := result.ModuleForTests(t, "libmakerustlibs", "android_arm64_armv8-a_static").MaybeRule("rustc")
+	libccstatic := result.ModuleForTests(t, "libccstatic", "android_arm64_armv8-a_static").MaybeRule("rustc")
+
+	if libmakerustlibs.Output == nil {
+		t.Errorf("cc_rustlibs_for_make is not generating a  Rust staticlib when it should")
+	}
+
+	if libccstatic.Output != nil {
+		t.Errorf("cc_library_static is generating a Rust staticlib when it should not")
+	}
+}
+
 func TestRustVersionScript(t *testing.T) {
 	ctx := testRust(t, `
 	rust_library {
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index f8d1ce5..d00c056 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -356,6 +356,8 @@
 	for _, symlink := range s.Symlinks() {
 		ctx.InstallSymlink(installDir, symlink, s.installedFile)
 	}
+	moduleInfoJSON := ctx.ModuleInfoJSON()
+	moduleInfoJSON.Class = []string{"EXECUTABLES"}
 }
 
 func (s *ShBinary) AndroidMkEntries() []android.AndroidMkEntries {