Merge "Clean environment variables to account for sandbox work directory." into main
diff --git a/android/Android.bp b/android/Android.bp
index 96e8133..78eca11 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -41,6 +41,7 @@
         "build_prop.go",
         "compliance_metadata.go",
         "config.go",
+        "container_violations.go",
         "container.go",
         "test_config.go",
         "configurable_properties.go",
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index f0675dd..6bfbf37 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -136,7 +136,7 @@
 			AconfigFiles: mergedAconfigFiles,
 			ModeInfos:    mergedModeInfos,
 		})
-		ctx.Module().base().aconfigFilePaths = getAconfigFilePaths(ctx.Module().base(), mergedAconfigFiles)
+		ctx.setAconfigPaths(getAconfigFilePaths(ctx.Module().base(), mergedAconfigFiles))
 	}
 }
 
diff --git a/android/androidmk.go b/android/androidmk.go
index 081bca9..68a6415 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -157,6 +157,7 @@
 }
 
 type AndroidMkEntriesContext interface {
+	OtherModuleProviderContext
 	Config() Config
 }
 
@@ -354,14 +355,15 @@
 		availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
 	}
 
+	info := OtherModuleProviderOrDefault(a.entryContext, mod, InstallFilesProvider)
 	// If the distFiles created by GenerateTaggedDistFiles contains paths for the
 	// DefaultDistTag then that takes priority so delete any existing paths.
-	if _, ok := amod.distFiles[DefaultDistTag]; ok {
+	if _, ok := info.DistFiles[DefaultDistTag]; ok {
 		delete(availableTaggedDists, DefaultDistTag)
 	}
 
 	// Finally, merge the distFiles created by GenerateTaggedDistFiles.
-	availableTaggedDists = availableTaggedDists.merge(amod.distFiles)
+	availableTaggedDists = availableTaggedDists.merge(info.DistFiles)
 
 	if len(availableTaggedDists) == 0 {
 		// Nothing dist-able for this module.
@@ -372,7 +374,7 @@
 	distContributions := &distContributions{}
 
 	if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) {
-		distContributions.licenseMetadataFile = amod.licenseMetadataFile
+		distContributions.licenseMetadataFile = info.LicenseMetadataFile
 	}
 
 	// Iterate over this module's dist structs, merged from the dist and dists properties.
@@ -516,6 +518,7 @@
 		a.Include = "$(BUILD_PREBUILT)"
 	}
 	a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...)
+	a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...)
 	a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
 	a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
 
@@ -589,10 +592,10 @@
 		}
 
 		if !base.InVendorRamdisk() {
-			a.AddPaths("LOCAL_FULL_INIT_RC", base.initRcPaths)
+			a.AddPaths("LOCAL_FULL_INIT_RC", info.InitRcPaths)
 		}
-		if len(base.vintfFragmentsPaths) > 0 {
-			a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", base.vintfFragmentsPaths)
+		if len(info.VintfFragmentsPaths) > 0 {
+			a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", info.VintfFragmentsPaths)
 		}
 		a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
 		if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
@@ -909,7 +912,6 @@
 		case "*phony.PhonyRule": // writes phony deps and acts like `.PHONY`
 		case "*selinux.selinuxContextsModule": // license properties written
 		case "*sysprop.syspropLibrary": // license properties written
-		case "*vintf.vintfCompatibilityMatrixRule": // use case like phony
 		default:
 			if !ctx.Config().IsEnvFalse("ANDROID_REQUIRE_LICENSES") {
 				return fmt.Errorf("custom make rules not allowed for %q (%q) module %q", ctx.ModuleType(mod), reflect.TypeOf(mod), ctx.ModuleName(mod))
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index 72b8654..c37eeab 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -46,7 +46,6 @@
 
 func (m *customModule) GenerateAndroidBuildActions(ctx ModuleContext) {
 
-	m.base().licenseMetadataFile = PathForOutput(ctx, "meta_lic")
 	var defaultDistPaths Paths
 
 	// If the dist_output_file: true then create an output file that is stored in
@@ -276,7 +275,8 @@
 		)
 	}
 	for idx, line := range androidMkLines {
-		expectedLine := strings.ReplaceAll(expectedAndroidMkLines[idx], "meta_lic", module.base().licenseMetadataFile.String())
+		expectedLine := strings.ReplaceAll(expectedAndroidMkLines[idx], "meta_lic",
+			OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).LicenseMetadataFile.String())
 		if line != expectedLine {
 			t.Errorf(
 				"Expected AndroidMk line to be '%s', got '%s'",
diff --git a/android/apex.go b/android/apex.go
index 028be57..b19c477 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"reflect"
 	"slices"
 	"sort"
 	"strconv"
@@ -145,6 +146,17 @@
 	return false
 }
 
+// To satisfy the comparable interface
+func (i ApexInfo) Equal(other any) bool {
+	otherApexInfo, ok := other.(ApexInfo)
+	return ok && i.ApexVariationName == otherApexInfo.ApexVariationName &&
+		i.MinSdkVersion == otherApexInfo.MinSdkVersion &&
+		i.Updatable == otherApexInfo.Updatable &&
+		i.UsePlatformApis == otherApexInfo.UsePlatformApis &&
+		reflect.DeepEqual(i.InApexVariants, otherApexInfo.InApexVariants) &&
+		reflect.DeepEqual(i.InApexModules, otherApexInfo.InApexModules)
+}
+
 // ApexTestForInfo stores the contents of APEXes for which this module is a test - although this
 // module is not part of the APEX - and thus has access to APEX internals.
 type ApexTestForInfo struct {
@@ -475,13 +487,6 @@
 	AvailableToAnyApex  = "//apex_available:anyapex"
 )
 
-var (
-	AvailableToRecognziedWildcards = []string{
-		AvailableToPlatform,
-		AvailableToAnyApex,
-	}
-)
-
 // CheckAvailableForApex provides the default algorithm for checking the apex availability. When the
 // availability is empty, it defaults to ["//apex_available:platform"] which means "available to the
 // platform but not available to any APEX". When the list is not empty, `what` is matched against
diff --git a/android/build_prop.go b/android/build_prop.go
index 13d59f9..ede93ed 100644
--- a/android/build_prop.go
+++ b/android/build_prop.go
@@ -63,6 +63,8 @@
 		return ctx.Config().SystemExtPropFiles(ctx)
 	} else if partition == "product" {
 		return ctx.Config().ProductPropFiles(ctx)
+	} else if partition == "odm" {
+		return ctx.Config().OdmPropFiles(ctx)
 	}
 	return nil
 }
diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go
index 4c92f71..a7b65e0 100644
--- a/android/compliance_metadata.go
+++ b/android/compliance_metadata.go
@@ -189,8 +189,8 @@
 		installed = append(installed, ctx.installFiles...)
 		installed = append(installed, ctx.katiInstalls.InstallPaths()...)
 		installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
-		installed = append(installed, m.katiInitRcInstalls.InstallPaths()...)
-		installed = append(installed, m.katiVintfInstalls.InstallPaths()...)
+		installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
+		installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
 		complianceMetadataInfo.SetListValue(ComplianceMetadataProp.INSTALLED_FILES, FirstUniqueStrings(installed.Strings()))
 	}
 	ctx.setProvider(ComplianceMetadataProvider, complianceMetadataInfo)
diff --git a/android/config.go b/android/config.go
index d6d76a4..bbb08dd 100644
--- a/android/config.go
+++ b/android/config.go
@@ -173,6 +173,13 @@
 	return c.IsEnvTrue("DISABLE_VERIFY_OVERLAPS") || c.ReleaseDisableVerifyOverlaps() || !c.ReleaseDefaultModuleBuildFromSource()
 }
 
+func (c Config) CoverageSuffix() string {
+	if v := c.IsEnvTrue("EMMA_INSTRUMENT"); v {
+		return "coverage."
+	}
+	return ""
+}
+
 // MaxPageSizeSupported returns the max page size supported by the device. This
 // value will define the ELF segment alignment for binaries (executables and
 // shared libraries).
@@ -2050,22 +2057,10 @@
 	return PathsForSource(ctx, c.productVariables.ProductPropFiles)
 }
 
+func (c *config) OdmPropFiles(ctx PathContext) Paths {
+	return PathsForSource(ctx, c.productVariables.OdmPropFiles)
+}
+
 func (c *config) EnableUffdGc() string {
 	return String(c.productVariables.EnableUffdGc)
 }
-
-func (c *config) DeviceFrameworkCompatibilityMatrixFile() []string {
-	return c.productVariables.DeviceFrameworkCompatibilityMatrixFile
-}
-
-func (c *config) DeviceProductCompatibilityMatrixFile() []string {
-	return c.productVariables.DeviceProductCompatibilityMatrixFile
-}
-
-func (c *config) BoardAvbEnable() bool {
-	return Bool(c.productVariables.BoardAvbEnable)
-}
-
-func (c *config) BoardAvbSystemAddHashtreeFooterArgs() []string {
-	return c.productVariables.BoardAvbSystemAddHashtreeFooterArgs
-}
diff --git a/android/container.go b/android/container.go
index 10aff4d..c048d6c 100644
--- a/android/container.go
+++ b/android/container.go
@@ -15,8 +15,10 @@
 package android
 
 import (
+	"fmt"
 	"reflect"
 	"slices"
+	"strings"
 
 	"github.com/google/blueprint"
 )
@@ -89,10 +91,18 @@
 	"framework-annotations-lib",
 	"unsupportedappusage",
 
+	// TODO(b/363016634): Remove from the allowlist when the module is converted
+	// to java_sdk_library and the java_aconfig_library modules depend on the stub.
+	"aconfig_storage_reader_java",
+
 	// framework-res provides core resources essential for building apps and system UI.
 	// This module is implicitly added as a dependency for java modules even when the
 	// dependency specifies sdk_version.
 	"framework-res",
+
+	// jacocoagent is implicitly added as a dependency in coverage builds, and is not installed
+	// on the device.
+	"jacocoagent",
 }
 
 // Returns true when the dependency is globally allowlisted for inter-container dependency
@@ -219,7 +229,6 @@
 // ----------------------------------------------------------------------------
 
 type InstallableModule interface {
-	ContainersInfo() ContainersInfo
 	StaticDependencyTags() []blueprint.DependencyTag
 	DynamicDependencyTags() []blueprint.DependencyTag
 }
@@ -391,6 +400,40 @@
 
 var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]()
 
