Merge "Add Gob support of ApiLevel and applicableLicensesPropertyImpl." into main
diff --git a/Android.bp b/Android.bp
index 337545b..7134591 100644
--- a/Android.bp
+++ b/Android.bp
@@ -176,6 +176,12 @@
     footer_files: [
         ":applied_backported_fixes",
     ],
+    dist: {
+        targets: [
+            "droidcore-unbundled",
+            "sdk",
+        ],
+    },
     // Currently, only microdroid, Ravenwood, and cf system image can refer to system-build.prop
     visibility: [
         "//build/soong/fsgen",
@@ -191,6 +197,10 @@
     system_ext_specific: true,
     product_config: ":product_config",
     relative_install_path: "etc", // system_ext/etc/build.prop
+    dist: {
+        targets: ["droidcore-unbundled"],
+        dest: "build.prop-system_ext",
+    },
     visibility: [
         "//build/make/target/product/gsi",
         "//build/soong/fsgen",
@@ -203,6 +213,10 @@
     product_specific: true,
     product_config: ":product_config",
     relative_install_path: "etc", // product/etc/build.prop
+    dist: {
+        targets: ["droidcore-unbundled"],
+        dest: "build.prop-product",
+    },
     visibility: [
         "//build/make/target/product/gsi",
         "//build/soong/fsgen",
@@ -215,6 +229,10 @@
     device_specific: true,
     product_config: ":product_config",
     relative_install_path: "etc", // odm/etc/build.prop
+    dist: {
+        targets: ["droidcore-unbundled"],
+        dest: "build.prop-odm",
+    },
     visibility: ["//build/soong/fsgen"],
 }
 
@@ -251,6 +269,10 @@
     ramdisk: true,
     product_config: ":product_config",
     relative_install_path: "etc/ramdisk", // ramdisk/system/etc/ramdisk/build.prop
+    dist: {
+        targets: ["droidcore-unbundled"],
+        dest: "build.prop-ramdisk",
+    },
     visibility: ["//visibility:private"],
 }
 
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index 3d07e16..f3c68c3 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -95,11 +95,44 @@
 	})
 }
 
+func GenerateExportedFlagCheck(ctx android.ModuleContext, outputPath android.WritablePath,
+	parsedFlagsFile android.Path, apiSurface ApiSurfaceContributorProperties) {
+
+	apiSignatureFiles := android.Paths{}
+	for _, apiSignatureFile := range apiSurface.Api_signature_files.GetOrDefault(ctx, nil) {
+		if path := android.PathForModuleSrc(ctx, apiSignatureFile); path != nil {
+			apiSignatureFiles = append(apiSignatureFiles, path)
+		}
+	}
+	finalizedFlagsFile := android.PathForModuleSrc(ctx, apiSurface.Finalized_flags_file)
+
+	ctx.Build(pctx, android.BuildParams{
+		Rule:   ExportedFlagCheckRule,
+		Inputs: append(apiSignatureFiles, finalizedFlagsFile, parsedFlagsFile),
+		Output: outputPath,
+		Args: map[string]string{
+			"api_signature_files":  android.JoinPathsWithPrefix(apiSignatureFiles, "--api-signature-file "),
+			"finalized_flags_file": "--finalized-flags-file " + finalizedFlagsFile.String(),
+			"parsed_flags_file":    "--parsed-flags-file " + parsedFlagsFile.String(),
+		},
+	})
+}
+
 func (this *allAconfigDeclarationsSingleton) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	parsedFlagsFile := android.PathForIntermediates(ctx, "all_aconfig_declarations.pb")
 	this.finalizedFlags = android.PathForIntermediates(ctx, "finalized-flags.txt")
 	GenerateFinalizedFlagsForApiSurface(ctx, this.finalizedFlags, parsedFlagsFile, this.properties)
-	ctx.Phony("all_aconfig_declarations", this.finalizedFlags)
+
+	depsFiles := android.Paths{this.finalizedFlags}
+	if checkExportedFlag, ok := ctx.Config().GetBuildFlag("RELEASE_EXPORTED_FLAG_CHECK"); ok {
+		if checkExportedFlag == "true" {
+			invalidExportedFlags := android.PathForIntermediates(ctx, "invalid_exported_flags.txt")
+			GenerateExportedFlagCheck(ctx, invalidExportedFlags, parsedFlagsFile, this.properties)
+			depsFiles = append(depsFiles, invalidExportedFlags)
+		}
+	}
+
+	ctx.Phony("all_aconfig_declarations", depsFiles...)
 
 	android.SetProvider(ctx, allAconfigDeclarationsInfoProvider, allAconfigDeclarationsInfo{
 		parsedFlagsFile: parsedFlagsFile,
@@ -111,7 +144,7 @@
 		// Find all of the aconfig_declarations modules
 		var packages = make(map[string]int)
 		var cacheFiles android.Paths
-		ctx.VisitAllModules(func(module android.Module) {
+		ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
 			decl, ok := android.OtherModuleProvider(ctx, module, android.AconfigReleaseDeclarationsProviderKey)
 			if !ok {
 				return
diff --git a/aconfig/build_flags/build_flags_singleton.go b/aconfig/build_flags/build_flags_singleton.go
index e375d9c..3a06e72 100644
--- a/aconfig/build_flags/build_flags_singleton.go
+++ b/aconfig/build_flags/build_flags_singleton.go
@@ -15,8 +15,9 @@
 package build_flags
 
 import (
-	"android/soong/android"
 	"fmt"
+
+	"android/soong/android"
 )
 
 // A singleton module that collects all of the build flags declared in the
@@ -42,7 +43,7 @@
 	var flagsFiles android.Paths
 	// Find all of the release_config_contribution modules
 	var contributionDirs android.Paths
-	ctx.VisitAllModules(func(module android.Module) {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
 		decl, ok := android.OtherModuleProvider(ctx, module, BuildFlagDeclarationsProviderKey)
 		if ok {
 			flagsFiles = append(flagsFiles, decl.IntermediateCacheOutputPath)
diff --git a/aconfig/init.go b/aconfig/init.go
index b2fe5a3..d8d5470 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -77,6 +77,13 @@
 				"${record-finalized-flags}",
 			},
 		}, "api_signature_files", "finalized_flags_file", "parsed_flags_file")
+	ExportedFlagCheckRule = pctx.AndroidStaticRule("ExportedFlagCheckRule",
+		blueprint.RuleParams{
+			Command: `${exported-flag-check} ${parsed_flags_file} ${finalized_flags_file} ${api_signature_files} > ${out}`,
+			CommandDeps: []string{
+				"${exported-flag-check}",
+			},
+		}, "api_signature_files", "finalized_flags_file", "parsed_flags_file")
 
 	CreateStorageRule = pctx.AndroidStaticRule("aconfig_create_storage",
 		blueprint.RuleParams{
@@ -124,6 +131,7 @@
 	pctx.HostBinToolVariable("aconfig", "aconfig")
 	pctx.HostBinToolVariable("soong_zip", "soong_zip")
 	pctx.HostBinToolVariable("record-finalized-flags", "record-finalized-flags")
+	pctx.HostBinToolVariable("exported-flag-check", "exported-flag-check")
 }
 
 func RegisterBuildComponents(ctx android.RegistrationContext) {
diff --git a/android/Android.bp b/android/Android.bp
index 1cc7ffe..4b75148 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -97,6 +97,7 @@
         "product_packages_file.go",
         "proto.go",
         "provider.go",
+        "provider_keys.go",
         "raw_files.go",
         "recovery_build_prop.go",
         "register.go",
@@ -170,3 +171,7 @@
     // Used by plugins
     visibility: ["//visibility:public"],
 }
+
+otatools_package_filegroup {
+    name: "otatools_package_filegroup",
+}
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index 7185a89..9c71d92 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -248,7 +248,7 @@
 // Please only access the module's internal data through providers.
 func getContainerUsingProviders(ctx OtherModuleProviderContext, m Module) string {
 	container := "system"
-	commonInfo, _ := OtherModuleProvider(ctx, m, CommonModuleInfoKey)
+	commonInfo, _ := OtherModuleProvider(ctx, m, CommonModuleInfoProvider)
 	if commonInfo.Vendor || commonInfo.Proprietary || commonInfo.SocSpecific {
 		container = "vendor"
 	} else if commonInfo.ProductSpecific {
diff --git a/android/all_teams.go b/android/all_teams.go
index 8b55ade..5e76e53 100644
--- a/android/all_teams.go
+++ b/android/all_teams.go
@@ -116,7 +116,7 @@
 			testOnly:           testModInfo.TestOnly,
 			topLevelTestTarget: testModInfo.TopLevelTarget,
 			kind:               ctx.ModuleType(module),
-			teamName:           OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).Team,
+			teamName:           OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoProvider).Team,
 		}
 		t.teams_for_mods[module.Name()] = entry
 
diff --git a/android/androidmk.go b/android/androidmk.go
index e4366fa..694f5d6 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -528,6 +528,14 @@
 
 	fmt.Fprintf(&a.header, "\ninclude $(CLEAR_VARS)  # type: %s, name: %s, variant: %s\n", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod))
 
+	// Add the TestSuites from the provider to LOCAL_SOONG_PROVIDER_TEST_SUITES.
+	// LOCAL_SOONG_PROVIDER_TEST_SUITES will be compared against LOCAL_COMPATIBILITY_SUITES
+	// in make and enforced they're the same, to ensure we've successfully translated all
+	// LOCAL_COMPATIBILITY_SUITES usages to the provider.
+	if testSuiteInfo, ok := OtherModuleProvider(ctx, mod, TestSuiteInfoProvider); ok {
+		a.AddStrings("LOCAL_SOONG_PROVIDER_TEST_SUITES", testSuiteInfo.TestSuites...)
+	}
+
 	// Collect make variable assignment entries.
 	a.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
 	a.SetString("LOCAL_MODULE", name+a.SubName)
@@ -880,7 +888,7 @@
 			}
 		}
 
-		commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey)
+		commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoProvider)
 		if commonInfo.SkipAndroidMkProcessing {
 			continue
 		}
@@ -1312,7 +1320,7 @@
 // Please only access the module's internal data through providers.
 func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON,
 	mod Module, providerInfo *AndroidMkProviderInfo) error {
-	commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey)
+	commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoProvider)
 	if commonInfo.SkipAndroidMkProcessing {
 		return nil
 	}
@@ -1476,12 +1484,17 @@
 	a.Host_required = append(a.Host_required, commonInfo.HostRequiredModuleNames...)
 	a.Target_required = append(a.Target_required, commonInfo.TargetRequiredModuleNames...)
 
-	for _, distString := range a.GetDistForGoals(ctx, mod, commonInfo) {
-		a.HeaderStrings = append(a.HeaderStrings, distString)
-	}
-
+	a.HeaderStrings = append(a.HeaderStrings, a.GetDistForGoals(ctx, mod, commonInfo)...)
 	a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS)  # type: %s, name: %s, variant: %s", ctx.ModuleType(mod), commonInfo.BaseModuleName, ctx.ModuleSubDir(mod)))
 
+	// Add the TestSuites from the provider to LOCAL_SOONG_PROVIDER_TEST_SUITES.
+	// LOCAL_SOONG_PROVIDER_TEST_SUITES will be compared against LOCAL_COMPATIBILITY_SUITES
+	// in make and enforced they're the same, to ensure we've successfully translated all
+	// LOCAL_COMPATIBILITY_SUITES usages to the provider.
+	if testSuiteInfo, ok := OtherModuleProvider(ctx, mod, TestSuiteInfoProvider); ok {
+		helperInfo.AddStrings("LOCAL_SOONG_PROVIDER_TEST_SUITES", testSuiteInfo.TestSuites...)
+	}
+
 	// Collect make variable assignment entries.
 	helperInfo.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
 	helperInfo.SetString("LOCAL_MODULE", name+a.SubName)
diff --git a/android/apex.go b/android/apex.go
index 39de6de..57baff5 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -695,7 +695,7 @@
 // Function called while walking an APEX's payload dependencies.
 //
 // Return true if the `to` module should be visited, false otherwise.
-type PayloadDepsCallback func(ctx BaseModuleContext, from Module, to ApexModule, externalDep bool) bool
+type PayloadDepsCallback func(ctx BaseModuleContext, from, to ModuleProxy, externalDep bool) bool
 type WalkPayloadDepsFunc func(ctx BaseModuleContext, do PayloadDepsCallback)
 
 // ModuleWithMinSdkVersionCheck represents a module that implements min_sdk_version checks
@@ -723,7 +723,7 @@
 		return
 	}
 