+func satisfyAllowedExceptions(ctx ModuleContext, allowedExceptionLabels []exceptionHandleFuncLabel, m, dep Module) bool {
+	for _, label := range allowedExceptionLabels {
+		if exceptionHandleFunctionsTable[label](ctx, m, dep) {
+			return true
+		}
+	}
+	return false
+}
+
+func (c *ContainersInfo) GetViolations(mctx ModuleContext, m, dep Module, depInfo ContainersInfo) []string {
+	var violations []string
+
+	// Any containers that the module belongs to but the dependency does not belong to must be examined.
+	_, containersUniqueToModule, _ := ListSetDifference(c.belongingContainers, depInfo.belongingContainers)
+
+	// Apex container should be examined even if both the module and the dependency belong to
+	// the apex container to check that the two modules belong to the same apex.
+	if InList(ApexContainer, c.belongingContainers) && !InList(ApexContainer, containersUniqueToModule) {
+		containersUniqueToModule = append(containersUniqueToModule, ApexContainer)
+	}
+
+	for _, containerUniqueToModule := range containersUniqueToModule {
+		for _, restriction := range containerUniqueToModule.restricted {
+			if InList(restriction.dependency, depInfo.belongingContainers) {
+				if !satisfyAllowedExceptions(mctx, restriction.allowedExceptions, m, dep) {
+					violations = append(violations, restriction.errorMessage)
+				}
+			}
+		}
+	}
+
+	return violations
+}
+
 func generateContainerInfo(ctx ModuleContext) ContainersInfo {
 	var containers []*container
 
@@ -413,7 +456,7 @@
 
 func getContainerModuleInfo(ctx ModuleContext, module Module) (ContainersInfo, bool) {
 	if ctx.Module() == module {
-		return module.ContainersInfo(), true
+		return ctx.getContainersInfo(), true
 	}
 
 	return OtherModuleProvider(ctx, module, ContainersInfoProvider)
@@ -428,7 +471,36 @@
 
 	if _, ok := ctx.Module().(InstallableModule); ok {
 		containersInfo := generateContainerInfo(ctx)
-		ctx.Module().base().containersInfo = containersInfo
+		ctx.setContainersInfo(containersInfo)
 		SetProvider(ctx, ContainersInfoProvider, containersInfo)
 	}
 }
+
+func checkContainerViolations(ctx ModuleContext) {
+	if _, ok := ctx.Module().(InstallableModule); ok {
+		containersInfo, _ := getContainerModuleInfo(ctx, ctx.Module())
+		ctx.VisitDirectDepsIgnoreBlueprint(func(dep Module) {
+			if !dep.Enabled(ctx) {
+				return
+			}
+
+			// Pre-existing violating dependencies are tracked in containerDependencyViolationAllowlist.
+			// If this dependency is allowlisted, do not check for violation.
+			// If not, check if this dependency matches any restricted dependency and
+			// satisfies any exception functions, which allows bypassing the
+			// restriction. If all of the exceptions are not satisfied, throw an error.
+			if depContainersInfo, ok := getContainerModuleInfo(ctx, dep); ok {
+				if allowedViolations, ok := ContainerDependencyViolationAllowlist[ctx.ModuleName()]; ok && InList(dep.Name(), allowedViolations) {
+					return
+				} else {
+					violations := containersInfo.GetViolations(ctx, ctx.Module(), dep, depContainersInfo)
+					if len(violations) > 0 {
+						errorMessage := fmt.Sprintf("%s cannot depend on %s. ", ctx.ModuleName(), dep.Name())
+						errorMessage += strings.Join(violations, " ")
+						ctx.ModuleErrorf(errorMessage)
+					}
+				}
+			}
+		})
+	}
+}
diff --git a/android/container_violations.go b/android/container_violations.go
new file mode 100644
index 0000000..e67533d
--- /dev/null
+++ b/android/container_violations.go
@@ -0,0 +1,1042 @@
+// Copyright 2024 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
+
+var ContainerDependencyViolationAllowlist = map[string][]string{
+	"android.car-module.impl": {
+		"modules-utils-preconditions", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi]
+	},
+
+	"AppInstalledOnMultipleUsers": {
+		"framework", // cts -> unstable
+	},
+
+	"art-aconfig-flags-java-lib": {
+		"framework-api-annotations-lib", // apex [com.android.art, com.android.art.debug, com.android.art.testing, test_imgdiag_com.android.art, test_jitzygote_com.android.art] -> system
+	},
+
+	"Bluetooth": {
+		"app-compat-annotations",         // apex [com.android.btservices] -> system
+		"framework-bluetooth-pre-jarjar", // apex [com.android.btservices] -> system
+	},
+
+	"bluetooth-nano-protos": {
+		"libprotobuf-java-nano", // apex [com.android.btservices] -> apex [com.android.wifi, test_com.android.wifi]
+	},
+
+	"bluetooth.change-ids": {
+		"app-compat-annotations", // apex [com.android.btservices] -> system
+	},
+
+	"CarServiceUpdatable": {
+		"modules-utils-os",                    // apex [com.android.car.framework] -> apex [com.android.permission, test_com.android.permission]
+		"modules-utils-preconditions",         // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi]
+		"modules-utils-shell-command-handler", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.art, com.android.art.debug, com.android.art.testing, com.android.btservices, com.android.configinfrastructure, com.android.mediaprovider, com.android.nfcservices, com.android.permission, com.android.scheduling, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.mediaprovider, test_com.android.permission, test_com.android.wifi, test_imgdiag_com.android.art, test_jitzygote_com.android.art]
+	},
+
+	"connectivity-net-module-utils-bpf": {
+		"net-utils-device-common-struct-base", // apex [com.android.tethering] -> system
+	},
+
+	"conscrypt-aconfig-flags-lib": {
+		"aconfig-annotations-lib-sdk-none", // apex [com.android.conscrypt, test_com.android.conscrypt] -> system
+	},
+
+	"cronet_aml_base_base_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+		"jsr305", // apex [com.android.tethering] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider]
+	},
+
+	"cronet_aml_build_android_build_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_components_cronet_android_base_feature_overrides_java_proto": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_components_cronet_android_cronet_api_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_components_cronet_android_cronet_impl_common_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_components_cronet_android_cronet_impl_native_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+		"jsr305", // apex [com.android.tethering] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider]
+	},
+
+	"cronet_aml_components_cronet_android_cronet_jni_registration_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_components_cronet_android_cronet_shared_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_components_cronet_android_cronet_stats_log_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_components_cronet_android_cronet_urlconnection_impl_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_components_cronet_android_flags_java_proto": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_components_cronet_android_request_context_config_java_proto": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_net_android_net_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+		"jsr305", // apex [com.android.tethering] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider]
+	},
+
+	"cronet_aml_net_android_net_thread_stats_uid_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_third_party_jni_zero_jni_zero_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"cronet_aml_url_url_java": {
+		"framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+	},
+
+	"CtsAdservicesHostTestApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAdServicesNotInAllowListEndToEndTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAdServicesPermissionsAppOptOutEndToEndTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAdServicesPermissionsNoPermEndToEndTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAdServicesPermissionsValidEndToEndTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAlarmManagerTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAndroidAppTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAppExitTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAppFgsStartTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAppFgsTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAppOpsTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAppSearchTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAppTestStubsApp2": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsAudioHostTestApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsBackgroundActivityAppAllowCrossUidFlagDefault": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsBatterySavingTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsBluetoothTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsBootDisplayModeApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsBroadcastTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsBRSTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsCompanionDeviceManagerCoreTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsCompanionDeviceManagerMultiProcessTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsCompanionDeviceManagerUiAutomationTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsContentSuggestionsTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsContentTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsCredentialManagerBackupRestoreApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsCrossProfileEnabledApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsCrossProfileEnabledNoPermsApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsCrossProfileNotEnabledApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsCrossProfileUserEnabledApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsDeviceAndProfileOwnerApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsDeviceAndProfileOwnerApp23": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsDeviceAndProfileOwnerApp25": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsDeviceAndProfileOwnerApp30": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsDeviceLockTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsDeviceOwnerApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsDevicePolicySimTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsDevicePolicyTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsDreamsTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsDrmTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsEphemeralTestsEphemeralApp1": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsFgsBootCompletedTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsFgsBootCompletedTestCasesApi35": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsFgsStartTestHelperApi34": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsFgsStartTestHelperCurrent": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsFileDescriptorTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsHostsideCompatChangeTestsApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsHostsideNetworkPolicyTestsApp2": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsIdentityTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsIkeTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsInstalledLoadingProgressDeviceTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsInstantAppTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsIntentSenderApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsJobSchedulerTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsKeystoreTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsLegacyNotification27TestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsLibcoreTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsLibcoreWycheproofConscryptTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsListeningPortsTest": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsLocationCoarseTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsLocationFineTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsLocationNoneTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsLocationPrivilegedTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsManagedProfileApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaAudioTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaBetterTogetherTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaCodecTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaDecoderTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaDrmFrameworkTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaEncoderTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaExtractorTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaMiscTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaMuxerTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaPerformanceClassTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaPlayerTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaProjectionSDK33TestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaProjectionSDK34TestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaProjectionTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaProviderTranscodeTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaRecorderTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaRouterHostSideTestBluetoothPermissionsApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaRouterHostSideTestMediaRoutingControlApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaRouterHostSideTestModifyAudioRoutingApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMediaV2TestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMimeMapTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsModifyQuietModeEnabledApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsMusicRecognitionTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsNativeMediaAAudioTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsNetTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsNetTestCasesLegacyApi22": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsNetTestCasesMaxTargetSdk30": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsNetTestCasesMaxTargetSdk31": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsNetTestCasesMaxTargetSdk33": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsNetTestCasesUpdateStatsPermission": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsNfcTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsOnDevicePersonalizationTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsPackageInstallerApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsPackageManagerTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsPackageSchemeTestsWithoutVisibility": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsPackageSchemeTestsWithVisibility": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsPermissionsSyncTestApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsPreservedSettingsApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsProtoTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsProviderTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsProxyMediaRouterTestHelperApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsRebootReadinessTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsResourcesLoaderTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsResourcesTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSandboxedAdIdManagerTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSandboxedAppSetIdManagerTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSandboxedFledgeManagerTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSandboxedMeasurementManagerTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSandboxedTopicsManagerTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSdkExtensionsTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSdkSandboxInprocessTests": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSecureElementTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSecurityTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSelinuxEphemeralTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSelinuxTargetSdk25TestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSelinuxTargetSdk27TestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSelinuxTargetSdk28TestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSelinuxTargetSdk29TestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSelinuxTargetSdk30TestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSelinuxTargetSdkCurrentTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSettingsDeviceOwnerApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSharedUserMigrationTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsShortFgsTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSimRestrictedApisTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSliceTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSpeechTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsStatsSecurityApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSuspendAppsTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsSystemUiTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsTareTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsTelephonyTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsTetheringTest": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsThreadNetworkTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsUsageStatsTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsUsbManagerTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsUserRestrictionTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsUtilTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsUwbTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsVcnTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsVideoCodecTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsVideoTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsViewReceiveContentTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsVirtualDevicesAppLaunchTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsVirtualDevicesAudioTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsVirtualDevicesCameraTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsVirtualDevicesSensorTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsVirtualDevicesTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsWearableSensingServiceTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsWebViewCompatChangeApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsWidgetTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsWidgetTestCases29": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsWifiNonUpdatableTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsWifiTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsWindowManagerExternalApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsWindowManagerTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"CtsZipValidateApp": {
+		"framework", // cts -> unstable
+	},
+
+	"CVE-2021-0965": {
+		"framework", // cts -> unstable
+	},
+
+	"device_config_reboot_flags_java_lib": {
+		"ext",       // apex [com.android.configinfrastructure] -> system
+		"framework", // apex [com.android.configinfrastructure] -> system
+	},
+
+	"devicelockcontroller-lib": {
+		"modules-utils-expresslog", // apex [com.android.devicelock] -> apex [com.android.btservices, com.android.car.framework]
+	},
+
+	"FederatedCompute": {
+		"auto_value_annotations", // apex [com.android.ondevicepersonalization] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+	},
+
+	"framework-adservices.impl": {
+		"adservices_flags_lib", // apex [com.android.adservices, com.android.extservices] -> system
+	},
+
+	"framework-bluetooth.impl": {
+		"app-compat-annotations", // apex [com.android.btservices] -> system
+	},
+
+	"framework-connectivity-t.impl": {
+		"app-compat-annotations",            // apex [com.android.tethering] -> system
+		"framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system
+	},
+
+	"framework-connectivity.impl": {
+		"app-compat-annotations", // apex [com.android.tethering] -> system
+	},
+
+	"framework-ondevicepersonalization.impl": {
+		"ondevicepersonalization_flags_lib", // apex [com.android.ondevicepersonalization] -> system
+	},
+
+	"framework-pdf.impl": {
+		"modules-utils-preconditions", // apex [com.android.mediaprovider, test_com.android.mediaprovider] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi]
+	},
+
+	"framework-permission-s.impl": {
+		"app-compat-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+	},
+
+	"framework-wifi.impl": {
+		"aconfig_storage_reader_java", // apex [com.android.wifi, test_com.android.wifi] -> system
+		"app-compat-annotations",      // apex [com.android.wifi, test_com.android.wifi] -> system
+	},
+
+	"grpc-java-core-internal": {
+		"gson",             // apex [com.android.adservices, com.android.devicelock, com.android.extservices] -> apex [com.android.virt]
+		"perfmark-api-lib", // apex [com.android.adservices, com.android.devicelock, com.android.extservices] -> system
+	},
+
+	"httpclient_impl": {
+		"httpclient_api", // apex [com.android.tethering] -> system
+	},
+
+	"IncrementalTestAppValidator": {
+		"framework", // cts -> unstable
+	},
+
+	"libcore-aconfig-flags-lib": {
+		"framework-api-annotations-lib", // apex [com.android.art, com.android.art.debug, com.android.art.testing, test_imgdiag_com.android.art, test_jitzygote_com.android.art] -> system
+	},
+
+	"loadlibrarytest_product_app": {
+		"libnativeloader_vendor_shared_lib", // product -> vendor
+	},
+
+	"loadlibrarytest_testlib": {
+		"libnativeloader_vendor_shared_lib", // system -> vendor
+	},
+
+	"MctsMediaDrmFrameworkTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"MctsMediaTranscodingTestCases": {
+		"framework", // cts -> unstable
+	},
+
+	"MediaProvider": {
+		"app-compat-annotations", // apex [com.android.mediaprovider, test_com.android.mediaprovider] -> system
+	},
+
+	"mediaprovider_flags_java_lib": {
+		"ext",       // apex [com.android.mediaprovider, test_com.android.mediaprovider] -> system
+		"framework", // apex [com.android.mediaprovider, test_com.android.mediaprovider] -> system
+	},
+
+	"MockSatelliteGatewayServiceApp": {
+		"framework", // cts -> unstable
+	},
+
+	"MockSatelliteServiceApp": {
+		"framework", // cts -> unstable
+	},
+
+	"net-utils-device-common-netlink": {
+		"net-utils-device-common-struct-base", // apex [com.android.tethering] -> system
+	},
+
+	"net-utils-device-common-struct": {
+		"net-utils-device-common-struct-base", // apex [com.android.tethering] -> system
+	},
+
+	"NfcNciApex": {
+		"android.permission.flags-aconfig-java", // apex [com.android.nfcservices] -> apex [com.android.permission, test_com.android.permission]
+	},
+
+	"okhttp-norepackage": {
+		"okhttp-android-util-log", // apex [com.android.adservices, com.android.devicelock, com.android.extservices] -> system
+	},
+
+	"ondevicepersonalization-plugin-lib": {
+		"auto_value_annotations", // apex [com.android.ondevicepersonalization] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+	},
+
+	"opencensus-java-api": {
+		"auto_value_annotations", // apex [com.android.devicelock] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+	},
+
+	"PermissionController-lib": {
+		"safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+	},
+
+	"PlatformProperties": {
+		"sysprop-library-stub-platform", // apex [com.android.btservices, com.android.nfcservices, com.android.tethering, com.android.virt, com.android.wifi, test_com.android.wifi] -> system
+	},
+
+	"safety-center-config": {
+		"safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+	},
+
+	"safety-center-internal-data": {
+		"safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+	},
+
+	"safety-center-pending-intents": {
+		"safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+	},
+
+	"safety-center-persistence": {
+		"safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+	},
+
+	"safety-center-resources-lib": {
+		"safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+	},
+
+	"SdkSandboxManagerDisabledTests": {
+		"framework", // cts -> unstable
+	},
+
+	"SdkSandboxManagerTests": {
+		"framework", // cts -> unstable
+	},
+
+	"service-art.impl": {
+		"auto_value_annotations", // apex [com.android.art, com.android.art.debug, com.android.art.testing, test_imgdiag_com.android.art, test_jitzygote_com.android.art] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+	},
+
+	"service-bluetooth-pre-jarjar": {
+		"framework-bluetooth-pre-jarjar", // apex [com.android.btservices] -> system
+		"service-bluetooth.change-ids",   // apex [com.android.btservices] -> system
+	},
+
+	"service-connectivity": {
+		"libprotobuf-java-nano", // apex [com.android.tethering] -> apex [com.android.wifi, test_com.android.wifi]
+	},
+
+	"service-connectivity-pre-jarjar": {
+		"framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system
+	},
+
+	"service-connectivity-protos": {
+		"libprotobuf-java-nano", // apex [com.android.tethering] -> apex [com.android.wifi, test_com.android.wifi]
+	},
+
+	"service-connectivity-tiramisu-pre-jarjar": {
+		"framework-connectivity-pre-jarjar",   // apex [com.android.tethering] -> system
+		"framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system
+	},
+
+	"service-entitlement": {
+		"auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+	},
+
+	"service-entitlement-api": {
+		"auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+	},
+
+	"service-entitlement-data": {
+		"auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+	},
+
+	"service-entitlement-impl": {
+		"auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+	},
+
+	"service-healthfitness.impl": {
+		"modules-utils-preconditions", // apex [com.android.healthfitness] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi]
+	},
+
+	"service-networksecurity-pre-jarjar": {
+		"framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system
+	},
+
+	"service-permission.impl": {
+		"jsr305",                    // apex [com.android.permission, test_com.android.permission] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider]
+		"safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+	},
+
+	"service-remoteauth-pre-jarjar": {
+		"framework-connectivity-pre-jarjar",   // apex [com.android.tethering] -> system
+		"framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system
+	},
+
+	"service-thread-pre-jarjar": {
+		"framework-connectivity-pre-jarjar",   // apex [com.android.tethering] -> system
+		"framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system
+	},
+
+	"service-uwb-pre-jarjar": {
+		"framework-uwb-pre-jarjar", // apex [com.android.uwb] -> system
+	},
+
+	"service-wifi": {
+		"auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+	},
+
+	"TelephonyDeviceTest": {
+		"framework", // cts -> unstable
+	},
+
+	"tensorflowlite_java": {
+		"android-support-annotations", // apex [com.android.adservices, com.android.extservices, com.android.ondevicepersonalization] -> system
+	},
+
+	"TestExternalImsServiceApp": {
+		"framework", // cts -> unstable
+	},
+
+	"TestSmsRetrieverApp": {
+		"framework", // cts -> unstable
+	},
+
+	"TetheringApiCurrentLib": {
+		"connectivity-internal-api-util", // apex [com.android.tethering] -> system
+	},
+
+	"TetheringNext": {
+		"connectivity-internal-api-util", // apex [com.android.tethering] -> system
+	},
+
+	"tetheringstatsprotos": {
+		"ext",       // apex [com.android.tethering] -> system
+		"framework", // apex [com.android.tethering] -> system
+	},
+
+	"uwb_aconfig_flags_lib": {
+		"ext",       // apex [com.android.uwb] -> system
+		"framework", // apex [com.android.uwb] -> system
+	},
+
+	"uwb_androidx_backend": {
+		"android-support-annotations", // apex [com.android.tethering] -> system
+	},
+
+	"wifi-service-pre-jarjar": {
+		"app-compat-annotations",    // apex [com.android.wifi, test_com.android.wifi] -> system
+		"auto_value_annotations",    // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+		"framework-wifi-pre-jarjar", // apex [com.android.wifi, test_com.android.wifi] -> system
+		"jsr305",                    // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider]
+	},
+}
diff --git a/android/defaults.go b/android/defaults.go
index c0a2fc6..0d51d9d 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -28,7 +28,7 @@
 var DefaultsDepTag defaultsDependencyTag
 
 type defaultsProperties struct {
-	Defaults proptools.Configurable[[]string]
+	Defaults []string
 }
 
 type DefaultableModuleBase struct {
@@ -278,13 +278,13 @@
 
 func defaultsDepsMutator(ctx BottomUpMutatorContext) {
 	if defaultable, ok := ctx.Module().(Defaultable); ok {
-		ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults.GetOrDefault(ctx, nil)...)
+		ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
 	}
 }
 
 func defaultsMutator(ctx TopDownMutatorContext) {
 	if defaultable, ok := ctx.Module().(Defaultable); ok {
-		defaults := defaultable.defaults().Defaults.GetOrDefault(ctx, nil)
+		defaults := defaultable.defaults().Defaults
 		if len(defaults) > 0 {
 			var defaultsList []Defaults
 			seen := make(map[Defaults]bool)
@@ -295,7 +295,7 @@
 						if !seen[defaults] {
 							seen[defaults] = true
 							defaultsList = append(defaultsList, defaults)
-							return len(defaults.defaults().Defaults.GetOrDefault(ctx, nil)) > 0
+							return len(defaults.defaults().Defaults) > 0
 						}
 					} else {
 						ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
diff --git a/android/license_metadata.go b/android/license_metadata.go
index cd69749..0ac975f 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -152,7 +152,7 @@
 
 	// Install map
 	args = append(args,
-		JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(base.licenseInstallMap), "-m "))
+		JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(ctx.licenseInstallMap), "-m "))
 
 	// Built files
 	if len(outputFiles) > 0 {
diff --git a/android/makevars.go b/android/makevars.go
index 810eb38..8305d8e 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -281,8 +281,8 @@
 		if m.ExportedToMake() {
 			info := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider)
 			katiInstalls = append(katiInstalls, info.KatiInstalls...)
-			katiInitRcInstalls = append(katiInitRcInstalls, m.base().katiInitRcInstalls...)
-			katiVintfManifestInstalls = append(katiVintfManifestInstalls, m.base().katiVintfInstalls...)
+			katiInitRcInstalls = append(katiInitRcInstalls, info.KatiInitRcInstalls...)
+			katiVintfManifestInstalls = append(katiVintfManifestInstalls, info.KatiVintfInstalls...)
 			katiSymlinks = append(katiSymlinks, info.KatiSymlinks...)
 		}
 	})
diff --git a/android/module.go b/android/module.go
index 664ac5c..7ce4e05 100644
--- a/android/module.go
+++ b/android/module.go
@@ -87,8 +87,6 @@
 	ReplacedByPrebuilt()
 	IsReplacedByPrebuilt() bool
 	ExportedToMake() bool
-	InitRc() Paths
-	VintfFragments() Paths
 	EffectiveLicenseKinds() []string
 	EffectiveLicenseFiles() Paths
 
@@ -113,14 +111,7 @@
 	TargetRequiredModuleNames() []string
 	VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string
 
-	// TransitivePackagingSpecs returns the PackagingSpecs for this module and any transitive
-	// dependencies with dependency tags for which IsInstallDepNeeded() returns true.
-	TransitivePackagingSpecs() []PackagingSpec
-
 	ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator
-
-	// Get the information about the containers this module belongs to.
-	ContainersInfo() ContainersInfo
 }
 
 // Qualified id for a module
@@ -835,22 +826,7 @@
 	// The primary licenses property, may be nil, records license metadata for the module.
 	primaryLicensesProperty applicableLicensesProperty
 
-	noAddressSanitizer   bool
-	installFilesDepSet   *DepSet[InstallPath]
-	packagingSpecsDepSet *DepSet[PackagingSpec]
-	// katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
-	// allowed to have duplicates across modules and variants.
-	katiInitRcInstalls katiInstalls
-	katiVintfInstalls  katiInstalls
-
-	// The files to copy to the dist as explicitly specified in the .bp file.
-	distFiles TaggedDistFiles
-
-	// Used by buildTargetSingleton to create checkbuild and per-directory build targets
-	// Only set on the final variant of each module
-	installTarget    WritablePath
-	checkbuildTarget WritablePath
-	blueprintDir     string
+	noAddressSanitizer bool
 
 	hooks hooks
 
@@ -860,38 +836,6 @@
 	buildParams []BuildParams
 	ruleParams  map[blueprint.Rule]blueprint.RuleParams
 	variables   map[string]string
-
-	initRcPaths         Paths
-	vintfFragmentsPaths Paths
-
-	installedInitRcPaths         InstallPaths
-	installedVintfFragmentsPaths InstallPaths
-
-	// Merged Aconfig files for all transitive deps.
-	aconfigFilePaths Paths
-
-	// set of dependency module:location mappings used to populate the license metadata for
-	// apex containers.
-	licenseInstallMap []string
-
-	// The path to the generated license metadata file for the module.
-	licenseMetadataFile WritablePath
-
-	// moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will
-	// be included in the final module-info.json produced by Make.
-	moduleInfoJSON *ModuleInfoJSON
-
-	// outputFiles stores the output of a module by tag and is used to set
-	// the OutputFilesProvider in GenerateBuildActions
-	outputFiles OutputFilesInfo
-
-	// complianceMetadataInfo is for different module types to dump metadata.
-	// See android.ModuleContext interface.
-	complianceMetadataInfo *ComplianceMetadataInfo
-
-	// containersInfo stores the information about the containers and the information of the
-	// apexes the module belongs to.
-	containersInfo ContainersInfo
 }
 
 func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
@@ -1464,12 +1408,13 @@
 		if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
 			// Installation is still handled by Make, so anything hidden from Make is not
 			// installable.
+			info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider)
 			if !dep.IsHideFromMake() && !dep.IsSkipInstall() {
-				installDeps = append(installDeps, dep.base().installFilesDepSet)
+				installDeps = append(installDeps, info.TransitiveInstallFiles)
 			}
 			// Add packaging deps even when the dependency is not installed so that uninstallable
 			// modules can still be packaged.  Often the package will be installed instead.
-			packagingSpecs = append(packagingSpecs, dep.base().packagingSpecsDepSet)
+			packagingSpecs = append(packagingSpecs, info.TransitivePackagingSpecs)
 		}
 	})
 
@@ -1487,10 +1432,6 @@
 	return IsInstallDepNeededTag(tag)
 }
 
-func (m *ModuleBase) TransitivePackagingSpecs() []PackagingSpec {
-	return m.packagingSpecsDepSet.ToList()
-}
-
 func (m *ModuleBase) NoAddressSanitizer() bool {
 	return m.noAddressSanitizer
 }
@@ -1604,24 +1545,6 @@
 	return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
 }
 
-func (m *ModuleBase) InitRc() Paths {
-	return append(Paths{}, m.initRcPaths...)
-}
-
-func (m *ModuleBase) VintfFragments() Paths {
-	return append(Paths{}, m.vintfFragmentsPaths...)
-}
-
-func (m *ModuleBase) CompileMultilib() *string {
-	return m.base().commonProperties.Compile_multilib
-}
-
-// SetLicenseInstallMap stores the set of dependency module:location mappings for files in an
-// apex container for use when generation the license metadata file.
-func (m *ModuleBase) SetLicenseInstallMap(installMap []string) {
-	m.licenseInstallMap = append(m.licenseInstallMap, installMap...)
-}
-
 func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
 	var allInstalledFiles InstallPaths
 	var allCheckbuildFiles Paths
@@ -1647,23 +1570,26 @@
 
 	var deps Paths
 
-	namespacePrefix := ctx.Namespace().id
-	if namespacePrefix != "" {
-		namespacePrefix = namespacePrefix + "-"
+	var namespacePrefix string
+	nameSpace := ctx.Namespace().Path
+	if nameSpace != "." {
+		namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-"
 	}
 
+	var info FinalModuleBuildTargetsInfo
+
 	if len(allInstalledFiles) > 0 {
 		name := namespacePrefix + ctx.ModuleName() + "-install"
 		ctx.Phony(name, allInstalledFiles.Paths()...)
-		m.installTarget = PathForPhony(ctx, name)
-		deps = append(deps, m.installTarget)
+		info.InstallTarget = PathForPhony(ctx, name)
+		deps = append(deps, info.InstallTarget)
 	}
 
 	if len(allCheckbuildFiles) > 0 {
 		name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
 		ctx.Phony(name, allCheckbuildFiles...)
-		m.checkbuildTarget = PathForPhony(ctx, name)
-		deps = append(deps, m.checkbuildTarget)
+		info.CheckbuildTarget = PathForPhony(ctx, name)
+		deps = append(deps, info.CheckbuildTarget)
 	}
 
 	if len(deps) > 0 {
@@ -1674,7 +1600,8 @@
 
 		ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
 
-		m.blueprintDir = ctx.ModuleDir()
+		info.BlueprintDir = ctx.ModuleDir()
+		SetProvider(ctx, FinalModuleBuildTargetsProvider, info)
 	}
 }
 
@@ -1784,30 +1711,61 @@
 	PackagingSpecs  []PackagingSpec
 	// katiInstalls tracks the install rules that were created by Soong but are being exported
 	// to Make to convert to ninja rules so that Make can add additional dependencies.
-	KatiInstalls katiInstalls
-	KatiSymlinks katiInstalls
-	TestData     []DataPath
+	KatiInstalls             katiInstalls
+	KatiSymlinks             katiInstalls
+	TestData                 []DataPath
+	TransitivePackagingSpecs *DepSet[PackagingSpec]
+	LicenseMetadataFile      WritablePath
+
+	// The following fields are private before, make it private again once we have
+	// better solution.
+	TransitiveInstallFiles *DepSet[InstallPath]
+	// katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
+	// allowed to have duplicates across modules and variants.
+	KatiInitRcInstalls           katiInstalls
+	KatiVintfInstalls            katiInstalls
+	InitRcPaths                  Paths
+	VintfFragmentsPaths          Paths
+	InstalledInitRcPaths         InstallPaths
+	InstalledVintfFragmentsPaths InstallPaths
+
+	// The files to copy to the dist as explicitly specified in the .bp file.
+	DistFiles TaggedDistFiles
 }
 
 var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]()
 
+type FinalModuleBuildTargetsInfo struct {
+	// Used by buildTargetSingleton to create checkbuild and per-directory build targets
+	// Only set on the final variant of each module
+	InstallTarget    WritablePath
+	CheckbuildTarget WritablePath
+	BlueprintDir     string
+}
+
+var FinalModuleBuildTargetsProvider = blueprint.NewProvider[FinalModuleBuildTargetsInfo]()
+
 func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
 	ctx := &moduleContext{
 		module:            m.module,
 		bp:                blueprintCtx,
 		baseModuleContext: m.baseModuleContextFactory(blueprintCtx),
 		variables:         make(map[string]string),
+		phonies:           make(map[string]Paths),
 	}
 
 	setContainerInfo(ctx)
+	if ctx.Config().Getenv("DISABLE_CONTAINER_CHECK") != "true" {
+		checkContainerViolations(ctx)
+	}
 
-	m.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
+	ctx.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
 
 	dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx)
-	// set m.installFilesDepSet to only the transitive dependencies to be used as the dependencies
+	// set the TransitiveInstallFiles to only the transitive dependencies to be used as the dependencies
 	// of installed files of this module.  It will be replaced by a depset including the installed
 	// files of this module at the end for use by modules that depend on this one.
-	m.installFilesDepSet = NewDepSet[InstallPath](TOPOLOGICAL, nil, dependencyInstallFiles)
+	ctx.TransitiveInstallFiles = NewDepSet[InstallPath](TOPOLOGICAL, nil, dependencyInstallFiles)
 
 	// Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
 	// reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
@@ -1851,6 +1809,8 @@
 		checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
 	}
 
+	var installFiles InstallFilesInfo
+
 	if m.Enabled(ctx) {
 		// ensure all direct android.Module deps are enabled
 		ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) {
@@ -1868,30 +1828,36 @@
 			// so only a single rule is created for each init.rc or vintf fragment file.
 
 			if !m.InVendorRamdisk() {
-				m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
+				ctx.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
 				rcDir := PathForModuleInstall(ctx, "etc", "init")
-				for _, src := range m.initRcPaths {
+				for _, src := range ctx.initRcPaths {
 					installedInitRc := rcDir.Join(ctx, src.Base())
-					m.katiInitRcInstalls = append(m.katiInitRcInstalls, katiInstall{
+					ctx.katiInitRcInstalls = append(ctx.katiInitRcInstalls, katiInstall{
 						from: src,
 						to:   installedInitRc,
 					})
 					ctx.PackageFile(rcDir, src.Base(), src)
-					m.installedInitRcPaths = append(m.installedInitRcPaths, installedInitRc)
+					ctx.installedInitRcPaths = append(ctx.installedInitRcPaths, installedInitRc)
 				}
+				installFiles.InitRcPaths = ctx.initRcPaths
+				installFiles.KatiInitRcInstalls = ctx.katiInitRcInstalls
+				installFiles.InstalledInitRcPaths = ctx.installedInitRcPaths
 			}
 
-			m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
+			ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
 			vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
-			for _, src := range m.vintfFragmentsPaths {
+			for _, src := range ctx.vintfFragmentsPaths {
 				installedVintfFragment := vintfDir.Join(ctx, src.Base())
-				m.katiVintfInstalls = append(m.katiVintfInstalls, katiInstall{
+				ctx.katiVintfInstalls = append(ctx.katiVintfInstalls, katiInstall{
 					from: src,
 					to:   installedVintfFragment,
 				})
 				ctx.PackageFile(vintfDir, src.Base(), src)
-				m.installedVintfFragmentsPaths = append(m.installedVintfFragmentsPaths, installedVintfFragment)
+				ctx.installedVintfFragmentsPaths = append(ctx.installedVintfFragmentsPaths, installedVintfFragment)
 			}
+			installFiles.VintfFragmentsPaths = ctx.vintfFragmentsPaths
+			installFiles.KatiVintfInstalls = ctx.katiVintfInstalls
+			installFiles.InstalledVintfFragmentsPaths = ctx.installedVintfFragmentsPaths
 		}
 
 		licensesPropertyFlattener(ctx)
@@ -1957,6 +1923,13 @@
 			if ctx.Failed() {
 				return
 			}
+
+			if x, ok := m.module.(IDEInfo); ok {
+				var result IdeInfo
+				x.IDEInfo(ctx, &result)
+				result.BaseModuleName = x.BaseModuleName()
+				SetProvider(ctx, IdeInfoProviderKey, result)
+			}
 		}
 
 		if incrementalEnabled && cacheKey != nil {
@@ -1967,19 +1940,18 @@
 		// as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
 		// output paths being set which must be done before or during
 		// GenerateAndroidBuildActions.
-		m.distFiles = m.GenerateTaggedDistFiles(ctx)
+		installFiles.DistFiles = m.GenerateTaggedDistFiles(ctx)
 		if ctx.Failed() {
 			return
 		}
 
-		SetProvider(ctx, InstallFilesProvider, InstallFilesInfo{
-			InstallFiles:    ctx.installFiles,
-			CheckbuildFiles: ctx.checkbuildFiles,
-			PackagingSpecs:  ctx.packagingSpecs,
-			KatiInstalls:    ctx.katiInstalls,
-			KatiSymlinks:    ctx.katiSymlinks,
-			TestData:        ctx.testData,
-		})
+		installFiles.LicenseMetadataFile = ctx.licenseMetadataFile
+		installFiles.InstallFiles = ctx.installFiles
+		installFiles.CheckbuildFiles = ctx.checkbuildFiles
+		installFiles.PackagingSpecs = ctx.packagingSpecs
+		installFiles.KatiInstalls = ctx.katiInstalls
+		installFiles.KatiSymlinks = ctx.katiSymlinks
+		installFiles.TestData = ctx.testData
 	} else if ctx.Config().AllowMissingDependencies() {
 		// If the module is not enabled it will not create any build rules, nothing will call
 		// ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
@@ -1995,17 +1967,19 @@
 		}
 	}
 
-	m.installFilesDepSet = NewDepSet[InstallPath](TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
-	m.packagingSpecsDepSet = NewDepSet[PackagingSpec](TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs)
+	ctx.TransitiveInstallFiles = NewDepSet[InstallPath](TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
+	installFiles.TransitiveInstallFiles = ctx.TransitiveInstallFiles
+	installFiles.TransitivePackagingSpecs = NewDepSet[PackagingSpec](TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs)
 
-	buildLicenseMetadata(ctx, m.licenseMetadataFile)
+	SetProvider(ctx, InstallFilesProvider, installFiles)
+	buildLicenseMetadata(ctx, ctx.licenseMetadataFile)
 
-	if m.moduleInfoJSON != nil {
+	if ctx.moduleInfoJSON != nil {
 		var installed InstallPaths
 		installed = append(installed, ctx.katiInstalls.InstallPaths()...)
 		installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
-		installed = append(installed, m.katiInitRcInstalls.InstallPaths()...)
-		installed = append(installed, m.katiVintfInstalls.InstallPaths()...)
+		installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
+		installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
 		installedStrings := installed.Strings()
 
 		var targetRequired, hostRequired []string
@@ -2020,38 +1994,44 @@
 			data = append(data, d.ToRelativeInstallPath())
 		}
 
-		if m.moduleInfoJSON.Uninstallable {
+		if ctx.moduleInfoJSON.Uninstallable {
 			installedStrings = nil
-			if len(m.moduleInfoJSON.CompatibilitySuites) == 1 && m.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
-				m.moduleInfoJSON.CompatibilitySuites = nil
-				m.moduleInfoJSON.TestConfig = nil
-				m.moduleInfoJSON.AutoTestConfig = nil
+			if len(ctx.moduleInfoJSON.CompatibilitySuites) == 1 && ctx.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
+				ctx.moduleInfoJSON.CompatibilitySuites = nil
+				ctx.moduleInfoJSON.TestConfig = nil
+				ctx.moduleInfoJSON.AutoTestConfig = nil
 				data = nil
 			}
 		}
 
-		m.moduleInfoJSON.core = CoreModuleInfoJSON{
-			RegisterName:       m.moduleInfoRegisterName(ctx, m.moduleInfoJSON.SubName),
+		ctx.moduleInfoJSON.core = CoreModuleInfoJSON{
+			RegisterName:       m.moduleInfoRegisterName(ctx, ctx.moduleInfoJSON.SubName),
 			Path:               []string{ctx.ModuleDir()},
 			Installed:          installedStrings,
-			ModuleName:         m.BaseModuleName() + m.moduleInfoJSON.SubName,
+			ModuleName:         m.BaseModuleName() + ctx.moduleInfoJSON.SubName,
 			SupportedVariants:  []string{m.moduleInfoVariant(ctx)},
 			TargetDependencies: targetRequired,
 			HostDependencies:   hostRequired,
 			Data:               data,
 			Required:           m.RequiredModuleNames(ctx),
 		}
-		SetProvider(ctx, ModuleInfoJSONProvider, m.moduleInfoJSON)
+		SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
 	}
 
 	m.buildParams = ctx.buildParams
 	m.ruleParams = ctx.ruleParams
 	m.variables = ctx.variables
 
-	if m.outputFiles.DefaultOutputFiles != nil || m.outputFiles.TaggedOutputFiles != nil {
-		SetProvider(ctx, OutputFilesProvider, m.outputFiles)
+	outputFiles := ctx.GetOutputFiles()
+	if outputFiles.DefaultOutputFiles != nil || outputFiles.TaggedOutputFiles != nil {
+		SetProvider(ctx, OutputFilesProvider, outputFiles)
 	}
 
+	if len(ctx.phonies) > 0 {
+		SetProvider(ctx, ModulePhonyProvider, ModulePhonyInfo{
+			Phonies: ctx.phonies,
+		})
+	}
 	buildComplianceMetadataProvider(ctx, m)
 }
 
@@ -2098,10 +2078,6 @@
 	return variant
 }
 
-func (m *ModuleBase) ContainersInfo() ContainersInfo {
-	return m.containersInfo
-}
-
 // Check the supplied dist structure to make sure that it is valid.
 //
 // property - the base property, e.g. dist or dists[1], which is combined with the
@@ -2543,13 +2519,14 @@
 	type OutputFilesProviderModuleContext interface {
 		OtherModuleProviderContext
 		Module() Module
+		GetOutputFiles() OutputFilesInfo
 	}
 
 	if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx {
 		if mctx.Module() != module {
 			outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
 		} else {
-			outputFiles = mctx.Module().base().outputFiles
+			outputFiles = mctx.GetOutputFiles()
 			fromProperty = true
 		}
 	} else if cta, isCta := ctx.(*singletonContextAdaptor); isCta {
@@ -2655,17 +2632,15 @@
 	modulesInDir := make(map[string]Paths)
 
 	ctx.VisitAllModules(func(module Module) {
-		blueprintDir := module.base().blueprintDir
-		installTarget := module.base().installTarget
-		checkbuildTarget := module.base().checkbuildTarget
+		info := OtherModuleProviderOrDefault(ctx, module, FinalModuleBuildTargetsProvider)
 
-		if checkbuildTarget != nil {
-			checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
-			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
+		if info.CheckbuildTarget != nil {
+			checkbuildDeps = append(checkbuildDeps, info.CheckbuildTarget)
+			modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.CheckbuildTarget)
 		}
 
-		if installTarget != nil {
-			modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
+		if info.InstallTarget != nil {
+			modulesInDir[info.BlueprintDir] = append(modulesInDir[info.BlueprintDir], info.InstallTarget)
 		}
 	})
 
@@ -2735,7 +2710,7 @@
 
 // Collect information for opening IDE project files in java/jdeps.go.
 type IDEInfo interface {
-	IDEInfo(ideInfo *IdeInfo)
+	IDEInfo(ctx BaseModuleContext, ideInfo *IdeInfo)
 	BaseModuleName() string
 }
 
@@ -2747,7 +2722,9 @@
 	IDECustomizedModuleName() string
 }
 
+// Collect information for opening IDE project files in java/jdeps.go.
 type IdeInfo struct {
+	BaseModuleName    string   `json:"-"`
 	Deps              []string `json:"dependencies,omitempty"`
 	Srcs              []string `json:"srcs,omitempty"`
 	Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
@@ -2761,6 +2738,31 @@
 	Libs              []string `json:"libs,omitempty"`
 }
 
+// Merge merges two IdeInfos and produces a new one, leaving the origional unchanged
+func (i IdeInfo) Merge(other IdeInfo) IdeInfo {
+	return IdeInfo{
+		Deps:              mergeStringLists(i.Deps, other.Deps),
+		Srcs:              mergeStringLists(i.Srcs, other.Srcs),
+		Aidl_include_dirs: mergeStringLists(i.Aidl_include_dirs, other.Aidl_include_dirs),
+		Jarjar_rules:      mergeStringLists(i.Jarjar_rules, other.Jarjar_rules),
+		Jars:              mergeStringLists(i.Jars, other.Jars),
+		Classes:           mergeStringLists(i.Classes, other.Classes),
+		Installed_paths:   mergeStringLists(i.Installed_paths, other.Installed_paths),
+		SrcJars:           mergeStringLists(i.SrcJars, other.SrcJars),
+		Paths:             mergeStringLists(i.Paths, other.Paths),
+		Static_libs:       mergeStringLists(i.Static_libs, other.Static_libs),
+		Libs:              mergeStringLists(i.Libs, other.Libs),
+	}
+}
+
+// mergeStringLists appends the two string lists together and returns a new string list,
+// leaving the originals unchanged. Duplicate strings will be deduplicated.
+func mergeStringLists(a, b []string) []string {
+	return FirstUniqueStrings(Concat(a, b))
+}
+
+var IdeInfoProviderKey = blueprint.NewProvider[IdeInfo]()
+
 func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
 	bpctx := ctx.blueprintBaseModuleContext()
 	return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents)
diff --git a/android/module_context.go b/android/module_context.go
index f619da2..c677f94 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -107,65 +107,65 @@
 	// InstallExecutable creates a rule to copy srcPath to name in the installPath directory,
 	// with the given additional dependencies.  The file is marked executable after copying.
 	//
-	// The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
-	// installed file will be returned by PackagingSpecs() on this module or by
-	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
-	// for which IsInstallDepNeeded returns true.
+	// The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+	// for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
+	// or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+	// dependency tags for which IsInstallDepNeeded returns true.
 	InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
 
 	// InstallFile creates a rule to copy srcPath to name in the installPath directory,
 	// with the given additional dependencies.
 	//
-	// The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
-	// installed file will be returned by PackagingSpecs() on this module or by
-	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
-	// for which IsInstallDepNeeded returns true.
+	// The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+	// for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
+	// or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+	// dependency tags for which IsInstallDepNeeded returns true.
 	InstallFile(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
 
 	// InstallFileWithExtraFilesZip creates a rule to copy srcPath to name in the installPath
 	// directory, and also unzip a zip file containing extra files to install into the same
 	// directory.
 	//
-	// The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
-	// installed file will be returned by PackagingSpecs() on this module or by
-	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
-	// for which IsInstallDepNeeded returns true.
+	// The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+	// for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
+	// or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+	// dependency tags for which IsInstallDepNeeded returns true.
 	InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path, extraZip Path, deps ...InstallPath) InstallPath
 
 	// InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath
 	// directory.
 	//
-	// The installed symlink will be returned by FilesToInstall(), and the PackagingSpec for the
-	// installed file will be returned by PackagingSpecs() on this module or by
-	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
-	// for which IsInstallDepNeeded returns true.
+	// The installed symlink can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+	// for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
+	// or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+	// dependency tags for which IsInstallDepNeeded returns true.
 	InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath
 
 	// InstallAbsoluteSymlink creates a rule to create an absolute symlink from src srcPath to name
 	// in the installPath directory.
 	//
-	// The installed symlink will be returned by FilesToInstall(), and the PackagingSpec for the
-	// installed file will be returned by PackagingSpecs() on this module or by
-	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
-	// for which IsInstallDepNeeded returns true.
+	// The installed symlink can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+	// for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
+	// or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+	// dependency tags for which IsInstallDepNeeded returns true.
 	InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath
 
 	// InstallTestData creates rules to install test data (e.g. data files used during a test) into
 	// the installPath directory.
 	//
-	// The installed files will be returned by FilesToInstall(), and the PackagingSpec for the
-	// installed files will be returned by PackagingSpecs() on this module or by
-	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
-	// for which IsInstallDepNeeded returns true.
+	// The installed files can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+	// for the installed files can be accessed by InstallFilesInfo.PackagingSpecs on this module
+	// or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+	// dependency tags for which IsInstallDepNeeded returns true.
 	InstallTestData(installPath InstallPath, data []DataPath) InstallPaths
 
 	// PackageFile creates a PackagingSpec as if InstallFile was called, but without creating
 	// the rule to copy the file.  This is useful to define how a module would be packaged
 	// without installing it into the global installation directories.
 	//
-	// The created PackagingSpec for the will be returned by PackagingSpecs() on this module or by
-	// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
-	// for which IsInstallDepNeeded returns true.
+	// The created PackagingSpec can be accessed by InstallFilesInfo.PackagingSpecs on this module
+	// or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+	// dependency tags for which IsInstallDepNeeded returns true.
 	PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec
 
 	CheckbuildFile(srcPath Path)
@@ -216,10 +216,22 @@
 	// to set the OutputFilesProvider later.
 	SetOutputFiles(outputFiles Paths, tag string)
 
+	GetOutputFiles() OutputFilesInfo
+
+	// SetLicenseInstallMap stores the set of dependency module:location mappings for files in an
+	// apex container for use when generation the license metadata file.
+	SetLicenseInstallMap(installMap []string)
+
 	// ComplianceMetadataInfo returns a ComplianceMetadataInfo instance for different module types to dump metadata,
 	// which usually happens in GenerateAndroidBuildActions() of a module type.
 	// See android.ModuleBase.complianceMetadataInfo
 	ComplianceMetadataInfo() *ComplianceMetadataInfo
+
+	// Get the information about the containers this module belongs to.
+	getContainersInfo() ContainersInfo
+	setContainersInfo(info ContainersInfo)
+
+	setAconfigPaths(paths Paths)
 }
 
 type moduleContext struct {
@@ -230,9 +242,29 @@
 	checkbuildFiles Paths
 	module          Module
 	phonies         map[string]Paths
+	// outputFiles stores the output of a module by tag and is used to set
+	// the OutputFilesProvider in GenerateBuildActions
+	outputFiles OutputFilesInfo
+
+	TransitiveInstallFiles *DepSet[InstallPath]
+
+	// set of dependency module:location mappings used to populate the license metadata for
+	// apex containers.
+	licenseInstallMap []string
+
+	// The path to the generated license metadata file for the module.
+	licenseMetadataFile WritablePath
 
 	katiInstalls katiInstalls
 	katiSymlinks katiInstalls
+	// katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
+	// allowed to have duplicates across modules and variants.
+	katiInitRcInstalls           katiInstalls
+	katiVintfInstalls            katiInstalls
+	initRcPaths                  Paths
+	vintfFragmentsPaths          Paths
+	installedInitRcPaths         InstallPaths
+	installedVintfFragmentsPaths InstallPaths
 
 	testData []DataPath
 
@@ -240,6 +272,21 @@
 	buildParams []BuildParams
 	ruleParams  map[blueprint.Rule]blueprint.RuleParams
 	variables   map[string]string
+
+	// moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will
+	// be included in the final module-info.json produced by Make.
+	moduleInfoJSON *ModuleInfoJSON
+
+	// containersInfo stores the information about the containers and the information of the
+	// apexes the module belongs to.
+	containersInfo ContainersInfo
+
+	// Merged Aconfig files for all transitive deps.
+	aconfigFilePaths Paths
+
+	// complianceMetadataInfo is for different module types to dump metadata.
+	// See android.ModuleContext interface.
+	complianceMetadataInfo *ComplianceMetadataInfo
 }
 
 var _ ModuleContext = &moduleContext{}
@@ -361,7 +408,7 @@
 }
 
 func (m *moduleContext) Phony(name string, deps ...Path) {
-	addPhony(m.config, name, deps...)
+	m.phonies[name] = append(m.phonies[name], deps...)
 }
 
 func (m *moduleContext) GetMissingDependencies() []string {
@@ -487,7 +534,11 @@
 }
 
 func (m *moduleContext) getAconfigPaths() *Paths {
-	return &m.module.base().aconfigFilePaths
+	return &m.aconfigFilePaths
+}
+
+func (m *moduleContext) setAconfigPaths(paths Paths) {
+	m.aconfigFilePaths = paths
 }
 
 func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool) PackagingSpec {
@@ -516,9 +567,9 @@
 	}
 
 	if m.requiresFullInstall() {
-		deps = append(deps, InstallPaths(m.module.base().installFilesDepSet.ToList())...)
-		deps = append(deps, m.module.base().installedInitRcPaths...)
-		deps = append(deps, m.module.base().installedVintfFragmentsPaths...)
+		deps = append(deps, InstallPaths(m.TransitiveInstallFiles.ToList())...)
+		deps = append(deps, m.installedInitRcPaths...)
+		deps = append(deps, m.installedVintfFragmentsPaths...)
 
 		var implicitDeps, orderOnlyDeps Paths
 
@@ -699,43 +750,49 @@
 }
 
 func (m *moduleContext) LicenseMetadataFile() Path {
-	return m.module.base().licenseMetadataFile
+	return m.licenseMetadataFile
 }
 
 func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON {
-	if moduleInfoJSON := m.module.base().moduleInfoJSON; moduleInfoJSON != nil {
+	if moduleInfoJSON := m.moduleInfoJSON; moduleInfoJSON != nil {
 		return moduleInfoJSON
 	}
 	moduleInfoJSON := &ModuleInfoJSON{}
-	m.module.base().moduleInfoJSON = moduleInfoJSON
+	m.moduleInfoJSON = moduleInfoJSON
 	return moduleInfoJSON
 }
 
 func (m *moduleContext) SetOutputFiles(outputFiles Paths, tag string) {
 	if tag == "" {
-		if len(m.module.base().outputFiles.DefaultOutputFiles) > 0 {
+		if len(m.outputFiles.DefaultOutputFiles) > 0 {
 			m.ModuleErrorf("Module %s default OutputFiles cannot be overwritten", m.ModuleName())
 		}
-		m.module.base().outputFiles.DefaultOutputFiles = outputFiles
+		m.outputFiles.DefaultOutputFiles = outputFiles
 	} else {
-		if m.module.base().outputFiles.TaggedOutputFiles == nil {
-			m.module.base().outputFiles.TaggedOutputFiles = make(map[string]Paths)
+		if m.outputFiles.TaggedOutputFiles == nil {
+			m.outputFiles.TaggedOutputFiles = make(map[string]Paths)
 		}
-		if _, exists := m.module.base().outputFiles.TaggedOutputFiles[tag]; exists {
+		if _, exists := m.outputFiles.TaggedOutputFiles[tag]; exists {
 			m.ModuleErrorf("Module %s OutputFiles at tag %s cannot be overwritten", m.ModuleName(), tag)
 		} else {
-			m.module.base().outputFiles.TaggedOutputFiles[tag] = outputFiles
+			m.outputFiles.TaggedOutputFiles[tag] = outputFiles
 		}
 	}
 }
 
+func (m *moduleContext) GetOutputFiles() OutputFilesInfo {
+	return m.outputFiles
+}
+
+func (m *moduleContext) SetLicenseInstallMap(installMap []string) {
+	m.licenseInstallMap = append(m.licenseInstallMap, installMap...)
+}
+
 func (m *moduleContext) ComplianceMetadataInfo() *ComplianceMetadataInfo {
-	if complianceMetadataInfo := m.module.base().complianceMetadataInfo; complianceMetadataInfo != nil {
-		return complianceMetadataInfo
+	if m.complianceMetadataInfo == nil {
+		m.complianceMetadataInfo = NewComplianceMetadataInfo()
 	}
-	complianceMetadataInfo := NewComplianceMetadataInfo()
-	m.module.base().complianceMetadataInfo = complianceMetadataInfo
-	return complianceMetadataInfo
+	return m.complianceMetadataInfo
 }
 
 // Returns a list of paths expanded from globs and modules referenced using ":module" syntax.  The property must
@@ -775,3 +832,11 @@
 func (m *moduleContext) TargetRequiredModuleNames() []string {
 	return m.module.TargetRequiredModuleNames()
 }
+
+func (m *moduleContext) getContainersInfo() ContainersInfo {
+	return m.containersInfo
+}
+
+func (m *moduleContext) setContainersInfo(info ContainersInfo) {
+	m.containersInfo = info
+}
diff --git a/android/module_test.go b/android/module_test.go
index 829c079..d64e3a5 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -722,6 +722,7 @@
 				propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "x86_64 a"},
 				propInfo{Name: "B", Type: "bool", Value: "true"},
 				propInfo{Name: "C", Type: "string slice", Values: []string{"default_c", "c"}},
+				propInfo{Name: "Defaults", Type: "string slice", Values: []string{"foo_defaults"}},
 				propInfo{Name: "Embedded_prop", Type: "string", Value: "a"},
 				propInfo{Name: "Name", Type: "string", Value: "foo"},
 				propInfo{Name: "Nested.E", Type: "string", Value: "nested e"},
@@ -993,6 +994,10 @@
 
 func (p *pathContextAddMissingDependenciesWrapper) Module() Module { return nil }
 
+func (p *pathContextAddMissingDependenciesWrapper) GetOutputFiles() OutputFilesInfo {
+	return OutputFilesInfo{}
+}
+
 func TestOutputFileForModule(t *testing.T) {
 	testcases := []struct {
 		name        string
diff --git a/android/neverallow.go b/android/neverallow.go
index 0f363e7..a68f5ea 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -287,7 +287,7 @@
 			continue
 		}
 
-		if !n.appliesToProperties(properties) {
+		if !n.appliesToProperties(ctx, properties) {
 			continue
 		}
 
@@ -604,9 +604,9 @@
 	return (len(r.moduleTypes) == 0 || InList(moduleType, r.moduleTypes)) && !InList(moduleType, r.unlessModuleTypes)
 }
 
-func (r *rule) appliesToProperties(properties []interface{}) bool {
-	includeProps := hasAllProperties(properties, r.props)
-	excludeProps := hasAnyProperty(properties, r.unlessProps)
+func (r *rule) appliesToProperties(ctx BottomUpMutatorContext, properties []interface{}) bool {
+	includeProps := hasAllProperties(ctx, properties, r.props)
+	excludeProps := hasAnyProperty(ctx, properties, r.unlessProps)
 	return includeProps && !excludeProps
 }
 
@@ -644,25 +644,25 @@
 	return names
 }
 
-func hasAnyProperty(properties []interface{}, props []ruleProperty) bool {
+func hasAnyProperty(ctx BottomUpMutatorContext, properties []interface{}, props []ruleProperty) bool {
 	for _, v := range props {
-		if hasProperty(properties, v) {
+		if hasProperty(ctx, properties, v) {
 			return true
 		}
 	}
 	return false
 }
 
-func hasAllProperties(properties []interface{}, props []ruleProperty) bool {
+func hasAllProperties(ctx BottomUpMutatorContext, properties []interface{}, props []ruleProperty) bool {
 	for _, v := range props {
-		if !hasProperty(properties, v) {
+		if !hasProperty(ctx, properties, v) {
 			return false
 		}
 	}
 	return true
 }
 
-func hasProperty(properties []interface{}, prop ruleProperty) bool {
+func hasProperty(ctx BottomUpMutatorContext, properties []interface{}, prop ruleProperty) bool {
 	for _, propertyStruct := range properties {
 		propertiesValue := reflect.ValueOf(propertyStruct).Elem()
 		for _, v := range prop.fields {
@@ -679,14 +679,14 @@
 			return prop.matcher.Test(value)
 		}
 
-		if matchValue(propertiesValue, check) {
+		if matchValue(ctx, propertiesValue, check) {
 			return true
 		}
 	}
 	return false
 }
 
-func matchValue(value reflect.Value, check func(string) bool) bool {
+func matchValue(ctx BottomUpMutatorContext, value reflect.Value, check func(string) bool) bool {
 	if !value.IsValid() {
 		return false
 	}
@@ -698,19 +698,26 @@
 		value = value.Elem()
 	}
 
-	switch value.Kind() {
-	case reflect.String:
-		return check(value.String())
-	case reflect.Bool:
-		return check(strconv.FormatBool(value.Bool()))
-	case reflect.Int:
-		return check(strconv.FormatInt(value.Int(), 10))
-	case reflect.Slice:
-		slice, ok := value.Interface().([]string)
-		if !ok {
-			panic("Can only handle slice of string")
+	switch v := value.Interface().(type) {
+	case string:
+		return check(v)
+	case bool:
+		return check(strconv.FormatBool(v))
+	case int:
+		return check(strconv.FormatInt((int64)(v), 10))
+	case []string:
+		for _, v := range v {
+			if check(v) {
+				return true
+			}
 		}
-		for _, v := range slice {
+		return false
+	case proptools.Configurable[string]:
+		return check(v.GetOrDefault(ctx, ""))
+	case proptools.Configurable[bool]:
+		return check(strconv.FormatBool(v.GetOrDefault(ctx, false)))
+	case proptools.Configurable[[]string]:
+		for _, v := range v.GetOrDefault(ctx, nil) {
 			if check(v) {
 				return true
 			}
diff --git a/android/notices.go b/android/notices.go
index b9c1682..3c41d92 100644
--- a/android/notices.go
+++ b/android/notices.go
@@ -36,10 +36,22 @@
 	return SortedUniqueStrings(dirs)
 }
 
-func modulesLicenseMetadata(ctx BuilderContext, modules ...Module) Paths {
+type BuilderAndOtherModuleProviderContext interface {
+	BuilderContext
+	OtherModuleProviderContext
+}
+
+func modulesLicenseMetadata(ctx OtherModuleProviderContext, modules ...Module) Paths {
 	result := make(Paths, 0, len(modules))
+	mctx, isMctx := ctx.(ModuleContext)
 	for _, module := range modules {
-		if mf := module.base().licenseMetadataFile; mf != nil {
+		var mf Path
+		if isMctx && mctx.Module() == module {
+			mf = mctx.LicenseMetadataFile()
+		} else {
+			mf = OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).LicenseMetadataFile
+		}
+		if mf != nil {
 			result = append(result, mf)
 		}
 	}
@@ -48,7 +60,7 @@
 
 // buildNoticeOutputFromLicenseMetadata writes out a notice file.
 func buildNoticeOutputFromLicenseMetadata(
-	ctx BuilderContext, tool, ruleName string, outputFile WritablePath,
+	ctx BuilderAndOtherModuleProviderContext, tool, ruleName string, outputFile WritablePath,
 	libraryName string, stripPrefix []string, modules ...Module) {
 	depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", "."))
 	rule := NewRuleBuilder(pctx, ctx)
@@ -84,7 +96,7 @@
 // on the license metadata files for the input `modules` defaulting to the
 // current context module if none given.
 func BuildNoticeTextOutputFromLicenseMetadata(
-	ctx BuilderContext, outputFile WritablePath, ruleName, libraryName string,
+	ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
 	stripPrefix []string, modules ...Module) {
 	buildNoticeOutputFromLicenseMetadata(ctx, "textnotice", "text_notice_"+ruleName,
 		outputFile, libraryName, stripPrefix, modules...)
@@ -94,7 +106,7 @@
 // on the license metadata files for the input `modules` defaulting to the
 // current context module if none given.
 func BuildNoticeHtmlOutputFromLicenseMetadata(
-	ctx BuilderContext, outputFile WritablePath, ruleName, libraryName string,
+	ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
 	stripPrefix []string, modules ...Module) {
 	buildNoticeOutputFromLicenseMetadata(ctx, "htmlnotice", "html_notice_"+ruleName,
 		outputFile, libraryName, stripPrefix, modules...)
@@ -104,7 +116,7 @@
 // on the license metadata files for the input `modules` defaulting to the
 // current context module if none given.
 func BuildNoticeXmlOutputFromLicenseMetadata(
-	ctx BuilderContext, outputFile WritablePath, ruleName, libraryName string,
+	ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
 	stripPrefix []string, modules ...Module) {
 	buildNoticeOutputFromLicenseMetadata(ctx, "xmlnotice", "xml_notice_"+ruleName,
 		outputFile, libraryName, stripPrefix, modules...)
diff --git a/android/packaging.go b/android/packaging.go
index c247ed2..42009d5 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -346,7 +346,8 @@
 		if pi, ok := ctx.OtherModuleDependencyTag(child).(PackagingItem); !ok || !pi.IsPackagingItem() {
 			return
 		}
-		for _, ps := range child.TransitivePackagingSpecs() {
+		for _, ps := range OtherModuleProviderOrDefault(
+			ctx, child, InstallFilesProvider).TransitivePackagingSpecs.ToList() {
 			if !filterArch(ps) {
 				continue
 			}
diff --git a/android/phony.go b/android/phony.go
index 814a9e3..f8db88d 100644
--- a/android/phony.go
+++ b/android/phony.go
@@ -26,14 +26,20 @@
 
 var phonyMapLock sync.Mutex
 
-func getPhonyMap(config Config) phonyMap {
+type ModulePhonyInfo struct {
+	Phonies map[string]Paths
+}
+
+var ModulePhonyProvider = blueprint.NewProvider[ModulePhonyInfo]()
+
+func getSingletonPhonyMap(config Config) phonyMap {
 	return config.Once(phonyMapOnceKey, func() interface{} {
 		return make(phonyMap)
 	}).(phonyMap)
 }
 
-func addPhony(config Config, name string, deps ...Path) {
-	phonyMap := getPhonyMap(config)
+func addSingletonPhony(config Config, name string, deps ...Path) {
+	phonyMap := getSingletonPhonyMap(config)
 	phonyMapLock.Lock()
 	defer phonyMapLock.Unlock()
 	phonyMap[name] = append(phonyMap[name], deps...)
@@ -47,7 +53,15 @@
 var _ SingletonMakeVarsProvider = (*phonySingleton)(nil)
 
 func (p *phonySingleton) GenerateBuildActions(ctx SingletonContext) {
-	p.phonyMap = getPhonyMap(ctx.Config())
+	p.phonyMap = getSingletonPhonyMap(ctx.Config())
+	ctx.VisitAllModules(func(m Module) {
+		if info, ok := OtherModuleProvider(ctx, m, ModulePhonyProvider); ok {
+			for k, v := range info.Phonies {
+				p.phonyMap[k] = append(p.phonyMap[k], v...)
+			}
+		}
+	})
+
 	p.phonyList = SortedKeys(p.phonyMap)
 	for _, phony := range p.phonyList {
 		p.phonyMap[phony] = SortedUniquePaths(p.phonyMap[phony])
diff --git a/android/product_config.go b/android/product_config.go
index 20b29a7..04180bf 100644
--- a/android/product_config.go
+++ b/android/product_config.go
@@ -37,8 +37,10 @@
 	if targetProduct != "" {
 		targetProduct += "."
 	}
-	soongVariablesPath := PathForOutput(ctx, "soong."+targetProduct+"variables")
-	extraVariablesPath := PathForOutput(ctx, "soong."+targetProduct+"extra.variables")
+
+	coverageSuffix := ctx.Config().CoverageSuffix()
+	soongVariablesPath := PathForOutput(ctx, "soong."+targetProduct+coverageSuffix+"variables")
+	extraVariablesPath := PathForOutput(ctx, "soong."+targetProduct+coverageSuffix+"extra.variables")
 
 	rule := NewRuleBuilder(pctx, ctx)
 	rule.Command().BuiltTool("merge_json").
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 464aca4..95e2b92 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -580,6 +580,16 @@
 				})
 			}
 
+			// Set OUT_DIR to the relative path of the sandboxed out directory.
+			// Otherwise, OUT_DIR will be inherited from the rest of the build,
+			// which will allow scripts to escape the sandbox if OUT_DIR is an
+			// absolute path.
+			command.Env = append(command.Env, &sbox_proto.EnvironmentVariable{
+				Name: proto.String("OUT_DIR"),
+				State: &sbox_proto.EnvironmentVariable_Value{
+					Value: sboxOutSubDir,
+				},
+			})
 			command.Chdir = proto.Bool(true)
 		}
 
diff --git a/android/sdk_version.go b/android/sdk_version.go
index 01b55d0..a9b88fb 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -93,6 +93,15 @@
 	}
 }
 
+func ToSdkKind(s string) SdkKind {
+	for kind := SdkNone; kind <= SdkPrivate; kind++ {
+		if s == kind.String() {
+			return kind
+		}
+	}
+	return SdkInvalid
+}
+
 func (k SdkKind) DefaultJavaLibraryName() string {
 	switch k {
 	case SdkPublic:
diff --git a/android/singleton.go b/android/singleton.go
index 92264d2..8542bd9 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -177,7 +177,7 @@
 }
 
 func (s *singletonContextAdaptor) Phony(name string, deps ...Path) {
-	addPhony(s.Config(), name, deps...)
+	addSingletonPhony(s.Config(), name, deps...)
 }
 
 func (s *singletonContextAdaptor) SetOutDir(pctx PackageContext, value string) {
diff --git a/android/testing.go b/android/testing.go
index 79d0c9b..816707d 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -1038,8 +1038,8 @@
 // Exits the test immediately if there is an error and
 // otherwise returns the result of calling Paths.RelativeToTop
 // on the returned Paths.
-func (m TestingModule) OutputFiles(t *testing.T, tag string) Paths {
-	outputFiles := m.Module().base().outputFiles
+func (m TestingModule) OutputFiles(ctx *TestContext, t *testing.T, tag string) Paths {
+	outputFiles := OtherModuleProviderOrDefault(ctx.OtherModuleProviderAdaptor(), m.Module(), OutputFilesProvider)
 	if tag == "" && outputFiles.DefaultOutputFiles != nil {
 		return outputFiles.DefaultOutputFiles.RelativeToTop()
 	} else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag {
diff --git a/android/variable.go b/android/variable.go
index c141437..14f1756 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -187,10 +187,10 @@
 		// release_aidl_use_unfrozen is "true" when a device can
 		// use the unfrozen versions of AIDL interfaces.
 		Release_aidl_use_unfrozen struct {
-			Cflags          []string
-			Cmd             *string
-			Required        []string
-			Vintf_fragments []string
+			Cflags                 []string
+			Cmd                    *string
+			Required               []string
+			Vintf_fragment_modules []string
 		}
 	} `android:"arch_variant"`
 }
@@ -380,6 +380,7 @@
 	SystemExtPrivateSepolicyDirs []string `json:",omitempty"`
 	BoardSepolicyM4Defs          []string `json:",omitempty"`
 
+	BoardPlatform           *string `json:",omitempty"`
 	BoardSepolicyVers       *string `json:",omitempty"`
 	PlatformSepolicyVersion *string `json:",omitempty"`
 
@@ -511,13 +512,9 @@
 	SystemPropFiles    []string `json:",omitempty"`
 	SystemExtPropFiles []string `json:",omitempty"`
 	ProductPropFiles   []string `json:",omitempty"`
+	OdmPropFiles       []string `json:",omitempty"`
 
 	EnableUffdGc *string `json:",omitempty"`
-
-	BoardAvbEnable                         *bool    `json:",omitempty"`
-	BoardAvbSystemAddHashtreeFooterArgs    []string `json:",omitempty"`
-	DeviceFrameworkCompatibilityMatrixFile []string `json:",omitempty"`
-	DeviceProductCompatibilityMatrixFile   []string `json:",omitempty"`
 }
 
 type PartitionQualifiedVariablesType struct {
diff --git a/apex/aconfig_test.go b/apex/aconfig_test.go
index 14c0b63..bb811f5 100644
--- a/apex/aconfig_test.go
+++ b/apex/aconfig_test.go
@@ -74,6 +74,8 @@
 					apex_available: [
 						"myapex",
 					],
+					sdk_version: "none",
+					system_modules: "none",
 				}`,
 		},
 		{
@@ -122,6 +124,8 @@
 					apex_available: [
 						"myapex",
 					],
+					sdk_version: "none",
+					system_modules: "none",
 				}`,
 		},
 		{
@@ -345,6 +349,8 @@
 					apex_available: [
 						"myapex",
 					],
+					sdk_version: "none",
+					system_modules: "none",
 				}`,
 			expectedError: `.*my_java_library_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
 		},
@@ -392,6 +398,8 @@
 					apex_available: [
 						"myapex",
 					],
+					sdk_version: "none",
+					system_modules: "none",
 				}`,
 			expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
 		},
@@ -693,6 +701,8 @@
 					apex_available: [
 						"myapex",
 					],
+					sdk_version: "none",
+					system_modules: "none",
 				}`,
 			expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
 		},
@@ -769,6 +779,8 @@
 					apex_available: [
 						"myapex",
 					],
+					sdk_version: "none",
+					system_modules: "none",
 				}`,
 		},
 	}
diff --git a/apex/apex.go b/apex/apex.go
index 77ebf26..d5776b5 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -213,6 +213,50 @@
 
 type ApexNativeDependencies struct {
 	// List of native libraries that are embedded inside this APEX.
+	Native_shared_libs proptools.Configurable[[]string]
+
+	// List of JNI libraries that are embedded inside this APEX.
+	Jni_libs []string
+
+	// List of rust dyn libraries that are embedded inside this APEX.
+	Rust_dyn_libs []string
+
+	// List of native executables that are embedded inside this APEX.
+	Binaries proptools.Configurable[[]string]
+
+	// List of native tests that are embedded inside this APEX.
+	Tests []string
+
+	// List of filesystem images that are embedded inside this APEX bundle.
+	Filesystems []string
+
+	// List of prebuilt_etcs that are embedded inside this APEX bundle.
+	Prebuilts proptools.Configurable[[]string]
+
+	// List of native libraries to exclude from this APEX.
+	Exclude_native_shared_libs []string
+
+	// List of JNI libraries to exclude from this APEX.
+	Exclude_jni_libs []string
+
+	// List of rust dyn libraries to exclude from this APEX.
+	Exclude_rust_dyn_libs []string
+
+	// List of native executables to exclude from this APEX.
+	Exclude_binaries []string
+
+	// List of native tests to exclude from this APEX.
+	Exclude_tests []string
+
+	// List of filesystem images to exclude from this APEX bundle.
+	Exclude_filesystems []string
+
+	// List of prebuilt_etcs to exclude from this APEX bundle.
+	Exclude_prebuilts []string
+}
+
+type ResolvedApexNativeDependencies struct {
+	// List of native libraries that are embedded inside this APEX.
 	Native_shared_libs []string
 
 	// List of JNI libraries that are embedded inside this APEX.
@@ -222,8 +266,7 @@
 	Rust_dyn_libs []string
 
 	// List of native executables that are embedded inside this APEX.
-	Binaries         proptools.Configurable[[]string]
-	ResolvedBinaries []string `blueprint:"mutated"`
+	Binaries []string
 
 	// List of native tests that are embedded inside this APEX.
 	Tests []string
@@ -232,8 +275,7 @@
 	Filesystems []string
 
 	// List of prebuilt_etcs that are embedded inside this APEX bundle.
-	Prebuilts         proptools.Configurable[[]string]
-	ResolvedPrebuilts []string `blueprint:"mutated"`
+	Prebuilts []string
 
 	// List of native libraries to exclude from this APEX.
 	Exclude_native_shared_libs []string
@@ -258,14 +300,14 @@
 }
 
 // Merge combines another ApexNativeDependencies into this one
-func (a *ApexNativeDependencies) Merge(ctx android.BaseMutatorContext, b ApexNativeDependencies) {
-	a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
+func (a *ResolvedApexNativeDependencies) Merge(ctx android.BaseMutatorContext, b ApexNativeDependencies) {
+	a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs.GetOrDefault(ctx, nil)...)
 	a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
 	a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
-	a.ResolvedBinaries = append(a.ResolvedBinaries, b.Binaries.GetOrDefault(ctx, nil)...)
+	a.Binaries = append(a.Binaries, b.Binaries.GetOrDefault(ctx, nil)...)
 	a.Tests = append(a.Tests, b.Tests...)
 	a.Filesystems = append(a.Filesystems, b.Filesystems...)
-	a.ResolvedPrebuilts = append(a.ResolvedPrebuilts, b.Prebuilts.GetOrDefault(ctx, nil)...)
+	a.Prebuilts = append(a.Prebuilts, b.Prebuilts.GetOrDefault(ctx, nil)...)
 
 	a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
 	a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
@@ -657,6 +699,8 @@
 	// If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
 	// also be added as exported members of that SDK.
 	memberType android.SdkMemberType
+
+	installable bool
 }
 
 func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
@@ -675,18 +719,23 @@
 	return !d.sourceOnly
 }
 
+func (d *dependencyTag) InstallDepNeeded() bool {
+	return d.installable
+}
+
 var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
 var _ android.SdkMemberDependencyTag = &dependencyTag{}
 
 var (
-	androidAppTag   = &dependencyTag{name: "androidApp", payload: true}
-	bpfTag          = &dependencyTag{name: "bpf", payload: true}
-	certificateTag  = &dependencyTag{name: "certificate"}
-	dclaTag         = &dependencyTag{name: "dcla"}
-	executableTag   = &dependencyTag{name: "executable", payload: true}
-	fsTag           = &dependencyTag{name: "filesystem", payload: true}
-	bcpfTag         = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
-	sscpfTag        = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
+	androidAppTag  = &dependencyTag{name: "androidApp", payload: true}
+	bpfTag         = &dependencyTag{name: "bpf", payload: true}
+	certificateTag = &dependencyTag{name: "certificate"}
+	dclaTag        = &dependencyTag{name: "dcla"}
+	executableTag  = &dependencyTag{name: "executable", payload: true}
+	fsTag          = &dependencyTag{name: "filesystem", payload: true}
+	bcpfTag        = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
+	// The dexpreopt artifacts of apex system server jars are installed onto system image.
+	sscpfTag        = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType, installable: true}
 	compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
 	javaLibTag      = &dependencyTag{name: "javaLib", payload: true}
 	jniLibTag       = &dependencyTag{name: "jniLib", payload: true}
@@ -700,7 +749,7 @@
 )
 
 // TODO(jiyong): shorten this function signature
-func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
+func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ResolvedApexNativeDependencies, target android.Target, imageVariation string) {
 	binVariations := target.Variations()
 	libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
 	rustLibVariations := append(
@@ -718,7 +767,7 @@
 	// this module. This is required since arch variant of an APEX bundle is 'common' but it is
 	// 'arm' or 'arm64' for native shared libs.
 	ctx.AddFarVariationDependencies(binVariations, executableTag,
-		android.RemoveListFromList(nativeModules.ResolvedBinaries, nativeModules.Exclude_binaries)...)
+		android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
 	ctx.AddFarVariationDependencies(binVariations, testTag,
 		android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
 	ctx.AddFarVariationDependencies(libVariations, jniLibTag,
@@ -730,7 +779,7 @@
 	ctx.AddFarVariationDependencies(target.Variations(), fsTag,
 		android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
 	ctx.AddFarVariationDependencies(target.Variations(), prebuiltTag,
-		android.RemoveListFromList(nativeModules.ResolvedPrebuilts, nativeModules.Exclude_prebuilts)...)
+		android.RemoveListFromList(nativeModules.Prebuilts, nativeModules.Exclude_prebuilts)...)
 }
 
 func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
@@ -781,7 +830,7 @@
 		}
 	}
 	for i, target := range targets {
-		var deps ApexNativeDependencies
+		var deps ResolvedApexNativeDependencies
 
 		// Add native modules targeting both ABIs. When multilib.* is omitted for
 		// native_shared_libs/jni_libs/tests, it implies multilib.both
@@ -798,7 +847,7 @@
 		if isPrimaryAbi {
 			deps.Merge(ctx, a.properties.Multilib.First)
 			deps.Merge(ctx, ApexNativeDependencies{
-				Native_shared_libs: nil,
+				Native_shared_libs: proptools.NewConfigurable[[]string](nil, nil),
 				Tests:              nil,
 				Jni_libs:           nil,
 				Binaries:           a.properties.Binaries,
@@ -1035,7 +1084,7 @@
 
 	if a.dynamic_common_lib_apex() {
 		android.SetProvider(mctx, DCLAInfoProvider, DCLAInfo{
-			ProvidedLibs: a.properties.Native_shared_libs,
+			ProvidedLibs: a.properties.Native_shared_libs.GetOrDefault(mctx, nil),
 		})
 	}
 }
@@ -1492,7 +1541,7 @@
 		imageVariation := a.getImageVariation()
 		for _, target := range ctx.MultiTargets() {
 			if target.Arch.ArchType.Multilib == "lib64" {
-				addDependenciesForNativeModules(ctx, ApexNativeDependencies{
+				addDependenciesForNativeModules(ctx, ResolvedApexNativeDependencies{
 					Native_shared_libs: []string{"libclang_rt.hwasan"},
 					Tests:              nil,
 					Jni_libs:           nil,
@@ -1644,12 +1693,10 @@
 	if sdkLib, ok := module.(*java.SdkLibrary); ok {
 		for _, install := range sdkLib.BuiltInstalledForApex() {
 			af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
-			install.PackageFile(ctx)
 		}
 	} else if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
 		for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
 			af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
-			install.PackageFile(ctx)
 		}
 	}
 	return af
@@ -2183,6 +2230,10 @@
 			addAconfigFiles(vctx, ctx, child)
 			return true // track transitive dependencies
 		} else if rm, ok := child.(*rust.Module); ok {
+			if !android.IsDepInSameApex(ctx, am, am) {
+				return false
+			}
+
 			af := apexFileForRustLibrary(ctx, rm)
 			af.transitiveDep = true
 			vctx.filesInfo = append(vctx.filesInfo, af)
@@ -2202,6 +2253,10 @@
 		}
 	} else if rust.IsDylibDepTag(depTag) {
 		if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
+			if !android.IsDepInSameApex(ctx, am, am) {
+				return false
+			}
+
 			af := apexFileForRustLibrary(ctx, rustm)
 			af.transitiveDep = true
 			vctx.filesInfo = append(vctx.filesInfo, af)
@@ -2818,7 +2873,7 @@
 }
 
 // Collect information for opening IDE project files in java/jdeps.go.
-func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
+func (a *apexBundle) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
 	dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...)
 	dpInfo.Deps = append(dpInfo.Deps, a.properties.Bootclasspath_fragments...)
 	dpInfo.Deps = append(dpInfo.Deps, a.properties.ResolvedSystemserverclasspathFragments...)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 6b9944d..8305333 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -906,7 +906,7 @@
 		cc_library {
 			name: "mylib",
 			srcs: ["mylib.cpp"],
-			shared_libs: ["mylib2", "mylib3"],
+			shared_libs: ["mylib2", "mylib3", "my_prebuilt_platform_lib", "my_prebuilt_platform_stub_only_lib"],
 			system_shared_libs: [],
 			stl: "none",
 			apex_available: [ "myapex" ],
@@ -919,6 +919,7 @@
 			system_shared_libs: [],
 			stl: "none",
 			stubs: {
+				symbol_file: "mylib2.map.txt",
 				versions: ["1", "2", "3"],
 			},
 		}
@@ -930,6 +931,7 @@
 			system_shared_libs: [],
 			stl: "none",
 			stubs: {
+				symbol_file: "mylib3.map.txt",
 				versions: ["10", "11", "12"],
 			},
 			apex_available: [ "myapex" ],
@@ -943,6 +945,24 @@
 			apex_available: [ "myapex" ],
 		}
 
+		cc_prebuilt_library_shared {
+			name: "my_prebuilt_platform_lib",
+			stubs: {
+				symbol_file: "my_prebuilt_platform_lib.map.txt",
+				versions: ["1", "2", "3"],
+			},
+			srcs: ["foo.so"],
+		}
+
+		// Similar to my_prebuilt_platform_lib, but this library only provides stubs, i.e. srcs is empty
+		cc_prebuilt_library_shared {
+			name: "my_prebuilt_platform_stub_only_lib",
+			stubs: {
+				symbol_file: "my_prebuilt_platform_stub_only_lib.map.txt",
+				versions: ["1", "2", "3"],
+			}
+		}
+
 		rust_binary {
 			name: "foo.rust",
 			srcs: ["foo.rs"],
@@ -1022,6 +1042,20 @@
 
 	apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
 	ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so")
+
+	// Ensure that mylib is linking with the latest version of stubs for my_prebuilt_platform_lib
+	ensureContains(t, mylibLdFlags, "my_prebuilt_platform_lib/android_arm64_armv8-a_shared_current/my_prebuilt_platform_lib.so")
+	// ... and not linking to the non-stub (impl) variant of my_prebuilt_platform_lib
+	ensureNotContains(t, mylibLdFlags, "my_prebuilt_platform_lib/android_arm64_armv8-a_shared/my_prebuilt_platform_lib.so")
+	// Ensure that genstub for platform-provided lib is invoked with --systemapi
+	ensureContains(t, ctx.ModuleForTests("my_prebuilt_platform_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
+
+	// Ensure that mylib is linking with the latest version of stubs for my_prebuilt_platform_lib
+	ensureContains(t, mylibLdFlags, "my_prebuilt_platform_stub_only_lib/android_arm64_armv8-a_shared_current/my_prebuilt_platform_stub_only_lib.so")
+	// ... and not linking to the non-stub (impl) variant of my_prebuilt_platform_lib
+	ensureNotContains(t, mylibLdFlags, "my_prebuilt_platform_stub_only_lib/android_arm64_armv8-a_shared/my_prebuilt_platform_stub_only_lib.so")
+	// Ensure that genstub for platform-provided lib is invoked with --systemapi
+	ensureContains(t, ctx.ModuleForTests("my_prebuilt_platform_stub_only_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
 }
 
 func TestApexShouldNotEmbedStubVariant(t *testing.T) {
@@ -1156,6 +1190,7 @@
 			system_shared_libs: [],
 			stl: "none",
 			stubs: {
+				symbol_file: "mylib2.map.txt",
 				versions: ["28", "29", "30", "current"],
 			},
 			min_sdk_version: "28",
@@ -1168,6 +1203,7 @@
 			system_shared_libs: [],
 			stl: "none",
 			stubs: {
+				symbol_file: "mylib3.map.txt",
 				versions: ["28", "29", "30", "current"],
 			},
 			apex_available: [ "myapex" ],
@@ -4893,6 +4929,7 @@
 		java_import {
 			name: "libfoo",
 			jars: ["libfoo.jar"],
+			sdk_version: "core_current",
 		}
 
 		java_sdk_library_import {
@@ -4933,6 +4970,22 @@
 	t.Run("prebuilt with source preferred", func(t *testing.T) {
 
 		bp := `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			updatable: false,
+			java_libs: [
+				"libfoo",
+				"libbar",
+			],
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
 		prebuilt_apex {
 			name: "myapex",
 			arch: {
@@ -4949,10 +5002,21 @@
 		java_import {
 			name: "libfoo",
 			jars: ["libfoo.jar"],
+			apex_available: [
+				"myapex",
+			],
+			compile_dex: true,
+			sdk_version: "core_current",
 		}
 
 		java_library {
 			name: "libfoo",
+			srcs: ["foo/bar/MyClass.java"],
+			apex_available: [
+				"myapex",
+			],
+			compile_dex: true,
+			sdk_version: "core_current",
 		}
 
 		java_sdk_library_import {
@@ -4960,12 +5024,21 @@
 			public: {
 				jars: ["libbar.jar"],
 			},
+			apex_available: [
+				"myapex",
+			],
+			compile_dex: true,
 		}
 
 		java_sdk_library {
 			name: "libbar",
 			srcs: ["foo/bar/MyClass.java"],
 			unsafe_ignore_missing_latest_api: true,
+			apex_available: [
+				"myapex",
+			],
+			compile_dex: true,
+			sdk_version: "core_current",
 		}
 	`
 
@@ -4974,11 +5047,9 @@
 
 		checkDexJarBuildPath(t, ctx, "prebuilt_libfoo")
 		checkDexJarInstallPath(t, ctx, "prebuilt_libfoo")
-		ensureNoSourceVariant(t, ctx, "libfoo")
 
 		checkDexJarBuildPath(t, ctx, "prebuilt_libbar")
 		checkDexJarInstallPath(t, ctx, "prebuilt_libbar")
-		ensureNoSourceVariant(t, ctx, "libbar")
 	})
 
 	t.Run("prebuilt preferred with source", func(t *testing.T) {
@@ -5004,6 +5075,7 @@
 
 		java_library {
 			name: "libfoo",
+			sdk_version: "core_current",
 		}
 
 		java_sdk_library_import {
@@ -5130,6 +5202,7 @@
 			jars: ["libfoo.jar"],
 			apex_available: ["myapex"],
 			permitted_packages: ["foo"],
+			sdk_version: "core_current",
 		}
 
 		java_sdk_library_import {
@@ -5284,12 +5357,14 @@
 			name: "libfoo",
 			jars: ["libfoo.jar"],
 			apex_available: ["myapex"],
+			sdk_version: "core_current",
 		}
 
 		java_library {
 			name: "libfoo",
 			srcs: ["foo/bar/MyClass.java"],
 			apex_available: ["myapex"],
+			sdk_version: "core_current",
 		}
 
 		java_sdk_library_import {
@@ -5381,6 +5456,7 @@
 			jars: ["libfoo.jar"],
 			apex_available: ["myapex"],
 			permitted_packages: ["foo"],
+			sdk_version: "core_current",
 		}
 
 		java_library {
@@ -5388,6 +5464,7 @@
 			srcs: ["foo/bar/MyClass.java"],
 			apex_available: ["myapex"],
 			installable: true,
+			sdk_version: "core_current",
 		}
 
 		java_sdk_library_import {
@@ -5478,6 +5555,7 @@
 			name: "libfoo",
 			jars: ["libfoo.jar"],
 			apex_available: ["myapex"],
+			sdk_version: "core_current",
 		}
 
 		java_library {
@@ -5486,6 +5564,7 @@
 			apex_available: ["myapex"],
 			permitted_packages: ["foo"],
 			installable: true,
+			sdk_version: "core_current",
 		}
 
 		java_sdk_library_import {
@@ -5504,6 +5583,7 @@
 			apex_available: ["myapex"],
 			permitted_packages: ["bar"],
 			compile_dex: true,
+			sdk_version: "core_current",
 		}
 	`
 
@@ -6098,6 +6178,7 @@
 			name: "TesterHelpAppFoo",
 			srcs: ["foo/bar/MyClass.java"],
 			apex_available: [ "myapex" ],
+			sdk_version: "test_current",
 		}
 
 	`)
@@ -7700,7 +7781,7 @@
 			srcs: ["foo/bar/MyClass.java"],
 			sdk_version: "none",
 			system_modules: "none",
-			libs: ["myotherjar"],
+			static_libs: ["myotherjar"],
 			apex_available: [
 				"myapex",
 				"myapex.updatable",
@@ -8361,6 +8442,7 @@
 			apex_available: [
 				"myapex",
 			],
+			sdk_version: "current",
 		}
 
 		systemserverclasspath_fragment {
@@ -9403,6 +9485,7 @@
 			srcs: ["mybootclasspathlib.java"],
 			apex_available: ["myapex"],
 			compile_dex: true,
+			sdk_version: "current",
 		}
 
 		systemserverclasspath_fragment {
@@ -9718,6 +9801,7 @@
 				unsafe_ignore_missing_latest_api: true,
 				min_sdk_version: "31",
 				static_libs: ["util"],
+				sdk_version: "core_current",
 			}
 
 			java_library {
@@ -9726,6 +9810,7 @@
 				apex_available: ["myapex"],
 				min_sdk_version: "31",
 				static_libs: ["another_util"],
+				sdk_version: "core_current",
 			}
 
 			java_library {
@@ -9733,6 +9818,7 @@
                 srcs: ["a.java"],
 				min_sdk_version: "31",
 				apex_available: ["myapex"],
+				sdk_version: "core_current",
 			}
 		`)
 	})
@@ -9788,7 +9874,7 @@
 	})
 
 	t.Run("bootclasspath_fragment jar must set min_sdk_version", func(t *testing.T) {
-		preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "mybootclasspathlib".*must set min_sdk_version`)).
+		preparer.
 			RunTestWithBp(t, `
 				apex {
 					name: "myapex",
@@ -9819,6 +9905,8 @@
 					apex_available: ["myapex"],
 					compile_dex: true,
 					unsafe_ignore_missing_latest_api: true,
+					sdk_version: "current",
+					min_sdk_version: "30",
 				}
 		`)
 	})
@@ -10071,6 +10159,9 @@
 			key: "myapex.key",
 			bootclasspath_fragments: ["mybootclasspathfragment"],
 			min_sdk_version: "29",
+			java_libs: [
+				"jacocoagent",
+			],
 		}
 		apex_key {
 			name: "myapex.key",
@@ -11940,7 +12031,7 @@
 		).RunTest(t)
 
 		ldRule := result.ModuleForTests("installedlib", "android_arm64_armv8-a_shared").Rule("ld")
-		android.AssertStringDoesContain(t, "", ldRule.Args["libFlags"], "android_arm64_armv8-a_shared/libfoo.so")
+		android.AssertStringDoesContain(t, "", ldRule.Args["libFlags"], "android_arm64_armv8-a_shared_current/libfoo.so")
 
 		installRules := result.InstallMakeRulesForTesting(t)
 
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 25131ee..7cad337 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -104,6 +104,7 @@
 			test: {
 				enabled: true,
 			},
+			sdk_version: "core_current",
 		}
 
 		java_library {
@@ -749,6 +750,7 @@
 			],
 			srcs: ["b.java"],
 			compile_dex: true,
+			sdk_version: "core_current",
 		}
 
 		java_sdk_library {
@@ -922,6 +924,7 @@
 			],
 			srcs: ["b.java"],
 			compile_dex: true,
+			sdk_version: "core_current",
 		}
 
 		java_library {
@@ -1093,6 +1096,7 @@
 			],
 			srcs: ["b.java"],
 			compile_dex: true,
+			sdk_version: "core_current",
 		}
 
 		java_library {
@@ -1245,6 +1249,7 @@
 			],
 			srcs: ["b.java"],
 			compile_dex: true,
+			sdk_version: "core_current",
 		}
 
 		java_library {
diff --git a/apex/builder.go b/apex/builder.go
index bfe1692..0d08483 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -595,7 +595,7 @@
 	if len(installMapSet) > 0 {
 		var installs []string
 		installs = append(installs, android.SortedKeys(installMapSet)...)
-		a.SetLicenseInstallMap(installs)
+		ctx.SetLicenseInstallMap(installs)
 	}
 
 	////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/apex/classpath_element_test.go b/apex/classpath_element_test.go
index b9a9198..9e1ac94 100644
--- a/apex/classpath_element_test.go
+++ b/apex/classpath_element_test.go
@@ -92,6 +92,7 @@
 			],
 			srcs: ["b.java"],
 			installable: true,
+			sdk_version: "core_current",
 		}
 
 		java_library {
diff --git a/apex/container_test.go b/apex/container_test.go
index 3931174..d28b1a6 100644
--- a/apex/container_test.go
+++ b/apex/container_test.go
@@ -30,7 +30,7 @@
 	result := android.GroupFixturePreparers(
 		prepareForApexTest,
 		java.PrepareForTestWithJavaSdkLibraryFiles,
-		java.FixtureWithLastReleaseApis("mybootclasspathlib"),
+		java.FixtureWithLastReleaseApis("mybootclasspathlib", "bar"),
 	).RunTestWithBp(t, `
 		apex {
 			name: "myapex",
@@ -68,16 +68,17 @@
 			],
 			compile_dex: true,
 			static_libs: [
-				"foo",
+				"food",
 				"baz",
 			],
 			libs: [
-				"bar",
+				"bar.stubs",
 			],
 			min_sdk_version: "30",
+			sdk_version: "current",
 		}
 		java_library {
-			name: "foo",
+			name: "food",
 			srcs:[
 				"A.java",
 			],
@@ -85,13 +86,15 @@
 				"myapex",
 			],
 			min_sdk_version: "30",
+			sdk_version: "core_current",
 		}
-		java_library {
+		java_sdk_library {
 			name: "bar",
 			srcs:[
 				"A.java",
 			],
 			min_sdk_version: "30",
+			sdk_version: "core_current",
 		}
 		java_library {
 			name: "baz",
@@ -103,6 +106,7 @@
 				"myapex",
 			],
 			min_sdk_version: "30",
+			sdk_version: "core_current",
 		}
 	`)
 	testcases := []struct {
@@ -130,7 +134,7 @@
 			isApexContainer:   false,
 		},
 		{
-			moduleName:        "foo",
+			moduleName:        "food",
 			variant:           "android_common_apex30",
 			isSystemContainer: true,
 			isApexContainer:   true,
@@ -162,7 +166,7 @@
 	result := android.GroupFixturePreparers(
 		prepareForApexTest,
 		java.PrepareForTestWithJavaSdkLibraryFiles,
-		java.FixtureWithLastReleaseApis("mybootclasspathlib"),
+		java.FixtureWithLastReleaseApis("mybootclasspathlib", "bar"),
 	).RunTestWithBp(t, `
 		apex {
 			name: "myapex",
@@ -199,26 +203,30 @@
 			],
 			compile_dex: true,
 			static_libs: [
-				"foo",
+				"food",
 			],
 			libs: [
-				"bar",
+				"bar.stubs",
 			],
+			sdk_version: "current",
 		}
 		java_library {
-			name: "foo",
+			name: "food",
 			srcs:[
 				"A.java",
 			],
 			apex_available: [
 				"myapex",
 			],
+			sdk_version: "core_current",
 		}
-		java_library {
+		java_sdk_library {
 			name: "bar",
 			srcs:[
 				"A.java",
 			],
+			sdk_version: "none",
+			system_modules: "none",
 		}
 	`)
 	testcases := []struct {
@@ -246,7 +254,7 @@
 			isApexContainer:   false,
 		},
 		{
-			moduleName:        "foo",
+			moduleName:        "food",
 			variant:           "android_common_apex10000",
 			isSystemContainer: true,
 			isApexContainer:   true,
diff --git a/apex/dexpreopt_bootjars_test.go b/apex/dexpreopt_bootjars_test.go
index 95db37d..d8ee4ba 100644
--- a/apex/dexpreopt_bootjars_test.go
+++ b/apex/dexpreopt_bootjars_test.go
@@ -409,3 +409,106 @@
 		android.AssertStringListContains(t, tc.desc, inputs, tc.expectedProfile)
 	}
 }
+
+// Check that dexpreopt works with Google mainline prebuilts even in workspaces where source is missing
+func TestDexpreoptWithMainlinePrebuiltNoSource(t *testing.T) {
+	bp := `
+		// Platform.
+
+		platform_bootclasspath {
+			name: "platform-bootclasspath",
+			fragments: [
+				{
+					apex: "com.android.art",
+					module: "art-bootclasspath-fragment",
+				},
+			],
+		}
+
+		// Source AOSP ART apex
+		java_library {
+			name: "core-oj",
+			srcs: ["core-oj.java"],
+			installable: true,
+			apex_available: [
+				"com.android.art",
+			],
+		}
+
+		bootclasspath_fragment {
+			name: "art-bootclasspath-fragment",
+			image_name: "art",
+			contents: ["core-oj"],
+			apex_available: [
+				"com.android.art",
+			],
+			hidden_api: {
+				split_packages: ["*"],
+			},
+		}
+
+		apex_key {
+			name: "com.android.art.key",
+			public_key: "com.android.art.avbpubkey",
+			private_key: "com.android.art.pem",
+		}
+
+		apex {
+			name: "com.android.art",
+			key: "com.android.art.key",
+			bootclasspath_fragments: ["art-bootclasspath-fragment"],
+			updatable: false,
+		}
+
+
+		// Prebuilt Google ART APEX.
+
+		java_import {
+			name: "core-oj",
+			jars: ["core-oj.jar"],
+			apex_available: [
+				"com.android.art",
+			],
+		}
+
+		prebuilt_bootclasspath_fragment {
+			name: "art-bootclasspath-fragment",
+			image_name: "art",
+			contents: ["core-oj"],
+			hidden_api: {
+				annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+				metadata: "my-bootclasspath-fragment/metadata.csv",
+				index: "my-bootclasspath-fragment/index.csv",
+				stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+				all_flags: "my-bootclasspath-fragment/all-flags.csv",
+			},
+			apex_available: [
+				"com.android.art",
+			],
+		}
+
+		prebuilt_apex {
+			name: "com.google.android.art",
+			apex_name: "com.android.art",
+			src: "com.android.art-arm.apex",
+			exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
+		}
+
+		apex_contributions {
+			name: "art.prebuilt.contributions",
+			api_domain: "com.android.art",
+			contents: ["prebuilt_com.google.android.art"],
+		}
+	`
+	res := android.GroupFixturePreparers(
+		java.PrepareForTestWithDexpreopt,
+		java.PrepareForTestWithJavaSdkLibraryFiles,
+		java.FixtureConfigureBootJars("com.android.art:core-oj"),
+		PrepareForTestWithApexBuildComponents,
+		prepareForTestWithArtApex,
+		android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "art.prebuilt.contributions"),
+	).RunTestWithBp(t, bp)
+	if !java.CheckModuleHasDependency(t, res.TestContext, "dex_bootjars", "android_common", "prebuilt_com.google.android.art") {
+		t.Errorf("Expected dexpreopt to use prebuilt apex")
+	}
+}
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 920fc0c..9c2d899 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -293,6 +293,7 @@
 			],
 			srcs: ["b.java"],
 			installable: true,
+			sdk_version: "core_current",
 		}
 
 		// Add a java_import that is not preferred and so won't have an appropriate apex variant created
@@ -791,6 +792,128 @@
 		`)
 }
 
+// Skip bcp_fragment content validation of source apexes if prebuilts are active.
+func TestNonBootJarInPrebuilts(t *testing.T) {
+	testCases := []struct {
+		description               string
+		selectedApexContributions string
+		expectedError             string
+	}{
+		{
+			description:               "source is active",
+			selectedApexContributions: "",
+			expectedError:             "in contents must also be declared in PRODUCT_APEX_BOOT_JARS",
+		},
+		{
+			description:               "prebuilts are active",
+			selectedApexContributions: "myapex.prebuilt.contributions",
+			expectedError:             "", // skip content validation of source bcp fragment
+		},
+	}
+	bp := `
+// Source
+apex {
+	name: "myapex",
+	key: "myapex.key",
+	bootclasspath_fragments: ["apex-fragment"],
+	updatable: false,
+	min_sdk_version: "29",
+}
+
+override_apex {
+	name: "myapex.override", // overrides the min_sdk_version, thereby creating different variants of its transitive deps
+	base: "myapex",
+	min_sdk_version: "34",
+}
+
+apex_key {
+	name: "myapex.key",
+	public_key: "testkey.avbpubkey",
+	private_key: "testkey.pem",
+}
+
+java_library {
+	name: "foo",
+	srcs: ["b.java"],
+	installable: true,
+	apex_available: ["myapex"],
+	permitted_packages: ["foo"],
+	min_sdk_version: "29",
+}
+
+java_library {
+	name: "bar",
+	srcs: ["b.java"],
+	installable: true,
+	apex_available: ["myapex"],
+	permitted_packages: ["bar"],
+	min_sdk_version: "29",
+}
+
+bootclasspath_fragment {
+	name: "apex-fragment",
+	contents: ["foo", "bar"],
+	apex_available:[ "myapex" ],
+	hidden_api: {
+		split_packages: ["*"],
+	},
+}
+
+platform_bootclasspath {
+	name: "myplatform-bootclasspath",
+	fragments: [{
+			apex: "myapex",
+			module:"apex-fragment",
+	}],
+}
+
+// prebuilts
+prebuilt_apex {
+	name: "myapex",
+		apex_name: "myapex",
+		src: "myapex.apex",
+		exported_bootclasspath_fragments: ["apex-fragment"],
+	}
+
+	prebuilt_bootclasspath_fragment {
+		name: "apex-fragment",
+		contents: ["foo"],
+		hidden_api: {
+			annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+			metadata: "my-bootclasspath-fragment/metadata.csv",
+			index: "my-bootclasspath-fragment/index.csv",
+			stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+			all_flags: "my-bootclasspath-fragment/all-flags.csv",
+		},
+	}
+	java_import {
+		name: "foo",
+		jars: ["foo.jar"],
+	}
+
+apex_contributions {
+	name: "myapex.prebuilt.contributions",
+	api_domain: "myapex",
+	contents: ["prebuilt_myapex"],
+}
+`
+
+	for _, tc := range testCases {
+		fixture := android.GroupFixturePreparers(
+			prepareForTestWithPlatformBootclasspath,
+			PrepareForTestWithApexBuildComponents,
+			prepareForTestWithMyapex,
+			java.FixtureConfigureApexBootJars("myapex:foo"),
+			android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", tc.selectedApexContributions),
+		)
+		if tc.expectedError != "" {
+			fixture = fixture.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError))
+		}
+		fixture.RunTestWithBp(t, bp)
+	}
+
+}
+
 // Source and prebuilt apex provide different set of boot jars
 func TestNonBootJarMissingInPrebuiltFragment(t *testing.T) {
 	bp := `
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 8cdfb89..f1a134e 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -15,9 +15,6 @@
 package apex
 
 import (
-	"fmt"
-	"io"
-	"path/filepath"
 	"strconv"
 	"strings"
 
@@ -70,10 +67,6 @@
 	// fragment for this apex for apexkeys.txt
 	apexKeysPath android.WritablePath
 
-	// A list of apexFile objects created in prebuiltCommon.initApexFilesForAndroidMk which are used
-	// to create make modules in prebuiltCommon.AndroidMkEntries.
-	apexFilesForAndroidMk []apexFile
-
 	// Installed locations of symlinks for backward compatibility.
 	compatSymlinks android.InstallPaths
 
@@ -202,7 +195,6 @@
 	// If this apex contains a system server jar, then the dexpreopt artifacts should be added as required
 	for _, install := range p.Dexpreopter.DexpreoptBuiltInstalledForApex() {
 		p.requiredModuleNames = append(p.requiredModuleNames, install.FullModuleName())
-		install.PackageFile(ctx)
 	}
 }
 
@@ -236,11 +228,6 @@
 }
 
 func (p *prebuiltCommon) addRequiredModules(entries *android.AndroidMkEntries) {
-	for _, fi := range p.apexFilesForAndroidMk {
-		entries.AddStrings("LOCAL_REQUIRED_MODULES", fi.requiredModuleNames...)
-		entries.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", fi.targetRequiredModuleNames...)
-		entries.AddStrings("LOCAL_HOST_REQUIRED_MODULES", fi.hostRequiredModuleNames...)
-	}
 	entries.AddStrings("LOCAL_REQUIRED_MODULES", p.requiredModuleNames...)
 }
 
@@ -272,54 +259,9 @@
 		entriesList = append(entriesList, install.ToMakeEntries())
 	}
 
-	// Iterate over the apexFilesForAndroidMk list and create an AndroidMkEntries struct for each
-	// file. This provides similar behavior to that provided in apexBundle.AndroidMk() as it makes the
-	// apex specific variants of the exported java modules available for use from within make.
-	apexName := p.BaseModuleName()
-	for _, fi := range p.apexFilesForAndroidMk {
-		entries := p.createEntriesForApexFile(fi, apexName)
-		entriesList = append(entriesList, entries)
-	}
-
 	return entriesList
 }
 
-// createEntriesForApexFile creates an AndroidMkEntries for the supplied apexFile
-func (p *prebuiltCommon) createEntriesForApexFile(fi apexFile, apexName string) android.AndroidMkEntries {
-	moduleName := fi.androidMkModuleName + "." + apexName
-	entries := android.AndroidMkEntries{
-		Class:        fi.class.nameInMake(),
-		OverrideName: moduleName,
-		OutputFile:   android.OptionalPathForPath(fi.builtFile),
-		Include:      "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
-		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
-			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
-				entries.SetString("LOCAL_MODULE_PATH", p.installDir.String())
-				entries.SetString("LOCAL_SOONG_INSTALLED_MODULE", filepath.Join(p.installDir.String(), fi.stem()))
-				entries.SetString("LOCAL_SOONG_INSTALL_PAIRS",
-					fi.builtFile.String()+":"+filepath.Join(p.installDir.String(), fi.stem()))
-
-				// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar  Therefore
-				// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
-				// we will have foo.jar.jar
-				entries.SetString("LOCAL_MODULE_STEM", strings.TrimSuffix(fi.stem(), ".jar"))
-				entries.SetString("LOCAL_SOONG_DEX_JAR", fi.builtFile.String())
-				entries.SetString("LOCAL_DEX_PREOPT", "false")
-			},
-		},
-		ExtraFooters: []android.AndroidMkExtraFootersFunc{
-			func(w io.Writer, name, prefix, moduleDir string) {
-				// m <module_name> will build <module_name>.<apex_name> as well.
-				if fi.androidMkModuleName != moduleName {
-					fmt.Fprintf(w, ".PHONY: %s\n", fi.androidMkModuleName)
-					fmt.Fprintf(w, "%s: %s\n", fi.androidMkModuleName, moduleName)
-				}
-			},
-		},
-	}
-	return entries
-}
-
 // prebuiltApexModuleCreator defines the methods that need to be implemented by prebuilt_apex and
 // apex_set in order to create the modules needed to provide access to the prebuilt .apex file.
 type prebuiltApexModuleCreator interface {
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index 452a43e..fd9020b 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -80,6 +80,7 @@
 			apex_available: [
 				"myapex",
 			],
+			sdk_version: "core_current",
 		}
 
 		systemserverclasspath_fragment {
@@ -350,6 +351,7 @@
 			apex_available: [
 				"myapex",
 			],
+			sdk_version: "core_current",
 		}
 
 		systemserverclasspath_fragment {
diff --git a/bin/aninja b/bin/aninja
index 5acb968..5cb5a55 100755
--- a/bin/aninja
+++ b/bin/aninja
@@ -34,5 +34,5 @@
 esac
 
 cd $(gettop)
-prebuilts/build-tools/${host_arch}/bin/ninja -f out/combined-${TARGET_PRODUCT}.ninja "$@"
+prebuilts/build-tools/${host_arch}/bin/ninja -f $(getoutdir)/combined-${TARGET_PRODUCT}.ninja "$@"
 
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 6445394..73c8800 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -157,7 +157,7 @@
 		// The architecture doesn't matter here, but asm/types.h is included by linux/types.h.
 		"-isystem bionic/libc/kernel/uapi/asm-arm64",
 		"-isystem bionic/libc/kernel/android/uapi",
-		"-I       packages/modules/Connectivity/staticlibs/native/bpf_headers/include/bpf",
+		"-I       packages/modules/Connectivity/bpf/headers/include",
 		// TODO(b/149785767): only give access to specific file with AID_* constants
 		"-I       system/core/libcutils/include",
 		"-I " + ctx.ModuleDir(),
diff --git a/cc/cc.go b/cc/cc.go
index 947dc1a..927935c 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3042,7 +3042,7 @@
 		}
 
 		if dep.Target().Os != ctx.Os() {
-			ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
+			ctx.ModuleErrorf("OS mismatch between %q (%s) and %q (%s)", ctx.ModuleName(), ctx.Os().Name, depName, dep.Target().Os.Name)
 			return
 		}
 		if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 779e53d..93630db 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -302,7 +302,7 @@
 	ctx := testCcWithConfig(t, config)
 	testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
 	testBinary := testingModule.Module().(*Module).linker.(*testBinary)
-	outputFiles := testingModule.OutputFiles(t, "")
+	outputFiles := testingModule.OutputFiles(ctx, t, "")
 	if len(outputFiles) != 1 {
 		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
 		return
@@ -355,7 +355,7 @@
 	testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
 	module := testingModule.Module()
 	testBinary := module.(*Module).linker.(*testBinary)
-	outputFiles := testingModule.OutputFiles(t, "")
+	outputFiles := testingModule.OutputFiles(ctx, t, "")
 	if len(outputFiles) != 1 {
 		t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles)
 	}
@@ -927,7 +927,7 @@
 
 	cc_prebuilt_library_shared {
 		name: "libllndkprebuilt",
-		stubs: { versions: ["1", "2"] },
+		stubs: { versions: ["1", "2"] , symbol_file: "libllndkprebuilt.map.txt" },
 		llndk: {
 			symbol_file: "libllndkprebuilt.map.txt",
 		},
@@ -1404,7 +1404,7 @@
 	testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon")
 	module := testingModule.Module()
 	testBinary := module.(*Module).linker.(*testBinary)
-	outputFiles := testingModule.OutputFiles(t, "")
+	outputFiles := testingModule.OutputFiles(ctx, t, "")
 	if len(outputFiles) != 1 {
 		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
 	}
@@ -3111,7 +3111,7 @@
 	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
 	ctx := testCcWithConfig(t, config)
 	testingModule := ctx.ModuleForTests("test_lib", "android_arm_armv7-a-neon_shared")
-	outputFile := testingModule.OutputFiles(t, "stripped_all")
+	outputFile := testingModule.OutputFiles(ctx, t, "stripped_all")
 	if !strings.HasSuffix(outputFile.Strings()[0], "/stripped_all/test_lib.so") {
 		t.Errorf("Unexpected output file: %s", outputFile.Strings()[0])
 		return
diff --git a/cc/compdb.go b/cc/compdb.go
index da28183..b33f490 100644
--- a/cc/compdb.go
+++ b/cc/compdb.go
@@ -85,23 +85,24 @@
 	if err != nil {
 		log.Fatalf("Could not create file %s: %s", compDBFile, err)
 	}
-	defer f.Close()
+	defer func() {
+		if err := f.Close(); err != nil {
+			log.Fatalf("Could not close file %s: %s", compDBFile, err)
+		}
+	}()
 
 	v := make([]compDbEntry, 0, len(m))
-
 	for _, value := range m {
 		v = append(v, value)
 	}
-	var dat []byte
+
+	w := json.NewEncoder(f)
 	if outputCompdbDebugInfo {
-		dat, err = json.MarshalIndent(v, "", " ")
-	} else {
-		dat, err = json.Marshal(v)
+		w.SetIndent("", " ")
 	}
-	if err != nil {
-		log.Fatalf("Failed to marshal: %s", err)
+	if err := w.Encode(v); err != nil {
+		log.Fatalf("Failed to encode: %s", err)
 	}
-	f.Write(dat)
 
 	if finalLinkDir := ctx.Config().Getenv(envVariableCompdbLink); finalLinkDir != "" {
 		finalLinkPath := filepath.Join(finalLinkDir, compdbFilename)
diff --git a/cc/config/darwin_host.go b/cc/config/darwin_host.go
index 2ea607a..1783f49 100644
--- a/cc/config/darwin_host.go
+++ b/cc/config/darwin_host.go
@@ -29,6 +29,7 @@
 	darwinCflags = []string{
 		"-fPIC",
 		"-funwind-tables",
+		"-fno-omit-frame-pointer",
 
 		"-isysroot ${macSdkRoot}",
 		"-mmacosx-version-min=${macMinVersion}",
diff --git a/cc/config/global.go b/cc/config/global.go
index 0e8fff6..c838357 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -287,8 +287,7 @@
 		"-Wno-error=deprecated-builtins", // http://b/241601211
 		"-Wno-error=deprecated",          // in external/googletest/googletest
 		// New warnings to be fixed after clang-r475365
-		"-Wno-error=single-bit-bitfield-constant-conversion", // http://b/243965903
-		"-Wno-error=enum-constexpr-conversion",               // http://b/243964282
+		"-Wno-error=enum-constexpr-conversion", // http://b/243964282
 		// New warnings to be fixed after clang-r522817
 		"-Wno-error=invalid-offsetof",
 		"-Wno-error=thread-safety-reference-return",
diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go
index 515cb21..ddc86c2 100644
--- a/cc/config/x86_linux_bionic_host.go
+++ b/cc/config/x86_linux_bionic_host.go
@@ -25,6 +25,8 @@
 
 		"-fPIC",
 
+		"-fno-omit-frame-pointer",
+
 		"-U_FORTIFY_SOURCE",
 		"-D_FORTIFY_SOURCE=2",
 		"-fstack-protector-strong",
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index 7f22377..287967c 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -26,6 +26,8 @@
 
 		"-fPIC",
 
+		"-fno-omit-frame-pointer",
+
 		"-U_FORTIFY_SOURCE",
 		"-D_FORTIFY_SOURCE=2",
 		"-fstack-protector",
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index ea7d342..a4d43b9 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -47,6 +47,8 @@
 		// Windows flags to generate PDB
 		"-g",
 		"-gcodeview",
+
+		"-fno-omit-frame-pointer",
 	}
 
 	windowsIncludeFlags = []string{
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index b3d5116..9a8049b 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -236,7 +236,7 @@
 	}
 	`
 	result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, bp)
-	gen_32bit := result.ModuleForTests("gen", "android_arm_armv7-a-neon").OutputFiles(t, "")
+	gen_32bit := result.ModuleForTests("gen", "android_arm_armv7-a-neon").OutputFiles(result.TestContext, t, "")
 	android.AssertPathsEndWith(t,
 		"genrule_out",
 		[]string{
@@ -245,7 +245,7 @@
 		gen_32bit,
 	)
 
-	gen_64bit := result.ModuleForTests("gen", "android_arm64_armv8-a").OutputFiles(t, "")
+	gen_64bit := result.ModuleForTests("gen", "android_arm64_armv8-a").OutputFiles(result.TestContext, t, "")
 	android.AssertPathsEndWith(t,
 		"genrule_out",
 		[]string{
diff --git a/cc/library.go b/cc/library.go
index 6017848..65a923a 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -594,43 +594,7 @@
 		return objs
 	}
 	if library.buildStubs() {
-		symbolFile := String(library.Properties.Stubs.Symbol_file)
-		if symbolFile != "" && !strings.HasSuffix(symbolFile, ".map.txt") {
-			ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
-			return Objects{}
-		}
-		library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
-		// b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
-		// systemapi, respectively. The former is for symbols defined in platform libraries
-		// and the latter is for symbols defined in APEXes.
-		// A single library can contain either # apex or # systemapi, but not both.
-		// The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op.
-		// However, having this distinction helps guard accidental
-		// promotion or demotion of API and also helps the API review process b/191371676
-		var flag string
-		if ctx.Module().(android.ApexModule).NotInPlatform() {
-			flag = "--apex"
-		} else {
-			flag = "--systemapi"
-		}
-		// b/184712170, unless the lib is an NDK library, exclude all public symbols from
-		// the stub so that it is mandated that all symbols are explicitly marked with
-		// either apex or systemapi.
-		if !ctx.Module().(*Module).IsNdk(ctx.Config()) {
-			flag = flag + " --no-ndk"
-		}
-		nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
-			android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
-		objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
-		library.versionScriptPath = android.OptionalPathForPath(
-			nativeAbiResult.versionScript)
-
-		// Parse symbol file to get API list for coverage
-		if library.stubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
-			library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
-		}
-
-		return objs
+		return library.compileModuleLibApiStubs(ctx, flags, deps)
 	}
 
 	srcs := library.baseCompiler.Properties.Srcs.GetOrDefault(ctx, nil)
@@ -681,6 +645,61 @@
 	return objs
 }
 
+// Compile stubs for the API surface between platform and apex
+// This method will be used by source and prebuilt cc module types.
+func (library *libraryDecorator) compileModuleLibApiStubs(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
+	// TODO (b/275273834): Make this a hard error when the symbol files have been added to module sdk.
+	if library.Properties.Stubs.Symbol_file == nil {
+		return Objects{}
+	}
+	symbolFile := String(library.Properties.Stubs.Symbol_file)
+	library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
+	// b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
+	// systemapi, respectively. The former is for symbols defined in platform libraries
+	// and the latter is for symbols defined in APEXes.
+	// A single library can contain either # apex or # systemapi, but not both.
+	// The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op.
+	// However, having this distinction helps guard accidental
+	// promotion or demotion of API and also helps the API review process b/191371676
+	var flag string
+	if ctx.Module().(android.ApexModule).NotInPlatform() {
+		flag = "--apex"
+	} else {
+		flag = "--systemapi"
+	}
+	// b/184712170, unless the lib is an NDK library, exclude all public symbols from
+	// the stub so that it is mandated that all symbols are explicitly marked with
+	// either apex or systemapi.
+	if !ctx.Module().(*Module).IsNdk(ctx.Config()) &&
+		// the symbol files of libclang libs are autogenerated and do not contain systemapi tags
+		// TODO (spandandas): Update mapfile.py to include #systemapi tag on all symbols
+		!strings.Contains(ctx.ModuleName(), "libclang_rt") {
+		flag = flag + " --no-ndk"
+	}
+	// TODO(b/361303067): Remove this special case if bionic/ projects are added to ART development branches.
+	if isBionic(ctx.baseModuleName()) {
+		// set the flags explicitly for bionic libs.
+		// this is necessary for development in minimal branches which does not contain bionic/*.
+		// In such minimal branches, e.g. on the prebuilt libc stubs
+		// 1. IsNdk will return false (since the ndk_library definition for libc does not exist)
+		// 2. NotInPlatform will return true (since the source com.android.runtime does not exist)
+		flag = "--apex"
+	}
+	nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
+		android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
+	objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
+
+	library.versionScriptPath = android.OptionalPathForPath(
+		nativeAbiResult.versionScript)
+
+	// Parse symbol file to get API list for coverage
+	if library.stubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
+		library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
+	}
+
+	return objs
+}
+
 type libraryInterface interface {
 	versionedInterface
 
@@ -1182,12 +1201,17 @@
 	return unstrippedOutputFile
 }
 
-func addStubDependencyProviders(ctx ModuleContext) {
+// Visits the stub variants of the library and returns a struct containing the stub .so paths
+func addStubDependencyProviders(ctx ModuleContext) []SharedStubLibrary {
+	stubsInfo := []SharedStubLibrary{}
 	stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
 	if len(stubs) > 0 {
-		var stubsInfo []SharedStubLibrary
 		for _, stub := range stubs {
-			stubInfo, _ := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
+			stubInfo, ok := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
+			// TODO (b/275273834): Make this a hard error when the symbol files have been added to module sdk.
+			if !ok {
+				continue
+			}
 			flagInfo, _ := android.OtherModuleProvider(ctx, stub, FlagExporterInfoProvider)
 			stubsInfo = append(stubsInfo, SharedStubLibrary{
 				Version:           moduleLibraryInterface(stub).stubsVersion(),
@@ -1195,11 +1219,14 @@
 				FlagExporterInfo:  flagInfo,
 			})
 		}
-		android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{
-			SharedStubLibraries: stubsInfo,
-			IsLLNDK:             ctx.IsLlndk(),
-		})
+		if len(stubsInfo) > 0 {
+			android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{
+				SharedStubLibraries: stubsInfo,
+				IsLLNDK:             ctx.IsLlndk(),
+			})
+		}
 	}
+	return stubsInfo
 }
 
 func (library *libraryDecorator) unstrippedOutputFilePath() android.Path {
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 3e35ef5..5250b86 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -484,7 +484,8 @@
 // Add a dependency on the header modules of this ndk_library
 func (linker *stubDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
 	return Deps{
-		HeaderLibs: linker.properties.Export_header_libs,
+		ReexportHeaderLibHeaders: linker.properties.Export_header_libs,
+		HeaderLibs:               linker.properties.Export_header_libs,
 	}
 }
 
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index fb151d8..299fb51 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -16,6 +16,7 @@
 
 import (
 	"path/filepath"
+	"strings"
 
 	"github.com/google/blueprint/proptools"
 
@@ -95,10 +96,6 @@
 	return p.libraryDecorator.linkerDeps(ctx, deps)
 }
 
-func (p *prebuiltLibraryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
-	return flags
-}
-
 func (p *prebuiltLibraryLinker) linkerProps() []interface{} {
 	return p.libraryDecorator.linkerProps()
 }
@@ -117,6 +114,30 @@
 
 	// TODO(ccross): verify shared library dependencies
 	srcs := p.prebuiltSrcs(ctx)
+	stubInfo := addStubDependencyProviders(ctx)
+
+	// Stub variants will create a stub .so file from stub .c files
+	if p.buildStubs() && objs.objFiles != nil {
+		// TODO (b/275273834): Make objs.objFiles == nil a hard error when the symbol files have been added to module sdk.
+
+		// The map.txt files of libclang_rt.* contain version information, but the checked in .so files do not.
+		// e.g. libclang_rt.* libs impl
+		// $ nm -D prebuilts/../libclang_rt.hwasan-aarch64-android.so
+		// __hwasan_init
+
+		// stubs generated from .map.txt
+		// $ nm -D out/soong/.intermediates/../<stubs>/libclang_rt.hwasan-aarch64-android.so
+		// __hwasan_init@@LIBCLANG_RT_ASAN
+
+		// Special-case libclang_rt.* libs to account for this discrepancy.
+		// TODO (spandandas): Remove this special case https://r.android.com/3236596 has been submitted, and a new set of map.txt
+		// files of libclang_rt.* libs have been generated.
+		if strings.Contains(ctx.ModuleName(), "libclang_rt.") {
+			p.versionScriptPath = android.OptionalPathForPath(nil)
+		}
+		return p.linkShared(ctx, flags, deps, objs)
+	}
+
 	if len(srcs) > 0 {
 		if len(srcs) > 1 {
 			ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
@@ -203,6 +224,16 @@
 
 			return outputFile
 		}
+	} else if p.shared() && len(stubInfo) > 0 {
+		// This is a prebuilt which does not have any implementation (nil `srcs`), but provides APIs.
+		// Provide the latest (i.e. `current`) stubs to reverse dependencies.
+		latestStub := stubInfo[len(stubInfo)-1].SharedLibraryInfo.SharedLibrary
+		android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{
+			SharedLibrary: latestStub,
+			Target:        ctx.Target(),
+		})
+
+		return latestStub
 	}
 
 	if p.header() {
@@ -257,11 +288,11 @@
 
 func NewPrebuiltLibrary(hod android.HostOrDeviceSupported, srcsProperty string) (*Module, *libraryDecorator) {
 	module, library := NewLibrary(hod)
-	module.compiler = nil
 
 	prebuilt := &prebuiltLibraryLinker{
 		libraryDecorator: library,
 	}
+	module.compiler = prebuilt
 	module.linker = prebuilt
 	module.library = prebuilt
 
@@ -280,6 +311,13 @@
 	return module, library
 }
 
+func (p *prebuiltLibraryLinker) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
+	if p.buildStubs() && p.stubsVersion() != "" {
+		return p.compileModuleLibApiStubs(ctx, flags, deps)
+	}
+	return Objects{}
+}
+
 // cc_prebuilt_library installs a precompiled shared library that are
 // listed in the srcs property in the device's directory.
 func PrebuiltLibraryFactory() android.Module {
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index 80facd8..a1cfb5c 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -794,47 +794,47 @@
 
 		android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in bin_with_ubsan static libs",
 			strings.Split(binWithUbsan.Rule("ld").Args["libFlags"], " "),
-			minimalRuntime.OutputFiles(t, "")[0].String())
+			minimalRuntime.OutputFiles(result.TestContext, t, "")[0].String())
 
 		android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in bin_depends_ubsan_static static libs",
 			strings.Split(binDependsUbsan.Rule("ld").Args["libFlags"], " "),
-			minimalRuntime.OutputFiles(t, "")[0].String())
+			minimalRuntime.OutputFiles(result.TestContext, t, "")[0].String())
 
 		android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in libsharedubsan static libs",
 			strings.Split(libSharedUbsan.Rule("ld").Args["libFlags"], " "),
-			minimalRuntime.OutputFiles(t, "")[0].String())
+			minimalRuntime.OutputFiles(result.TestContext, t, "")[0].String())
 
 		android.AssertStringListDoesNotContain(t, "unexpected libclang_rt.ubsan_minimal in bin_depends_ubsan_shared static libs",
 			strings.Split(binDependsUbsanShared.Rule("ld").Args["libFlags"], " "),
-			minimalRuntime.OutputFiles(t, "")[0].String())
+			minimalRuntime.OutputFiles(result.TestContext, t, "")[0].String())
 
 		android.AssertStringListDoesNotContain(t, "unexpected libclang_rt.ubsan_minimal in bin_no_ubsan static libs",
 			strings.Split(binNoUbsan.Rule("ld").Args["libFlags"], " "),
-			minimalRuntime.OutputFiles(t, "")[0].String())
+			minimalRuntime.OutputFiles(result.TestContext, t, "")[0].String())
 
 		android.AssertStringListContains(t, "missing -Wl,--exclude-libs for minimal runtime in bin_with_ubsan",
 			strings.Split(binWithUbsan.Rule("ld").Args["ldFlags"], " "),
-			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(result.TestContext, t, "")[0].Base())
 
 		android.AssertStringListContains(t, "missing -Wl,--exclude-libs for minimal runtime in bin_depends_ubsan_static static libs",
 			strings.Split(binDependsUbsan.Rule("ld").Args["ldFlags"], " "),
-			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(result.TestContext, t, "")[0].Base())
 
 		android.AssertStringListContains(t, "missing -Wl,--exclude-libs for minimal runtime in libsharedubsan static libs",
 			strings.Split(libSharedUbsan.Rule("ld").Args["ldFlags"], " "),
-			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(result.TestContext, t, "")[0].Base())
 
 		android.AssertStringListDoesNotContain(t, "unexpected -Wl,--exclude-libs for minimal runtime in bin_depends_ubsan_shared static libs",
 			strings.Split(binDependsUbsanShared.Rule("ld").Args["ldFlags"], " "),
-			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(result.TestContext, t, "")[0].Base())
 
 		android.AssertStringListDoesNotContain(t, "unexpected -Wl,--exclude-libs for minimal runtime in bin_no_ubsan static libs",
 			strings.Split(binNoUbsan.Rule("ld").Args["ldFlags"], " "),
-			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+			"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(result.TestContext, t, "")[0].Base())
 
 		android.AssertStringListContains(t, "missing libclang_rt.ubsan_standalone.static in static_bin_with_ubsan_dep static libs",
 			strings.Split(staticBin.Rule("ld").Args["libFlags"], " "),
-			standaloneRuntime.OutputFiles(t, "")[0].String())
+			standaloneRuntime.OutputFiles(result.TestContext, t, "")[0].String())
 
 	}
 
diff --git a/cc/stub_library.go b/cc/stub_library.go
index f15a604..e746a33 100644
--- a/cc/stub_library.go
+++ b/cc/stub_library.go
@@ -61,7 +61,7 @@
 					}
 				}
 			}
-			if m.library != nil {
+			if m.library != nil && android.IsModulePreferred(m) {
 				if p := m.library.getAPIListCoverageXMLPath().String(); p != "" {
 					s.apiListCoverageXmlPaths = append(s.apiListCoverageXmlPaths, p)
 				}
diff --git a/cc/testing.go b/cc/testing.go
index ed567af..159f86c 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -713,7 +713,7 @@
 func checkSnapshotIncludeExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string, include bool, fake bool) {
 	t.Helper()
 	mod := ctx.ModuleForTests(moduleName, variant)
-	outputFiles := mod.OutputFiles(t, "")
+	outputFiles := mod.OutputFiles(ctx, t, "")
 	if len(outputFiles) != 1 {
 		t.Errorf("%q must have single output\n", moduleName)
 		return
diff --git a/cmd/release_config/release_config_lib/flag_artifact.go b/cmd/release_config/release_config_lib/flag_artifact.go
index 93c50cd..51c02d2 100644
--- a/cmd/release_config/release_config_lib/flag_artifact.go
+++ b/cmd/release_config/release_config_lib/flag_artifact.go
@@ -102,7 +102,7 @@
 	if description := fa.FlagDeclaration.GetDescription(); description != "" {
 		ret.Description = proto.String(description)
 	}
-	if workflow := fa.FlagDeclaration.GetWorkflow(); workflow != rc_proto.Workflow_Workflow_Unspecified {
+	if workflow := fa.FlagDeclaration.GetWorkflow(); workflow != rc_proto.Workflow_WORKFLOW_UNSPECIFIED {
 		ret.Workflow = &workflow
 	}
 	if containers := fa.FlagDeclaration.GetContainers(); containers != nil {
diff --git a/cmd/release_config/release_config_proto/build_flags_common.pb.go b/cmd/release_config/release_config_proto/build_flags_common.pb.go
index 82fbcfa..f8ad38f 100644
--- a/cmd/release_config/release_config_proto/build_flags_common.pb.go
+++ b/cmd/release_config/release_config_proto/build_flags_common.pb.go
@@ -38,6 +38,8 @@
 type Workflow int32
 
 const (
+	Workflow_WORKFLOW_UNSPECIFIED Workflow = 0
+	// Deprecated.  Use WORKFLOW_UNSPECIFIED instead.
 	Workflow_Workflow_Unspecified Workflow = 0
 	// Boolean value flags that progress from false to true.
 	Workflow_LAUNCH Workflow = 1
@@ -52,12 +54,14 @@
 // Enum value maps for Workflow.
 var (
 	Workflow_name = map[int32]string{
-		0: "Workflow_Unspecified",
+		0: "WORKFLOW_UNSPECIFIED",
+		// Duplicate value: 0: "Workflow_Unspecified",
 		1: "LAUNCH",
 		2: "PREBUILT",
 		3: "MANUAL",
 	}
 	Workflow_value = map[string]int32{
+		"WORKFLOW_UNSPECIFIED": 0,
 		"Workflow_Unspecified": 0,
 		"LAUNCH":               1,
 		"PREBUILT":             2,
@@ -108,15 +112,17 @@
 	0x0a, 0x18, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x63, 0x6f,
 	0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x61, 0x6e, 0x64, 0x72,
 	0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, 0x4a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b,
-	0x66, 0x6c, 0x6f, 0x77, 0x12, 0x18, 0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
-	0x5f, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0a,
-	0x0a, 0x06, 0x4c, 0x41, 0x55, 0x4e, 0x43, 0x48, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52,
-	0x45, 0x42, 0x55, 0x49, 0x4c, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x41, 0x4e, 0x55,
-	0x41, 0x4c, 0x10, 0x03, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
-	0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, 0x68, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b,
+	0x66, 0x6c, 0x6f, 0x77, 0x12, 0x18, 0x0a, 0x14, 0x57, 0x4f, 0x52, 0x4b, 0x46, 0x4c, 0x4f, 0x57,
+	0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18,
+	0x0a, 0x14, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x55, 0x6e, 0x73, 0x70, 0x65,
+	0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x41, 0x55, 0x4e,
+	0x43, 0x48, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52, 0x45, 0x42, 0x55, 0x49, 0x4c, 0x54,
+	0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x41, 0x4e, 0x55, 0x41, 0x4c, 0x10, 0x03, 0x1a, 0x02,
+	0x10, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f,
+	0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 }
 
 var (
@@ -133,7 +139,7 @@
 
 var file_build_flags_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
 var file_build_flags_common_proto_goTypes = []interface{}{
-	(Workflow)(0), // 0: android.release_config_proto.workflow
+	(Workflow)(0), // 0: android.release_config_proto.Workflow
 }
 var file_build_flags_common_proto_depIdxs = []int32{
 	0, // [0:0] is the sub-list for method output_type
diff --git a/cmd/release_config/release_config_proto/build_flags_common.proto b/cmd/release_config/release_config_proto/build_flags_common.proto
index d5d6101..cd9f1e0 100644
--- a/cmd/release_config/release_config_proto/build_flags_common.proto
+++ b/cmd/release_config/release_config_proto/build_flags_common.proto
@@ -20,7 +20,11 @@
 // This protobuf file defines common messages used in the rest of the build flag
 // protos.
 
-enum workflow {
+enum Workflow {
+  option allow_alias = true;
+  WORKFLOW_UNSPECIFIED = 0;
+
+  // Deprecated.  Use WORKFLOW_UNSPECIFIED instead.
   Workflow_Unspecified = 0;
 
   // Boolean value flags that progress from false to true.
diff --git a/cmd/release_config/release_config_proto/build_flags_declarations.pb.go b/cmd/release_config/release_config_proto/build_flags_declarations.pb.go
index d2de89a..7db945a 100644
--- a/cmd/release_config/release_config_proto/build_flags_declarations.pb.go
+++ b/cmd/release_config/release_config_proto/build_flags_declarations.pb.go
@@ -121,7 +121,7 @@
 	if x != nil && x.Workflow != nil {
 		return *x.Workflow
 	}
-	return Workflow_Workflow_Unspecified
+	return Workflow_WORKFLOW_UNSPECIFIED
 }
 
 func (x *FlagDeclarationArtifact) GetContainers() []string {
@@ -187,37 +187,37 @@
 	0x12, 0x1c, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
 	0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18,
 	0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
-	0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8e, 0x02, 0x0a, 0x19, 0x66, 0x6c, 0x61,
-	0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72,
-	0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61,
-	0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e,
-	0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63,
-	0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64,
-	0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x65,
-	0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x50, 0x61, 0x74, 0x68, 0x12, 0x43, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
-	0x77, 0x18, 0xcd, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
-	0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
-	0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1f, 0x0a, 0x0a, 0x63, 0x6f,
-	0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0xce, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
-	0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10,
-	0x05, 0x4a, 0x06, 0x08, 0xcf, 0x01, 0x10, 0xd0, 0x01, 0x22, 0x9a, 0x01, 0x0a, 0x1a, 0x66, 0x6c,
-	0x61, 0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61,
-	0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x7c, 0x0a, 0x1e, 0x66, 0x6c, 0x61, 0x67,
-	0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x74,
-	0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x37, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61,
-	0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
-	0x66, 0x6c, 0x61, 0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x1b, 0x66, 0x6c, 0x61, 0x67, 0x44,
-	0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61,
-	0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
-	0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8c, 0x02, 0x0a, 0x17, 0x46, 0x6c, 0x61,
+	0x67, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x74, 0x69,
+	0x66, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65,
+	0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d,
+	0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
+	0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x65, 0x63, 0x6c,
+	0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50,
+	0x61, 0x74, 0x68, 0x12, 0x43, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18,
+	0xcd, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+	0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x08,
+	0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x1f, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74,
+	0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0xce, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63,
+	0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a,
+	0x06, 0x08, 0xcf, 0x01, 0x10, 0xd0, 0x01, 0x22, 0x96, 0x01, 0x0a, 0x18, 0x46, 0x6c, 0x61, 0x67,
+	0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x74, 0x69, 0x66,
+	0x61, 0x63, 0x74, 0x73, 0x12, 0x7a, 0x0a, 0x1e, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x64, 0x65, 0x63,
+	0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63,
+	0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61,
+	0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x6c, 0x61, 0x67,
+	0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x74, 0x69, 0x66,
+	0x61, 0x63, 0x74, 0x52, 0x1b, 0x66, 0x6c, 0x61, 0x67, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74,
+	0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e,
+	0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
+	0x70, 0x72, 0x6f, 0x74, 0x6f,
 }
 
 var (
@@ -234,13 +234,13 @@
 
 var file_build_flags_declarations_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
 var file_build_flags_declarations_proto_goTypes = []interface{}{
-	(*FlagDeclarationArtifact)(nil),  // 0: android.release_config_proto.flag_declaration_artifact
-	(*FlagDeclarationArtifacts)(nil), // 1: android.release_config_proto.flag_declaration_artifacts
-	(Workflow)(0),                    // 2: android.release_config_proto.workflow
+	(*FlagDeclarationArtifact)(nil),  // 0: android.release_config_proto.FlagDeclarationArtifact
+	(*FlagDeclarationArtifacts)(nil), // 1: android.release_config_proto.FlagDeclarationArtifacts
+	(Workflow)(0),                    // 2: android.release_config_proto.Workflow
 }
 var file_build_flags_declarations_proto_depIdxs = []int32{
-	2, // 0: android.release_config_proto.flag_declaration_artifact.workflow:type_name -> android.release_config_proto.workflow
-	0, // 1: android.release_config_proto.flag_declaration_artifacts.flag_declaration_artifact_list:type_name -> android.release_config_proto.flag_declaration_artifact
+	2, // 0: android.release_config_proto.FlagDeclarationArtifact.workflow:type_name -> android.release_config_proto.Workflow
+	0, // 1: android.release_config_proto.FlagDeclarationArtifacts.flag_declaration_artifact_list:type_name -> android.release_config_proto.FlagDeclarationArtifact
 	2, // [2:2] is the sub-list for method output_type
 	2, // [2:2] is the sub-list for method input_type
 	2, // [2:2] is the sub-list for extension type_name
diff --git a/cmd/release_config/release_config_proto/build_flags_declarations.proto b/cmd/release_config/release_config_proto/build_flags_declarations.proto
index 233158e..d755e02 100644
--- a/cmd/release_config/release_config_proto/build_flags_declarations.proto
+++ b/cmd/release_config/release_config_proto/build_flags_declarations.proto
@@ -39,7 +39,7 @@
 //      com.android.mypackage is a valid name while com.android.myPackage,
 //      com.android.1mypackage are invalid
 
-message flag_declaration_artifact {
+message FlagDeclarationArtifact {
   // The name of the flag.
   // See # name for format detail
   optional string name = 1;
@@ -58,7 +58,7 @@
   optional string declaration_path = 5;
 
   // Workflow for this flag.
-  optional workflow workflow = 205;
+  optional Workflow workflow = 205;
 
   // The container for this flag.  This overrides any default container given
   // in the release_config_map message.
@@ -69,7 +69,7 @@
   reserved 207;
 }
 
-message flag_declaration_artifacts {
+message FlagDeclarationArtifacts {
   // The artifacts
-  repeated flag_declaration_artifact flag_declaration_artifact_list = 1;
+  repeated FlagDeclarationArtifact flag_declaration_artifact_list = 1;
 }
diff --git a/cmd/release_config/release_config_proto/build_flags_out.pb.go b/cmd/release_config/release_config_proto/build_flags_out.pb.go
index c63ea26..60ba2e1 100644
--- a/cmd/release_config/release_config_proto/build_flags_out.pb.go
+++ b/cmd/release_config/release_config_proto/build_flags_out.pb.go
@@ -399,89 +399,88 @@
 	0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
 	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61,
 	0x67, 0x73, 0x5f, 0x73, 0x72, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x60, 0x0a, 0x0a,
-	0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f,
+	0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f,
 	0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72,
 	0x63, 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01,
 	0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c,
 	0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xe8,
-	0x01, 0x0a, 0x0d, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
-	0x12, 0x59, 0x0a, 0x10, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x61, 0x6e, 0x64,
-	0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x64,
-	0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x66, 0x6c, 0x61, 0x67,
-	0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x76,
-	0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e,
-	0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65,
-	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x40, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65,
-	0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+	0x6f, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xe6,
+	0x01, 0x0a, 0x0c, 0x46, 0x6c, 0x61, 0x67, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12,
+	0x58, 0x0a, 0x10, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x61, 0x6e, 0x64, 0x72,
+	0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x44, 0x65, 0x63,
+	0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x66, 0x6c, 0x61, 0x67, 0x44, 0x65,
+	0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c,
+	0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72,
+	0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x40, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x18,
+	0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+	0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52,
+	0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x22, 0x61, 0x0a, 0x0d, 0x46, 0x6c, 0x61, 0x67, 0x41,
+	0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x40, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67,
+	0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
 	0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e,
-	0x74, 0x52, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x22, 0x63, 0x0a, 0x0e, 0x66, 0x6c, 0x61,
-	0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x41, 0x0a, 0x05, 0x66,
-	0x6c, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x6e, 0x64,
-	0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x61,
-	0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x52, 0x0e,
-	0x66, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22, 0xdd,
-	0x02, 0x0a, 0x17, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
-	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f,
-	0x0a, 0x0b, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20,
-	0x03, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12,
-	0x41, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b,
-	0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
-	0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x66, 0x6c,
-	0x61, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x05, 0x66, 0x6c, 0x61,
-	0x67, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x61,
-	0x6c, 0x75, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10,
-	0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65, 0x74, 0x73,
-	0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03,
-	0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x12, 0x20, 0x0a, 0x0b,
-	0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
-	0x09, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x21,
-	0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73, 0x18, 0x07,
-	0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x67, 0x65,
-	0x73, 0x12, 0x2b, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63,
-	0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x76, 0x61,
-	0x6c, 0x75, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x0e,
-	0x66, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22, 0xe8,
-	0x03, 0x0a, 0x18, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x73, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x5c, 0x0a, 0x0e, 0x72,
-	0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65,
-	0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x0d, 0x72, 0x65, 0x6c, 0x65,
-	0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x69, 0x0a, 0x15, 0x6f, 0x74, 0x68,
-	0x65, 0x72, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+	0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x41, 0x72, 0x74, 0x69, 0x66,
+	0x61, 0x63, 0x74, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x52, 0x0e, 0x66, 0x6c, 0x61, 0x67,
+	0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22, 0xda, 0x02, 0x0a, 0x15, 0x52,
+	0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x72, 0x74, 0x69,
+	0x66, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x74, 0x68, 0x65,
+	0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6f,
+	0x74, 0x68, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x05, 0x66, 0x6c, 0x61,
+	0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
 	0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52,
-	0x13, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x73, 0x12, 0x87, 0x01, 0x0a, 0x17, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
-	0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x73, 0x5f, 0x6d, 0x61, 0x70,
-	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x50, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
-	0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x73, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52,
-	0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x73,
-	0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
-	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x73, 0x4d, 0x61, 0x70, 0x1a, 0x79,
-	0x0a, 0x19, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d,
-	0x61, 0x70, 0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
-	0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a,
-	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x61,
-	0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65,
-	0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x52, 0x05,
-	0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64,
-	0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61,
-	0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
-	0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x41, 0x72, 0x74, 0x69,
+	0x66, 0x61, 0x63, 0x74, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x61,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x73, 0x65, 0x74,
+	0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x68,
+	0x65, 0x72, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x68,
+	0x65, 0x72, 0x69, 0x74, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f,
+	0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65,
+	0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6f, 0x72,
+	0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70,
+	0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x76, 0x61,
+	0x6c, 0x75, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18,
+	0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x69, 0x72, 0x65,
+	0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x0e, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x72,
+	0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22, 0xde, 0x03, 0x0a, 0x16, 0x52, 0x65, 0x6c, 0x65,
+	0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61,
+	0x63, 0x74, 0x12, 0x5a, 0x0a, 0x0e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x61, 0x6e, 0x64,
+	0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73,
+	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52,
+	0x0d, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x67,
+	0x0a, 0x15, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e,
+	0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x6c,
+	0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61,
+	0x63, 0x74, 0x52, 0x13, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x17, 0x72, 0x65, 0x6c, 0x65,
+	0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x73, 0x5f,
+	0x6d, 0x61, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4e, 0x2e, 0x61, 0x6e, 0x64, 0x72,
+	0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e,
+	0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70,
+	0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x72, 0x65, 0x6c, 0x65, 0x61,
+	0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x73, 0x4d, 0x61, 0x70, 0x1a,
+	0x77, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x4d, 0x61, 0x70, 0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
+	0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x44,
+	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e,
+	0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x6c,
+	0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x52, 0x05, 0x76,
+	0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72,
+	0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
+	0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
+	0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 }
 
 var (
@@ -498,27 +497,27 @@
 
 var file_build_flags_out_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
 var file_build_flags_out_proto_goTypes = []interface{}{
-	(*Tracepoint)(nil),             // 0: android.release_config_proto.tracepoint
-	(*FlagArtifact)(nil),           // 1: android.release_config_proto.flag_artifact
-	(*FlagArtifacts)(nil),          // 2: android.release_config_proto.flag_artifacts
-	(*ReleaseConfigArtifact)(nil),  // 3: android.release_config_proto.release_config_artifact
-	(*ReleaseConfigsArtifact)(nil), // 4: android.release_config_proto.release_configs_artifact
-	nil,                            // 5: android.release_config_proto.release_configs_artifact.ReleaseConfigMapsMapEntry
-	(*Value)(nil),                  // 6: android.release_config_proto.value
-	(*FlagDeclaration)(nil),        // 7: android.release_config_proto.flag_declaration
-	(*ReleaseConfigMap)(nil),       // 8: android.release_config_proto.release_config_map
+	(*Tracepoint)(nil),             // 0: android.release_config_proto.Tracepoint
+	(*FlagArtifact)(nil),           // 1: android.release_config_proto.FlagArtifact
+	(*FlagArtifacts)(nil),          // 2: android.release_config_proto.FlagArtifacts
+	(*ReleaseConfigArtifact)(nil),  // 3: android.release_config_proto.ReleaseConfigArtifact
+	(*ReleaseConfigsArtifact)(nil), // 4: android.release_config_proto.ReleaseConfigsArtifact
+	nil,                            // 5: android.release_config_proto.ReleaseConfigsArtifact.ReleaseConfigMapsMapEntry
+	(*Value)(nil),                  // 6: android.release_config_proto.Value
+	(*FlagDeclaration)(nil),        // 7: android.release_config_proto.FlagDeclaration
+	(*ReleaseConfigMap)(nil),       // 8: android.release_config_proto.ReleaseConfigMap
 }
 var file_build_flags_out_proto_depIdxs = []int32{
-	6,  // 0: android.release_config_proto.tracepoint.value:type_name -> android.release_config_proto.value
-	7,  // 1: android.release_config_proto.flag_artifact.flag_declaration:type_name -> android.release_config_proto.flag_declaration
-	6,  // 2: android.release_config_proto.flag_artifact.value:type_name -> android.release_config_proto.value
-	0,  // 3: android.release_config_proto.flag_artifact.traces:type_name -> android.release_config_proto.tracepoint
-	1,  // 4: android.release_config_proto.flag_artifacts.flags:type_name -> android.release_config_proto.flag_artifact
-	1,  // 5: android.release_config_proto.release_config_artifact.flags:type_name -> android.release_config_proto.flag_artifact
-	3,  // 6: android.release_config_proto.release_configs_artifact.release_config:type_name -> android.release_config_proto.release_config_artifact
-	3,  // 7: android.release_config_proto.release_configs_artifact.other_release_configs:type_name -> android.release_config_proto.release_config_artifact
-	5,  // 8: android.release_config_proto.release_configs_artifact.release_config_maps_map:type_name -> android.release_config_proto.release_configs_artifact.ReleaseConfigMapsMapEntry
-	8,  // 9: android.release_config_proto.release_configs_artifact.ReleaseConfigMapsMapEntry.value:type_name -> android.release_config_proto.release_config_map
+	6,  // 0: android.release_config_proto.Tracepoint.value:type_name -> android.release_config_proto.Value
+	7,  // 1: android.release_config_proto.FlagArtifact.flag_declaration:type_name -> android.release_config_proto.FlagDeclaration
+	6,  // 2: android.release_config_proto.FlagArtifact.value:type_name -> android.release_config_proto.Value
+	0,  // 3: android.release_config_proto.FlagArtifact.traces:type_name -> android.release_config_proto.Tracepoint
+	1,  // 4: android.release_config_proto.FlagArtifacts.flags:type_name -> android.release_config_proto.FlagArtifact
+	1,  // 5: android.release_config_proto.ReleaseConfigArtifact.flags:type_name -> android.release_config_proto.FlagArtifact
+	3,  // 6: android.release_config_proto.ReleaseConfigsArtifact.release_config:type_name -> android.release_config_proto.ReleaseConfigArtifact
+	3,  // 7: android.release_config_proto.ReleaseConfigsArtifact.other_release_configs:type_name -> android.release_config_proto.ReleaseConfigArtifact
+	5,  // 8: android.release_config_proto.ReleaseConfigsArtifact.release_config_maps_map:type_name -> android.release_config_proto.ReleaseConfigsArtifact.ReleaseConfigMapsMapEntry
+	8,  // 9: android.release_config_proto.ReleaseConfigsArtifact.ReleaseConfigMapsMapEntry.value:type_name -> android.release_config_proto.ReleaseConfigMap
 	10, // [10:10] is the sub-list for method output_type
 	10, // [10:10] is the sub-list for method input_type
 	10, // [10:10] is the sub-list for extension type_name
diff --git a/cmd/release_config/release_config_proto/build_flags_out.proto b/cmd/release_config/release_config_proto/build_flags_out.proto
index 4dc84e9..2ab62d1 100644
--- a/cmd/release_config/release_config_proto/build_flags_out.proto
+++ b/cmd/release_config/release_config_proto/build_flags_out.proto
@@ -39,30 +39,30 @@
 //      com.android.mypackage is a valid name while com.android.myPackage,
 //      com.android.1mypackage are invalid
 
-message tracepoint {
+message Tracepoint {
   // Path to declaration or value file relative to $TOP
   optional string source = 1;
-  optional value value = 201;
+  optional Value value = 201;
 }
 
-message flag_artifact {
+message FlagArtifact {
   // The original declaration
-  optional flag_declaration flag_declaration = 1;
+  optional FlagDeclaration flag_declaration = 1;
 
   // Value for the flag
-  optional value value = 201;
+  optional Value value = 201;
 
   // Trace of where the flag value was assigned.
-  repeated tracepoint traces = 8;
+  repeated Tracepoint traces = 8;
 }
 
-message flag_artifacts {
+message FlagArtifacts {
   // The artifacts
-  repeated flag_artifact flags = 1;
+  repeated FlagArtifact flags = 1;
   reserved "flag_artifacts";
 }
 
-message release_config_artifact {
+message ReleaseConfigArtifact {
   // The name of the release config.
   // See # name for format detail
   optional string name = 1;
@@ -72,7 +72,7 @@
 
   // The complete set of build flags in this release config, after all
   // inheritance and other processing is complete.
-  repeated flag_artifact flags = 3;
+  repeated FlagArtifact flags = 3;
   reserved "flag_artifacts";
 
   // The (complete) list of aconfig_value_sets Soong modules to use.
@@ -98,14 +98,14 @@
   repeated string value_directories = 8;
 }
 
-message release_configs_artifact {
+message ReleaseConfigsArtifact {
   // The active release config for this build.
-  optional release_config_artifact release_config = 1;
+  optional ReleaseConfigArtifact release_config = 1;
 
   // All other release configs defined for this TARGET_PRODUCT.
-  repeated release_config_artifact other_release_configs = 2;
+  repeated ReleaseConfigArtifact other_release_configs = 2;
 
   // Map of release_config_artifact.directories to release_config_map message.
-  map<string, release_config_map> release_config_maps_map = 3;
+  map<string, ReleaseConfigMap> release_config_maps_map = 3;
 }
 
diff --git a/cmd/release_config/release_config_proto/build_flags_src.pb.go b/cmd/release_config/release_config_proto/build_flags_src.pb.go
index bc5f5c0..d784dee 100644
--- a/cmd/release_config/release_config_proto/build_flags_src.pb.go
+++ b/cmd/release_config/release_config_proto/build_flags_src.pb.go
@@ -232,7 +232,7 @@
 	if x != nil && x.Workflow != nil {
 		return *x.Workflow
 	}
-	return Workflow_Workflow_Unspecified
+	return Workflow_WORKFLOW_UNSPECIFIED
 }
 
 func (x *FlagDeclaration) GetContainers() []string {
@@ -531,7 +531,7 @@
 	0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
 	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61,
 	0x67, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
-	0xa5, 0x01, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x0a, 0x11, 0x75, 0x6e, 0x73,
+	0xa5, 0x01, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x0a, 0x11, 0x75, 0x6e, 0x73,
 	0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc8,
 	0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x10, 0x75, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69,
 	0x66, 0x69, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x24, 0x0a, 0x0c, 0x73, 0x74, 0x72,
@@ -541,62 +541,62 @@
 	0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75,
 	0x65, 0x12, 0x1d, 0x0a, 0x08, 0x6f, 0x62, 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65, 0x18, 0xcb, 0x01,
 	0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x6f, 0x62, 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65,
-	0x42, 0x05, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x96, 0x02, 0x0a, 0x10, 0x66, 0x6c, 0x61, 0x67,
-	0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04,
-	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-	0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20,
-	0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x42, 0x05, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x95, 0x02, 0x0a, 0x0f, 0x46, 0x6c, 0x61, 0x67,
+	0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+	0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a,
+	0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
+	0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
+	0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56,
+	0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, 0x0a, 0x08, 0x77,
+	0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0xcd, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26,
+	0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
+	0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x6f,
+	0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
+	0x12, 0x1f, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0xce,
+	0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
+	0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x06, 0x08, 0xcf, 0x01, 0x10, 0xd0, 0x01, 0x22,
+	0x78, 0x0a, 0x09, 0x46, 0x6c, 0x61, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04,
+	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
 	0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, 0x0b,
 	0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61,
 	0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
-	0x76, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, 0x0a, 0x08,
-	0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0xcd, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
-	0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
-	0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x77,
-	0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
-	0x77, 0x12, 0x1f, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18,
-	0xce, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
-	0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x06, 0x08, 0xcf, 0x01, 0x10, 0xd0, 0x01,
-	0x22, 0x79, 0x0a, 0x0a, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12,
-	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
-	0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c,
-	0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b,
-	0x0a, 0x08, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x65, 0x64, 0x18, 0xca, 0x01, 0x20, 0x01, 0x28,
-	0x08, 0x52, 0x08, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x65, 0x64, 0x22, 0xbf, 0x01, 0x0a, 0x0e,
-	0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12,
-	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
-	0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x18, 0x02,
-	0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x12, 0x2c,
-	0x0a, 0x12, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f,
-	0x73, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65, 0x74, 0x73, 0x12, 0x2c, 0x0a, 0x12,
-	0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x6f, 0x6e,
-	0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72,
-	0x69, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09,
-	0x52, 0x0b, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x22, 0x3b, 0x0a,
-	0x0d, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x12,
-	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
-	0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xac, 0x01, 0x0a, 0x12, 0x72,
-	0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61,
-	0x70, 0x12, 0x45, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c,
-	0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x52,
-	0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63,
-	0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64,
-	0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x64, 0x65,
-	0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73,
-	0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43,
-	0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64,
-	0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61,
-	0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
-	0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x0a, 0x08,
+	0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x65, 0x64, 0x18, 0xca, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
+	0x08, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x65, 0x64, 0x22, 0xbe, 0x01, 0x0a, 0x0d, 0x52, 0x65,
+	0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+	0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
+	0x09, 0x52, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x61,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x73, 0x65, 0x74,
+	0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65, 0x74, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18,
+	0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x6c,
+	0x61, 0x67, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6f, 0x72,
+	0x5f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70,
+	0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x67, 0x65, 0x73, 0x22, 0x3a, 0x0a, 0x0c, 0x52, 0x65,
+	0x6c, 0x65, 0x61, 0x73, 0x65, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16,
+	0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
+	0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xa9, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x6c, 0x65, 0x61,
+	0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x12, 0x44, 0x0a, 0x07, 0x61,
+	0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61,
+	0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x6c, 0x65,
+	0x61, 0x73, 0x65, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65,
+	0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63,
+	0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52,
+	0x11, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
+	0x72, 0x73, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f,
+	0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 }
 
 var (
@@ -613,19 +613,19 @@
 
 var file_build_flags_src_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
 var file_build_flags_src_proto_goTypes = []interface{}{
-	(*Value)(nil),            // 0: android.release_config_proto.value
-	(*FlagDeclaration)(nil),  // 1: android.release_config_proto.flag_declaration
-	(*FlagValue)(nil),        // 2: android.release_config_proto.flag_value
-	(*ReleaseConfig)(nil),    // 3: android.release_config_proto.release_config
-	(*ReleaseAlias)(nil),     // 4: android.release_config_proto.release_alias
-	(*ReleaseConfigMap)(nil), // 5: android.release_config_proto.release_config_map
-	(Workflow)(0),            // 6: android.release_config_proto.workflow
+	(*Value)(nil),            // 0: android.release_config_proto.Value
+	(*FlagDeclaration)(nil),  // 1: android.release_config_proto.FlagDeclaration
+	(*FlagValue)(nil),        // 2: android.release_config_proto.FlagValue
+	(*ReleaseConfig)(nil),    // 3: android.release_config_proto.ReleaseConfig
+	(*ReleaseAlias)(nil),     // 4: android.release_config_proto.ReleaseAlias
+	(*ReleaseConfigMap)(nil), // 5: android.release_config_proto.ReleaseConfigMap
+	(Workflow)(0),            // 6: android.release_config_proto.Workflow
 }
 var file_build_flags_src_proto_depIdxs = []int32{
-	0, // 0: android.release_config_proto.flag_declaration.value:type_name -> android.release_config_proto.value
-	6, // 1: android.release_config_proto.flag_declaration.workflow:type_name -> android.release_config_proto.workflow
-	0, // 2: android.release_config_proto.flag_value.value:type_name -> android.release_config_proto.value
-	4, // 3: android.release_config_proto.release_config_map.aliases:type_name -> android.release_config_proto.release_alias
+	0, // 0: android.release_config_proto.FlagDeclaration.value:type_name -> android.release_config_proto.Value
+	6, // 1: android.release_config_proto.FlagDeclaration.workflow:type_name -> android.release_config_proto.Workflow
+	0, // 2: android.release_config_proto.FlagValue.value:type_name -> android.release_config_proto.Value
+	4, // 3: android.release_config_proto.ReleaseConfigMap.aliases:type_name -> android.release_config_proto.ReleaseAlias
 	4, // [4:4] is the sub-list for method output_type
 	4, // [4:4] is the sub-list for method input_type
 	4, // [4:4] is the sub-list for extension type_name
diff --git a/cmd/release_config/release_config_proto/build_flags_src.proto b/cmd/release_config/release_config_proto/build_flags_src.proto
index 4fad478..e1925bc 100644
--- a/cmd/release_config/release_config_proto/build_flags_src.proto
+++ b/cmd/release_config/release_config_proto/build_flags_src.proto
@@ -44,7 +44,7 @@
 //      com.android.mypackage is a valid name while com.android.myPackage,
 //      com.android.1mypackage are invalid
 
-message value {
+message Value {
   oneof val {
     bool unspecified_value = 200;
     string string_value = 201;
@@ -55,7 +55,7 @@
 }
 
 // The proto used in the source tree.
-message flag_declaration {
+message FlagDeclaration {
   // The name of the flag.
   // See # name for format detail
   optional string name = 1;
@@ -71,10 +71,10 @@
   reserved 4;
 
   // Value for the flag
-  optional value value = 201;
+  optional Value value = 201;
 
   // Workflow for this flag.
-  optional workflow workflow = 205;
+  optional Workflow workflow = 205;
 
   // The container for this flag.  This overrides any default container given
   // in the release_config_map message.
@@ -85,13 +85,13 @@
   reserved 207;
 }
 
-message flag_value {
+message FlagValue {
   // Name of the flag.
   // See # name for format detail
   optional string name = 2;
 
   // Value for the flag
-  optional value value = 201;
+  optional Value value = 201;
 
   // If true, the flag is completely removed from the release config as if
   // never declared.
@@ -99,7 +99,7 @@
 }
 
 // This replaces $(call declare-release-config).
-message release_config {
+message ReleaseConfig {
   // The name of the release config.
   // See # name for format detail
   optional string name = 1;
@@ -120,7 +120,7 @@
 }
 
 // Any aliases.  These are used for continuous integration builder config.
-message release_alias {
+message ReleaseAlias {
   // The name of the alias.
   optional string name = 1;
 
@@ -129,9 +129,9 @@
 }
 
 // This provides the data from release_config_map.mk
-message release_config_map {
+message ReleaseConfigMap {
   // Any aliases.
-  repeated release_alias aliases = 1;
+  repeated ReleaseAlias aliases = 1;
 
   // Description of this map and its intended use.
   optional string description = 2;
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index e69a930..6459ea1 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -27,6 +27,7 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"regexp"
 	"strconv"
 	"strings"
 	"time"
@@ -51,6 +52,8 @@
 	sandboxDirPlaceholder = "__SBOX_SANDBOX_DIR__"
 )
 
+var envVarNameRegex = regexp.MustCompile("^[a-zA-Z0-9_-]+$")
+
 func init() {
 	flag.StringVar(&sandboxesRoot, "sandbox-path", "",
 		"root of temp directory to put the sandbox into")
@@ -238,6 +241,48 @@
 	return &manifest, nil
 }
 
+func createEnv(command *sbox_proto.Command) ([]string, error) {
+	env := []string{}
+	if command.DontInheritEnv == nil || !*command.DontInheritEnv {
+		env = os.Environ()
+	}
+	for _, envVar := range command.Env {
+		if envVar.Name == nil || !envVarNameRegex.MatchString(*envVar.Name) {
+			name := "nil"
+			if envVar.Name != nil {
+				name = *envVar.Name
+			}
+			return nil, fmt.Errorf("Invalid environment variable name: %q", name)
+		}
+		if envVar.State == nil {
+			return nil, fmt.Errorf("Must set state")
+		}
+		switch state := envVar.State.(type) {
+		case *sbox_proto.EnvironmentVariable_Value:
+			env = append(env, *envVar.Name+"="+state.Value)
+		case *sbox_proto.EnvironmentVariable_Unset:
+			if !state.Unset {
+				return nil, fmt.Errorf("Can't have unset set to false")
+			}
+			prefix := *envVar.Name + "="
+			for i := 0; i < len(env); i++ {
+				if strings.HasPrefix(env[i], prefix) {
+					env = append(env[:i], env[i+1:]...)
+					i--
+				}
+			}
+		case *sbox_proto.EnvironmentVariable_Inherit:
+			if !state.Inherit {
+				return nil, fmt.Errorf("Can't have inherit set to false")
+			}
+			env = append(env, *envVar.Name+"="+os.Getenv(*envVar.Name))
+		default:
+			return nil, fmt.Errorf("Unhandled state type")
+		}
+	}
+	return env, nil
+}
+
 // runCommand runs a single command from a manifest.  If the command references the
 // __SBOX_DEPFILE__ placeholder it returns the name of the depfile that was used.
 func runCommand(command *sbox_proto.Command, tempDir string, commandIndex int) (depFile string, err error) {
@@ -313,6 +358,12 @@
 			return "", fmt.Errorf("Failed to update PATH: %w", err)
 		}
 	}
+
+	cmd.Env, err = createEnv(command)
+	if err != nil {
+		return "", err
+	}
+
 	err = cmd.Run()
 
 	if err != nil {
diff --git a/cmd/sbox/sbox_proto/sbox.pb.go b/cmd/sbox/sbox_proto/sbox.pb.go
index 7c84f2c..271039c 100644
--- a/cmd/sbox/sbox_proto/sbox.pb.go
+++ b/cmd/sbox/sbox_proto/sbox.pb.go
@@ -14,8 +14,8 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.26.0
-// 	protoc        v3.9.1
+// 	protoc-gen-go v1.33.0
+// 	protoc        v3.21.12
 // source: sbox.proto
 
 package sbox_proto
@@ -116,6 +116,13 @@
 	// A list of files that will be copied before the sandboxed command, and whose contents should be
 	// copied as if they were listed in copy_before.
 	RspFiles []*RspFile `protobuf:"bytes,6,rep,name=rsp_files,json=rspFiles" json:"rsp_files,omitempty"`
+	// The environment variables that will be set or unset while running the command.
+	// Also see dont_inherit_env.
+	Env []*EnvironmentVariable `protobuf:"bytes,7,rep,name=env" json:"env,omitempty"`
+	// By default, all environment variables are inherited from the calling process, but may be
+	// replaced or unset by env. If dont_inherit_env is set, no environment variables will be
+	// inherited, and instead only the variables in env will be defined.
+	DontInheritEnv *bool `protobuf:"varint,8,opt,name=dont_inherit_env,json=dontInheritEnv" json:"dont_inherit_env,omitempty"`
 }
 
 func (x *Command) Reset() {
@@ -192,6 +199,129 @@
 	return nil
 }
 
+func (x *Command) GetEnv() []*EnvironmentVariable {
+	if x != nil {
+		return x.Env
+	}
+	return nil
+}
+
+func (x *Command) GetDontInheritEnv() bool {
+	if x != nil && x.DontInheritEnv != nil {
+		return *x.DontInheritEnv
+	}
+	return false
+}
+
+type EnvironmentVariable struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The name of the environment variable
+	Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
+	// Types that are assignable to State:
+	//
+	//	*EnvironmentVariable_Value
+	//	*EnvironmentVariable_Unset
+	//	*EnvironmentVariable_Inherit
+	State isEnvironmentVariable_State `protobuf_oneof:"state"`
+}
+
+func (x *EnvironmentVariable) Reset() {
+	*x = EnvironmentVariable{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_sbox_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *EnvironmentVariable) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*EnvironmentVariable) ProtoMessage() {}
+
+func (x *EnvironmentVariable) ProtoReflect() protoreflect.Message {
+	mi := &file_sbox_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use EnvironmentVariable.ProtoReflect.Descriptor instead.
+func (*EnvironmentVariable) Descriptor() ([]byte, []int) {
+	return file_sbox_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *EnvironmentVariable) GetName() string {
+	if x != nil && x.Name != nil {
+		return *x.Name
+	}
+	return ""
+}
+
+func (m *EnvironmentVariable) GetState() isEnvironmentVariable_State {
+	if m != nil {
+		return m.State
+	}
+	return nil
+}
+
+func (x *EnvironmentVariable) GetValue() string {
+	if x, ok := x.GetState().(*EnvironmentVariable_Value); ok {
+		return x.Value
+	}
+	return ""
+}
+
+func (x *EnvironmentVariable) GetUnset() bool {
+	if x, ok := x.GetState().(*EnvironmentVariable_Unset); ok {
+		return x.Unset
+	}
+	return false
+}
+
+func (x *EnvironmentVariable) GetInherit() bool {
+	if x, ok := x.GetState().(*EnvironmentVariable_Inherit); ok {
+		return x.Inherit
+	}
+	return false
+}
+
+type isEnvironmentVariable_State interface {
+	isEnvironmentVariable_State()
+}
+
+type EnvironmentVariable_Value struct {
+	// The value to set the environment variable to.
+	Value string `protobuf:"bytes,2,opt,name=value,oneof"`
+}
+
+type EnvironmentVariable_Unset struct {
+	// This environment variable should be unset in the command.
+	Unset bool `protobuf:"varint,3,opt,name=unset,oneof"`
+}
+
+type EnvironmentVariable_Inherit struct {
+	// This environment variable should be inherited from the parent process.
+	// Can be combined with dont_inherit_env to only inherit certain environment
+	// variables.
+	Inherit bool `protobuf:"varint,4,opt,name=inherit,oneof"`
+}
+
+func (*EnvironmentVariable_Value) isEnvironmentVariable_State() {}
+
+func (*EnvironmentVariable_Unset) isEnvironmentVariable_State() {}
+
+func (*EnvironmentVariable_Inherit) isEnvironmentVariable_State() {}
+
 // Copy describes a from-to pair of files to copy.  The paths may be relative, the root that they
 // are relative to is specific to the context the Copy is used in and will be different for
 // from and to.
@@ -209,7 +339,7 @@
 func (x *Copy) Reset() {
 	*x = Copy{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_sbox_proto_msgTypes[2]
+		mi := &file_sbox_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -222,7 +352,7 @@
 func (*Copy) ProtoMessage() {}
 
 func (x *Copy) ProtoReflect() protoreflect.Message {
-	mi := &file_sbox_proto_msgTypes[2]
+	mi := &file_sbox_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -235,7 +365,7 @@
 
 // Deprecated: Use Copy.ProtoReflect.Descriptor instead.
 func (*Copy) Descriptor() ([]byte, []int) {
-	return file_sbox_proto_rawDescGZIP(), []int{2}
+	return file_sbox_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *Copy) GetFrom() string {
@@ -274,7 +404,7 @@
 func (x *RspFile) Reset() {
 	*x = RspFile{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_sbox_proto_msgTypes[3]
+		mi := &file_sbox_proto_msgTypes[4]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -287,7 +417,7 @@
 func (*RspFile) ProtoMessage() {}
 
 func (x *RspFile) ProtoReflect() protoreflect.Message {
-	mi := &file_sbox_proto_msgTypes[3]
+	mi := &file_sbox_proto_msgTypes[4]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -300,7 +430,7 @@
 
 // Deprecated: Use RspFile.ProtoReflect.Descriptor instead.
 func (*RspFile) Descriptor() ([]byte, []int) {
-	return file_sbox_proto_rawDescGZIP(), []int{3}
+	return file_sbox_proto_rawDescGZIP(), []int{4}
 }
 
 func (x *RspFile) GetFile() string {
@@ -330,7 +460,7 @@
 func (x *PathMapping) Reset() {
 	*x = PathMapping{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_sbox_proto_msgTypes[4]
+		mi := &file_sbox_proto_msgTypes[5]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -343,7 +473,7 @@
 func (*PathMapping) ProtoMessage() {}
 
 func (x *PathMapping) ProtoReflect() protoreflect.Message {
-	mi := &file_sbox_proto_msgTypes[4]
+	mi := &file_sbox_proto_msgTypes[5]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -356,7 +486,7 @@
 
 // Deprecated: Use PathMapping.ProtoReflect.Descriptor instead.
 func (*PathMapping) Descriptor() ([]byte, []int) {
-	return file_sbox_proto_rawDescGZIP(), []int{4}
+	return file_sbox_proto_rawDescGZIP(), []int{5}
 }
 
 func (x *PathMapping) GetFrom() string {
@@ -383,7 +513,7 @@
 	0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x75, 0x74,
 	0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x70, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
 	0x09, 0x52, 0x0d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x44, 0x65, 0x70, 0x66, 0x69, 0x6c, 0x65,
-	0x22, 0xdc, 0x01, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2b, 0x0a, 0x0b,
+	0x22, 0xb3, 0x02, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2b, 0x0a, 0x0b,
 	0x63, 0x6f, 0x70, 0x79, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28,
 	0x0b, 0x32, 0x0a, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x43, 0x6f, 0x70, 0x79, 0x52, 0x0a, 0x63,
 	0x6f, 0x70, 0x79, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x64,
@@ -396,23 +526,37 @@
 	0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x48,
 	0x61, 0x73, 0x68, 0x12, 0x2a, 0x0a, 0x09, 0x72, 0x73, 0x70, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73,
 	0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x52, 0x73,
-	0x70, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x72, 0x73, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x22,
-	0x4a, 0x0a, 0x04, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18,
-	0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74,
-	0x6f, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x65,
-	0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
-	0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x55, 0x0a, 0x07, 0x52,
-	0x73, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01,
-	0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x61,
-	0x74, 0x68, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x11, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70,
-	0x70, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x70, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e,
-	0x67, 0x73, 0x22, 0x31, 0x0a, 0x0b, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e,
-	0x67, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52,
-	0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x02, 0x28,
-	0x09, 0x52, 0x02, 0x74, 0x6f, 0x42, 0x23, 0x5a, 0x21, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
-	0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x73, 0x62, 0x6f, 0x78, 0x2f,
-	0x73, 0x62, 0x6f, 0x78, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x70, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x72, 0x73, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12,
+	0x2b, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73,
+	0x62, 0x6f, 0x78, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56,
+	0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x28, 0x0a, 0x10,
+	0x64, 0x6f, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x5f, 0x65, 0x6e, 0x76,
+	0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x6f, 0x6e, 0x74, 0x49, 0x6e, 0x68, 0x65,
+	0x72, 0x69, 0x74, 0x45, 0x6e, 0x76, 0x22, 0x7e, 0x0a, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f,
+	0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x75, 0x6e, 0x73,
+	0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x05, 0x75, 0x6e, 0x73, 0x65,
+	0x74, 0x12, 0x1a, 0x0a, 0x07, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x08, 0x48, 0x00, 0x52, 0x07, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x42, 0x07, 0x0a,
+	0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x4a, 0x0a, 0x04, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x12,
+	0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72,
+	0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x02,
+	0x74, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62,
+	0x6c, 0x65, 0x22, 0x55, 0x0a, 0x07, 0x52, 0x73, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a,
+	0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c,
+	0x65, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e,
+	0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e,
+	0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x70, 0x61, 0x74,
+	0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x31, 0x0a, 0x0b, 0x50, 0x61, 0x74,
+	0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d,
+	0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02,
+	0x74, 0x6f, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x42, 0x23, 0x5a, 0x21,
+	0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x63, 0x6d,
+	0x64, 0x2f, 0x73, 0x62, 0x6f, 0x78, 0x2f, 0x73, 0x62, 0x6f, 0x78, 0x5f, 0x70, 0x72, 0x6f, 0x74,
+	0x6f,
 }
 
 var (
@@ -427,25 +571,27 @@
 	return file_sbox_proto_rawDescData
 }
 
-var file_sbox_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
+var file_sbox_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
 var file_sbox_proto_goTypes = []interface{}{
-	(*Manifest)(nil),    // 0: sbox.Manifest
-	(*Command)(nil),     // 1: sbox.Command
-	(*Copy)(nil),        // 2: sbox.Copy
-	(*RspFile)(nil),     // 3: sbox.RspFile
-	(*PathMapping)(nil), // 4: sbox.PathMapping
+	(*Manifest)(nil),            // 0: sbox.Manifest
+	(*Command)(nil),             // 1: sbox.Command
+	(*EnvironmentVariable)(nil), // 2: sbox.EnvironmentVariable
+	(*Copy)(nil),                // 3: sbox.Copy
+	(*RspFile)(nil),             // 4: sbox.RspFile
+	(*PathMapping)(nil),         // 5: sbox.PathMapping
 }
 var file_sbox_proto_depIdxs = []int32{
 	1, // 0: sbox.Manifest.commands:type_name -> sbox.Command
-	2, // 1: sbox.Command.copy_before:type_name -> sbox.Copy
-	2, // 2: sbox.Command.copy_after:type_name -> sbox.Copy
-	3, // 3: sbox.Command.rsp_files:type_name -> sbox.RspFile
-	4, // 4: sbox.RspFile.path_mappings:type_name -> sbox.PathMapping
-	5, // [5:5] is the sub-list for method output_type
-	5, // [5:5] is the sub-list for method input_type
-	5, // [5:5] is the sub-list for extension type_name
-	5, // [5:5] is the sub-list for extension extendee
-	0, // [0:5] is the sub-list for field type_name
+	3, // 1: sbox.Command.copy_before:type_name -> sbox.Copy
+	3, // 2: sbox.Command.copy_after:type_name -> sbox.Copy
+	4, // 3: sbox.Command.rsp_files:type_name -> sbox.RspFile
+	2, // 4: sbox.Command.env:type_name -> sbox.EnvironmentVariable
+	5, // 5: sbox.RspFile.path_mappings:type_name -> sbox.PathMapping
+	6, // [6:6] is the sub-list for method output_type
+	6, // [6:6] is the sub-list for method input_type
+	6, // [6:6] is the sub-list for extension type_name
+	6, // [6:6] is the sub-list for extension extendee
+	0, // [0:6] is the sub-list for field type_name
 }
 
 func init() { file_sbox_proto_init() }
@@ -479,7 +625,7 @@
 			}
 		}
 		file_sbox_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Copy); i {
+			switch v := v.(*EnvironmentVariable); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -491,7 +637,7 @@
 			}
 		}
 		file_sbox_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*RspFile); i {
+			switch v := v.(*Copy); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -503,6 +649,18 @@
 			}
 		}
 		file_sbox_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RspFile); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_sbox_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*PathMapping); i {
 			case 0:
 				return &v.state
@@ -515,13 +673,18 @@
 			}
 		}
 	}
+	file_sbox_proto_msgTypes[2].OneofWrappers = []interface{}{
+		(*EnvironmentVariable_Value)(nil),
+		(*EnvironmentVariable_Unset)(nil),
+		(*EnvironmentVariable_Inherit)(nil),
+	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_sbox_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   5,
+			NumMessages:   6,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/cmd/sbox/sbox_proto/sbox.proto b/cmd/sbox/sbox_proto/sbox.proto
index 2f0dcf0..1158554 100644
--- a/cmd/sbox/sbox_proto/sbox.proto
+++ b/cmd/sbox/sbox_proto/sbox.proto
@@ -51,6 +51,30 @@
   // A list of files that will be copied before the sandboxed command, and whose contents should be
   // copied as if they were listed in copy_before.
   repeated RspFile rsp_files = 6;
+
+  // The environment variables that will be set or unset while running the command.
+  // Also see dont_inherit_env.
+  repeated EnvironmentVariable env = 7;
+
+  // By default, all environment variables are inherited from the calling process, but may be
+  // replaced or unset by env. If dont_inherit_env is set, no environment variables will be
+  // inherited, and instead only the variables in env will be defined.
+  optional bool dont_inherit_env = 8;
+}
+
+message EnvironmentVariable {
+  // The name of the environment variable
+  required string name = 1;
+  oneof state {
+    // The value to set the environment variable to.
+    string value = 2;
+    // This environment variable should be unset in the command.
+    bool unset = 3;
+    // This environment variable should be inherited from the parent process.
+    // Can be combined with dont_inherit_env to only inherit certain environment
+    // variables.
+    bool inherit = 4;
+  }
 }
 
 // Copy describes a from-to pair of files to copy.  The paths may be relative, the root that they
diff --git a/filesystem/logical_partition.go b/filesystem/logical_partition.go
index e483fe4..988a57b 100644
--- a/filesystem/logical_partition.go
+++ b/filesystem/logical_partition.go
@@ -146,9 +146,16 @@
 				partitionNames[pName] = true
 			}
 			// Get size of the partition by reading the -size.txt file
-			pSize := fmt.Sprintf("$(cat %s)", sparseImageSizes[pName])
+			var pSize string
+			if size, hasSize := sparseImageSizes[pName]; hasSize {
+				pSize = fmt.Sprintf("$(cat %s)", size)
+			} else {
+				pSize = "0"
+			}
 			cmd.FlagWithArg("--partition=", fmt.Sprintf("%s:readonly:%s:%s", pName, pSize, gName))
-			cmd.FlagWithInput("--image="+pName+"=", sparseImages[pName])
+			if image, hasImage := sparseImages[pName]; hasImage {
+				cmd.FlagWithInput("--image="+pName+"=", image)
+			}
 		}
 	}
 
@@ -192,6 +199,9 @@
 // Add a rule that converts the filesystem for the given partition to the given rule builder. The
 // path to the sparse file and the text file having the size of the partition are returned.
 func sparseFilesystem(ctx android.ModuleContext, p partitionProperties, builder *android.RuleBuilder) (sparseImg android.OutputPath, sizeTxt android.OutputPath) {
+	if p.Filesystem == nil {
+		return
+	}
 	img := android.PathForModuleSrc(ctx, proptools.String(p.Filesystem))
 	name := proptools.String(p.Name)
 	sparseImg = android.PathForModuleOut(ctx, name+".img").OutputPath
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
index 7c71b77..4f1b320 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -17,7 +17,6 @@
 var (
 	SandboxingDenyModuleList = []string{
 		// go/keep-sorted start
-		"aidl_camera_build_version",
 		"com.google.pixel.camera.hal.manifest",
 		// go/keep-sorted end
 	}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 9195643..fd72d3c 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -243,13 +243,35 @@
 	}
 }
 
+var buildNumberAllowlistKey = android.NewOnceKey("genruleBuildNumberAllowlistKey")
+
 // This allowlist should be kept to the bare minimum, it's
 // intended for things that existed before the build number
 // was tightly controlled. Prefer using libbuildversion
 // via the use_version_lib property of cc modules.
-var genrule_build_number_allowlist = map[string]bool{
-	"build/soong/tests:gen":                   true,
-	"tools/tradefederation/core:tradefed_zip": true,
+// This is a function instead of a global map so that
+// soong plugins cannot add entries to the allowlist
+func isModuleInBuildNumberAllowlist(ctx android.ModuleContext) bool {
+	allowlist := ctx.Config().Once(buildNumberAllowlistKey, func() interface{} {
+		// Define the allowlist as a list and then copy it into a map so that
+		// gofmt doesn't change unnecessary lines trying to align the values of the map.
+		allowlist := []string{
+			// go/keep-sorted start
+			"build/soong/tests:gen",
+			"hardware/google/camera/common/hal/aidl_service:aidl_camera_build_version",
+			"tools/tradefederation/core:tradefed_zip",
+			"vendor/google/services/LyricCameraHAL/src/apex:com.google.pixel.camera.hal.manifest",
+			// go/keep-sorted end
+		}
+		allowlistMap := make(map[string]bool, len(allowlist))
+		for _, a := range allowlist {
+			allowlistMap[a] = true
+		}
+		return allowlistMap
+	}).(map[string]bool)
+
+	_, ok := allowlist[ctx.ModuleDir()+":"+ctx.ModuleName()]
+	return ok
 }
 
 // generateCommonBuildActions contains build action generation logic
@@ -320,7 +342,8 @@
 						ctx.ModuleErrorf("host tool %q missing output file", tool)
 						return
 					}
-					if specs := t.TransitivePackagingSpecs(); specs != nil {
+					if specs := android.OtherModuleProviderOrDefault(
+						ctx, t, android.InstallFilesProvider).TransitivePackagingSpecs.ToList(); specs != nil {
 						// If the HostToolProvider has PackgingSpecs, which are definitions of the
 						// required relative locations of the tool and its dependencies, use those
 						// instead.  They will be copied to those relative locations in the sbox
@@ -546,7 +569,7 @@
 		cmd.ImplicitTools(tools)
 		cmd.ImplicitPackagedTools(packagedTools)
 		if proptools.Bool(g.properties.Uses_order_only_build_number_file) {
-			if _, ok := genrule_build_number_allowlist[ctx.ModuleDir()+":"+ctx.ModuleName()]; !ok {
+			if !isModuleInBuildNumberAllowlist(ctx) {
 				ctx.ModuleErrorf("Only allowlisted modules may use uses_order_only_build_number_file: true")
 			}
 			cmd.OrderOnly(ctx.Config().BuildNumberFile(ctx))
@@ -624,7 +647,7 @@
 }
 
 // Collect information for opening IDE project files in java/jdeps.go.
-func (g *Module) IDEInfo(dpInfo *android.IdeInfo) {
+func (g *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
 	dpInfo.Srcs = append(dpInfo.Srcs, g.Srcs().Strings()...)
 	for _, src := range g.properties.ResolvedSrcs {
 		if strings.HasPrefix(src, ":") {
diff --git a/java/aar.go b/java/aar.go
index e6ad502..1bd372f 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -914,12 +914,12 @@
 	setOutputFiles(ctx, a.Library.Module)
 }
 
-func (a *AndroidLibrary) IDEInfo(dpInfo *android.IdeInfo) {
-	a.Library.IDEInfo(dpInfo)
-	a.aapt.IDEInfo(dpInfo)
+func (a *AndroidLibrary) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
+	a.Library.IDEInfo(ctx, dpInfo)
+	a.aapt.IDEInfo(ctx, dpInfo)
 }
 
-func (a *aapt) IDEInfo(dpInfo *android.IdeInfo) {
+func (a *aapt) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
 	if a.rJar != nil {
 		dpInfo.Jars = append(dpInfo.Jars, a.rJar.String())
 	}
@@ -1451,6 +1451,6 @@
 	return module
 }
 
-func (a *AARImport) IDEInfo(dpInfo *android.IdeInfo) {
+func (a *AARImport) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
 	dpInfo.Jars = append(dpInfo.Jars, a.headerJarFile.String(), a.rJar.String())
 }
diff --git a/java/aar_test.go b/java/aar_test.go
index 877e2c7..aa4f0af 100644
--- a/java/aar_test.go
+++ b/java/aar_test.go
@@ -159,9 +159,9 @@
 	bar := result.ModuleForTests("bar", "android_common")
 	baz := result.ModuleForTests("baz", "android_common")
 
-	fooOutputPaths := foo.OutputFiles(t, "")
-	barOutputPaths := bar.OutputFiles(t, "")
-	bazOutputPaths := baz.OutputFiles(t, "")
+	fooOutputPaths := foo.OutputFiles(result.TestContext, t, "")
+	barOutputPaths := bar.OutputFiles(result.TestContext, t, "")
+	bazOutputPaths := baz.OutputFiles(result.TestContext, t, "")
 
 	android.AssertPathsRelativeToTopEquals(t, "foo output path",
 		[]string{"out/soong/.intermediates/foo/android_common/withres/foo.jar"}, fooOutputPaths)
diff --git a/java/app.go b/java/app.go
index 1ebf658..abd78b7 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1243,9 +1243,9 @@
 
 var _ cc.Coverage = (*AndroidApp)(nil)
 
-func (a *AndroidApp) IDEInfo(dpInfo *android.IdeInfo) {
-	a.Library.IDEInfo(dpInfo)
-	a.aapt.IDEInfo(dpInfo)
+func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
+	a.Library.IDEInfo(ctx, dpInfo)
+	a.aapt.IDEInfo(ctx, dpInfo)
 }
 
 func (a *AndroidApp) productCharacteristicsRROPackageName() string {
diff --git a/java/app_test.go b/java/app_test.go
index 6b7d522..ec97a55 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -119,7 +119,7 @@
 		foo.Output(expectedOutput)
 	}
 
-	outputFiles := foo.OutputFiles(t, "")
+	outputFiles := foo.OutputFiles(ctx, t, "")
 	android.AssertPathsRelativeToTopEquals(t, `OutputFiles("")`, expectedOutputs, outputFiles)
 }
 
diff --git a/java/base.go b/java/base.go
index 4ab82c5..e516891 100644
--- a/java/base.go
+++ b/java/base.go
@@ -229,6 +229,10 @@
 	Ravenizer struct {
 		Enabled *bool
 	}
+
+	// Contributing api surface of the stub module. Is not visible to bp modules, and should
+	// only be set for stub submodules generated by the java_sdk_library
+	Stub_contributing_api *string `blueprint:"mutated"`
 }
 
 // Properties that are specific to device modules. Host module factories should not add these when
@@ -589,6 +593,13 @@
 	return j.ProductSpecific()
 }
 
+var _ android.StubsAvailableModule = (*Module)(nil)
+
+// To safisfy the StubsAvailableModule interface
+func (j *Module) IsStubsModule() bool {
+	return proptools.Bool(j.properties.Is_stubs_module)
+}
+
 func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
 	sdkVersion := j.SdkVersion(ctx)
 	if sdkVersion.Stable() {
@@ -1541,7 +1552,7 @@
 		// outputFile should be agnostic to the build configuration,
 		// thus "combine" the single static lib in order to prevent the static lib from being exposed
 		// to the copy rules.
-		stub, _ := moduleStubLinkType(ctx.ModuleName())
+		stub, _ := moduleStubLinkType(j)
 
 		if stub {
 			combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
@@ -2045,7 +2056,7 @@
 }
 
 // Collect information for opening IDE project files in java/jdeps.go.
-func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
+func (j *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
 	// jarjar rules will repackage the sources. To prevent misleading results, IdeInfo should contain the
 	// repackaged jar instead of the input sources.
 	if j.expandJarjarRules != nil {
@@ -2169,6 +2180,25 @@
 	getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool)
 }
 
+func sdkLinkTypeFromSdkKind(k android.SdkKind) sdkLinkType {
+	switch k {
+	case android.SdkCore:
+		return javaCore
+	case android.SdkSystem:
+		return javaSystem
+	case android.SdkPublic:
+		return javaSdk
+	case android.SdkModule:
+		return javaModule
+	case android.SdkSystemServer:
+		return javaSystemServer
+	case android.SdkPrivate, android.SdkNone, android.SdkCorePlatform, android.SdkTest:
+		return javaPlatform
+	default:
+		return javaSdk
+	}
+}
+
 func (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) {
 	switch name {
 	case android.SdkCore.DefaultJavaLibraryName(),
@@ -2190,30 +2220,16 @@
 		return javaSystem, true
 	}
 
-	if stub, linkType := moduleStubLinkType(name); stub {
+	if stub, linkType := moduleStubLinkType(m); stub {
 		return linkType, true
 	}
 
 	ver := m.SdkVersion(ctx)
-	switch ver.Kind {
-	case android.SdkCore:
-		return javaCore, false
-	case android.SdkSystem:
-		return javaSystem, false
-	case android.SdkPublic:
-		return javaSdk, false
-	case android.SdkModule:
-		return javaModule, false
-	case android.SdkSystemServer:
-		return javaSystemServer, false
-	case android.SdkPrivate, android.SdkNone, android.SdkCorePlatform, android.SdkTest:
-		return javaPlatform, false
-	}
-
 	if !ver.Valid() {
 		panic(fmt.Errorf("sdk_version is invalid. got %q", ver.Raw))
 	}
-	return javaSdk, false
+
+	return sdkLinkTypeFromSdkKind(ver.Kind), false
 }
 
 // checkSdkLinkType make sures the given dependency doesn't have a lower SDK link type rank than
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index bce507a..bef3b58 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -836,7 +836,7 @@
 }
 
 // Collect information for opening IDE project files in java/jdeps.go.
-func (b *BootclasspathFragmentModule) IDEInfo(dpInfo *android.IdeInfo) {
+func (b *BootclasspathFragmentModule) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
 	dpInfo.Deps = append(dpInfo.Deps, b.properties.Contents...)
 }
 
diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp
index cee7a19..1cca7ad 100644
--- a/java/core-libraries/Android.bp
+++ b/java/core-libraries/Android.bp
@@ -38,6 +38,7 @@
     visibility: ["//visibility:public"],
     sdk_version: "none",
     system_modules: "none",
+    is_stubs_module: true,
 }
 
 java_library {
@@ -289,6 +290,7 @@
     sdk_version: "none",
     system_modules: "none",
     patch_module: "java.base",
+    is_stubs_module: true,
 }
 
 // Same as legacy.core.platform.api.stubs, but android annotations are
@@ -307,6 +309,7 @@
         "legacy.core.platform.api.stubs",
     ],
     patch_module: "java.base",
+    is_stubs_module: true,
 }
 
 java_library {
@@ -339,6 +342,7 @@
         "stable.core.platform.api.stubs",
     ],
     patch_module: "java.base",
+    is_stubs_module: true,
 }
 
 // Used when compiling higher-level code against *.core.platform.api.stubs.
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 63b69d0..7cc06fc 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -192,7 +192,7 @@
 // implement the following interface for IDE completion.
 var _ android.IDEInfo = (*DeviceHostConverter)(nil)
 
-func (d *DeviceHostConverter) IDEInfo(ideInfo *android.IdeInfo) {
+func (d *DeviceHostConverter) IDEInfo(ctx android.BaseModuleContext, ideInfo *android.IdeInfo) {
 	ideInfo.Deps = append(ideInfo.Deps, d.properties.Libs...)
 	ideInfo.Libs = append(ideInfo.Libs, d.properties.Libs...)
 }
diff --git a/java/dex.go b/java/dex.go
index d88e8f8..6c739a2 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -289,15 +289,18 @@
 	// - suppress ProGuard warnings of referencing symbols unknown to the lower SDK version.
 	// - prevent ProGuard stripping subclass in the support library that extends class added in the higher SDK version.
 	// See b/20667396
-	var proguardRaiseDeps classpath
-	ctx.VisitDirectDepsWithTag(proguardRaiseTag, func(m android.Module) {
-		if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
-			proguardRaiseDeps = append(proguardRaiseDeps, dep.RepackagedHeaderJars...)
-		}
-	})
+	// TODO(b/360905238): Remove SdkSystemServer exception after resolving missing class references.
+	if !dexParams.sdkVersion.Stable() || dexParams.sdkVersion.Kind == android.SdkSystemServer {
+		var proguardRaiseDeps classpath
+		ctx.VisitDirectDepsWithTag(proguardRaiseTag, func(m android.Module) {
+			if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
+				proguardRaiseDeps = append(proguardRaiseDeps, dep.RepackagedHeaderJars...)
+			}
+		})
+		r8Flags = append(r8Flags, proguardRaiseDeps.FormJavaClassPath("-libraryjars"))
+		r8Deps = append(r8Deps, proguardRaiseDeps...)
+	}
 
-	r8Flags = append(r8Flags, proguardRaiseDeps.FormJavaClassPath("-libraryjars"))
-	r8Deps = append(r8Deps, proguardRaiseDeps...)
 	r8Flags = append(r8Flags, flags.bootClasspath.FormJavaClassPath("-libraryjars"))
 	r8Deps = append(r8Deps, flags.bootClasspath...)
 	r8Flags = append(r8Flags, flags.dexClasspath.FormJavaClassPath("-libraryjars"))
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index a38642a..f949b12 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -88,18 +88,11 @@
 				entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String())
 				entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice)
 				entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false")
-				// Unset LOCAL_SOONG_INSTALLED_MODULE so that this does not default to the primary .apex file
-				// Without this, installation of the dexpreopt artifacts get skipped
-				entries.SetString("LOCAL_SOONG_INSTALLED_MODULE", "")
 			},
 		},
 	}
 }
 
-func (install dexpreopterInstall) PackageFile(ctx android.ModuleContext) android.PackagingSpec {
-	return ctx.PackageFile(install.installDirOnDevice, install.installFileOnDevice, install.outputPathOnHost)
-}
-
 type Dexpreopter struct {
 	dexpreopter
 }
@@ -217,15 +210,19 @@
 		}
 	})
 	// Find the apex variant for this module
-	_, apexVariantsWithoutTestApexes, _ := android.ListSetDifference(apexInfo.InApexVariants, apexInfo.TestApexes)
+	var apexVariantsWithoutTestApexes []string
+	if apexInfo.BaseApexName != "" {
+		// This is a transitive dependency of an override_apex
+		apexVariantsWithoutTestApexes = []string{apexInfo.BaseApexName}
+	} else {
+		_, apexVariantsWithoutTestApexes, _ = android.ListSetDifference(apexInfo.InApexVariants, apexInfo.TestApexes)
+	}
 	disableSource := false
 	// find the selected apexes
 	for _, apexVariant := range apexVariantsWithoutTestApexes {
-		for _, selected := range psi.GetSelectedModulesForApiDomain(apexVariant) {
-			// If the apex_contribution for this api domain contains a prebuilt apex, disable the source variant
-			if strings.HasPrefix(selected, "prebuilt_com.google.android") {
-				disableSource = true
-			}
+		if len(psi.GetSelectedModulesForApiDomain(apexVariant)) > 0 {
+			// If the apex_contribution for this api domain is non-empty, disable the source variant
+			disableSource = true
 		}
 	}
 	return disableSource
@@ -583,13 +580,16 @@
 				// Preopting of boot classpath jars in the ART APEX are handled in
 				// java/dexpreopt_bootjars.go, and other APEX jars are not preopted.
 				// The installs will be handled by Make as sub-modules of the java library.
-				d.builtInstalledForApex = append(d.builtInstalledForApex, dexpreopterInstall{
+				di := dexpreopterInstall{
 					name:                arch + "-" + installBase,
 					moduleName:          libName,
 					outputPathOnHost:    install.From,
 					installDirOnDevice:  installPath,
 					installFileOnDevice: installBase,
-				})
+				}
+				ctx.InstallFile(di.installDirOnDevice, di.installFileOnDevice, di.outputPathOnHost)
+				d.builtInstalledForApex = append(d.builtInstalledForApex, di)
+
 			}
 		} else if !d.preventInstall {
 			ctx.InstallFile(installPath, installBase, install.From)
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index a81ab83..a2e4734 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -558,6 +558,10 @@
 			apexVariationOfSelected := append(ctx.Target().Variations(), blueprint.Variation{Mutator: "apex", Variation: apex})
 			if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, selected) {
 				ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, selected)
+			} else if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, android.RemoveOptionalPrebuiltPrefix(selected)) {
+				// The prebuilt might have been renamed by prebuilt_rename mutator if the source module does not exist.
+				// Remove the prebuilt_ prefix.
+				ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, android.RemoveOptionalPrebuiltPrefix(selected))
 			}
 		}
 	}
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index 73e33f4..07d0595 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -54,6 +54,7 @@
 					name: "foo",
 					installable: true,
 					srcs: ["a.java"],
+					sdk_version: "current",
 				}`,
 			enabled: true,
 		},
@@ -98,6 +99,7 @@
 				java_library {
 					name: "foo",
 					installable: true,
+					sdk_version: "current",
 				}`,
 			enabled: false,
 		},
@@ -107,6 +109,7 @@
 				java_library {
 					name: "foo",
 					srcs: ["a.java"],
+					sdk_version: "current",
 				}`,
 			enabled: false,
 		},
@@ -144,6 +147,7 @@
 					name: "foo",
 					srcs: ["a.java"],
 					compile_dex: true,
+					sdk_version: "current",
 				}`,
 			enabled: false,
 		},
@@ -164,6 +168,7 @@
 					installable: true,
 					srcs: ["a.java"],
 					apex_available: ["com.android.apex1"],
+					sdk_version: "current",
 				}`,
 			apexVariant: true,
 			enabled:     false,
@@ -176,6 +181,7 @@
 					installable: true,
 					srcs: ["a.java"],
 					apex_available: ["com.android.apex1"],
+					sdk_version: "current",
 				}`,
 			moduleName:  "service-foo",
 			apexVariant: true,
@@ -189,6 +195,7 @@
 					installable: true,
 					srcs: ["a.java"],
 					apex_available: ["com.android.apex1"],
+					sdk_version: "current",
 				}`,
 			moduleName:  "prebuilt_service-foo",
 			apexVariant: true,
@@ -202,6 +209,7 @@
 					installable: true,
 					srcs: ["a.java"],
 					apex_available: ["com.android.apex1"],
+					sdk_version: "current",
 				}`,
 			moduleName:  "service-foo",
 			apexVariant: false,
@@ -311,6 +319,7 @@
 			installable: true,
 			srcs: ["a.java"],
 			apex_available: ["com.android.apex1"],
+			sdk_version: "current",
 		}`)
 	ctx := result.TestContext
 	module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
@@ -342,6 +351,7 @@
 			name: "foo",
 			installable: true,
 			srcs: ["a.java"],
+			sdk_version: "current",
 		}`)
 	ctx = result.TestContext
 	module = ctx.ModuleForTests("foo", "android_common")
@@ -398,6 +408,7 @@
 			installable: true,
 			srcs: ["a.java"],
 			apex_available: ["com.android.apex1"],
+			sdk_version: "current",
 		}`)
 	ctx := result.TestContext
 	module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
@@ -429,6 +440,7 @@
 			name: "foo",
 			installable: true,
 			srcs: ["a.java"],
+			sdk_version: "current",
 		}`)
 	ctx = result.TestContext
 	module = ctx.ModuleForTests("foo", "android_common")
@@ -454,6 +466,7 @@
 				profile: "art-profile",
 			},
 			srcs: ["a.java"],
+			sdk_version: "current",
 		}`)
 
 	ctx := result.TestContext
diff --git a/java/droiddoc_test.go b/java/droiddoc_test.go
index e584640..9e1ebbe 100644
--- a/java/droiddoc_test.go
+++ b/java/droiddoc_test.go
@@ -69,7 +69,7 @@
 			"bar-doc/a.java": nil,
 			"bar-doc/b.java": nil,
 		})
-	barStubsOutputs := ctx.ModuleForTests("bar-stubs", "android_common").OutputFiles(t, "")
+	barStubsOutputs := ctx.ModuleForTests("bar-stubs", "android_common").OutputFiles(ctx, t, "")
 	if len(barStubsOutputs) != 1 {
 		t.Errorf("Expected one output from \"bar-stubs\" got %s", barStubsOutputs)
 	}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index d622903..6bcdf85 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -970,6 +970,15 @@
 		d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
 		cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO:  Change to ":api-lint"
 
+		// If UnflaggedApi issues have not already been configured then make sure that existing
+		// UnflaggedApi issues are reported as warnings but issues in new/changed code are treated as
+		// errors by the Build Warnings Aye Aye Analyzer in Gerrit.
+		// Once existing issues have been fixed this will be changed to error.
+		// TODO(b/362771529): Switch to --error
+		if !strings.Contains(cmd.String(), " UnflaggedApi ") {
+			cmd.Flag("--error-when-new UnflaggedApi")
+		}
+
 		// TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
 		if d.Name() != "android.car-system-stubs-docs" &&
 			d.Name() != "android.car-stubs-docs" {
diff --git a/java/java.go b/java/java.go
index 258ebba..55c878e 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1864,10 +1864,12 @@
 	if ctx.Arch().ArchType == android.Common {
 		j.deps(ctx)
 	}
-	if ctx.Arch().ArchType != android.Common {
-		// These dependencies ensure the host installation rules will install the jar file and
-		// the jni libraries when the wrapper is installed.
+	// These dependencies ensure the installation rules will install the jar file when the
+	// wrapper is installed, and the jni libraries on host when the wrapper is installed.
+	if ctx.Arch().ArchType != android.Common && ctx.Os().Class == android.Host {
 		ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...)
+	}
+	if ctx.Arch().ArchType != android.Common {
 		ctx.AddVariationDependencies(
 			[]blueprint.Variation{{Mutator: "arch", Variation: android.CommonArch.String()}},
 			binaryInstallTag, ctx.ModuleName())
@@ -2402,15 +2404,15 @@
 	return al.SdkVersion(ctx).ApiLevel
 }
 
-func (al *ApiLibrary) IDEInfo(i *android.IdeInfo) {
-	i.Deps = append(i.Deps, al.ideDeps()...)
+func (al *ApiLibrary) IDEInfo(ctx android.BaseModuleContext, i *android.IdeInfo) {
+	i.Deps = append(i.Deps, al.ideDeps(ctx)...)
 	i.Libs = append(i.Libs, al.properties.Libs...)
 	i.Static_libs = append(i.Static_libs, al.properties.Static_libs...)
 	i.SrcJars = append(i.SrcJars, al.stubsSrcJar.String())
 }
 
 // deps of java_api_library for module_bp_java_deps.json
-func (al *ApiLibrary) ideDeps() []string {
+func (al *ApiLibrary) ideDeps(ctx android.BaseModuleContext) []string {
 	ret := []string{}
 	ret = append(ret, al.properties.Libs...)
 	ret = append(ret, al.properties.Static_libs...)
@@ -2931,7 +2933,7 @@
 
 // Collect information for opening IDE project files in java/jdeps.go.
 
-func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
+func (j *Import) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
 	dpInfo.Jars = append(dpInfo.Jars, j.combinedHeaderFile.String())
 }
 
diff --git a/java/java_test.go b/java/java_test.go
index 477a0b3..9e39b51 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -2919,9 +2919,9 @@
 	bar := result.ModuleForTests("bar", "android_common")
 	baz := result.ModuleForTests("baz", "android_common")
 
-	fooOutputPaths := foo.OutputFiles(t, "")
-	barOutputPaths := bar.OutputFiles(t, "")
-	bazOutputPaths := baz.OutputFiles(t, "")
+	fooOutputPaths := foo.OutputFiles(result.TestContext, t, "")
+	barOutputPaths := bar.OutputFiles(result.TestContext, t, "")
+	bazOutputPaths := baz.OutputFiles(result.TestContext, t, "")
 
 	android.AssertPathsRelativeToTopEquals(t, "foo output path",
 		[]string{"out/soong/.intermediates/foo/android_common/javac/foo.jar"}, fooOutputPaths)
diff --git a/java/jdeps.go b/java/jdeps.go
index e856b37..c2ce503 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -57,27 +57,19 @@
 			return
 		}
 
-		ideInfoProvider, ok := module.(android.IDEInfo)
+		ideInfoProvider, ok := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
 		if !ok {
 			return
 		}
-		name := ideInfoProvider.BaseModuleName()
+		name := ideInfoProvider.BaseModuleName
 		ideModuleNameProvider, ok := module.(android.IDECustomizedModuleName)
 		if ok {
 			name = ideModuleNameProvider.IDECustomizedModuleName()
 		}
 
 		dpInfo := moduleInfos[name]
-		ideInfoProvider.IDEInfo(&dpInfo)
-		dpInfo.Deps = android.FirstUniqueStrings(dpInfo.Deps)
-		dpInfo.Srcs = android.FirstUniqueStrings(dpInfo.Srcs)
-		dpInfo.Aidl_include_dirs = android.FirstUniqueStrings(dpInfo.Aidl_include_dirs)
-		dpInfo.Jarjar_rules = android.FirstUniqueStrings(dpInfo.Jarjar_rules)
-		dpInfo.Jars = android.FirstUniqueStrings(dpInfo.Jars)
-		dpInfo.SrcJars = android.FirstUniqueStrings(dpInfo.SrcJars)
+		dpInfo = dpInfo.Merge(ideInfoProvider)
 		dpInfo.Paths = []string{ctx.ModuleDir(module)}
-		dpInfo.Static_libs = android.FirstUniqueStrings(dpInfo.Static_libs)
-		dpInfo.Libs = android.FirstUniqueStrings(dpInfo.Libs)
 		moduleInfos[name] = dpInfo
 
 		mkProvider, ok := module.(android.AndroidMkDataProvider)
diff --git a/java/jdeps_test.go b/java/jdeps_test.go
index ff54da9..d282f19 100644
--- a/java/jdeps_test.go
+++ b/java/jdeps_test.go
@@ -32,9 +32,7 @@
 		}
 	`)
 	module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
-	dpInfo := &android.IdeInfo{}
-
-	module.IDEInfo(dpInfo)
+	dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
 
 	for _, expected := range []string{"Foo", "Bar"} {
 		if !android.InList(expected, dpInfo.Deps) {
@@ -54,9 +52,7 @@
 		}
 	`)
 	module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
-	dpInfo := &android.IdeInfo{}
-
-	module.IDEInfo(dpInfo)
+	dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
 
 	for _, expected := range []string{"Foo", "Bar"} {
 		if !android.InList(expected, dpInfo.Deps) {
@@ -66,26 +62,36 @@
 }
 
 func TestCollectJavaLibraryPropertiesAddScrs(t *testing.T) {
-	expected := []string{"Foo", "Bar"}
-	module := LibraryFactory().(*Library)
-	module.expandIDEInfoCompiledSrcs = append(module.expandIDEInfoCompiledSrcs, expected...)
-	dpInfo := &android.IdeInfo{}
+	ctx, _ := testJava(t,
+		`
+		java_library {
+			name: "javalib",
+			srcs: ["Foo.java", "Bar.java"],
+		}
+	`)
+	module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+	dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
 
-	module.IDEInfo(dpInfo)
-
+	expected := []string{"Foo.java", "Bar.java"}
 	if !reflect.DeepEqual(dpInfo.Srcs, expected) {
 		t.Errorf("Library.IDEInfo() Srcs = %v, want %v", dpInfo.Srcs, expected)
 	}
 }
 
 func TestCollectJavaLibraryPropertiesAddAidlIncludeDirs(t *testing.T) {
+	ctx, _ := testJava(t,
+		`
+		java_library {
+			name: "javalib",
+			aidl: {
+				include_dirs: ["Foo", "Bar"],
+			},
+		}
+	`)
+	module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+	dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
+
 	expected := []string{"Foo", "Bar"}
-	module := LibraryFactory().(*Library)
-	module.deviceProperties.Aidl.Include_dirs = append(module.deviceProperties.Aidl.Include_dirs, expected...)
-	dpInfo := &android.IdeInfo{}
-
-	module.IDEInfo(dpInfo)
-
 	if !reflect.DeepEqual(dpInfo.Aidl_include_dirs, expected) {
 		t.Errorf("Library.IDEInfo() Aidl_include_dirs = %v, want %v", dpInfo.Aidl_include_dirs, expected)
 	}
@@ -101,9 +107,8 @@
 		}
 	`)
 	module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