-	walk(ctx, func(ctx BaseModuleContext, from Module, to ApexModule, externalDep bool) bool {
+	walk(ctx, func(ctx BaseModuleContext, from, to ModuleProxy, externalDep bool) bool {
 		if externalDep {
 			// external deps are outside the payload boundary, which is "stable"
 			// interface. We don't have to check min_sdk_version for external
@@ -733,7 +733,7 @@
 		if !IsDepInSameApex(ctx, from, to) {
 			return false
 		}
-		if info, ok := OtherModuleProvider(ctx, to, CommonModuleInfoKey); ok && info.ModuleWithMinSdkVersionCheck {
+		if info, ok := OtherModuleProvider(ctx, to, CommonModuleInfoProvider); ok && info.ModuleWithMinSdkVersionCheck {
 			if info.MinSdkVersion.ApiLevel == nil || !info.MinSdkVersion.ApiLevel.Specified() {
 				// This dependency performs its own min_sdk_version check, just make sure it sets min_sdk_version
 				// to trigger the check.
@@ -765,7 +765,7 @@
 // implementing this interface should provide an implementation. A module supports an sdk
 // version when the module's min_sdk_version is equal to or less than the given sdk version.
 func ShouldSupportSdkVersion(ctx BaseModuleContext, module Module, sdkVersion ApiLevel) error {
-	info, ok := OtherModuleProvider(ctx, module, CommonModuleInfoKey)
+	info, ok := OtherModuleProvider(ctx, module, CommonModuleInfoProvider)
 	if !ok || info.MinSdkVersionSupported.IsNone() {
 		return fmt.Errorf("min_sdk_version is not specified")
 	}
diff --git a/android/base_module_context.go b/android/base_module_context.go
index d2404fd..eba3670 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -410,7 +410,7 @@
 		return &aModule
 	}
 
-	if !OtherModuleProviderOrDefault(b, module, CommonModuleInfoKey).Enabled {
+	if !OtherModuleProviderOrDefault(b, module, CommonModuleInfoProvider).Enabled {
 		if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependencyProxy(b, aModule) {
 			if b.Config().AllowMissingDependencies() {
 				b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
@@ -440,7 +440,7 @@
 func (b *baseModuleContext) getDirectDepsProxyInternal(name string, tag blueprint.DependencyTag) []ModuleProxy {
 	var deps []ModuleProxy
 	b.VisitDirectDepsProxy(func(module ModuleProxy) {
-		if OtherModuleProviderOrDefault(b, module, CommonModuleInfoKey).BaseModuleName == name {
+		if OtherModuleProviderOrDefault(b, module, CommonModuleInfoProvider).BaseModuleName == name {
 			returnedTag := b.OtherModuleDependencyTag(module)
 			if tag == nil || returnedTag == tag {
 				deps = append(deps, module)
diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go
index a6dbb8d..c15a206 100644
--- a/android/compliance_metadata.go
+++ b/android/compliance_metadata.go
@@ -18,7 +18,9 @@
 	"bytes"
 	"encoding/csv"
 	"fmt"
+	"path/filepath"
 	"slices"
+	"sort"
 	"strconv"
 	"strings"
 
@@ -127,27 +129,37 @@
 // dependencies, built/installed files, etc. It is a wrapper on a map[string]string with some utility
 // methods to get/set properties' values.
 type ComplianceMetadataInfo struct {
-	properties map[string]string
+	properties          map[string]string
+	filesContained      []string
+	prebuiltFilesCopied []string
 }
 
 type complianceMetadataInfoGob struct {
-	Properties map[string]string
+	Properties          map[string]string
+	FilesContained      []string
+	PrebuiltFilesCopied []string
 }
 
 func NewComplianceMetadataInfo() *ComplianceMetadataInfo {
 	return &ComplianceMetadataInfo{
-		properties: map[string]string{},
+		properties:          map[string]string{},
+		filesContained:      make([]string, 0),
+		prebuiltFilesCopied: make([]string, 0),
 	}
 }
 
 func (m *ComplianceMetadataInfo) ToGob() *complianceMetadataInfoGob {
 	return &complianceMetadataInfoGob{
-		Properties: m.properties,
+		Properties:          m.properties,
+		FilesContained:      m.filesContained,
+		PrebuiltFilesCopied: m.prebuiltFilesCopied,
 	}
 }
 
 func (m *ComplianceMetadataInfo) FromGob(data *complianceMetadataInfoGob) {
 	m.properties = data.Properties
+	m.filesContained = data.FilesContained
+	m.prebuiltFilesCopied = data.PrebuiltFilesCopied
 }
 
 func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) {
@@ -169,6 +181,22 @@
 	c.SetStringValue(propertyName, strings.TrimSpace(strings.Join(value, " ")))
 }
 
+func (c *ComplianceMetadataInfo) SetFilesContained(files []string) {
+	c.filesContained = files
+}
+
+func (c *ComplianceMetadataInfo) GetFilesContained() []string {
+	return c.filesContained
+}
+
+func (c *ComplianceMetadataInfo) SetPrebuiltFilesCopied(files []string) {
+	c.prebuiltFilesCopied = files
+}
+
+func (c *ComplianceMetadataInfo) GetPrebuiltFilesCopied() []string {
+	return c.prebuiltFilesCopied
+}
+
 func (c *ComplianceMetadataInfo) getStringValue(propertyName string) string {
 	if !slices.Contains(COMPLIANCE_METADATA_PROPS, propertyName) {
 		panic(fmt.Errorf("Unknown metadata property: %s.", propertyName))
@@ -276,7 +304,7 @@
 
 	rowId := -1
 	ctx.VisitAllModuleProxies(func(module ModuleProxy) {
-		commonInfo, _ := OtherModuleProvider(ctx, module, CommonModuleInfoKey)
+		commonInfo, _ := OtherModuleProvider(ctx, module, CommonModuleInfoProvider)
 		if !commonInfo.Enabled {
 			return
 		}
@@ -316,9 +344,42 @@
 	makeMetadataCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-metadata.csv")
 	makeModulesCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-modules.csv")
 
+	productOutPath := filepath.Join(ctx.Config().OutDir(), "target", "product", String(ctx.Config().productVariables.DeviceName))
 	if !ctx.Config().KatiEnabled() {
-		WriteFileRule(ctx, makeMetadataCsv, "installed_file,module_path,is_soong_module,is_prebuilt_make_module,product_copy_files,kernel_module_copy_files,is_platform_generated,static_libs,whole_static_libs,license_text")
-		WriteFileRule(ctx, makeModulesCsv, "name,module_path,module_class,module_type,static_libs,whole_static_libs,built_files,installed_files")
+		ctx.VisitAllModuleProxies(func(module ModuleProxy) {
+			// In soong-only build the installed file list is from android_device module
+			if androidDeviceInfo, ok := OtherModuleProvider(ctx, module, AndroidDeviceInfoProvider); ok && androidDeviceInfo.Main_device {
+				if metadataInfo, ok := OtherModuleProvider(ctx, module, ComplianceMetadataProvider); ok {
+					if len(metadataInfo.filesContained) > 0 || len(metadataInfo.prebuiltFilesCopied) > 0 {
+						allFiles := make([]string, 0, len(metadataInfo.filesContained)+len(metadataInfo.prebuiltFilesCopied))
+						allFiles = append(allFiles, metadataInfo.filesContained...)
+						prebuiltFilesSrcDest := make(map[string]string)
+						for _, srcDestPair := range metadataInfo.prebuiltFilesCopied {
+							prebuiltFilePath := filepath.Join(productOutPath, strings.Split(srcDestPair, ":")[1])
+							allFiles = append(allFiles, prebuiltFilePath)
+							prebuiltFilesSrcDest[prebuiltFilePath] = srcDestPair
+						}
+						sort.Strings(allFiles)
+
+						csvHeaders := "installed_file,module_path,is_soong_module,is_prebuilt_make_module,product_copy_files,kernel_module_copy_files,is_platform_generated,static_libs,whole_static_libs,license_text"
+						csvContent := make([]string, 0, len(allFiles)+1)
+						csvContent = append(csvContent, csvHeaders)
+						for _, file := range allFiles {
+							if _, ok := prebuiltFilesSrcDest[file]; ok {
+								srcDestPair := prebuiltFilesSrcDest[file]
+								csvContent = append(csvContent, file+",,,,"+srcDestPair+",,,,,")
+							} else {
+								csvContent = append(csvContent, file+",,Y,,,,,,,")
+							}
+						}
+
+						WriteFileRuleVerbatim(ctx, makeMetadataCsv, strings.Join(csvContent, "\n"))
+						WriteFileRuleVerbatim(ctx, makeModulesCsv, "name,module_path,module_class,module_type,static_libs,whole_static_libs,built_files,installed_files")
+					}
+					return
+				}
+			}
+		})
 	}
 
 	// Import metadata from Make and Soong to sqlite3 database
diff --git a/android/config.go b/android/config.go
index 696e772..2a4b927 100644
--- a/android/config.go
+++ b/android/config.go
@@ -200,6 +200,11 @@
 	return c.config.productVariables.ReleaseAconfigValueSets
 }
 
+// If native modules should have symbols stripped by default. Default false, enabled for build tools
+func (c Config) StripByDefault() bool {
+	return proptools.Bool(c.config.productVariables.StripByDefault)
+}
+
 func (c Config) ReleaseAconfigExtraReleaseConfigs() []string {
 	result := []string{}
 	if val, ok := c.config.productVariables.BuildFlags["RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS"]; ok {
@@ -385,24 +390,28 @@
 }
 
 type partialCompileFlags struct {
-	// Is partial compilation enabled at all?
-	Enabled bool
-
 	// Whether to use d8 instead of r8
 	Use_d8 bool
 
+	// Whether to disable stub validation.  This is slightly more surgical
+	// than DISABLE_STUB_VALIDATION, in that it only applies to partial
+	// compile builds.
+	Disable_stub_validation bool
+
+	// Whether to disable api lint.
+	Disable_api_lint bool
+
 	// Add others as needed.
 }
 
 // These are the flags when `SOONG_PARTIAL_COMPILE` is empty or not set.
-var defaultPartialCompileFlags = partialCompileFlags{
-	Enabled: false,
-}
+var defaultPartialCompileFlags = partialCompileFlags{}
 
 // These are the flags when `SOONG_PARTIAL_COMPILE=true`.
 var enabledPartialCompileFlags = partialCompileFlags{
-	Enabled: true,
-	Use_d8:  true,
+	Use_d8:                  true,
+	Disable_stub_validation: false,
+	Disable_api_lint:        false,
 }
 
 type deviceConfig struct {
@@ -477,13 +486,29 @@
 			state = "+"
 		}
 		switch tok {
+		case "all":
+			// Turn on **all** of the flags.
+			ret = partialCompileFlags{
+				Use_d8:                  true,
+				Disable_stub_validation: true,
+				Disable_api_lint:        true,
+			}
 		case "true":
 			ret = enabledPartialCompileFlags
 		case "false":
 			// Set everything to false.
 			ret = partialCompileFlags{}
-		case "enabled":
-			ret.Enabled = makeVal(state, defaultPartialCompileFlags.Enabled)
+
+		case "api_lint", "enable_api_lint":
+			ret.Disable_api_lint = !makeVal(state, !defaultPartialCompileFlags.Disable_api_lint)
+		case "disable_api_lint":
+			ret.Disable_api_lint = makeVal(state, defaultPartialCompileFlags.Disable_api_lint)
+
+		case "stub_validation", "enable_stub_validation":
+			ret.Disable_stub_validation = !makeVal(state, !defaultPartialCompileFlags.Disable_stub_validation)
+		case "disable_stub_validation":
+			ret.Disable_stub_validation = makeVal(state, defaultPartialCompileFlags.Disable_stub_validation)
+
 		case "use_d8":
 			ret.Use_d8 = makeVal(state, defaultPartialCompileFlags.Use_d8)
 		default:
diff --git a/android/config_test.go b/android/config_test.go
index 3d86860..d1b26c1 100644
--- a/android/config_test.go
+++ b/android/config_test.go
@@ -213,13 +213,18 @@
 	})
 }
 
-func (p partialCompileFlags) updateEnabled(value bool) partialCompileFlags {
-	p.Enabled = value
+func (p partialCompileFlags) updateUseD8(value bool) partialCompileFlags {
+	p.Use_d8 = value
 	return p
 }
 
-func (p partialCompileFlags) updateUseD8(value bool) partialCompileFlags {
-	p.Use_d8 = value
+func (p partialCompileFlags) updateDisableApiLint(value bool) partialCompileFlags {
+	p.Disable_api_lint = value
+	return p
+}
+
+func (p partialCompileFlags) updateDisableStubValidation(value bool) partialCompileFlags {
+	p.Disable_stub_validation = value
 	return p
 }
 
@@ -241,10 +246,29 @@
 		{"false", true, partialCompileFlags{}},
 		{"true", true, enabledPartialCompileFlags},
 		{"true", false, partialCompileFlags{}},
+		{"all", true, partialCompileFlags{}.updateUseD8(true).updateDisableApiLint(true).updateDisableStubValidation(true)},
+
+		// This verifies both use_d8 and the processing order.
 		{"true,use_d8", true, enabledPartialCompileFlags.updateUseD8(true)},
 		{"true,-use_d8", true, enabledPartialCompileFlags.updateUseD8(false)},
 		{"use_d8,false", true, partialCompileFlags{}},
 		{"false,+use_d8", true, partialCompileFlags{}.updateUseD8(true)},
+
+		// disable_api_lint can be specified with any of 3 options.
+		{"false,-api_lint", true, partialCompileFlags{}.updateDisableApiLint(true)},
+		{"false,-enable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(true)},
+		{"false,+disable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(true)},
+		{"false,+api_lint", true, partialCompileFlags{}.updateDisableApiLint(false)},
+		{"false,+enable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(false)},
+		{"false,-disable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(false)},
+
+		// disable_stub_validation can be specified with any of 3 options.
+		{"false,-stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(true)},
+		{"false,-enable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(true)},
+		{"false,+disable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(true)},
+		{"false,+stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(false)},
+		{"false,+enable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(false)},
+		{"false,-disable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(false)},
 	}
 
 	for _, test := range tests {
diff --git a/android/container.go b/android/container.go
index a5aab79..5d223b8 100644
--- a/android/container.go
+++ b/android/container.go
@@ -39,7 +39,7 @@
 
 // Returns true if the dependency module is a stubs module
 var depIsStubsModule exceptionHandleFunc = func(mctx ModuleContext, _ Module, dep ModuleProxy) bool {
-	return OtherModuleProviderOrDefault(mctx, dep, CommonModuleInfoKey).IsStubsModule
+	return OtherModuleProviderOrDefault(mctx, dep, CommonModuleInfoProvider).IsStubsModule
 }
 
 // Returns true if the dependency module belongs to any of the apexes.
@@ -474,7 +474,7 @@
 	if _, ok := ctx.Module().(InstallableModule); ok {
 		containersInfo, _ := getContainerModuleInfo(ctx, ctx.Module())
 		ctx.VisitDirectDepsProxy(func(dep ModuleProxy) {
-			if !OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey).Enabled {
+			if !OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoProvider).Enabled {
 				return
 			}
 
diff --git a/android/filegroup.go b/android/filegroup.go
index 4fad52a..9bcfd0a 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -33,6 +33,7 @@
 func RegisterFilegroupBuildComponents(ctx RegistrationContext) {
 	ctx.RegisterModuleType("filegroup", FileGroupFactory)
 	ctx.RegisterModuleType("filegroup_defaults", FileGroupDefaultsFactory)
+	ctx.RegisterModuleType("otatools_package_filegroup", OtatoolsFileGroupFactory)
 }
 
 type fileGroupProperties struct {
@@ -163,3 +164,54 @@
 		}
 	}
 }
+
+type OtatoolsFileGroup struct {
+	ModuleBase
+}
+
+func OtatoolsFileGroupFactory() Module {
+	module := &OtatoolsFileGroup{}
+	InitAndroidModule(module)
+	AddLoadHook(module, func(ctx LoadHookContext) {
+		module.createOTAToolsPackagefilegroup(ctx)
+	})
+	return module
+}
+
+func (fg *OtatoolsFileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
+}
+
+// Create the filegroup to collect cert files for otatools.zip.
+func (fg *OtatoolsFileGroup) createOTAToolsPackagefilegroup(ctx LoadHookContext) {
+	ctx.CreateModuleInDirectory(
+		FileGroupFactory,
+		".",
+		&struct {
+			Name       *string
+			Srcs       []string
+			Visibility []string
+		}{
+			Name: proptools.StringPtr("soong_generated_otatools_package_filegroup"),
+			Srcs: []string{
+				"build/make/target/product/security/**/*.x509.pem",
+				"build/make/target/product/security/**/*.pk8",
+				"device/**/*.pk8",
+				"device/**/verifiedboot*",
+				"device/**/*.pem",
+				"device/**/oem*.prop",
+				"device/**/*.avbpubkey",
+				"external/avb/test/data/**/testkey_*.pem",
+				"external/avb/test/data/**/atx_metadata.bin",
+				"packages/modules/**/*.x509.pem",
+				"packages/modules/**/*.pk8",
+				"packages/modules/**/*.key.pem",
+				"vendor/**/*.pk8",
+				"vendor/**/verifiedboot*",
+				"vendor/**/*.pem",
+				"vendor/**/oem*.prop",
+				"vendor/**/*.avbpubkey",
+			},
+			Visibility: []string{"//build/make/tools/otatools_package"},
+		},
+	)
+}
diff --git a/android/gen_notice.go b/android/gen_notice.go
index 482b1e0..ae83118 100644
--- a/android/gen_notice.go
+++ b/android/gen_notice.go
@@ -60,7 +60,7 @@
 		for _, name := range gm.For {
 			mods := ctx.ModuleVariantsFromName(m, name)
 			for _, mod := range mods {
-				if !OtherModuleProviderOrDefault(ctx, mod, CommonModuleInfoKey).Enabled { // don't depend on variants without build rules
+				if !OtherModuleProviderOrDefault(ctx, mod, CommonModuleInfoProvider).Enabled { // don't depend on variants without build rules
 					continue
 				}
 				modules = append(modules, mod)
diff --git a/android/license_metadata.go b/android/license_metadata.go
index d15dfa8..e79febb 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -65,7 +65,7 @@
 	var allDepMetadataDepSets []depset.DepSet[Path]
 
 	ctx.VisitDirectDepsProxy(func(dep ModuleProxy) {
-		if !OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey).Enabled {
+		if !OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoProvider).Enabled {
 			return
 		}
 
diff --git a/android/logtags.go b/android/logtags.go
index 88d36ec..ef7a612 100644
--- a/android/logtags.go
+++ b/android/logtags.go
@@ -43,7 +43,7 @@
 func (l *logtagsSingleton) GenerateBuildActions(ctx SingletonContext) {
 	var allLogtags Paths
 	ctx.VisitAllModuleProxies(func(module ModuleProxy) {
-		if !OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).ExportedToMake {
+		if !OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoProvider).ExportedToMake {
 			return
 		}
 		if logtagsInfo, ok := OtherModuleProvider(ctx, module, LogtagsProviderKey); ok {
diff --git a/android/makevars.go b/android/makevars.go
index 692b27e..e1d947d 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -259,7 +259,7 @@
 	singletonDists.lock.Unlock()
 
 	ctx.VisitAllModuleProxies(func(m ModuleProxy) {
-		commonInfo, _ := OtherModuleProvider(ctx, m, CommonModuleInfoKey)
+		commonInfo, _ := OtherModuleProvider(ctx, m, CommonModuleInfoProvider)
 		if provider, ok := OtherModuleProvider(ctx, m, ModuleMakeVarsInfoProvider); ok &&
 			commonInfo.Enabled {
 			mctx := &makeVarsContext{
diff --git a/android/module.go b/android/module.go
index 5457539..c6c4fd8 100644
--- a/android/module.go
+++ b/android/module.go
@@ -520,6 +520,11 @@
 
 	// names of other modules to install on target if this module is installed
 	Target_required []string `android:"arch_variant"`
+
+	// If this is a soong config module, this property will be set to the name of the original
+	// module type. This is used by neverallow to ensure you can't bypass a ModuleType() matcher
+	// just by creating a soong config module type.
+	Soong_config_base_module_type *string `blueprint:"mutated"`
 }
 
 type distProperties struct {
@@ -1483,7 +1488,7 @@
 			// Installation is still handled by Make, so anything hidden from Make is not
 			// installable.
 			info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider)
-			commonInfo := OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey)
+			commonInfo := OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoProvider)
 			if !commonInfo.HideFromMake && !commonInfo.SkipInstall {
 				installDeps = append(installDeps, info.TransitiveInstallFiles)
 			}
@@ -1500,7 +1505,7 @@
 // should also install the output files of the given dependency and dependency tag.
 func isInstallDepNeeded(ctx ModuleContext, dep ModuleProxy) bool {
 	// Don't add a dependency from the platform to a library provided by an apex.
-	if OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey).UninstallableApexPlatformVariant {
+	if OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoProvider).UninstallableApexPlatformVariant {
 		return false
 	}
 	// Only install modules if the dependency tag is an InstallDepNeeded tag.
@@ -1915,6 +1920,7 @@
 	Dists                                        []Dist
 	ExportedToMake                               bool
 	Team                                         string
+	PartitionTag                                 string
 }
 
 type ApiLevelOrPlatform struct {
@@ -1922,7 +1928,7 @@
 	IsPlatform bool
 }
 
-var CommonModuleInfoKey = blueprint.NewProvider[CommonModuleInfo]()
+var CommonModuleInfoProvider = blueprint.NewProvider[CommonModuleInfo]()
 
 type PrebuiltModuleInfo struct {
 	SourceExists bool
@@ -2282,6 +2288,7 @@
 		Dists:                                        m.Dists(),
 		ExportedToMake:                               m.ExportedToMake(),
 		Team:                                         m.Team(),
+		PartitionTag:                                 m.PartitionTag(ctx.DeviceConfig()),
 	}
 	if mm, ok := m.module.(interface {
 		MinSdkVersion(ctx EarlyModuleContext) ApiLevel
@@ -2329,7 +2336,7 @@
 	if mm, ok := m.module.(interface{ BaseModuleName() string }); ok {
 		commonData.BaseModuleName = mm.BaseModuleName()
 	}
-	SetProvider(ctx, CommonModuleInfoKey, commonData)
+	SetProvider(ctx, CommonModuleInfoProvider, commonData)
 	if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil {
 		SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{
 			SourceExists: p.Prebuilt().SourceExists(),
diff --git a/android/neverallow.go b/android/neverallow.go
index 8995a0f..a7bfd2d 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -60,7 +60,8 @@
 	AddNeverAllowRules(createCcStubsRule())
 	AddNeverAllowRules(createProhibitHeaderOnlyRule())
 	AddNeverAllowRules(createLimitNdkExportRule()...)
-	AddNeverAllowRules(createLimitDirgroupRule()...)
+	AddNeverAllowRules(createLimitDirgroupRules()...)
+	AddNeverAllowRules(createLimitGenruleRules()...)
 	AddNeverAllowRules(createFilesystemIsAutoGeneratedRule())
 	AddNeverAllowRules(createKotlinPluginRule()...)
 	AddNeverAllowRules(createPrebuiltEtcBpDefineRule())
@@ -287,45 +288,45 @@
 	}
 }
 
-func createLimitDirgroupRule() []Rule {
-	reason := "dirgroup module and dir_srcs / keep_gendir property of genrule is allowed only to Trusty build rule."
+func createLimitDirgroupRules() []Rule {
+	reason := "The dirgroup module can only be used with Trusty visibility"
+	scriptsDirsList := []string{"//trusty/vendor/google/aosp/scripts", "//trusty/vendor/google/proprietary/scripts"}
 	return []Rule{
 		NeverAllow().
 			ModuleType("dirgroup").
-			WithMatcher("visibility", NotInList([]string{"//trusty/vendor/google/aosp/scripts", "//trusty/vendor/google/proprietary/scripts"})).Because(reason),
+			WithMatcher("visibility", NotInList(scriptsDirsList)).Because(reason),
 		NeverAllow().
 			ModuleType("dirgroup").
-			WithoutMatcher("visibility", InAllowedList([]string{"//trusty/vendor/google/aosp/scripts", "//trusty/vendor/google/proprietary/scripts"})).Because(reason),
+			WithoutMatcher("visibility", InAllowedList(scriptsDirsList)).Because(reason),
+	}
+}
+
+func createLimitGenruleRules() []Rule {
+	dirSrcsReason := "The `dir_srcs` property in a `genrule` module can only be used by Trusty"
+	keepGendirReason := "The `keep_gendir` property in a `genrule` module can only be used by Trusty"
+	allowedModuleNameList := []string{
+		// Trusty TEE target names
+		"trusty_tee_package_goog",
+		"trusty_tee_package",
+		// Trusty vm target names
+		"trusty_test_vm_arm64.bin",
+		"trusty_test_vm_x86_64.elf",
+		"trusty_test_vm_os_arm64.bin",
+		"trusty_test_vm_os_x86_64.elf",
+		"trusty_security_vm_arm64.bin",
+		"trusty_security_vm_x86_64.elf",
+		"trusty_widevine_vm_arm64.bin",
+		"trusty_widevine_vm_x86_64.elf",
+	}
+	return []Rule{
 		NeverAllow().
 			ModuleType("genrule").
-			// 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_test_vm_os_arm64.bin").
-			Without("name", "trusty_test_vm_os_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),
+			WithoutMatcher("name", InAllowedList(allowedModuleNameList)).
+			WithMatcher("dir_srcs", isSetMatcherInstance).Because(dirSrcsReason),
 		NeverAllow().
 			ModuleType("genrule").
-			// 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_test_vm_os_arm64.bin").
-			Without("name", "trusty_test_vm_os_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),
+			WithoutMatcher("name", InAllowedList(allowedModuleNameList)).
+			With("keep_gendir", "true").Because(keepGendirReason),
 	}
 }
 
@@ -378,6 +379,8 @@
 			"prebuilt_sbin",
 			"prebuilt_system",
 			"prebuilt_first_stage_ramdisk",
+			"prebuilt_radio",
+			"prebuilt_gpu",
 		).
 		DefinedInBpFile().
 		Because("module type not allowed to be defined in bp file")
@@ -409,7 +412,8 @@
 			continue
 		}
 
-		if !n.appliesToModuleType(ctx.ModuleType()) {
+		modType := proptools.StringDefault(m.base().baseProperties.Soong_config_base_module_type, ctx.ModuleType())
+		if !n.appliesToModuleType(modType) {
 			continue
 		}
 
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index c74d5ff..3ccc883 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -388,6 +388,30 @@
 			`module type not allowed to be defined in bp file`,
 		},
 	},
+	// Test the a neverallowed module type can't be smuggled through a soong config module type
+	{
+		name: `smuggling module types through soong config modules`,
+		fs: map[string][]byte{
+			"a/b/Android.bp": []byte(`
+				soong_config_bool_variable {
+					name: "my_var",
+				}
+				soong_config_module_type {
+					name: "smuggled_prebuilt_usr_srec",
+					module_type: "prebuilt_usr_srec",
+					config_namespace: "ANDROID",
+					variables: ["my_var"],
+					properties: ["enabled"],
+				}
+				smuggled_prebuilt_usr_srec {
+					name: "foo",
+				}
+			`),
+		},
+		expectedErrors: []string{
+			`module type not allowed to be defined in bp file`,
+		},
+	},
 }
 
 var prepareForNeverAllowTest = GroupFixturePreparers(
@@ -399,6 +423,7 @@
 		ctx.RegisterModuleType("filesystem", newMockFilesystemModule)
 		ctx.RegisterModuleType("prebuilt_usr_srec", newMockPrebuiltUsrSrecModule)
 	}),
+	PrepareForTestWithSoongConfigModuleBuildComponents,
 )
 
 func TestNeverallow(t *testing.T) {
diff --git a/android/package.go b/android/package.go
index 42f17b1..0f6a767 100644
--- a/android/package.go
+++ b/android/package.go
@@ -62,7 +62,7 @@
 }
 
 func (p *packageModule) GenerateBuildActions(ctx blueprint.ModuleContext) {
-	ctx.SetProvider(CommonModuleInfoKey, CommonModuleInfo{
+	ctx.SetProvider(CommonModuleInfoProvider, CommonModuleInfo{
 		Enabled:                 true,
 		PrimaryLicensesProperty: p.primaryLicensesProperty,
 	})
diff --git a/android/paths.go b/android/paths.go
index 9c0c9a2..f7fcd35 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -683,7 +683,7 @@
 	if module == nil {
 		return nil, missingDependencyError{[]string{moduleName}}
 	}
-	if !OtherModuleProviderOrDefault(ctx, *module, CommonModuleInfoKey).Enabled {
+	if !OtherModuleProviderOrDefault(ctx, *module, CommonModuleInfoProvider).Enabled {
 		return nil, missingDependencyError{[]string{moduleName}}
 	}
 
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 4a94c0b..0178f76 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -358,7 +358,7 @@
 }
 
 func IsModulePreferredProxy(ctx OtherModuleProviderContext, module ModuleProxy) bool {
-	if OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).ReplacedByPrebuilt {
+	if OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoProvider).ReplacedByPrebuilt {
 		// A source module that has been replaced by a prebuilt counterpart.
 		return false
 	}
@@ -397,7 +397,7 @@
 // the right module. This function is only safe to call after all TransitionMutators
 // have run, e.g. in GenerateAndroidBuildActions.
 func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module {
-	if !OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).ReplacedByPrebuilt {
+	if !OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoProvider).ReplacedByPrebuilt {
 		return module
 	}
 	if _, ok := OtherModuleProvider(ctx, module, PrebuiltModuleInfoProvider); ok {
@@ -607,11 +607,6 @@
 		if !moduleInFamily.ExportedToMake() {
 			continue
 		}
-		// Skip for the top-level java_sdk_library_(_import). This has some special cases that need to be addressed first.
-		// This does not run into non-determinism because PrebuiltPostDepsMutator also has the special case
-		if sdkLibrary, ok := moduleInFamily.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil {
-			continue
-		}
 		if p := GetEmbeddedPrebuilt(moduleInFamily); p != nil && p.properties.UsePrebuilt {
 			if selectedPrebuilt == nil {
 				selectedPrebuilt = moduleInFamily
@@ -638,26 +633,10 @@
 	if p := GetEmbeddedPrebuilt(m); p != nil {
 		bmn, _ := m.(baseModuleName)
 		name := bmn.BaseModuleName()
-		psi := PrebuiltSelectionInfoMap{}
-		ctx.VisitDirectDepsWithTag(AcDepTag, func(am Module) {
-			psi, _ = OtherModuleProvider(ctx, am, PrebuiltSelectionInfoProvider)
-		})
 
 		if p.properties.UsePrebuilt {
 			if p.properties.SourceExists {
 				ctx.ReplaceDependenciesIf(name, func(from blueprint.Module, tag blueprint.DependencyTag, to blueprint.Module) bool {
-					if sdkLibrary, ok := m.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil {
-						// Do not replace deps to the top-level prebuilt java_sdk_library hook.
-						// This hook has been special-cased in #isSelected to be _always_ active, even in next builds
-						// for dexpreopt and hiddenapi processing.
-						// If we do not special-case this here, rdeps referring to a java_sdk_library in next builds via libs
-						// will get prebuilt stubs
-						// TODO (b/308187268): Remove this after the apexes have been added to apex_contributions
-						if psi.IsSelected(name) {
-							return false
-						}
-					}
-
 					if t, ok := tag.(ReplaceSourceWithPrebuilt); ok {
 						return t.ReplaceSourceWithPrebuilt()
 					}
@@ -679,23 +658,13 @@
 // java_sdk_library_import is a macro that creates
 // 1. top-level "impl" library
 // 2. stub libraries (suffixed with .stubs...)
-//
-// the impl of java_sdk_library_import is a "hook" for hiddenapi and dexpreopt processing. It does not have an impl jar, but acts as a shim
-// to provide the jar deapxed from the prebuilt apex
-//
-// isSelected uses `all_apex_contributions` to supersede source vs prebuilts selection of the stub libraries. It does not supersede the
-// selection of the top-level "impl" library so that this hook can work
-//
-// TODO (b/308174306) - Fix this when we need to support multiple prebuilts in main
 func isSelected(psi PrebuiltSelectionInfoMap, m Module) bool {
 	if sdkLibrary, ok := m.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil {
 		sln := proptools.String(sdkLibrary.SdkLibraryName())
 
 		// This is the top-level library
-		// Do not supersede the existing prebuilts vs source selection mechanisms
-		// TODO (b/308187268): Remove this after the apexes have been added to apex_contributions
 		if bmn, ok := m.(baseModuleName); ok && sln == bmn.BaseModuleName() {
-			return false
+			return psi.IsSelected(m.Name())
 		}
 
 		// Stub library created by java_sdk_library_import
diff --git a/android/provider_keys.go b/android/provider_keys.go
new file mode 100644
index 0000000..60b383f
--- /dev/null
+++ b/android/provider_keys.go
@@ -0,0 +1,24 @@
+// Copyright 2025 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import "github.com/google/blueprint"
+
+// Providers of package filesystem
+type AndroidDeviceInfo struct {
+	Main_device bool
+}
+
+var AndroidDeviceInfoProvider = blueprint.NewProvider[AndroidDeviceInfo]()
diff --git a/android/rule_builder.go b/android/rule_builder.go
index ea6aaa4..01fe6d8 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -660,12 +660,17 @@
 			}
 			for _, c := range r.commands {
 				for _, tool := range c.packagedTools {
-					command.CopyBefore = append(command.CopyBefore, &sbox_proto.Copy{
-						From:       proto.String(tool.srcPath.String()),
-						To:         proto.String(sboxPathForPackagedToolRel(tool)),
-						Executable: proto.Bool(tool.executable),
-					})
-					tools = append(tools, tool.srcPath)
+					if tool.srcPath != nil {
+						command.CopyBefore = append(command.CopyBefore, &sbox_proto.Copy{
+							From:       proto.String(tool.srcPath.String()),
+							To:         proto.String(sboxPathForPackagedToolRel(tool)),
+							Executable: proto.Bool(tool.executable),
+						})
+						tools = append(tools, tool.srcPath)
+					} else if tool.SymlinkTarget() == "" {
+						// We ignore symlinks for now, could be added later if needed
+						panic("Expected tool packagingSpec to either be a file or symlink")
+					}
 				}
 			}
 		}
diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go
index e0b1d7c..a61c9d3 100644
--- a/android/soong_config_modules.go
+++ b/android/soong_config_modules.go
@@ -506,6 +506,10 @@
 		conditionalProps := proptools.CloneEmptyProperties(conditionalFactoryProps)
 		props = append(props, conditionalProps.Interface())
 
+		if m, ok := module.(Module); ok {
+			m.base().baseProperties.Soong_config_base_module_type = &moduleType.BaseModuleType
+		}
+
 		// Regular Soong operation wraps the existing module factory with a
 		// conditional on Soong config variables by reading the product
 		// config variables from Make.
diff --git a/android/test_suites.go b/android/test_suites.go
index 39317ec..9eaf785 100644
--- a/android/test_suites.go
+++ b/android/test_suites.go
@@ -29,10 +29,7 @@
 	return &testSuiteFiles{}
 }
 
-type testSuiteFiles struct {
-	robolectric []Path
-	ravenwood   []Path
-}
+type testSuiteFiles struct{}
 
 type TestSuiteModule interface {
 	Module
@@ -61,22 +58,22 @@
 		}
 	})
 
-	t.robolectric = robolectricTestSuite(ctx, files["robolectric-tests"])
-	ctx.Phony("robolectric-tests", t.robolectric...)
+	robolectricZip, robolectrictListZip := buildTestSuite(ctx, "robolectric-tests", files["robolectric-tests"])
+	ctx.Phony("robolectric-tests", robolectricZip, robolectrictListZip)
+	ctx.DistForGoal("robolectric-tests", robolectricZip, robolectrictListZip)
 
-	t.ravenwood = ravenwoodTestSuite(ctx, files["ravenwood-tests"])
-	ctx.Phony("ravenwood-tests", t.ravenwood...)
-	ctx.DistForGoal("robolectric-tests", t.robolectric...)
-	ctx.DistForGoal("ravenwood-tests", t.ravenwood...)
+	ravenwoodZip, ravenwoodListZip := buildTestSuite(ctx, "ravenwood-tests", files["ravenwood-tests"])
+	ctx.Phony("ravenwood-tests", ravenwoodZip, ravenwoodListZip)
+	ctx.DistForGoal("ravenwood-tests", ravenwoodZip, ravenwoodListZip)
 }
 
-func robolectricTestSuite(ctx SingletonContext, files map[string]InstallPaths) []Path {
+func buildTestSuite(ctx SingletonContext, suiteName string, files map[string]InstallPaths) (Path, Path) {
 	var installedPaths InstallPaths
 	for _, module := range SortedKeys(files) {
 		installedPaths = append(installedPaths, files[module]...)
 	}
 
-	outputFile := pathForPackaging(ctx, "robolectric-tests.zip")
+	outputFile := pathForPackaging(ctx, suiteName+".zip")
 	rule := NewRuleBuilder(pctx, ctx)
 	rule.Command().BuiltTool("soong_zip").
 		FlagWithOutput("-o ", outputFile).
@@ -85,8 +82,8 @@
 		FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths()).
 		Flag("-sha256") // necessary to save cas_uploader's time
 
-	testList := buildTestList(ctx, "robolectric-tests_list", installedPaths)
-	testListZipOutputFile := pathForPackaging(ctx, "robolectric-tests_list.zip")
+	testList := buildTestList(ctx, suiteName+"_list", installedPaths)
+	testListZipOutputFile := pathForPackaging(ctx, suiteName+"_list.zip")
 
 	rule.Command().BuiltTool("soong_zip").
 		FlagWithOutput("-o ", testListZipOutputFile).
@@ -94,38 +91,9 @@
 		FlagWithInput("-f ", testList).
 		Flag("-sha256")
 
-	rule.Build("robolectric_tests_zip", "robolectric-tests.zip")
+	rule.Build(strings.ReplaceAll(suiteName, "-", "_")+"_zip", suiteName+".zip")
 
-	return []Path{outputFile, testListZipOutputFile}
-}
-
-func ravenwoodTestSuite(ctx SingletonContext, files map[string]InstallPaths) []Path {
-	var installedPaths InstallPaths
-	for _, module := range SortedKeys(files) {
-		installedPaths = append(installedPaths, files[module]...)
-	}
-
-	outputFile := pathForPackaging(ctx, "ravenwood-tests.zip")
-	rule := NewRuleBuilder(pctx, ctx)
-	rule.Command().BuiltTool("soong_zip").
-		FlagWithOutput("-o ", outputFile).
-		FlagWithArg("-P ", "host/testcases").
-		FlagWithArg("-C ", pathForTestCases(ctx).String()).
-		FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths()).
-		Flag("-sha256") // necessary to save cas_uploader's time
-
-	testList := buildTestList(ctx, "ravenwood-tests_list", installedPaths)
-	testListZipOutputFile := pathForPackaging(ctx, "ravenwood-tests_list.zip")
-
-	rule.Command().BuiltTool("soong_zip").
-		FlagWithOutput("-o ", testListZipOutputFile).
-		FlagWithArg("-C ", pathForPackaging(ctx).String()).
-		FlagWithInput("-f ", testList).
-		Flag("-sha256")
-
-	rule.Build("ravenwood_tests_zip", "ravenwood-tests.zip")
-
-	return []Path{outputFile, testListZipOutputFile}
+	return outputFile, testListZipOutputFile
 }
 
 func buildTestList(ctx SingletonContext, listFile string, installedPaths InstallPaths) Path {
diff --git a/android/testing.go b/android/testing.go
index 1962fde..08c8083 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -1197,7 +1197,7 @@
 
 	info := OtherModuleProviderOrDefault(ctx, mod, AndroidMkInfoProvider)
 	aconfigUpdateAndroidMkInfos(ctx, mod, info)
-	commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey)
+	commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoProvider)
 	info.PrimaryInfo.fillInEntries(ctx, mod, &commonInfo)
 	if len(info.ExtraInfo) > 0 {
 		for _, ei := range info.ExtraInfo {
diff --git a/android/variable.go b/android/variable.go
index 5bc0b29..c59857a 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -216,6 +216,7 @@
 	Platform_display_version_name          *string  `json:",omitempty"`
 	Platform_version_name                  *string  `json:",omitempty"`
 	Platform_sdk_version                   *int     `json:",omitempty"`
+	Platform_sdk_minor_version             *int     `json:",omitempty"`
 	Platform_sdk_codename                  *string  `json:",omitempty"`
 	Platform_sdk_version_or_codename       *string  `json:",omitempty"`
 	Platform_sdk_final                     *bool    `json:",omitempty"`
@@ -553,6 +554,8 @@
 	OdmManifestFiles       []string `json:",omitempty"`
 
 	UseSoongNoticeXML *bool `json:",omitempty"`
+
+	StripByDefault *bool `json:",omitempty"`
 }
 
 type PartitionQualifiedVariablesType struct {
@@ -653,6 +656,7 @@
 	ProductUseDynamicPartitions       bool                                     `json:",omitempty"`
 	ProductRetrofitDynamicPartitions  bool                                     `json:",omitempty"`
 	ProductBuildSuperPartition        bool                                     `json:",omitempty"`
+	BuildingSuperEmptyImage           bool                                     `json:",omitempty"`
 	BoardSuperPartitionSize           string                                   `json:",omitempty"`
 	BoardSuperPartitionMetadataDevice string                                   `json:",omitempty"`
 	BoardSuperPartitionBlockDevices   []string                                 `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 196f389..dc44e58 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -550,6 +550,9 @@
 
 	// Required modules, filled out during GenerateAndroidBuildActions and used in AndroidMk
 	required []string
+
+	// appinfo of the apk-in-apex of this module
+	appInfos java.AppInfos
 }
 
 // apexFileClass represents a type of file that can be included in APEX.
@@ -1499,7 +1502,7 @@
 func apexFileForJavaModuleWithFile(ctx android.ModuleContext, module android.Module,
 	javaInfo *java.JavaInfo, dexImplementationJar android.Path) apexFile {
 	dirInApex := "javalib"
-	commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey)
+	commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider)
 	af := newApexFile(ctx, dexImplementationJar, commonInfo.BaseModuleName, dirInApex, javaSharedLib, module)
 	af.jacocoReportClassesFile = javaInfo.JacocoReportClassesFile
 	if lintInfo, ok := android.OtherModuleProvider(ctx, module, java.LintProvider); ok {
@@ -1604,35 +1607,8 @@
 // to the child modules. Returning false makes the visit to continue in the sibling or the parent
 // modules. This is used in check* functions below.
 func (a *apexBundle) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
-	ctx.WalkDeps(func(child, parent android.Module) bool {
-		am, ok := child.(android.ApexModule)
-		if !ok || !am.CanHaveApexVariants() {
-			return false
-		}
-
-		// Filter-out unwanted depedendencies
-		depTag := ctx.OtherModuleDependencyTag(child)
-		if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
-			return false
-		}
-		if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
-			return false
-		}
-		if depTag == android.RequiredDepTag {
-			return false
-		}
-
-		externalDep := !android.IsDepInSameApex(ctx, parent, child)
-
-		// Visit actually
-		return do(ctx, parent, am, externalDep)
-	})
-}
-
-func (a *apexBundle) WalkPayloadDepsProxy(ctx android.BaseModuleContext,
-	do func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool) {
 	ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
-		if !android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoKey).CanHaveApexVariants {
+		if !android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoProvider).CanHaveApexVariants {
 			return false
 		}
 		// Filter-out unwanted depedendencies
@@ -1845,7 +1821,7 @@
 	if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
 		return false
 	}
-	commonInfo := android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoKey)
+	commonInfo := android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoProvider)
 	if !commonInfo.Enabled {
 		return false
 	}
@@ -1931,6 +1907,7 @@
 			}
 		case androidAppTag:
 			if appInfo, ok := android.OtherModuleProvider(ctx, child, java.AppInfoProvider); ok {
+				a.appInfos = append(a.appInfos, *appInfo)
 				if appInfo.AppSet {
 					appDir := "app"
 					if appInfo.Privileged {
@@ -2267,6 +2244,8 @@
 	})
 
 	android.SetProvider(ctx, filesystem.ApexKeyPathInfoProvider, filesystem.ApexKeyPathInfo{a.apexKeysPath})
+
+	android.SetProvider(ctx, java.AppInfosProvider, a.appInfos)
 }
 
 // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
@@ -2551,7 +2530,7 @@
 		librariesDirectlyInApex[ctx.OtherModuleName(dep)] = true
 	})
 
-	a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
+	a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
 		if info, ok := android.OtherModuleProvider(ctx, to, cc.LinkableInfoProvider); ok {
 			// If `to` is not actually in the same APEX as `from` then it does not need
 			// apex_available and neither do any of its dependencies.
@@ -2665,7 +2644,7 @@
 		return
 	}
 
-	a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
+	a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
 		// As soon as the dependency graph crosses the APEX boundary, don't go further.
 		if externalDep {
 			return false
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index dabec49..0bf4ba7 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -164,7 +164,7 @@
 		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 && !android.OtherModuleProviderOrDefault(ctx, m, android.CommonModuleInfoKey).HideFromMake {
+		if exists && !android.OtherModuleProviderOrDefault(ctx, m, android.CommonModuleInfoProvider).HideFromMake {
 			prebuiltInfos = append(prebuiltInfos, prebuiltInfo)
 		}
 	})
diff --git a/apex/builder.go b/apex/builder.go
index 2fc4902..8042a3b 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -1102,7 +1102,7 @@
 	}
 
 	depInfos := android.DepNameToDepInfoMap{}
-	a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
+	a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
 		if from.Name() == to.Name() {
 			// This can happen for cc.reuseObjTag. We are not interested in tracking this.
 			// As soon as the dependency graph crosses the APEX boundary, don't go further.
@@ -1111,7 +1111,7 @@
 
 		// Skip dependencies that are only available to APEXes; they are developed with updatability
 		// in mind and don't need manual approval.
-		if android.OtherModuleProviderOrDefault(ctx, to, android.CommonModuleInfoKey).NotAvailableForPlatform {
+		if android.OtherModuleProviderOrDefault(ctx, to, android.CommonModuleInfoProvider).NotAvailableForPlatform {
 			return !externalDep
 		}
 
@@ -1129,7 +1129,7 @@
 			depInfos[to.Name()] = info
 		} else {
 			toMinSdkVersion := "(no version)"
-			if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoKey); ok &&
+			if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoProvider); ok &&
 				!info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil {
 				toMinSdkVersion = info.MinSdkVersion.ApiLevel.String()
 			}
diff --git a/bloaty/bloaty.go b/bloaty/bloaty.go
index 26f2aa8..a076d47 100644
--- a/bloaty/bloaty.go
+++ b/bloaty/bloaty.go
@@ -84,8 +84,8 @@
 
 func (singleton *sizesSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	var deps android.Paths
-	ctx.VisitAllModules(func(m android.Module) {
-		if !m.ExportedToMake() {
+	ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
+		if !android.OtherModuleProviderOrDefault(ctx, m, android.CommonModuleInfoProvider).ExportedToMake {
 			return
 		}
 		filePaths, ok := android.OtherModuleProvider(ctx, m, fileSizeMeasurerKey)
diff --git a/cc/afdo.go b/cc/afdo.go
index 1233e33..9be3918 100644
--- a/cc/afdo.go
+++ b/cc/afdo.go
@@ -108,6 +108,8 @@
 		// Salvage stale profile by fuzzy matching and use the remapped location for sample profile query.
 		flags.Local.CFlags = append([]string{"-mllvm", "--salvage-stale-profile=true"}, flags.Local.CFlags...)
 		flags.Local.CFlags = append([]string{"-mllvm", "--salvage-stale-profile-max-callsites=2000"}, flags.Local.CFlags...)
+		// Salvage stale profile by fuzzy matching renamed functions.
+		flags.Local.CFlags = append([]string{"-mllvm", "--salvage-unused-profile=true"}, flags.Local.CFlags...)
 		flags.Local.LdFlags = append([]string{profileUseFlag, "-Wl,-mllvm,-no-warn-sample-unused=true"}, flags.Local.LdFlags...)
 
 		// Update CFlagsDeps and LdFlagsDeps so the module is rebuilt
diff --git a/cc/api_level.go b/cc/api_level.go
index deca723..fa8dfaf 100644
--- a/cc/api_level.go
+++ b/cc/api_level.go
@@ -31,11 +31,7 @@
 	case android.Arm64, android.X86_64:
 		return android.FirstLp64Version
 	case android.Riscv64:
-		apiLevel, err := android.ApiLevelFromUser(ctx, "VanillaIceCream")
-		if err != nil {
-			panic(err)
-		}
-		return apiLevel
+		return android.FutureApiLevel
 	default:
 		panic(fmt.Errorf("Unknown arch %q", arch))
 	}
diff --git a/cc/binary.go b/cc/binary.go
index 627d5e5..608251a 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -551,6 +551,10 @@
 	binary.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON)
 }
 
+func (binary *binaryDecorator) testSuiteInfo(ctx ModuleContext) {
+	// not a test
+}
+
 var _ overridable = (*binaryDecorator)(nil)
 
 func init() {
diff --git a/cc/cc.go b/cc/cc.go
index 4da1103..ae6f3b0 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -81,12 +81,13 @@
 	HeaderLibs               []string
 	ImplementationModuleName *string
 
-	BinaryDecoratorInfo    *BinaryDecoratorInfo
-	LibraryDecoratorInfo   *LibraryDecoratorInfo
-	TestBinaryInfo         *TestBinaryInfo
-	BenchmarkDecoratorInfo *BenchmarkDecoratorInfo
-	ObjectLinkerInfo       *ObjectLinkerInfo
-	StubDecoratorInfo      *StubDecoratorInfo
+	BinaryDecoratorInfo       *BinaryDecoratorInfo
+	LibraryDecoratorInfo      *LibraryDecoratorInfo
+	TestBinaryInfo            *TestBinaryInfo
+	BenchmarkDecoratorInfo    *BenchmarkDecoratorInfo
+	ObjectLinkerInfo          *ObjectLinkerInfo
+	StubDecoratorInfo         *StubDecoratorInfo
+	PrebuiltLibraryLinkerInfo *PrebuiltLibraryLinkerInfo
 }
 
 type BinaryDecoratorInfo struct{}
@@ -96,6 +97,7 @@
 	// Location of the static library in the sysroot. Empty if the library is
 	// not included in the NDK.
 	NdkSysrootPath android.Path
+	VndkFileName   string
 }
 
 type SnapshotInfo struct {
@@ -120,6 +122,10 @@
 	NdkSysrootPath android.Path
 }
 
+type PrebuiltLibraryLinkerInfo struct {
+	VndkFileName string
+}
+
 type LibraryInfo struct {
 	BuildStubs bool
 }
@@ -128,6 +134,13 @@
 	StubDecoratorInfo *StubDecoratorInfo
 }
 
+type LocalOrGlobalFlagsInfo struct {
+	CommonFlags []string // Flags that apply to C, C++, and assembly source files
+	CFlags      []string // Flags that apply to C and C++ source files
+	ConlyFlags  []string // Flags that apply to C source files
+	CppFlags    []string // Flags that apply to C++ source files
+}
+
 // Common info about the cc module.
 type CcInfo struct {
 	IsPrebuilt             bool
@@ -148,6 +161,7 @@
 	StaticExecutable     bool
 	Static               bool
 	Shared               bool
+	Header               bool
 	HasStubsVariants     bool
 	StubsVersion         string
 	IsStubs              bool
@@ -195,7 +209,11 @@
 	APIListCoverageXMLPath android.ModuleOutPath
 	// FuzzSharedLibraries returns the shared library dependencies for this module.
 	// Expects that IsFuzzModule returns true.
-	FuzzSharedLibraries android.RuleBuilderInstalls
+	FuzzSharedLibraries      android.RuleBuilderInstalls
+	IsVndkPrebuiltLibrary    bool
+	HasLLNDKStubs            bool
+	IsLLNDKMovedToApex       bool
+	ImplementationModuleName string
 }
 
 var LinkableInfoProvider = blueprint.NewProvider[*LinkableInfo]()
@@ -779,6 +797,8 @@
 	defaultDistFiles() []android.Path
 
 	moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON)
+
+	testSuiteInfo(ctx ModuleContext)
 }
 
 // specifiedDeps is a tuple struct representing dependencies of a linked binary owned by the linker.
@@ -2356,9 +2376,11 @@
 		case *binaryDecorator:
 			ccInfo.LinkerInfo.BinaryDecoratorInfo = &BinaryDecoratorInfo{}
 		case *libraryDecorator:
+			lk := c.linker.(*libraryDecorator)
 			ccInfo.LinkerInfo.LibraryDecoratorInfo = &LibraryDecoratorInfo{
-				InjectBsslHash: Bool(c.linker.(*libraryDecorator).Properties.Inject_bssl_hash),
-				NdkSysrootPath: c.linker.(*libraryDecorator).ndkSysrootPath,
+				InjectBsslHash: Bool(lk.Properties.Inject_bssl_hash),
+				NdkSysrootPath: lk.ndkSysrootPath,
+				VndkFileName:   lk.getLibNameHelper(c.BaseModuleName(), true, false) + ".so",
 			}
 		case *testBinary:
 			ccInfo.LinkerInfo.TestBinaryInfo = &TestBinaryInfo{
@@ -2372,6 +2394,11 @@
 			}
 		case *stubDecorator:
 			ccInfo.LinkerInfo.StubDecoratorInfo = &StubDecoratorInfo{}
+		case *prebuiltLibraryLinker:
+			ccInfo.LinkerInfo.PrebuiltLibraryLinkerInfo = &PrebuiltLibraryLinkerInfo{
+				VndkFileName: c.linker.(*prebuiltLibraryLinker).getLibNameHelper(
+					c.BaseModuleName(), true, false) + ".so",
+			}
 		}
 
 		if s, ok := c.linker.(SnapshotInterface); ok {
@@ -2383,6 +2410,8 @@
 			name := v.ImplementationModuleName(ctx.OtherModuleName(c))
 			ccInfo.LinkerInfo.ImplementationModuleName = &name
 		}
+
+		c.linker.testSuiteInfo(ctx)
 	}
 	if c.library != nil {
 		ccInfo.LibraryInfo = &LibraryInfo{
@@ -2441,12 +2470,17 @@
 		Multilib:                        mod.Multilib(),
 		ImplementationModuleNameForMake: mod.ImplementationModuleNameForMake(),
 		Symlinks:                        mod.Symlinks(),
+		Header:                          mod.Header(),
+		IsVndkPrebuiltLibrary:           mod.IsVndkPrebuiltLibrary(),
 	}
 
 	vi := mod.VersionedInterface()
 	if vi != nil {
 		info.IsStubsImplementationRequired = vi.IsStubsImplementationRequired()
 		info.APIListCoverageXMLPath = vi.GetAPIListCoverageXMLPath()
+		info.HasLLNDKStubs = vi.HasLLNDKStubs()
+		info.IsLLNDKMovedToApex = vi.IsLLNDKMovedToApex()
+		info.ImplementationModuleName = vi.ImplementationModuleName(mod.BaseModuleName())
 	}
 
 	if !mod.PreventInstall() && fuzz.IsValid(ctx, mod.FuzzModuleStruct()) && mod.IsFuzzModule() {
@@ -3388,7 +3422,7 @@
 			return
 		}
 
-		commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey)
+		commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoProvider)
 		if commonInfo.Target.Os != ctx.Os() {
 			ctx.ModuleErrorf("OS mismatch between %q (%s) and %q (%s)", ctx.ModuleName(), ctx.Os().Name, depName, dep.Target().Os.Name)
 			return
@@ -3745,7 +3779,7 @@
 		// platform APIs, use stubs only when it is from an APEX (and not from
 		// platform) However, for host, ramdisk, vendor_ramdisk, recovery or
 		// bootstrap modules, always link to non-stub variant
-		isNotInPlatform := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey).NotInPlatform
+		isNotInPlatform := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoProvider).NotInPlatform
 
 		useStubs = isNotInPlatform && !bootstrap
 	} else {
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 325354b..ba34387 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -486,7 +486,7 @@
 			sharedLibsInstallDirPrefix = "lib/vendor"
 		}
 
-		commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey)
+		commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider)
 		isHost := commonInfo.Target.Os.Class == android.Host
 		hostOrTargetString := "target"
 		if commonInfo.Target.HostCross {
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index 438eb98..4e700a2 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -17,6 +17,7 @@
 import (
 	"reflect"
 	"slices"
+	"strings"
 	"testing"
 
 	"android/soong/android"
@@ -254,3 +255,42 @@
 		gen_64bit,
 	)
 }
+
+// Test that a genrule can depend on a tool with symlinks. The symlinks are ignored, but
+// at least it doesn't cause errors.
+func TestGenruleToolWithSymlinks(t *testing.T) {
+	bp := `
+	genrule {
+		name: "gen",
+		tools: ["tool_with_symlinks"],
+		cmd: "$(location tool_with_symlinks) $(in) $(out)",
+		out: ["out"],
+	}
+
+	cc_binary_host {
+		name: "tool_with_symlinks",
+		symlinks: ["symlink1", "symlink2"],
+	}
+	`
+	ctx := PrepareForIntegrationTestWithCc.
+		ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
+		RunTestWithBp(t, bp)
+	gen := ctx.ModuleForTests(t, "gen", "").Output("out")
+	toolFound := false
+	symlinkFound := false
+	for _, dep := range gen.RuleParams.CommandDeps {
+		if strings.HasSuffix(dep, "/tool_with_symlinks") {
+			toolFound = true
+		}
+		if strings.HasSuffix(dep, "/symlink1") || strings.HasSuffix(dep, "/symlink2") {
+			symlinkFound = true
+		}
+	}
+	if !toolFound {
+		t.Errorf("Tool not found")
+	}
+	// We may want to change genrules to include symlinks later
+	if symlinkFound {
+		t.Errorf("Symlinks found")
+	}
+}
diff --git a/cc/library.go b/cc/library.go
index 8a2b6bd..5299771 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -606,10 +606,22 @@
 			panic(err)
 		}
 
+		llndkFlag := "--llndk"
+		if ctx.baseModuleName() == "libbinder_ndk" && ctx.inProduct() {
+			// This is a special case only for the libbinder_ndk. As the product partition is in the
+			// framework side along with system and system_ext partitions in Treble, libbinder_ndk
+			// provides different binder interfaces between product and vendor modules.
+			// In libbinder_ndk, 'llndk' annotation is for the vendor APIs; while 'systemapi'
+			// annotation is for the product APIs.
+			// Use '--systemapi' flag for building the llndk stub of product variant for the
+			// libbinder_ndk.
+			llndkFlag = "--systemapi"
+		}
+
 		// This is the vendor variant of an LLNDK library, build the LLNDK stubs.
 		nativeAbiResult := ParseNativeAbiDefinition(ctx,
 			String(library.Properties.Llndk.Symbol_file),
-			nativeClampedApiLevel(ctx, version), "--llndk")
+			nativeClampedApiLevel(ctx, version), llndkFlag)
 		objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, sharedFlags)
 		if !Bool(library.Properties.Llndk.Unversioned) {
 			library.versionScriptPath = android.OptionalPathForPath(
@@ -1066,6 +1078,10 @@
 	library.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON)
 }
 
+func (library *libraryDecorator) testSuiteInfo(ctx ModuleContext) {
+	// not a test
+}
+
 func (library *libraryDecorator) linkStatic(ctx ModuleContext,
 	flags Flags, deps PathDeps, objs Objects) android.Path {
 
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 8ca3ca1..b119fda 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -82,11 +82,10 @@
 func (s *movedToApexLlndkLibraries) GenerateBuildActions(ctx android.SingletonContext) {
 	// Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to generate the linker config.
 	movedToApexLlndkLibrariesMap := make(map[string]bool)
-	ctx.VisitAllModules(func(module android.Module) {
-		if library := moduleVersionedInterface(module); library != nil && library.HasLLNDKStubs() {
-			if library.IsLLNDKMovedToApex() {
-				name := library.ImplementationModuleName(module.(*Module).BaseModuleName())
-				movedToApexLlndkLibrariesMap[name] = true
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+		if library, ok := android.OtherModuleProvider(ctx, module, LinkableInfoProvider); ok {
+			if library.HasLLNDKStubs && library.IsLLNDKMovedToApex {
+				movedToApexLlndkLibrariesMap[library.ImplementationModuleName] = true
 			}
 		}
 	})
@@ -151,14 +150,16 @@
 	etc.SetCommonPrebuiltEtcInfo(ctx, txt)
 }
 
-func getVndkFileName(m *Module) (string, error) {
-	if library, ok := m.linker.(*libraryDecorator); ok {
-		return library.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
+func getVndkFileName(info *LinkerInfo) (string, error) {
+	if info != nil {
+		if info.LibraryDecoratorInfo != nil {
+			return info.LibraryDecoratorInfo.VndkFileName, nil
+		}
+		if info.PrebuiltLibraryLinkerInfo != nil {
+			return info.PrebuiltLibraryLinkerInfo.VndkFileName, nil
+		}
 	}
-	if prebuilt, ok := m.linker.(*prebuiltLibraryLinker); ok {
-		return prebuilt.libraryDecorator.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
-	}
-	return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker)
+	return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", info)
 }
 
 func (txt *llndkLibrariesTxtModule) GenerateSingletonBuildActions(ctx android.SingletonContext) {
@@ -167,9 +168,17 @@
 		return
 	}
 
-	ctx.VisitAllModules(func(m android.Module) {
-		if c, ok := m.(*Module); ok && c.VendorProperties.IsLLNDK && !c.Header() && !c.IsVndkPrebuiltLibrary() {
-			filename, err := getVndkFileName(c)
+	ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
+		ccInfo, ok := android.OtherModuleProvider(ctx, m, CcInfoProvider)
+		if !ok {
+			return
+		}
+		linkableInfo, ok := android.OtherModuleProvider(ctx, m, LinkableInfoProvider)
+		if !ok {
+			return
+		}
+		if linkableInfo.IsLlndk && !linkableInfo.Header && !linkableInfo.IsVndkPrebuiltLibrary {
+			filename, err := getVndkFileName(ccInfo.LinkerInfo)
 			if err != nil {
 				ctx.ModuleErrorf(m, "%s", err)
 			}
diff --git a/cc/ndk_abi.go b/cc/ndk_abi.go
index a9f26a4..a59cc11 100644
--- a/cc/ndk_abi.go
+++ b/cc/ndk_abi.go
@@ -40,7 +40,7 @@
 func (n *ndkAbiDumpSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	var depPaths android.Paths
 	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
-		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
 			return
 		}
 
@@ -78,7 +78,7 @@
 func (n *ndkAbiDiffSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	var depPaths android.Paths
 	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
-		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
 			return
 		}
 
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index 34f6195..82a19d0 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -212,7 +212,7 @@
 	var licensePaths android.Paths
 	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
 
-		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
 			return
 		}
 
diff --git a/cc/object.go b/cc/object.go
index 95a8beb..ea3ed61 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -250,3 +250,7 @@
 	object.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON)
 	moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"}
 }
+
+func (object *objectLinker) testSuiteInfo(ctx ModuleContext) {
+	// not a test
+}
diff --git a/cc/strip.go b/cc/strip.go
index a950df8..42c9137 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -23,8 +23,9 @@
 // StripProperties defines the type of stripping applied to the module.
 type StripProperties struct {
 	Strip struct {
-		// Device and host modules default to stripping enabled leaving mini debuginfo.
-		// This can be disabled by setting none to true.
+		// Device modules default to stripping enabled leaving mini debuginfo.
+		// Host modules default to stripping disabled, but can be enabled by setting any other
+		// strip boolean property.
 		None *bool `android:"arch_variant"`
 
 		// all forces stripping everything, including the mini debug info.
@@ -50,7 +51,12 @@
 // NeedsStrip determines if stripping is required for a module.
 func (stripper *Stripper) NeedsStrip(actx android.ModuleContext) bool {
 	forceDisable := Bool(stripper.StripProperties.Strip.None)
-	return !forceDisable
+	// Strip is enabled by default for device variants.
+	defaultEnable := actx.Device() || actx.Config().StripByDefault()
+	forceEnable := Bool(stripper.StripProperties.Strip.All) ||
+		Bool(stripper.StripProperties.Strip.Keep_symbols) ||
+		Bool(stripper.StripProperties.Strip.Keep_symbols_and_debug_frame)
+	return !forceDisable && (forceEnable || defaultEnable)
 }
 
 func (stripper *Stripper) strip(actx android.ModuleContext, in android.Path, out android.ModuleOutPath,
diff --git a/cc/test.go b/cc/test.go
index d2c4b28..9c276b8 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -274,6 +274,12 @@
 	}
 }
 
+func (test *testDecorator) testSuiteInfo(ctx ModuleContext) {
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: test.InstallerProperties.Test_suites,
+	})
+}
+
 func NewTestInstaller() *baseInstaller {
 	return NewBaseInstaller("nativetest", "nativetest64", InstallInData)
 }
@@ -342,6 +348,10 @@
 
 }
 
+func (test *testBinary) testSuiteInfo(ctx ModuleContext) {
+	test.testDecorator.testSuiteInfo(ctx)
+}
+
 func (test *testBinary) installerProps() []interface{} {
 	return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...)
 }
@@ -455,6 +465,9 @@
 			if standaloneTestDep.SkipInstall() {
 				continue
 			}
+			if standaloneTestDep.Partition() == "data" {
+				continue
+			}
 			test.binaryDecorator.baseInstaller.installStandaloneTestDep(ctx, standaloneTestDep)
 		}
 	}
@@ -575,6 +588,10 @@
 	test.testDecorator.moduleInfoJSON(ctx, moduleInfoJSON)
 }
 
+func (test *testLibrary) testSuiteInfo(ctx ModuleContext) {
+	test.testDecorator.testSuiteInfo(ctx)
+}
+
 func (test *testLibrary) installerProps() []interface{} {
 	return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...)
 }
@@ -692,6 +709,12 @@
 	}
 }
 
+func (benchmark *benchmarkDecorator) testSuiteInfo(ctx ModuleContext) {
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: benchmark.Properties.Test_suites,
+	})
+}
+
 func NewBenchmark(hod android.HostOrDeviceSupported) *Module {
 	module, binary := newBinary(hod)
 	module.multilib = android.MultilibBoth
diff --git a/cc/tidy.go b/cc/tidy.go
index 8e7f899..e8e1dc2 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -220,7 +220,7 @@
 
 	// (1) Collect all obj/tidy files into OS-specific groups.
 	ctx.VisitAllModuleVariantProxies(module, func(variant android.ModuleProxy) {
-		osName := android.OtherModuleProviderOrDefault(ctx, variant, android.CommonModuleInfoKey).Target.Os.Name
+		osName := android.OtherModuleProviderOrDefault(ctx, variant, android.CommonModuleInfoProvider).Target.Os.Name
 		info := android.OtherModuleProviderOrDefault(ctx, variant, CcObjectInfoProvider)
 		addToOSGroup(osName, info.ObjFiles, allObjFileGroups, subsetObjFileGroups)
 		addToOSGroup(osName, info.TidyFiles, allTidyFileGroups, subsetTidyFileGroups)
diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go
index 0db3f9f..f8c4578 100644
--- a/ci_tests/ci_test_package_zip.go
+++ b/ci_tests/ci_test_package_zip.go
@@ -20,6 +20,7 @@
 	"strings"
 
 	"android/soong/android"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
@@ -149,7 +150,7 @@
 
 	// dist the test output
 	if ctx.ModuleName() == "platform_tests" {
-		distedName := ctx.Config().Getenv("TARGET_PRODUCT") + "-tests-" + ctx.Config().BuildId() + ".zip"
+		distedName := ctx.Config().Getenv("TARGET_PRODUCT") + "-tests-FILE_NAME_TAG_PLACEHOLDER.zip"
 		ctx.DistForGoalWithFilename("platform_tests", p.output, distedName)
 	}
 }
@@ -214,7 +215,13 @@
 		ctx.ModuleErrorf("Module %s doesn't set InstallFilesProvider", m.Name())
 	}
 
-	for _, installedFile := range installedFilesInfo.InstallFiles {
+	for _, spec := range installedFilesInfo.PackagingSpecs {
+		if spec.SrcPath() == nil {
+			// Probably a symlink
+			continue
+		}
+		installedFile := spec.FullInstallPath()
+
 		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"
@@ -236,23 +243,26 @@
 		if strings.HasPrefix(f, "out") {
 			continue
 		}
-		f = strings.ReplaceAll(f, "system/", "DATA/")
+		if strings.HasPrefix(f, "system/") {
+			f = strings.Replace(f, "system/", "DATA/", 1)
+		}
 		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/")
+		if strings.HasPrefix(f, "testcases") {
+			f = strings.Replace(f, "testcases", filepath.Join("DATA", class), 1)
+		}
+		if strings.HasPrefix(f, "data/") {
+			f = strings.Replace(f, "data/", "DATA/", 1)
+		}
 		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)
+		// Copy srcPath instead of installedFile because some rules like target-files.zip
+		// are non-hermetic and would be affected if we built the installed files.
+		builder.Command().Text("cp").Flag("-Rf").Input(spec.SrcPath()).Output(tempOut)
 		builder.Temporary(tempOut)
 	}
 }
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index af1d33d..7f50912 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -291,6 +291,11 @@
 	// For prebuilts, library should have the same name as the source module.
 	lib = android.RemoveOptionalPrebuiltPrefix(lib)
 
+	// Bootclasspath libraries should not be added to CLC.
+	if android.InList(lib, ctx.Config().BootJars()) {
+		return nil
+	}
+
 	devicePath := UnknownInstallLibraryPath
 	if installPath == nil {
 		if android.InList(lib, CompatUsesLibs) || android.InList(lib, OptionalCompatUsesLibs) {
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index f3c2b2c..9cec9db 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -465,7 +465,7 @@
 func (d dex2oatDependencyTag) AllowDisabledModuleDependencyProxy(
 	ctx android.OtherModuleProviderContext, target android.ModuleProxy) bool {
 	return android.OtherModuleProviderOrDefault(
-		ctx, target, android.CommonModuleInfoKey).ReplacedByPrebuilt
+		ctx, target, android.CommonModuleInfoProvider).ReplacedByPrebuilt
 }
 
 // Dex2oatDepTag represents the dependency onto the dex2oatd module. It is added to any module that
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index fad8f07..d0da728 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -65,6 +65,7 @@
 	ctx.RegisterModuleType("prebuilt_font", PrebuiltFontFactory)
 	ctx.RegisterModuleType("prebuilt_overlay", PrebuiltOverlayFactory)
 	ctx.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory)
+	ctx.RegisterModuleType("prebuilt_gpu", PrebuiltGPUFactory)
 	ctx.RegisterModuleType("prebuilt_dsp", PrebuiltDSPFactory)
 	ctx.RegisterModuleType("prebuilt_rfsa", PrebuiltRFSAFactory)
 	ctx.RegisterModuleType("prebuilt_renderscript_bitcode", PrebuiltRenderScriptBitcodeFactory)
@@ -73,6 +74,7 @@
 	ctx.RegisterModuleType("prebuilt_bin", PrebuiltBinaryFactory)
 	ctx.RegisterModuleType("prebuilt_wallpaper", PrebuiltWallpaperFactory)
 	ctx.RegisterModuleType("prebuilt_priv_app", PrebuiltPrivAppFactory)
+	ctx.RegisterModuleType("prebuilt_radio", PrebuiltRadioFactory)
 	ctx.RegisterModuleType("prebuilt_rfs", PrebuiltRfsFactory)
 	ctx.RegisterModuleType("prebuilt_framework", PrebuiltFrameworkFactory)
 	ctx.RegisterModuleType("prebuilt_res", PrebuiltResFactory)
@@ -831,6 +833,15 @@
 	return module
 }
 
+// prebuilt_gpu is for a prebuilt artifact in <partition>/gpu directory.
+func PrebuiltGPUFactory() android.Module {
+	module := &PrebuiltEtc{}
+	InitPrebuiltEtcModule(module, "gpu")
+	// This module is device-only
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+	return module
+}
+
 // prebuilt_dsp installs a DSP related file to <partition>/etc/dsp directory for system image.
 // If soc_specific property is set to true, the DSP related file is installed to the
 // vendor <partition>/dsp directory for vendor image.
@@ -921,6 +932,16 @@
 	return module
 }
 
+// prebuilt_radio installs files in <partition>/radio directory.
+func PrebuiltRadioFactory() android.Module {
+	module := &PrebuiltEtc{}
+	InitPrebuiltEtcModule(module, "radio")
+	// This module is device-only
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+	android.InitDefaultableModule(module)
+	return module
+}
+
 // prebuilt_rfs installs files in <partition>/rfs directory.
 func PrebuiltRfsFactory() android.Module {
 	module := &PrebuiltEtc{}
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 3d306e3..45a8620 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -19,6 +19,7 @@
 	"fmt"
 	"path/filepath"
 	"slices"
+	"sort"
 	"strings"
 	"sync/atomic"
 
@@ -114,6 +115,7 @@
 	miscInfo                    android.Path
 	rootDirForFsConfig          string
 	rootDirForFsConfigTimestamp android.Path
+	apkCertsInfo                android.Path
 }
 
 func AndroidDeviceFactory() android.Module {
@@ -188,7 +190,8 @@
 
 	allInstalledModules := a.allInstalledModules(ctx)
 
-	a.kernelConfig, a.kernelVersion = a.extractKernelVersionAndConfigs(ctx)
+	a.apkCertsInfo = a.buildApkCertsInfo(ctx, allInstalledModules)
+	a.kernelVersion, a.kernelConfig = a.extractKernelVersionAndConfigs(ctx)
 	a.miscInfo = a.addMiscInfo(ctx)
 	a.buildTargetFilesZip(ctx, allInstalledModules)
 	a.buildProguardZips(ctx, allInstalledModules)
@@ -278,6 +281,39 @@
 	a.setVbmetaPhonyTargets(ctx)
 
 	a.distFiles(ctx)
+
+	android.SetProvider(ctx, android.AndroidDeviceInfoProvider, android.AndroidDeviceInfo{
+		Main_device: android.Bool(a.deviceProps.Main_device),
+	})
+
+	if proptools.String(a.partitionProps.Super_partition_name) != "" {
+		buildComplianceMetadata(ctx, superPartitionDepTag, filesystemDepTag)
+	} else {
+		buildComplianceMetadata(ctx, filesystemDepTag)
+	}
+}
+
+func buildComplianceMetadata(ctx android.ModuleContext, tags ...blueprint.DependencyTag) {
+	// Collect metadata from deps
+	filesContained := make([]string, 0)
+	prebuiltFilesCopied := make([]string, 0)
+	for _, tag := range tags {
+		ctx.VisitDirectDepsProxyWithTag(tag, func(m android.ModuleProxy) {
+			if complianceMetadataInfo, ok := android.OtherModuleProvider(ctx, m, android.ComplianceMetadataProvider); ok {
+				filesContained = append(filesContained, complianceMetadataInfo.GetFilesContained()...)
+				prebuiltFilesCopied = append(prebuiltFilesCopied, complianceMetadataInfo.GetPrebuiltFilesCopied()...)
+			}
+		})
+	}
+	// Merge to module's ComplianceMetadataInfo
+	complianceMetadataInfo := ctx.ComplianceMetadataInfo()
+	filesContained = append(filesContained, complianceMetadataInfo.GetFilesContained()...)
+	sort.Strings(filesContained)
+	complianceMetadataInfo.SetFilesContained(filesContained)
+
+	prebuiltFilesCopied = append(prebuiltFilesCopied, complianceMetadataInfo.GetPrebuiltFilesCopied()...)
+	sort.Strings(prebuiltFilesCopied)
+	complianceMetadataInfo.SetPrebuiltFilesCopied(prebuiltFilesCopied)
 }
 
 // Returns a list of modules that are installed, which are collected from the dependency
@@ -317,18 +353,32 @@
 	return strings.TrimSuffix(file, ext) + insertion + ext
 }
 
+func (a *androidDevice) distInstalledFiles(ctx android.ModuleContext) {
+	distInstalledFilesJsonAndTxt := func(installedFiles InstalledFilesStruct) {
+		if installedFiles.Json != nil {
+			ctx.DistForGoal("droidcore-unbundled", installedFiles.Json)
+		}
+		if installedFiles.Txt != nil {
+			ctx.DistForGoal("droidcore-unbundled", installedFiles.Txt)
+		}
+	}
+
+	fsInfoMap := a.getFsInfos(ctx)
+	for _, partition := range android.SortedKeys(fsInfoMap) {
+		// installed-files-*{.txt | .json} is not disted for userdata partition
+		if partition == "userdata" {
+			continue
+		}
+		fsInfo := fsInfoMap[partition]
+		for _, installedFiles := range fsInfo.InstalledFilesDepSet.ToList() {
+			distInstalledFilesJsonAndTxt(installedFiles)
+		}
+	}
+}
+
 func (a *androidDevice) distFiles(ctx android.ModuleContext) {
 	if !ctx.Config().KatiEnabled() && proptools.Bool(a.deviceProps.Main_device) {
-		fsInfoMap := a.getFsInfos(ctx)
-		for _, partition := range android.SortedKeys(fsInfoMap) {
-			fsInfo := fsInfoMap[partition]
-			if fsInfo.InstalledFiles.Json != nil {
-				ctx.DistForGoal("droidcore-unbundled", fsInfo.InstalledFiles.Json)
-			}
-			if fsInfo.InstalledFiles.Txt != nil {
-				ctx.DistForGoal("droidcore-unbundled", fsInfo.InstalledFiles.Txt)
-			}
-		}
+		a.distInstalledFiles(ctx)
 
 		namePrefix := ""
 		if ctx.Config().HasDeviceProduct() {
@@ -573,6 +623,10 @@
 					builder.Command().Textf("cp ").Input(info.SubImageInfo[partition].MapFile).Textf(" %s/IMAGES/", targetFilesDir.String())
 				}
 			}
+			// super_empty.img
+			if info.SuperEmptyImage != nil {
+				builder.Command().Textf("cp ").Input(info.SuperEmptyImage).Textf(" %s/IMAGES/", targetFilesDir.String())
+			}
 		} else {
 			ctx.ModuleErrorf("Super partition %s does set SuperImageProvider\n", superPartition.Name())
 		}
@@ -631,7 +685,13 @@
 		}
 		if partition == "vendor_ramdisk" {
 			// Create vendor_boot_filesystem_config from the assembled VENDOR_BOOT/RAMDISK intermediates directory
-			a.generateFilesystemConfigForTargetFiles(ctx, builder, nil, targetFilesDir.String(), targetFilesDir.String()+"/VENDOR_BOOT/RAMDISK", "vendor_boot_filesystem_config.txt")
+			vendorRamdiskStagingDir := targetFilesDir.String() + "/VENDOR_BOOT/RAMDISK"
+			vendorRamdiskFsConfigOut := targetFilesDir.String() + "/META/vendor_boot_filesystem_config.txt"
+			fsConfigBin := ctx.Config().HostToolPath(ctx, "fs_config")
+			builder.Command().Textf(
+				`(cd %s; find . -type d | sed 's,$,/,'; find . \! -type d) | cut -c 3- | sort | sed 's,^,,' | %s -C -D %s -R \"\" > %s`,
+				vendorRamdiskStagingDir, fsConfigBin, vendorRamdiskStagingDir, vendorRamdiskFsConfigOut).
+				Implicit(fsConfigBin)
 		}
 	}
 	// Copy ramdisk_node_list
@@ -651,6 +711,9 @@
 	}
 	installedApexKeys = android.SortedUniquePaths(installedApexKeys) // Sort by keypath to match make
 	builder.Command().Text("cat").Inputs(installedApexKeys).Textf(" >> %s/META/apexkeys.txt", targetFilesDir.String())
+	// apkcerts.txt
+	builder.Command().Textf("cp").Input(a.apkCertsInfo).Textf(" %s/META/", 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
@@ -836,11 +899,12 @@
 		Flag("--tools lz4:"+lz4tool.String()).Implicit(lz4tool).
 		FlagWithInput("--input ", kernel).
 		FlagWithOutput("--output-release ", extractedVersionFile).
-		FlagWithOutput("--output-configs ", extractedConfigsFile)
+		FlagWithOutput("--output-configs ", extractedConfigsFile).
+		Textf(`&& printf "\n" >> %s`, extractedVersionFile)
 
 	if specifiedVersion := proptools.String(a.deviceProps.Kernel_version); specifiedVersion != "" {
 		specifiedVersionFile := android.PathForModuleOut(ctx, "specified_kernel_version.txt")
-		android.WriteFileRuleVerbatim(ctx, specifiedVersionFile, specifiedVersion)
+		android.WriteFileRule(ctx, specifiedVersionFile, specifiedVersion)
 		builder.Command().Text("diff -q").
 			Input(specifiedVersionFile).
 			Input(extractedVersionFile).
@@ -864,3 +928,51 @@
 
 	return extractedVersionFile, extractedConfigsFile
 }
+
+func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalledModules []android.Module) android.Path {
+	// TODO (spandandas): Add compressed
+	formatLine := func(cert java.Certificate, name, partition string) string {
+		pem := cert.AndroidMkString()
+		var key string
+		if cert.Key == nil {
+			key = ""
+		} else {
+			key = cert.Key.String()
+		}
+		return fmt.Sprintf(`name="%s" certificate="%s" private_key="%s" partition="%s"`, name, pem, key, partition)
+	}
+
+	apkCerts := []string{}
+	for _, installedModule := range allInstalledModules {
+		partition := ""
+		if commonInfo, ok := android.OtherModuleProvider(ctx, installedModule, android.CommonModuleInfoProvider); ok {
+			partition = commonInfo.PartitionTag
+		} else {
+			ctx.ModuleErrorf("%s does not set CommonModuleInfoKey", installedModule.Name())
+		}
+		if info, ok := android.OtherModuleProvider(ctx, installedModule, java.AppInfoProvider); ok {
+			apkCerts = append(apkCerts, formatLine(info.Certificate, info.InstallApkName+".apk", partition))
+		} else if info, ok := android.OtherModuleProvider(ctx, installedModule, java.AppInfosProvider); ok {
+			for _, certInfo := range info {
+				// Partition information of apk-in-apex is not exported to the legacy Make packaging system.
+				// Hardcode the partition to "system"
+				apkCerts = append(apkCerts, formatLine(certInfo.Certificate, certInfo.InstallApkName+".apk", "system"))
+			}
+		} else if info, ok := android.OtherModuleProvider(ctx, installedModule, java.RuntimeResourceOverlayInfoProvider); ok {
+			apkCerts = append(apkCerts, formatLine(info.Certificate, info.OutputFile.Base(), partition))
+		}
+	}
+	slices.Sort(apkCerts) // sort by name
+	fsInfos := a.getFsInfos(ctx)
+	if fsInfos["system"].HasFsverity {
+		defaultPem, defaultKey := ctx.Config().DefaultAppCertificate(ctx)
+		apkCerts = append(apkCerts, formatLine(java.Certificate{Pem: defaultPem, Key: defaultKey}, "BuildManifest.apk", "system"))
+		if info, ok := fsInfos["system_ext"]; ok && info.HasFsverity {
+			apkCerts = append(apkCerts, formatLine(java.Certificate{Pem: defaultPem, Key: defaultKey}, "BuildManifestSystemExt.apk", "system_ext"))
+		}
+	}
+
+	apkCertsInfo := android.PathForModuleOut(ctx, "apkcerts.txt")
+	android.WriteFileRuleVerbatim(ctx, apkCertsInfo, strings.Join(apkCerts, "\n")+"\n")
+	return apkCertsInfo
+}
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index effbd65..c06c200 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -201,7 +201,8 @@
 		return
 	}
 
-	unsignedOutput := b.buildBootImage(ctx, b.getKernelPath(ctx))
+	kernelPath := b.getKernelPath(ctx)
+	unsignedOutput := b.buildBootImage(ctx, kernelPath)
 
 	output := unsignedOutput
 	if proptools.Bool(b.properties.Use_avb) {
@@ -212,7 +213,7 @@
 		case "default":
 			output = b.signImage(ctx, unsignedOutput)
 		case "make_legacy":
-			output = b.addAvbFooter(ctx, unsignedOutput, b.getKernelPath(ctx))
+			output = b.addAvbFooter(ctx, unsignedOutput, kernelPath)
 		default:
 			ctx.PropertyErrorf("avb_mode", `Unknown value for avb_mode, expected "default" or "make_legacy", got: %q`, *b.properties.Avb_mode)
 		}
@@ -235,10 +236,11 @@
 	}
 
 	// Set BootimgInfo for building target_files.zip
+	dtbPath := b.getDtbPath(ctx)
 	android.SetProvider(ctx, BootimgInfoProvider, BootimgInfo{
 		Cmdline:    b.properties.Cmdline,
-		Kernel:     b.getKernelPath(ctx),
-		Dtb:        b.getDtbPath(ctx),
+		Kernel:     kernelPath,
+		Dtb:        dtbPath,
 		Bootconfig: b.getBootconfigPath(ctx),
 		Output:     output,
 	})
@@ -263,6 +265,21 @@
 		PublicKey:             extractedPublicKey,
 		Output:                output,
 	})
+
+	// Dump compliance metadata
+	complianceMetadataInfo := ctx.ComplianceMetadataInfo()
+	prebuiltFilesCopied := make([]string, 0)
+	if kernelPath != nil {
+		prebuiltFilesCopied = append(prebuiltFilesCopied, kernelPath.String()+":kernel")
+	}
+	if dtbPath != nil {
+		prebuiltFilesCopied = append(prebuiltFilesCopied, dtbPath.String()+":dtb.img")
+	}
+	complianceMetadataInfo.SetPrebuiltFilesCopied(prebuiltFilesCopied)
+
+	if ramdisk := proptools.String(b.properties.Ramdisk_module); ramdisk != "" {
+		buildComplianceMetadata(ctx, bootimgRamdiskDep)
+	}
 }
 
 var BootimgInfoProvider = blueprint.NewProvider[BootimgInfo]()
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 35fdd00..d5188d7 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -30,6 +30,7 @@
 	"android/soong/linkerconfig"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/depset"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -424,8 +425,8 @@
 
 	FullInstallPaths []FullInstallPathInfo
 
-	// Installed files list
-	InstalledFiles InstalledFilesStruct
+	// Installed files dep set of this module and its dependency filesystem modules
+	InstalledFilesDepSet depset.DepSet[InstalledFilesStruct]
 
 	// Path to compress hints file for erofs filesystems
 	// This will be nil for other fileystems like ext4
@@ -438,6 +439,8 @@
 	Owners []InstalledModuleInfo
 
 	UseAvb bool
+
+	HasFsverity bool
 }
 
 // FullInstallPathInfo contains information about the "full install" paths of all the files
@@ -541,13 +544,13 @@
 	}
 }
 
-func buildInstalledFiles(ctx android.ModuleContext, partition string, rootDir android.Path, image android.Path) (txt android.ModuleOutPath, json android.ModuleOutPath) {
+func buildInstalledFiles(ctx android.ModuleContext, partition string, rootDir android.Path, image android.Path) InstalledFilesStruct {
 	fileName := "installed-files"
 	if len(partition) > 0 {
 		fileName += fmt.Sprintf("-%s", partition)
 	}
-	txt = android.PathForModuleOut(ctx, fmt.Sprintf("%s.txt", fileName))
-	json = android.PathForModuleOut(ctx, fmt.Sprintf("%s.json", fileName))
+	txt := android.PathForModuleOut(ctx, fmt.Sprintf("%s.txt", fileName))
+	json := android.PathForModuleOut(ctx, fmt.Sprintf("%s.json", fileName))
 
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        installedFilesJsonRule,
@@ -566,7 +569,10 @@
 		Description: "Installed file list txt",
 	})
 
-	return txt, json
+	return InstalledFilesStruct{
+		Txt:  txt,
+		Json: json,
+	}
 }
 
 func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -649,11 +655,15 @@
 	fileListFile := android.PathForModuleOut(ctx, "fileList")
 	android.WriteFileRule(ctx, fileListFile, f.installedFilesList())
 
-	partitionName := f.partitionName()
-	if partitionName == "system" {
-		partitionName = ""
+	var partitionNameForInstalledFiles string
+	switch f.partitionName() {
+	case "system":
+		partitionNameForInstalledFiles = ""
+	case "vendor_ramdisk":
+		partitionNameForInstalledFiles = "vendor-ramdisk"
+	default:
+		partitionNameForInstalledFiles = f.partitionName()
 	}
-	installedFileTxt, installedFileJson := buildInstalledFiles(ctx, partitionName, rootDir, f.output)
 
 	var erofsCompressHints android.Path
 	if f.properties.Erofs.Compress_hints != nil {
@@ -674,15 +684,17 @@
 		BuildImagePropFileDeps: buildImagePropFileDeps,
 		SpecsForSystemOther:    f.systemOtherFiles(ctx),
 		FullInstallPaths:       fullInstallPaths,
-		InstalledFiles: InstalledFilesStruct{
-			Txt:  installedFileTxt,
-			Json: installedFileJson,
-		},
+		InstalledFilesDepSet: depset.New(
+			depset.POSTORDER,
+			[]InstalledFilesStruct{buildInstalledFiles(ctx, partitionNameForInstalledFiles, rootDir, f.output)},
+			includeFilesInstalledFiles(ctx),
+		),
 		ErofsCompressHints: erofsCompressHints,
 		SelinuxFc:          f.selinuxFc,
 		FilesystemConfig:   f.generateFilesystemConfig(ctx, rootDir, rebasedDir),
 		Owners:             f.gatherOwners(specs),
 		UseAvb:             proptools.Bool(f.properties.Use_avb),
+		HasFsverity:        f.properties.Fsverity.Inputs.GetOrDefault(ctx, nil) != nil,
 	}
 
 	android.SetProvider(ctx, FilesystemProvider, fsInfo)
@@ -698,6 +710,14 @@
 	}
 
 	f.setVbmetaPartitionProvider(ctx)
+
+	// Dump metadata that can not be done in android/compliance-metadata.go
+	complianceMetadataInfo := ctx.ComplianceMetadataInfo()
+	filesContained := make([]string, 0, len(fullInstallPaths))
+	for _, file := range fullInstallPaths {
+		filesContained = append(filesContained, file.FullInstallPath.String())
+	}
+	complianceMetadataInfo.SetFilesContained(filesContained)
 }
 
 func (f *filesystem) fileystemStagingDirTimestamp(ctx android.ModuleContext) android.WritablePath {
@@ -882,13 +902,24 @@
 		builder.Command().Text("mkdir -p").Text(filepath.Dir(dst.String()))
 		builder.Command().Text("ln -sf").Text(proptools.ShellEscape(target)).Text(dst.String())
 		f.appendToEntry(ctx, dst)
-		// Only add the fullInstallPath logic for files in the rebased dir. The root dir
-		// is harder to install to.
-		if strings.HasPrefix(name, rebasedPrefix) {
+		// Add the fullInstallPath logic for files in the rebased dir, and for non-rebased files in "system" partition
+		// the fullInstallPath is changed to "root" which aligns to the behavior in Make.
+		if f.PartitionType() == "system" {
+			installPath := android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), strings.TrimPrefix(name, rebasedPrefix))
+			if !strings.HasPrefix(name, rebasedPrefix) {
+				installPath = android.PathForModuleInPartitionInstall(ctx, "root", name)
+			}
 			*fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
-				FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), strings.TrimPrefix(name, rebasedPrefix)),
+				FullInstallPath: installPath,
 				SymlinkTarget:   target,
 			})
+		} else {
+			if strings.HasPrefix(name, rebasedPrefix) {
+				*fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{
+					FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), strings.TrimPrefix(name, rebasedPrefix)),
+					SymlinkTarget:   target,
+				})
+			}
 		}
 	}
 
@@ -1167,6 +1198,15 @@
 	return rootDirs, partitions
 }
 
+func includeFilesInstalledFiles(ctx android.ModuleContext) (ret []depset.DepSet[InstalledFilesStruct]) {
+	ctx.VisitDirectDepsWithTag(interPartitionInstallDependencyTag, func(m android.Module) {
+		if fsProvider, ok := android.OtherModuleProvider(ctx, m, FilesystemProvider); ok {
+			ret = append(ret, fsProvider.InstalledFilesDepSet)
+		}
+	})
+	return
+}
+
 func (f *filesystem) buildCpioImage(
 	ctx android.ModuleContext,
 	builder *android.RuleBuilder,
@@ -1429,7 +1469,7 @@
 
 	deps := f.gatherFilteredPackagingSpecs(ctx)
 	ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
-		if !android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoKey).Enabled {
+		if !android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoProvider).Enabled {
 			return false
 		}
 		for _, ps := range android.OtherModuleProviderOrDefault(
@@ -1450,7 +1490,7 @@
 
 	var requireModules []android.ModuleProxy
 	ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
-		if !android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoKey).Enabled {
+		if !android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoProvider).Enabled {
 			return false
 		}
 		_, parentInPackage := modulesInPackageByModule[parent]
diff --git a/filesystem/super_image.go b/filesystem/super_image.go
index 5e62fa7..8e2b532 100644
--- a/filesystem/super_image.go
+++ b/filesystem/super_image.go
@@ -80,6 +80,8 @@
 	}
 	// Whether the super image will be disted in the update package
 	Super_image_in_update_package *bool
+	// Whether a super_empty.img should be created
+	Create_super_empty *bool
 }
 
 type PartitionGroupsInfo struct {
@@ -118,6 +120,8 @@
 	SubImageInfo map[string]FilesystemInfo
 
 	DynamicPartitionsInfo android.Path
+
+	SuperEmptyImage android.Path
 }
 
 var SuperImageProvider = blueprint.NewProvider[SuperImageInfo]()
@@ -163,7 +167,7 @@
 }
 
 func (s *superImage) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	miscInfo, deps, subImageInfos := s.buildMiscInfo(ctx)
+	miscInfo, deps, subImageInfos := s.buildMiscInfo(ctx, false)
 	builder := android.NewRuleBuilder(pctx, ctx)
 	output := android.PathForModuleOut(ctx, s.installFileName())
 	lpMake := ctx.Config().HostToolPath(ctx, "lpmake")
@@ -176,20 +180,39 @@
 		Implicits(deps).
 		Output(output)
 	builder.Build("build_super_image", fmt.Sprintf("Creating super image %s", s.BaseModuleName()))
+	var superEmptyImage android.WritablePath
+	if proptools.Bool(s.properties.Create_super_empty) {
+		superEmptyImageBuilder := android.NewRuleBuilder(pctx, ctx)
+		superEmptyImage = android.PathForModuleOut(ctx, "super_empty.img")
+		superEmptyMiscInfo, superEmptyDeps, _ := s.buildMiscInfo(ctx, true)
+		if superEmptyDeps != nil {
+			ctx.ModuleErrorf("TODO: Handle additional deps when building super_empty.img")
+		}
+		superEmptyImageBuilder.Command().Textf("PATH=%s:\\$PATH", lpMakeDir).
+			BuiltTool("build_super_image").
+			Text("-v").
+			Input(superEmptyMiscInfo).
+			Implicit(lpMake).
+			Output(superEmptyImage)
+		superEmptyImageBuilder.Build("build_super_empty_image", fmt.Sprintf("Creating super empty image %s", s.BaseModuleName()))
+	}
 	android.SetProvider(ctx, SuperImageProvider, SuperImageInfo{
 		SuperImage:            output,
 		SubImageInfo:          subImageInfos,
 		DynamicPartitionsInfo: s.generateDynamicPartitionsInfo(ctx),
+		SuperEmptyImage:       superEmptyImage,
 	})
 	ctx.SetOutputFiles([]android.Path{output}, "")
 	ctx.CheckbuildFile(output)
+
+	buildComplianceMetadata(ctx, subImageDepTag)
 }
 
 func (s *superImage) installFileName() string {
 	return "super.img"
 }
 
-func (s *superImage) buildMiscInfo(ctx android.ModuleContext) (android.Path, android.Paths, map[string]FilesystemInfo) {
+func (s *superImage) buildMiscInfo(ctx android.ModuleContext, superEmpty bool) (android.Path, android.Paths, map[string]FilesystemInfo) {
 	var miscInfoString strings.Builder
 	partitionList := s.dumpDynamicPartitionInfo(ctx, &miscInfoString)
 	addStr := func(name string, value string) {
@@ -198,6 +221,12 @@
 		miscInfoString.WriteString(value)
 		miscInfoString.WriteRune('\n')
 	}
+	addStr("ab_update", strconv.FormatBool(proptools.Bool(s.properties.Ab_update)))
+	if superEmpty {
+		miscInfo := android.PathForModuleOut(ctx, "misc_info_super_empty.txt")
+		android.WriteFileRule(ctx, miscInfo, miscInfoString.String())
+		return miscInfo, nil, nil
+	}
 
 	subImageInfo := make(map[string]FilesystemInfo)
 	var deps android.Paths
@@ -297,6 +326,9 @@
 	}
 
 	addStr("build_super_partition", "true")
+	if proptools.Bool(s.properties.Create_super_empty) {
+		addStr("build_super_empty_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")
@@ -327,8 +359,6 @@
 	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) {
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index f00e491..b73fb21 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -505,6 +505,7 @@
 		}
 		fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
 		fsProps.Stem = proptools.StringPtr("system_ext.img")
+		fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
 	case "product":
 		fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
 		fsProps.Android_filesystem_deps.System = proptools.StringPtr(partitions.nameForType("system"))
@@ -853,19 +854,29 @@
 		Product_config *string
 		Android_info   *string
 		Licenses       []string
+		Dist           android.Dist
 	}{
 		Name:           proptools.StringPtr(generatedModuleName(ctx.Config(), "vendor-build.prop")),
 		Vendor:         proptools.BoolPtr(true),
 		Stem:           proptools.StringPtr("build.prop"),
 		Product_config: proptools.StringPtr(":product_config"),
 		Android_info:   proptools.StringPtr(":" + generatedModuleName(ctx.Config(), "android_info.prop")),
-		Licenses:       []string{"Android-Apache-2.0"},
+		Dist: android.Dist{
+			Targets: []string{"droidcore-unbundled"},
+			Dest:    proptools.StringPtr("build.prop-vendor"),
+		},
+		Licenses: []string{"Android-Apache-2.0"},
 	}
 	vendorBuildProp := ctx.CreateModule(
 		android.BuildPropFactory,
 		vendorBuildProps,
 	)
-	vendorBuildProp.HideFromMake()
+	// We don't want this to conflict with the make-built vendor build.prop, but unfortunately
+	// calling HideFromMake() prevents disting files, even in soong-only mode. So only call
+	// HideFromMake() on soong+make builds.
+	if ctx.Config().KatiEnabled() {
+		vendorBuildProp.HideFromMake()
+	}
 }
 
 func createRecoveryBuildProp(ctx android.LoadHookContext) string {
diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go
index 9b25e77..d34ae77 100644
--- a/fsgen/fsgen_mutators.go
+++ b/fsgen/fsgen_mutators.go
@@ -105,12 +105,14 @@
 					"libgsi":                                    defaultDepCandidateProps(ctx.Config()),
 					"llndk.libraries.txt":                       defaultDepCandidateProps(ctx.Config()),
 					"logpersist.start":                          defaultDepCandidateProps(ctx.Config()),
+					"notice_xml_system":                         defaultDepCandidateProps(ctx.Config()),
 					"update_engine_sideload":                    defaultDepCandidateProps(ctx.Config()),
 					// keep-sorted end
 				},
 				"vendor": {
 					"fs_config_files_vendor":                               defaultDepCandidateProps(ctx.Config()),
 					"fs_config_dirs_vendor":                                defaultDepCandidateProps(ctx.Config()),
+					"notice_xml_vendor":                                    defaultDepCandidateProps(ctx.Config()),
 					generatedModuleName(ctx.Config(), "vendor-build.prop"): defaultDepCandidateProps(ctx.Config()),
 				},
 				"odm": {
@@ -118,34 +120,41 @@
 					// https://cs.android.com/android/_/android/platform/build/+/e4849e87ab660b59a6501b3928693db065ee873b:tools/fs_config/Android.mk;l=34;drc=8d6481b92c4b4e9b9f31a61545b6862090fcc14b;bpv=1;bpt=0
 					"fs_config_files_odm": defaultDepCandidateProps(ctx.Config()),
 					"fs_config_dirs_odm":  defaultDepCandidateProps(ctx.Config()),
+					"notice_xml_odm":      defaultDepCandidateProps(ctx.Config()),
 				},
-				"product": {},
+				"product": {
+					"notice_xml_product": defaultDepCandidateProps(ctx.Config()),
+				},
 				"system_ext": {
 					// VNDK apexes are automatically included.
 					// This hardcoded list will need to be updated if `PRODUCT_EXTRA_VNDK_VERSIONS` is updated.
 					// https://cs.android.com/android/_/android/platform/build/+/adba533072b00c53ac0f198c550a3cbd7a00e4cd:core/main.mk;l=984;bpv=1;bpt=0;drc=174db7b179592cf07cbfd2adb0119486fda911e7
-					"com.android.vndk.v30": defaultDepCandidateProps(ctx.Config()),
-					"com.android.vndk.v31": defaultDepCandidateProps(ctx.Config()),
-					"com.android.vndk.v32": defaultDepCandidateProps(ctx.Config()),
-					"com.android.vndk.v33": defaultDepCandidateProps(ctx.Config()),
-					"com.android.vndk.v34": defaultDepCandidateProps(ctx.Config()),
+					"com.android.vndk.v30":  defaultDepCandidateProps(ctx.Config()),
+					"com.android.vndk.v31":  defaultDepCandidateProps(ctx.Config()),
+					"com.android.vndk.v32":  defaultDepCandidateProps(ctx.Config()),
+					"com.android.vndk.v33":  defaultDepCandidateProps(ctx.Config()),
+					"com.android.vndk.v34":  defaultDepCandidateProps(ctx.Config()),
+					"notice_xml_system_ext": defaultDepCandidateProps(ctx.Config()),
 				},
 				"userdata": {},
 				"system_dlkm": {
 					// these are phony required deps of the phony fs_config_dirs_nonsystem
 					"fs_config_dirs_system_dlkm":  defaultDepCandidateProps(ctx.Config()),
 					"fs_config_files_system_dlkm": defaultDepCandidateProps(ctx.Config()),
+					"notice_xml_system_dlkm":      defaultDepCandidateProps(ctx.Config()),
 					// build props are automatically added to `ALL_DEFAULT_INSTALLED_MODULES`
 					"system_dlkm-build.prop": defaultDepCandidateProps(ctx.Config()),
 				},
 				"vendor_dlkm": {
 					"fs_config_dirs_vendor_dlkm":  defaultDepCandidateProps(ctx.Config()),
 					"fs_config_files_vendor_dlkm": defaultDepCandidateProps(ctx.Config()),
+					"notice_xml_vendor_dlkm":      defaultDepCandidateProps(ctx.Config()),
 					"vendor_dlkm-build.prop":      defaultDepCandidateProps(ctx.Config()),
 				},
 				"odm_dlkm": {
 					"fs_config_dirs_odm_dlkm":  defaultDepCandidateProps(ctx.Config()),
 					"fs_config_files_odm_dlkm": defaultDepCandidateProps(ctx.Config()),
+					"notice_xml_odm_dlkm":      defaultDepCandidateProps(ctx.Config()),
 					"odm_dlkm-build.prop":      defaultDepCandidateProps(ctx.Config()),
 				},
 				"ramdisk":        {},
diff --git a/fsgen/prebuilt_etc_modules_gen.go b/fsgen/prebuilt_etc_modules_gen.go
index e028b1d..2025c91 100644
--- a/fsgen/prebuilt_etc_modules_gen.go
+++ b/fsgen/prebuilt_etc_modules_gen.go
@@ -199,6 +199,7 @@
 		"etc/dsp":             etc.PrebuiltDSPFactory,
 		"etc/firmware":        etc.PrebuiltFirmwareFactory,
 		"firmware":            etc.PrebuiltFirmwareFactory,
+		"gpu":                 etc.PrebuiltGPUFactory,
 		"first_stage_ramdisk": etc.PrebuiltFirstStageRamdiskFactory,
 		"fonts":               etc.PrebuiltFontFactory,
 		"framework":           etc.PrebuiltFrameworkFactory,
@@ -210,6 +211,7 @@
 		"optee":               etc.PrebuiltOpteeFactory,
 		"overlay":             etc.PrebuiltOverlayFactory,
 		"priv-app":            etc.PrebuiltPrivAppFactory,
+		"radio":               etc.PrebuiltRadioFactory,
 		"sbin":                etc.PrebuiltSbinFactory,
 		"system":              etc.PrebuiltSystemFactory,
 		"res":                 etc.PrebuiltResFactory,
diff --git a/fsgen/super_img.go b/fsgen/super_img.go
index f564636..1d610f6 100644
--- a/fsgen/super_img.go
+++ b/fsgen/super_img.go
@@ -46,6 +46,7 @@
 		Retrofit:                      proptools.BoolPtr(partitionVars.ProductRetrofitDynamicPartitions),
 		Use_dynamic_partitions:        proptools.BoolPtr(partitionVars.ProductUseDynamicPartitions),
 		Super_image_in_update_package: proptools.BoolPtr(partitionVars.BoardSuperImageInUpdatePackage),
+		Create_super_empty:            proptools.BoolPtr(partitionVars.BuildingSuperEmptyImage),
 	}
 	if partitionVars.ProductVirtualAbOta {
 		superImageProps.Virtual_ab.Enable = proptools.BoolPtr(true)
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 6bd1fcc..e976e6b 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -113,7 +113,7 @@
 func (t hostToolDependencyTag) AllowDisabledModuleDependencyProxy(
 	ctx android.OtherModuleProviderContext, target android.ModuleProxy) bool {
 	return android.OtherModuleProviderOrDefault(
-		ctx, target, android.CommonModuleInfoKey).ReplacedByPrebuilt
+		ctx, target, android.CommonModuleInfoProvider).ReplacedByPrebuilt
 }
 
 var _ android.AllowDisabledModuleDependency = (*hostToolDependencyTag)(nil)
@@ -353,7 +353,7 @@
 				if h, ok := android.OtherModuleProvider(ctx, module, android.HostToolProviderInfoProvider); ok {
 					// A HostToolProvider provides the path to a tool, which will be copied
 					// into the sandbox.
-					if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
+					if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
 						if ctx.Config().AllowMissingDependencies() {
 							ctx.AddMissingDependencies([]string{tool})
 						} else {
diff --git a/java/Android.bp b/java/Android.bp
index 911af83..99d9c38 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -78,6 +78,7 @@
         "system_modules.go",
         "systemserver_classpath_fragment.go",
         "testing.go",
+        "tracereferences.go",
         "tradefed.go",
     ],
     testSrcs: [
diff --git a/java/app.go b/java/app.go
index fe5eec3..560129b 100644
--- a/java/app.go
+++ b/java/app.go
@@ -425,6 +425,10 @@
 	} else {
 		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
 	}
+
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: a.appTestHelperAppProperties.Test_suites,
+	})
 }
 
 func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -531,7 +535,7 @@
 		if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); !ok {
 			panic(fmt.Errorf("jni dependency is not a cc module: %v", m))
 		}
-		commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoKey)
+		commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoProvider)
 		if !ok {
 			panic(fmt.Errorf("jni dependency doesn't have CommonModuleInfo provider: %v", m))
 		}
@@ -1229,7 +1233,7 @@
 	seenModulePaths := make(map[string]bool)
 
 	ctx.WalkDepsProxy(func(module, parent android.ModuleProxy) bool {
-		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
 			return false
 		}
 		otherName := ctx.OtherModuleName(module)
@@ -1249,7 +1253,7 @@
 					}
 					seenModulePaths[path.String()] = true
 
-					commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey)
+					commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider)
 					if checkNativeSdkVersion && commonInfo.SdkVersion == "" {
 						ctx.PropertyErrorf("jni_libs", "JNI dependency %q uses platform APIs, but this module does not",
 							otherName)
@@ -1287,13 +1291,13 @@
 }
 
 func (a *AndroidApp) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) {
-	ctx.WalkDeps(func(child, parent android.Module) bool {
+	ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
 		// TODO(ccross): Should this use android.DepIsInSameApex?  Right now it is applying the android app
 		// heuristics to every transitive dependency, when it should probably be using the heuristics of the
 		// immediate parent.
 		isExternal := !a.GetDepInSameApexChecker().OutgoingDepIsInSameApex(ctx.OtherModuleDependencyTag(child))
-		if am, ok := child.(android.ApexModule); ok {
-			if !do(ctx, parent, am, isExternal) {
+		if am, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); ok && am.IsApexModule {
+			if !do(ctx, parent, child, isExternal) {
 				return false
 			}
 		}
@@ -1307,12 +1311,12 @@
 	}
 
 	depsInfo := android.DepNameToDepInfoMap{}
-	a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool {
+	a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
 		depName := to.Name()
 
 		// Skip dependencies that are only available to APEXes; they are developed with updatability
 		// in mind and don't need manual approval.
-		if android.OtherModuleProviderOrDefault(ctx, to, android.CommonModuleInfoKey).NotAvailableForPlatform {
+		if android.OtherModuleProviderOrDefault(ctx, to, android.CommonModuleInfoProvider).NotAvailableForPlatform {
 			return true
 		}
 
@@ -1322,7 +1326,7 @@
 			depsInfo[depName] = info
 		} else {
 			toMinSdkVersion := "(no version)"
-			if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoKey); ok &&
+			if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoProvider); ok &&
 				!info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil {
 				toMinSdkVersion = info.MinSdkVersion.ApiLevel.String()
 			}
@@ -1703,6 +1707,10 @@
 		moduleInfoJSON.AutoTestConfig = []string{"true"}
 	}
 	moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...)
+
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: a.testProperties.Test_suites,
+	})
 }
 
 func testcaseRel(paths android.Paths) []string {
@@ -2209,3 +2217,7 @@
 	appInfo.Certificate = m.Certificate()
 	appInfo.PrivAppAllowlist = m.PrivAppAllowlist()
 }
+
+type AppInfos []AppInfo
+
+var AppInfosProvider = blueprint.NewProvider[AppInfos]()
diff --git a/java/app_import.go b/java/app_import.go
index 37c673c..b9e91cd 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -787,6 +787,10 @@
 	a.updateModuleInfoJSON(ctx)
 
 	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
+
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: a.testProperties.Test_suites,
+	})
 }
 
 func (a *AndroidTestImport) updateModuleInfoJSON(ctx android.ModuleContext) {
diff --git a/java/base.go b/java/base.go
index 0833831..8453a68 100644
--- a/java/base.go
+++ b/java/base.go
@@ -629,7 +629,7 @@
 			return nil
 		}
 		if info.SdkVersion.Kind == android.SdkCorePlatform {
-			if useLegacyCorePlatformApi(ctx, android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).BaseModuleName) {
+			if useLegacyCorePlatformApi(ctx, android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).BaseModuleName) {
 				return fmt.Errorf("non stable SDK %v - uses legacy core platform", info.SdkVersion)
 			} else {
 				// Treat stable core platform as stable.
@@ -888,6 +888,10 @@
 	// Add dependency on libraries that provide additional hidden api annotations.
 	ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...)
 
+	// Add dependency on (soft) downstream libs from which to trace references during optimization.
+	traceRefs := j.dexProperties.Optimize.Trace_references_from.GetOrDefault(ctx, []string{})
+	ctx.AddVariationDependencies(nil, traceReferencesTag, traceRefs...)
+
 	// For library dependencies that are component libraries (like stubs), add the implementation
 	// as a dependency (dexpreopt needs to be against the implementation library, not stubs).
 	for _, dep := range libDeps {
diff --git a/java/config/config.go b/java/config/config.go
index 71025de..fdb8d78 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -173,6 +173,7 @@
 	pctx.HostBinToolVariable("R8Cmd", "r8")
 	pctx.HostBinToolVariable("ExtractR8RulesCmd", "extract-r8-rules")
 	pctx.HostBinToolVariable("ResourceShrinkerCmd", "resourceshrinker")
+	pctx.HostBinToolVariable("TraceReferencesCmd", "tracereferences")
 	pctx.HostBinToolVariable("HiddenAPICmd", "hiddenapi")
 	pctx.HostBinToolVariable("ExtractApksCmd", "extract_apks")
 	pctx.VariableFunc("TurbineJar", func(ctx android.PackageVarContext) string {
diff --git a/java/dex.go b/java/dex.go
index ed2df21..ed9c82b 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -103,6 +103,34 @@
 		// If true, transitive reverse dependencies of this module will have this
 		// module's proguard spec appended to their optimization action
 		Export_proguard_flags_files *bool
+
+		// Path to a file containing a list of class names that should not be compiled using R8.
+		// These classes will be compiled by D8 similar to when Optimize.Enabled is false.
+		//
+		// Example:
+		//
+		//   r8.exclude:
+		//   com.example.Foo
+		//   com.example.Bar
+		//   com.example.Bar$Baz
+		//
+		// By default all classes are compiled using R8 when Optimize.Enabled is set.
+		Exclude *string `android:"path"`
+
+		// Optional list of downstream (Java) libraries from which to trace and preserve references
+		// when optimizing. Note that this requires that the source reference does *not* have
+		// a strict lib dependency on this target; dependencies should be on intermediate targets
+		// statically linked into this target, e.g., if A references B, and we want to trace and
+		// keep references from A when optimizing B, you would create an intermediate B.impl (
+		// containing all static code), have A depend on `B.impl` via libs, and set
+		// `trace_references_from: ["A"]` on B.
+		//
+		// Also note that these are *not* inherited across targets, they must be specified at the
+		// top-level target that is optimized.
+		//
+		// TODO(b/212737576): Handle this implicitly using bottom-up deps mutation and implicit
+		// creation of a proxy `.impl` library.
+		Trace_references_from proptools.Configurable[[]string] `android:"arch_variant"`
 	}
 
 	// Keep the data uncompressed. We always need uncompressed dex for execution,
@@ -445,6 +473,20 @@
 
 	flagFiles = append(flagFiles, android.PathsForModuleSrc(ctx, opt.Proguard_flags_files)...)
 
+	traceReferencesSources := android.Paths{}
+	ctx.VisitDirectDepsProxyWithTag(traceReferencesTag, func(m android.ModuleProxy) {
+		if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+			traceReferencesSources = append(traceReferencesSources, dep.ImplementationJars...)
+		}
+	})
+	if len(traceReferencesSources) > 0 {
+		traceTarget := dexParams.classesJar
+		traceLibs := android.FirstUniquePaths(append(flags.bootClasspath.Paths(), flags.dexClasspath.Paths()...))
+		traceReferencesFlags := android.PathForModuleOut(ctx, "proguard", "trace_references.flags")
+		TraceReferences(ctx, traceReferencesSources, traceTarget, traceLibs, traceReferencesFlags)
+		flagFiles = append(flagFiles, traceReferencesFlags)
+	}
+
 	flagFiles = android.FirstUniquePaths(flagFiles)
 
 	r8Flags = append(r8Flags, android.JoinWithPrefix(flagFiles.Strings(), "-include "))
@@ -528,6 +570,11 @@
 		r8Flags = append(r8Flags, "--store-store-fence-constructor-inlining")
 	}
 
+	if opt.Exclude != nil {
+		r8Flags = append(r8Flags, "--exclude", *opt.Exclude)
+		r8Deps = append(r8Deps, android.PathForModuleSrc(ctx, *opt.Exclude))
+	}
+
 	return r8Flags, r8Deps, artProfileOutput
 }
 
diff --git a/java/dex_test.go b/java/dex_test.go
index 66d801d..e94864b 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -866,3 +866,46 @@
 		})
 	}
 }
+
+func TestTraceReferences(t *testing.T) {
+	t.Parallel()
+	bp := `
+		android_app {
+			name: "app",
+			libs: ["lib.impl"],
+			srcs: ["foo.java"],
+			platform_apis: true,
+		}
+
+		java_library {
+			name: "lib",
+			optimize: {
+				enabled: true,
+				trace_references_from: ["app"],
+			},
+			srcs: ["bar.java"],
+			static_libs: ["lib.impl"],
+			installable: true,
+		}
+
+		java_library {
+			name: "lib.impl",
+			srcs: ["baz.java"],
+		}
+	`
+	result := android.GroupFixturePreparers(
+		PrepareForTestWithJavaDefaultModules,
+	).RunTestWithBp(t, bp)
+
+	appJar := result.ModuleForTests(t, "app", "android_common").Output("combined/app.jar").Output
+	libJar := result.ModuleForTests(t, "lib", "android_common").Output("combined/lib.jar").Output
+	libTraceRefs := result.ModuleForTests(t, "lib", "android_common").Rule("traceReferences")
+	libR8 := result.ModuleForTests(t, "lib", "android_common").Rule("r8")
+
+	android.AssertStringDoesContain(t, "expected trace reference source from app jar",
+		libTraceRefs.Args["sources"], "--source "+appJar.String())
+	android.AssertStringEquals(t, "expected trace reference target into lib jar",
+		libJar.String(), libTraceRefs.Input.String())
+	android.AssertStringDoesContain(t, "expected trace reference proguard flags in lib r8 flags",
+		libR8.Args["r8Flags"], "trace_references.flags")
+}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index b21cfc9..e8e1cd4 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -650,6 +650,9 @@
 		// for now just exclude any known irrelevant dependencies that would lead to incorrect errors.
 		if _, ok := tag.(bootclasspathDependencyTag); ok {
 			return false
+		} else if tag == traceReferencesTag {
+			// Allow ordering inversion if the dependency is purely for tracing references.
+			return false
 		}
 		depIndex := jars.IndexOfJar(dep.Name())
 		if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