-	dpInfo := &android.IdeInfo{}
+	dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
 
-	module.IDEInfo(dpInfo)
 	android.AssertBoolEquals(t, "IdeInfo.Srcs of repackaged library should be empty", true, len(dpInfo.Srcs) == 0)
 	android.AssertStringEquals(t, "IdeInfo.Jar_rules of repackaged library should not be empty", "jarjar_rules.txt", dpInfo.Jarjar_rules[0])
 	if !android.SubstringInList(dpInfo.Jars, "soong/.intermediates/javalib/android_common/jarjar/turbine/javalib.jar") {
@@ -125,8 +130,7 @@
 		}
 	`)
 	module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
-	dpInfo := &android.IdeInfo{}
+	dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
 
-	module.IDEInfo(dpInfo)
 	android.AssertStringListContains(t, "IdeInfo.Deps should contain versioned sdk module", dpInfo.Deps, "sdk_public_29_android")
 }
diff --git a/java/sdk.go b/java/sdk.go
index dd198ac..4537f19 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -308,10 +308,12 @@
 
 			rule.Command().
 				Text("rm -f").Output(aidl)
+
 			rule.Command().
 				BuiltTool("sdkparcelables").
 				Input(jar).
-				Output(aidl)
+				Output(aidl).
+				Flag("--guarantee_stable")
 
 			aidls = append(aidls, aidl)
 		}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 4f95a99..a7a254a 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1548,6 +1548,8 @@
 			scopeTag.extractDepInfo(ctx, to, scopePaths)
 
 			exportedComponents[ctx.OtherModuleName(to)] = struct{}{}
+
+			ctx.Phony(ctx.ModuleName(), scopePaths.stubsHeaderPath...)
 		}
 
 		if tag == implLibraryTag {
@@ -1794,7 +1796,8 @@
 		Dir     *string
 		Tag     *string
 	}
-	Is_stubs_module *bool
+	Is_stubs_module       *bool
+	Stub_contributing_api *string
 }
 
 func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
@@ -1820,6 +1823,7 @@
 	// interop with older developer tools that don't support 1.9.
 	props.Java_version = proptools.StringPtr("1.8")
 	props.Is_stubs_module = proptools.BoolPtr(true)
+	props.Stub_contributing_api = proptools.StringPtr(apiScope.kind.String())
 
 	return props
 }
@@ -2087,12 +2091,15 @@
 	}
 	props.Compile_dex = compileDex
 
+	props.Stub_contributing_api = proptools.StringPtr(apiScope.kind.String())
+
 	if !Bool(module.sdkLibraryProperties.No_dist) && doDist {
 		props.Dist.Targets = []string{"sdk", "win_sdk"}
 		props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
 		props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
 		props.Dist.Tag = proptools.StringPtr(".jar")
 	}
+	props.Is_stubs_module = proptools.BoolPtr(true)
 
 	return props
 }
@@ -2423,36 +2430,25 @@
 
 var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil)
 
-func hasStubsLibrarySuffix(name string, apiScope *apiScope) bool {
-	return strings.HasSuffix(name, apiScope.stubsLibraryModuleNameSuffix()) ||
-		strings.HasSuffix(name, apiScope.exportableStubsLibraryModuleNameSuffix())
-}
-
-func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) {
-	name = strings.TrimSuffix(name, ".from-source")
-
-	// This suffix-based approach is fragile and could potentially mis-trigger.
-	// TODO(b/155164730): Clean this up when modules no longer reference sdk_lib stubs directly.
-	if hasStubsLibrarySuffix(name, apiScopePublic) {
-		if name == "hwbinder.stubs" || name == "libcore_private.stubs" {
-			// Due to a previous bug, these modules were not considered stubs, so we retain that.
-			return false, javaPlatform
-		}
+func moduleStubLinkType(j *Module) (stub bool, ret sdkLinkType) {
+	kind := android.ToSdkKind(proptools.String(j.properties.Stub_contributing_api))
+	switch kind {
+	case android.SdkPublic:
 		return true, javaSdk
-	}
-	if hasStubsLibrarySuffix(name, apiScopeSystem) {
+	case android.SdkSystem:
 		return true, javaSystem
-	}
-	if hasStubsLibrarySuffix(name, apiScopeModuleLib) {
+	case android.SdkModule:
 		return true, javaModule
-	}
-	if hasStubsLibrarySuffix(name, apiScopeTest) {
+	case android.SdkTest:
 		return true, javaSystem
-	}
-	if hasStubsLibrarySuffix(name, apiScopeSystemServer) {
+	case android.SdkSystemServer:
 		return true, javaSystemServer
+	// Default value for all modules other than java_sdk_library-generated stub submodules
+	case android.SdkInvalid:
+		return false, javaPlatform
+	default:
+		panic(fmt.Sprintf("stub_contributing_api set as an unsupported sdk kind %s", kind.String()))
 	}
-	return false, javaPlatform
 }
 
 // java_sdk_library is a special Java library that provides optional platform APIs to apps.
@@ -3604,8 +3600,8 @@
 }
 
 // TODO(b/358613520): This can be removed when modules are no longer allowed to depend on the top-level library.
-func (s *SdkLibrary) IDEInfo(dpInfo *android.IdeInfo) {
-	s.Library.IDEInfo(dpInfo)
+func (s *SdkLibrary) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
+	s.Library.IDEInfo(ctx, dpInfo)
 	if s.implLibraryModule != nil {
 		dpInfo.Deps = append(dpInfo.Deps, s.implLibraryModule.Name())
 	} else {
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 52d4af0..485776b 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -1858,3 +1858,39 @@
 		android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, tc.expectedStubPath)
 	}
 }
+
+func TestStubLinkType(t *testing.T) {
+	android.GroupFixturePreparers(
+		prepareForJavaTest,
+		PrepareForTestWithJavaSdkLibraryFiles,
+		FixtureWithLastReleaseApis("foo"),
+	).ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(
+		`module "baz" variant "android_common": compiles against system API, but dependency `+
+			`"bar.stubs.system" is compiling against module API. In order to fix this, `+
+			`consider adjusting sdk_version: OR platform_apis: property of the source or `+
+			`target module so that target module is built with the same or smaller API set `+
+			`when compared to the source.`),
+	).RunTestWithBp(t, `
+		java_sdk_library {
+			name: "foo",
+			srcs: ["a.java"],
+			sdk_version: "current",
+		}
+		java_library {
+			name: "bar.stubs.system",
+			srcs: ["a.java"],
+			sdk_version: "module_current",
+			is_stubs_module: false,
+		}
+
+		java_library {
+			name: "baz",
+			srcs: ["b.java"],
+			libs: [
+				"foo.stubs.system",
+				"bar.stubs.system",
+			],
+			sdk_version: "system_current",
+		}
+		`)
+}
diff --git a/java/system_modules.go b/java/system_modules.go
index 5b00079..f89bf9e 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -307,7 +307,7 @@
 // implement the following interface for IDE completion.
 var _ android.IDEInfo = (*SystemModules)(nil)
 
-func (s *SystemModules) IDEInfo(ideInfo *android.IdeInfo) {
+func (s *SystemModules) IDEInfo(ctx android.BaseModuleContext, ideInfo *android.IdeInfo) {
 	ideInfo.Deps = append(ideInfo.Deps, s.properties.Libs...)
 	ideInfo.Libs = append(ideInfo.Libs, s.properties.Libs...)
 }
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index bad2cf1..924abd4 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -216,6 +216,11 @@
 	return tag == systemServerClasspathFragmentContentDepTag
 }
 
+// The dexpreopt artifacts of apex system server jars are installed onto system image.
+func (s systemServerClasspathFragmentContentDependencyTag) InstallDepNeeded() bool {
+	return true
+}
+
 func (s *SystemServerClasspathModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
 	module := ctx.Module()
 	_, isSourceModule := module.(*SystemServerClasspathModule)
@@ -234,7 +239,7 @@
 }
 
 // Collect information for opening IDE project files in java/jdeps.go.
-func (s *SystemServerClasspathModule) IDEInfo(dpInfo *android.IdeInfo) {
+func (s *SystemServerClasspathModule) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
 	dpInfo.Deps = append(dpInfo.Deps, s.properties.Contents...)
 	dpInfo.Deps = append(dpInfo.Deps, s.properties.Standalone_contents...)
 }
diff --git a/java/testing.go b/java/testing.go
index 0e85022..03dcee6 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -184,6 +184,10 @@
 			host_supported: true,
 			srcs: ["Test.java"],
 			sdk_version: "current",
+			apex_available: [
+				"//apex_available:anyapex",
+				"//apex_available:platform",
+			],
 		}
 	`)),
 )