diff --git a/java/dexpreopt_check.go b/java/dexpreopt_check.go
index c971565..9d0f539 100644
--- a/java/dexpreopt_check.go
+++ b/java/dexpreopt_check.go
@@ -100,7 +100,12 @@
 		if systemServerJar.InstallInSystemExt() && ctx.Config().InstallApexSystemServerDexpreoptSamePartition() {
 			partition = ctx.DeviceConfig().SystemExtPath() // system_ext
 		}
-		dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, systemServerJar.Name())
+		var dexLocation string
+		if m, ok := systemServerJar.(ModuleWithStem); ok {
+			dexLocation = dexpreopt.GetSystemServerDexLocation(ctx, global, m.Stem())
+		} else {
+			ctx.PropertyErrorf("dexpreopt_systemserver_check", "%v is not a ModuleWithStem", systemServerJar.Name())
+		}
 		odexLocation := dexpreopt.ToOdexPath(dexLocation, targets[0].Arch.ArchType, partition)
 		odexPath := getInstallPath(ctx, odexLocation)
 		vdexPath := getInstallPath(ctx, pathtools.ReplaceExtension(odexLocation, "vdex"))
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 225f201..3faf294 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -195,6 +195,9 @@
 				"them instead.")
 		}
 		return false
+	} else if ctx.Config().PartialCompileFlags().Disable_stub_validation &&
+		!ctx.Config().BuildFromTextStub() {
+		return false
 	} else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
 		return true
 	} else if String(apiToCheck.Api_file) != "" {
diff --git a/java/droidstubs.go b/java/droidstubs.go
index b3241cc..c215925 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -1243,7 +1243,7 @@
 
 	// Add options for the other optional tasks: API-lint and check-released.
 	// We generate separate timestamp files for them.
-	doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false)
+	doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().PartialCompileFlags().Disable_api_lint
 	doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released")
 
 	writeSdkValues := Bool(d.properties.Write_sdk_values)
diff --git a/java/java.go b/java/java.go
index c1e4f8c..7f897a0 100644
--- a/java/java.go
+++ b/java/java.go
@@ -578,6 +578,7 @@
 	extraLintCheckTag       = dependencyTag{name: "extra-lint-check", toolchain: true}
 	jniLibTag               = dependencyTag{name: "jnilib", runtimeLinked: true}
 	r8LibraryJarTag         = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
+	traceReferencesTag      = dependencyTag{name: "trace-references"}
 	syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
 	javaApiContributionTag  = dependencyTag{name: "java-api-contribution"}
 	aconfigDeclarationTag   = dependencyTag{name: "aconfig-declaration"}
@@ -608,6 +609,7 @@
 		kotlinPluginTag,
 		syspropPublicStubDepTag,
 		instrumentationForTag,
+		traceReferencesTag,
 	}
 )
 
@@ -1954,6 +1956,10 @@
 			ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile)
 		}
 	}
+
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: j.testProperties.Test_suites,
+	})
 }
 
 func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1970,6 +1976,10 @@
 	if optionalConfig.Valid() {
 		moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String())
 	}
+
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: j.testHelperLibraryProperties.Test_suites,
+	})
 }
 
 func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -2225,7 +2235,7 @@
 	// install these alongside the java binary.
 	ctx.VisitDirectDepsProxyWithTag(jniInstallTag, func(jni android.ModuleProxy) {
 		// Use the BaseModuleName of the dependency (without any prebuilt_ prefix)
-		commonInfo, _ := android.OtherModuleProvider(ctx, jni, android.CommonModuleInfoKey)
+		commonInfo, _ := android.OtherModuleProvider(ctx, jni, android.CommonModuleInfoProvider)
 		j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, commonInfo.BaseModuleName+":"+commonInfo.Target.Arch.ArchType.Bitness())
 	})
 	// Check that native libraries are not listed in `required`. Prompt users to use `jni_libs` instead.