@@ -408,7 +412,6 @@
 		"core.current.stubs",
 		"legacy.core.platform.api.stubs",
 		"stable.core.platform.api.stubs",
-
 		"android_stubs_current_exportable",
 		"android_system_stubs_current_exportable",
 		"android_test_stubs_current_exportable",
@@ -416,13 +419,11 @@
 		"android_system_server_stubs_current_exportable",
 		"core.current.stubs.exportable",
 		"legacy.core.platform.api.stubs.exportable",
-
 		"kotlin-stdlib",
 		"kotlin-stdlib-jdk7",
 		"kotlin-stdlib-jdk8",
 		"kotlin-annotations",
 		"stub-annotations",
-
 		"aconfig-annotations-lib",
 		"unsupportedappusage",
 	}
@@ -435,6 +436,7 @@
 				sdk_version: "none",
 				system_modules: "stable-core-platform-api-stubs-system-modules",
 				compile_dex: true,
+				is_stubs_module: true,
 			}
 		`, extra)
 	}
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 533ec62..05b99fd 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -98,6 +98,7 @@
 	builder.Command().
 		BuiltTool("conv_linker_config").
 		Flag("proto").
+		Flag("--force").
 		FlagWithInput("-s ", input).
 		FlagWithOutput("-o ", interimOutput)
 
diff --git a/rust/config/global.go b/rust/config/global.go
index 6943467..990a643 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
 var (
 	pctx = android.NewPackageContext("android/soong/rust/config")
 
-	RustDefaultVersion = "1.78.0"
+	RustDefaultVersion = "1.80.1"
 	RustDefaultBase    = "prebuilts/rust/"
 	DefaultEdition     = "2021"
 	Stdlibs            = []string{
diff --git a/rust/library.go b/rust/library.go
index 50d5a72..7db8f36 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -70,6 +70,10 @@
 
 	// Whether this library is part of the Rust toolchain sysroot.
 	Sysroot *bool
+
+	// Exclude this rust_ffi target from being included in APEXes.
+	// TODO(b/362509506): remove this once stubs are properly supported by rust_ffi targets.
+	Apex_exclude *bool
 }
 
 type LibraryMutatedProperties struct {
@@ -122,6 +126,7 @@
 	shared() bool
 	sysroot() bool
 	source() bool
+	apexExclude() bool
 
 	// Returns true if the build options for the module have selected a particular build type
 	buildRlib() bool
@@ -186,6 +191,10 @@
 	return library.MutatedProperties.VariantIsSource
 }
 
+func (library *libraryDecorator) apexExclude() bool {
+	return Bool(library.Properties.Apex_exclude)
+}
+
 func (library *libraryDecorator) buildRlib() bool {
 	return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
 }
diff --git a/rust/rust.go b/rust/rust.go
index 3402adc..5a973c4 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -294,6 +294,15 @@
 	return mod.StaticallyLinked()
 }
 
+func (mod *Module) ApexExclude() bool {
+	if mod.compiler != nil {
+		if library, ok := mod.compiler.(libraryInterface); ok {
+			return library.apexExclude()
+		}
+	}
+	return false
+}
+
 func (mod *Module) Object() bool {
 	// Rust has no modules which produce only object files.
 	return false
@@ -1863,6 +1872,10 @@
 		return false
 	}
 
+	if rustDep, ok := dep.(*Module); ok && rustDep.ApexExclude() {
+		return false
+	}
+
 	return true
 }
 
diff --git a/rust/test_test.go b/rust/test_test.go
index dc796c8..1097da2 100644
--- a/rust/test_test.go
+++ b/rust/test_test.go
@@ -108,7 +108,7 @@
 
 	testingModule := ctx.ModuleForTests("main_test", "android_arm64_armv8-a")
 	testBinary := testingModule.Module().(*Module).compiler.(*testDecorator)
-	outputFiles := testingModule.OutputFiles(t, "")
+	outputFiles := testingModule.OutputFiles(ctx, t, "")
 	if len(outputFiles) != 1 {
 		t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles)
 	}
@@ -168,7 +168,7 @@
 	testingModule := ctx.ModuleForTests("main_test", "android_arm64_armv8-a")
 	module := testingModule.Module()
 	testBinary := module.(*Module).compiler.(*testDecorator)
-	outputFiles := testingModule.OutputFiles(t, "")
+	outputFiles := testingModule.OutputFiles(ctx, t, "")
 	if len(outputFiles) != 1 {
 		t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles)
 	}
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 7ee548f..8b994eb 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -338,6 +338,7 @@
 				shared_library: false,
 				public: {enabled: true},
 				min_sdk_version: "2",
+				sdk_version: "current",
 			}
 
 			java_sdk_library {
@@ -348,6 +349,7 @@
 				public: {enabled: true},
 				min_sdk_version: "2",
 				permitted_packages: ["myothersdklibrary"],
+				sdk_version: "current",
 			}
 
 			java_sdk_library {
@@ -357,6 +359,7 @@
 				compile_dex: true,
 				public: {enabled: true},
 				min_sdk_version: "2",
+				sdk_version: "current",
 			}
 		`),
 	).RunTest(t)