@@ -2530,6 +2540,7 @@
 	apiContributions := al.properties.Api_contributions
 	addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") &&
 		!ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") &&
+		!ctx.Config().PartialCompileFlags().Disable_stub_validation &&
 		proptools.BoolDefault(al.properties.Enable_validation, true)
 	for _, apiContributionName := range apiContributions {
 		ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName)
diff --git a/java/java_test.go b/java/java_test.go
index 6df81e5..1ba78d4 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -3193,3 +3193,72 @@
 	deps := findDepsOfModule(res, res.ModuleForTests(t, "myjavabin", "android_common").Module(), "mynativelib")
 	android.AssertIntEquals(t, "Create a dep on the first variant", 1, len(deps))
 }
+
+func TestBootJarNotInUsesLibs(t *testing.T) {
+	t.Parallel()
+	result := android.GroupFixturePreparers(
+		PrepareForTestWithJavaDefaultModules,
+		PrepareForTestWithJavaSdkLibraryFiles,
+		FixtureWithLastReleaseApis("mysdklibrary", "myothersdklibrary"),
+		FixtureConfigureApexBootJars("myapex:mysdklibrary"),
+	).RunTestWithBp(t, `
+		bootclasspath_fragment {
+			name: "myfragment",
+			contents: ["mysdklibrary"],
+			hidden_api: {
+				split_packages: ["*"],
+			},
+		}
+
+		java_sdk_library {
+			name: "mysdklibrary",
+			srcs: ["Test.java"],
+			compile_dex: true,
+			public: {enabled: true},
+			min_sdk_version: "2",
+			permitted_packages: ["mysdklibrary"],
+			sdk_version: "current",
+		}
+
+		java_sdk_library {
+			name: "myothersdklibrary",
+			srcs: ["Test.java"],
+			compile_dex: true,
+			public: {enabled: true},
+			min_sdk_version: "2",
+			permitted_packages: ["myothersdklibrary"],
+			sdk_version: "current",
+		}
+
+		java_library {
+			name: "foo",
+			libs: [
+				"bar",
+				"mysdklibrary.stubs",
+			],
+			srcs: ["A.java"],
+		}
+
+		java_library {
+			name: "bar",
+			libs: [
+				"myothersdklibrary.stubs"
+			],
+		}
+	`)
+	ctx := result.TestContext
+	fooModule := ctx.ModuleForTests(t, "foo", "android_common")
+
+	androidMkEntries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0]
+	localExportSdkLibraries := androidMkEntries.EntryMap["LOCAL_EXPORT_SDK_LIBRARIES"]
+	android.AssertStringListDoesNotContain(t,
+		"boot jar should not be included in uses libs entries",
+		localExportSdkLibraries,
+		"mysdklibrary",
+	)
+	android.AssertStringListContains(t,
+		"non boot jar is included in uses libs entries",
+		localExportSdkLibraries,
+		"myothersdklibrary",
+	)
+}
diff --git a/java/jdeps.go b/java/jdeps.go
index 4711dc1..7ef6c89 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -46,7 +46,7 @@
 	moduleInfos := make(map[string]android.IdeInfo)
 
 	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
-		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
 			return
 		}
 
diff --git a/java/lint.go b/java/lint.go
index c31dfd0..61b50dc 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -659,7 +659,7 @@
 	var outputs []*LintInfo
 	var dirs []string
 	ctx.VisitAllModuleProxies(func(m android.ModuleProxy) {
-		commonInfo, _ := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoKey)
+		commonInfo, _ := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoProvider)
 		if ctx.Config().KatiEnabled() && !commonInfo.ExportedToMake {
 			return
 		}
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index ab4f8f8..b2d6ca1 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -277,7 +277,7 @@
 	var compatConfigMetadata android.Paths
 
 	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
-		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
 			return
 		}
 		if c, ok := android.OtherModuleProvider(ctx, module, PlatformCompatConfigMetadataInfoProvider); ok {
diff --git a/java/rro.go b/java/rro.go
index b3d9348..42d42b8 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -427,6 +427,11 @@
 	// Install the signed apk
 	installDir := android.PathForModuleInstall(ctx, "overlay")
 	ctx.InstallFile(installDir, signed.Base(), signed)
+
+	android.SetProvider(ctx, RuntimeResourceOverlayInfoProvider, RuntimeResourceOverlayInfo{
+		OutputFile:  signed,
+		Certificate: a.certificate,
+	})
 }
 
 func (a *AutogenRuntimeResourceOverlay) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 0fee529..00ba8b2 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1337,10 +1337,10 @@
 
 func CheckMinSdkVersion(ctx android.ModuleContext, module *Library) {
 	android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx), func(c android.BaseModuleContext, do android.PayloadDepsCallback) {
-		ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
+		ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
 			isExternal := !android.IsDepInSameApex(ctx, module, child)
-			if am, ok := child.(android.ApexModule); ok {
-				if !do(ctx, parent, am, isExternal) {
+			if am, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); ok && am.IsApexModule {
+				if !do(ctx, parent, child, isExternal) {
 					return false
 				}
 			}
diff --git a/java/testing.go b/java/testing.go
index 3abbb84..d7878d6 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -424,7 +424,6 @@
 		"kotlin-stdlib-jdk8",
 		"kotlin-annotations",
 		"stub-annotations",
-
 		"aconfig-annotations-lib",
 		"aconfig_storage_stub",
 		"unsupportedappusage",
diff --git a/java/tracereferences.go b/java/tracereferences.go
new file mode 100644
index 0000000..342b6a6
--- /dev/null
+++ b/java/tracereferences.go
@@ -0,0 +1,54 @@
+// Copyright 2025 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+	"android/soong/android"
+
+	"github.com/google/blueprint"
+)
+
+var traceReferences = pctx.AndroidStaticRule("traceReferences",
+	blueprint.RuleParams{
+		Command: `${config.TraceReferencesCmd} ` +
+			// Note that we suppress missing def errors, as we're only interested
+			// in the direct deps between the sources and target.
+			`--map-diagnostics:MissingDefinitionsDiagnostic error none ` +
+			`--keep-rules ` +
+			`--output ${out} ` +
+			`--target ${in} ` +
+			// `--source` and `--lib` are already prepended to each
+			// jar reference in the sources and libs joined string args.
+			`${sources} ` +
+			`${libs}`,
+		CommandDeps: []string{"${config.TraceReferencesCmd}"},
+	}, "sources", "libs")
+
+// Generates keep rules in output corresponding to any references from sources
+// (a list of jars) onto target (the referenced jar) that are not included in
+// libs (a list of external jars).
+func TraceReferences(ctx android.ModuleContext, sources android.Paths, target android.Path, libs android.Paths,
+	output android.WritablePath) {
+	ctx.Build(pctx, android.BuildParams{
+		Rule:      traceReferences,
+		Input:     target,
+		Output:    output,
+		Implicits: append(sources, libs...),
+		Args: map[string]string{
+			"sources": android.JoinWithPrefix(sources.Strings(), "--source "),
+			"libs":    android.JoinWithPrefix(libs.Strings(), "--lib "),
+		},
+	})
+}
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 43fe8aa..d117c52 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -127,7 +127,7 @@
 	for _, m := range requireModules {
 		if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); ok {
 			if android.OtherModuleProviderOrDefault(ctx, m, cc.LinkableInfoProvider).HasStubsVariants &&
-				!android.OtherModuleProviderOrDefault(ctx, m, android.CommonModuleInfoKey).Host {
+				!android.OtherModuleProviderOrDefault(ctx, m, android.CommonModuleInfoProvider).Host {
 				name := ctx.OtherModuleName(m)
 				if ccInfo, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); ok && ccInfo.LinkerInfo != nil && ccInfo.LinkerInfo.ImplementationModuleName != nil {
 					name = *ccInfo.LinkerInfo.ImplementationModuleName
diff --git a/phony/phony.go b/phony/phony.go
index 4f61c45..e75f4c8 100644
--- a/phony/phony.go
+++ b/phony/phony.go
@@ -104,8 +104,7 @@
 	android.ModuleBase
 	android.DefaultableModuleBase
 
-	phonyDepsModuleNames []string
-	properties           PhonyProperties
+	properties PhonyProperties
 }
 
 type PhonyProperties struct {
@@ -126,18 +125,8 @@
 }
 
 func (p *PhonyRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	p.phonyDepsModuleNames = p.properties.Phony_deps.GetOrDefault(ctx, nil)
-}
-
-func (p *PhonyRule) AndroidMk() android.AndroidMkData {
-	return android.AndroidMkData{
-		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
-			if len(p.phonyDepsModuleNames) > 0 {
-				depModulesStr := strings.Join(p.phonyDepsModuleNames, " ")
-				fmt.Fprintln(w, ".PHONY:", name)
-				fmt.Fprintln(w, name, ":", depModulesStr)
-			}
-		},
+	for _, dep := range p.properties.Phony_deps.GetOrDefault(ctx, nil) {
+		ctx.Phony(ctx.ModuleName(), android.PathForPhony(ctx, dep))
 	}
 }
 
diff --git a/python/binary.go b/python/binary.go
index feac72a..af7d30f 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -159,6 +159,10 @@
 		sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep))
 	}
 	p.androidMkSharedLibs = sharedLibs