@@ -624,6 +627,7 @@
 				min_sdk_version: "2",
 				permitted_packages: ["myothersdklibrary"],
 				compile_dex: true,
+				sdk_version: "current",
 			}
 		`),
 
@@ -655,6 +659,7 @@
 				shared_library: false,
 				public: {enabled: true},
 				min_sdk_version: "2",
+				sdk_version: "current",
 			}
 		`),
 	).RunTest(t)
@@ -877,6 +882,7 @@
 				public: {enabled: true},
 				permitted_packages: ["mysdklibrary"],
 				min_sdk_version: "current",
+				sdk_version: "current",
 			}
 
 			java_sdk_library {
@@ -895,6 +901,7 @@
 					package_prefixes: ["newlibrary.all.mine"],
 					single_packages: ["newlibrary.mine"],
 				},
+				sdk_version: "current",
 			}
 		`),
 	).RunTest(t)
@@ -1080,6 +1087,7 @@
 				shared_library: false,
 				public: {enabled: true},
 				min_sdk_version: "S",
+				sdk_version: "current",
 			}
 
 			java_sdk_library {
@@ -1090,6 +1098,7 @@
 				public: {enabled: true},
 				min_sdk_version: "Tiramisu",
 				permitted_packages: ["mynewsdklibrary"],
+				sdk_version: "current",
 			}
 		`),
 	).RunTest(t)
@@ -1287,6 +1296,7 @@
 				shared_library: false,
 				public: {enabled: true},
 				min_sdk_version: "Tiramisu",
+				sdk_version: "current",
 			}
 			java_sdk_library {
 				name: "mynewsdklibrary",
@@ -1296,6 +1306,7 @@
 				public: {enabled: true},
 				min_sdk_version: "Tiramisu",
 				permitted_packages: ["mynewsdklibrary"],
+				sdk_version: "current",
 			}
 		`),
 	).RunTest(t)
diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
index c1c4ed6..fd6c4e7 100644
--- a/sdk/systemserverclasspath_fragment_sdk_test.go
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -80,6 +80,7 @@
 				dex_preopt: {
 					profile: "art-profile",
 				},
+				sdk_version: "current",
 			}
 		`),
 	).RunTest(t)
@@ -110,12 +111,14 @@
 			apex_available: ["myapex"],
 			srcs: ["Test.java"],
 			min_sdk_version: "33", // Tiramisu
+			sdk_version: "current",
 		}
 		java_sdk_library {
 			name: "mysdklibrary-future",
 			apex_available: ["myapex"],
 			srcs: ["Test.java"],
 			min_sdk_version: "34", // UpsideDownCake
+			sdk_version: "current",
 		}
 		sdk {
 			name: "mysdk",
@@ -199,6 +202,7 @@
 			apex_available: ["myapex"],
 			srcs: ["Test.java"],
 			min_sdk_version: "34", // UpsideDownCake
+			sdk_version: "current",
 		}
 		sdk {
 			name: "mysdk",
diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go
index bbac2db..2bad5a8 100644
--- a/ui/build/androidmk_denylist.go
+++ b/ui/build/androidmk_denylist.go
@@ -33,6 +33,7 @@
 	"kernel/tests/",
 	"libcore/",
 	"libnativehelper/",
+	"packages/",
 	"pdk/",
 	"prebuilts/",
 	"sdk/",
diff --git a/ui/build/config.go b/ui/build/config.go
index 90b98f5..11fe08f 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -1644,6 +1644,12 @@
 	return c.PrebuiltBuildTool(binName)
 }
 
+func (c *configImpl) N2Bin() string {
+	path := c.PrebuiltBuildTool("n2")
+	// Use musl instead of glibc because glibc on the build server is old and has bugs
+	return strings.ReplaceAll(path, "/linux-x86/", "/linux_musl-x86/")
+}
+
 func (c *configImpl) PrebuiltBuildTool(name string) string {
 	if v, ok := c.environ.Get("SANITIZE_HOST"); ok {
 		if sanitize := strings.Fields(v); inList("address", sanitize) {
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index 8ca62d3..4e3e544 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -57,7 +57,7 @@
 		"--frontend_file", fifo,
 	}
 	if config.useN2 {
-		executable = config.PrebuiltBuildTool("n2")
+		executable = config.N2Bin()
 		args = []string{
 			"-d", "trace",
 			// TODO: implement these features, or remove them.
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 2ccdfec..a9c2cc7 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -663,7 +663,7 @@
 		ninjaArgs = append(ninjaArgs, targets...)
 		ninjaCmd := config.NinjaBin()
 		if config.useN2 {
-			ninjaCmd = config.PrebuiltBuildTool("n2")
+			ninjaCmd = config.N2Bin()
 		}
 
 		cmd := Command(ctx, config, "soong bootstrap",