+
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: p.binaryProperties.Test_suites,
+	})
 }
 
 func (p *PythonBinaryModule) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/python/python.go b/python/python.go
index f8f4165..10c11ad 100644
--- a/python/python.go
+++ b/python/python.go
@@ -400,8 +400,7 @@
 
 	// generate the zipfile of all source and data files
 	p.srcsZip = p.createSrcsZip(ctx, pkgPath)
-	// TODO(b/388344853): precompilation temporarily disabled for python3.13 upgrade
-	p.precompiledSrcsZip = p.srcsZip //p.precompileSrcs(ctx)
+	p.precompiledSrcsZip = p.precompileSrcs(ctx)
 
 	android.SetProvider(ctx, PythonLibraryInfoProvider, PythonLibraryInfo{
 		SrcsPathMappings:   p.getSrcsPathMappings(),
diff --git a/rust/benchmark.go b/rust/benchmark.go
index daba964..3aa2f17 100644
--- a/rust/benchmark.go
+++ b/rust/benchmark.go
@@ -146,4 +146,8 @@
 	} else {
 		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
 	}
+
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: benchmark.Properties.Test_suites,
+	})
 }
diff --git a/rust/doc.go b/rust/doc.go
index fe20523..cf2f8b3 100644
--- a/rust/doc.go
+++ b/rust/doc.go
@@ -37,14 +37,14 @@
 		FlagWithArg("-C ", docDir.String()).
 		FlagWithArg("-D ", docDir.String())
 
-	ctx.VisitAllModules(func(module android.Module) {
-		if !module.Enabled(ctx) {
+	ctx.VisitAllModuleProxies(func(module android.ModuleProxy) {
+		if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled {
 			return
 		}
 
-		if m, ok := module.(*Module); ok {
-			if m.docTimestampFile.Valid() {
-				zipCmd.Implicit(m.docTimestampFile.Path())
+		if m, ok := android.OtherModuleProvider(ctx, module, RustInfoProvider); ok {
+			if m.DocTimestampFile.Valid() {
+				zipCmd.Implicit(m.DocTimestampFile.Path())
 			}
 		}
 	})
diff --git a/rust/rust.go b/rust/rust.go
index d8a0444..5f3d7a9 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -61,6 +61,7 @@
 	SnapshotInfo                  *cc.SnapshotInfo
 	SourceProviderInfo            *SourceProviderInfo
 	XrefRustFiles                 android.Paths
+	DocTimestampFile              android.OptionalPath
 }
 
 var RustInfoProvider = blueprint.NewProvider[*RustInfo]()
@@ -1173,6 +1174,7 @@
 		RustSubName:                   mod.Properties.RustSubName,
 		TransitiveAndroidMkSharedLibs: mod.transitiveAndroidMkSharedLibs,
 		XrefRustFiles:                 mod.XrefRustFiles(),
+		DocTimestampFile:              mod.docTimestampFile,
 	}
 	if mod.compiler != nil {
 		rustInfo.CompilerInfo = &CompilerInfo{
@@ -1478,7 +1480,7 @@
 		rustInfo, hasRustInfo := android.OtherModuleProvider(ctx, dep, RustInfoProvider)
 		ccInfo, _ := android.OtherModuleProvider(ctx, dep, cc.CcInfoProvider)
 		linkableInfo, hasLinkableInfo := android.OtherModuleProvider(ctx, dep, cc.LinkableInfoProvider)
-		commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey)
+		commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoProvider)
 		if hasRustInfo && !linkableInfo.Static && !linkableInfo.Shared {
 			//Handle Rust Modules
 			makeLibName := rustMakeLibName(rustInfo, linkableInfo, &commonInfo, depName+rustInfo.RustSubName)
diff --git a/rust/test.go b/rust/test.go
index 9833ffd..2fed0d6 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -165,7 +165,7 @@
 		if linkableDep.OutputFile.Valid() {
 			// Copy the output in "lib[64]" so that it's compatible with
 			// the default rpath values.
-			commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey)
+			commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoProvider)
 			libDir := "lib"
 			if commonInfo.Target.Arch.ArchType.Multilib == "lib64" {
 				libDir = "lib64"
@@ -242,6 +242,10 @@
 		flags.RustFlags = append(flags.RustFlags, "-Z panic_abort_tests")
 	}
 
+	// Add a default rpath to allow tests to dlopen libraries specified in data_libs.
+	flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, `-Wl,-rpath,\$$ORIGIN/lib64`)
+	flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, `-Wl,-rpath,\$$ORIGIN/lib`)
+
 	return flags
 }
 
@@ -316,6 +320,10 @@
 	} else {
 		moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite")
 	}
+
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: test.Properties.Test_suites,
+	})
 }
 
 func rustTestHostMultilib(ctx android.LoadHookContext) {
diff --git a/scripts/gen_build_prop.py b/scripts/gen_build_prop.py
index 74befd5..a0d2546 100644
--- a/scripts/gen_build_prop.py
+++ b/scripts/gen_build_prop.py
@@ -113,6 +113,7 @@
   print("####################################")
 
   config = args.config
+  build_flags = config["BuildFlags"]
   partition = args.partition
 
   if partition == "system":
@@ -164,6 +165,7 @@
   print(f"ro.{partition}.build.version.release={config['Platform_version_last_stable']}")
   print(f"ro.{partition}.build.version.release_or_codename={config['Platform_version_name']}")
   print(f"ro.{partition}.build.version.sdk={config['Platform_sdk_version']}")
+  print(f"ro.{partition}.build.version.sdk_minor={build_flags['RELEASE_PLATFORM_SDK_MINOR_VERSION']}")
 
 def generate_build_info(args):
   print()
@@ -196,6 +198,7 @@
     print(f"ro.build.display.id?={config['BuildDesc']}")
   print(f"ro.build.version.incremental={config['BuildNumber']}")
   print(f"ro.build.version.sdk={config['Platform_sdk_version']}")
+  print(f"ro.build.version.sdk_minor={build_flags['RELEASE_PLATFORM_SDK_MINOR_VERSION']}")
   print(f"ro.build.version.preview_sdk={config['Platform_preview_sdk_version']}")
   print(f"ro.build.version.preview_sdk_fingerprint={config['PlatformPreviewSdkFingerprint']}")
   print(f"ro.build.version.codename={config['Platform_sdk_codename']}")
diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py
index 175451e..96dc5a6 100755
--- a/scripts/manifest_check.py
+++ b/scripts/manifest_check.py
@@ -132,7 +132,7 @@
 
     #pylint: disable=line-too-long
     errmsg = ''.join([
-        'mismatch in the <uses-library> tags between the build system and the '
+        'mismatch or misordering in the <uses-library> tags between the build system and the '
         'manifest:\n',
         '\t- required libraries in build system: %s[%s]%s\n' % (C_RED, ', '.join(required), C_OFF),
         '\t                 vs. in the manifest: %s[%s]%s\n' % (C_RED, ', '.join(manifest_required), C_OFF),
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index d00c056..7041642 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -510,7 +510,7 @@
 				// so that it's compatible with the default rpath values.
 				var relPath string
 				linkableInfo := android.OtherModuleProviderOrDefault(ctx, dep, cc.LinkableInfoProvider)
-				commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey)
+				commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoProvider)
 
 				if commonInfo.Target.Arch.ArchType.Multilib == "lib64" {
 					relPath = filepath.Join("lib64", linkableInfo.OutputFile.Path().Base())
@@ -574,6 +574,10 @@
 		moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String())
 	}
 	moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...)
+
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: s.testProperties.Test_suites,
+	})
 }
 
 func addArch(archType string, paths android.Paths) []string {
diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go
index 6dd48eb..2b34128 100644
--- a/tradefed_modules/test_module_config.go
+++ b/tradefed_modules/test_module_config.go
@@ -426,6 +426,10 @@
 		LocalCertificate:        m.provider.LocalCertificate,
 		IsUnitTest:              m.provider.IsUnitTest,
 	})
+
+	android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{
+		TestSuites: m.tradefedProperties.Test_suites,
+	})
 }
 
 var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil)