Merge "java_binary with kotlin sources"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 868a8bc..fb56ee1 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -1322,8 +1322,6 @@
 		"libc_musl_sysroot",
 	}
 
-	Bp2buildCcLibraryStaticOnlyList = []string{}
-
 	MixedBuildsDisabledList = []string{
 		"libruy_static", "libtflite_kernel_utils", // TODO(b/237315968); Depend on prebuilt stl, not from source
 
diff --git a/android/bazel.go b/android/bazel.go
index 3731dfe..10e9251 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -66,8 +66,8 @@
 	//
 	// This is a bool pointer to support tristates: true, false, not set.
 	//
-	// To opt-in a module, set bazel_module: { bp2build_available: true }
-	// To opt-out a module, set bazel_module: { bp2build_available: false }
+	// To opt in a module, set bazel_module: { bp2build_available: true }
+	// To opt out a module, set bazel_module: { bp2build_available: false }
 	// To defer the default setting for the directory, do not set the value.
 	Bp2build_available *bool
 
@@ -126,7 +126,7 @@
 	// one with the single member called Soong_config_variables, which itself is
 	// a struct containing fields for each supported feature in that namespace.
 	//
-	// The reason for using an slice of interface{} is to support defaults
+	// The reason for using a slice of interface{} is to support defaults
 	// propagation of the struct pointers.
 	namespacedVariableProps() namespacedVariableProperties
 	setNamespacedVariableProps(props namespacedVariableProperties)
@@ -237,16 +237,6 @@
 
 	// Per-module denylist to always opt modules out of bp2build conversion.
 	moduleDoNotConvert map[string]bool
-
-	// Per-module denylist of cc_library modules to only generate the static
-	// variant if their shared variant isn't ready or buildable by Bazel.
-	ccLibraryStaticOnly map[string]bool
-}
-
-// GenerateCcLibraryStaticOnly returns whether a cc_library module should only
-// generate a static version of itself based on the current global configuration.
-func (a Bp2BuildConversionAllowlist) GenerateCcLibraryStaticOnly(moduleName string) bool {
-	return a.ccLibraryStaticOnly[moduleName]
 }
 
 // NewBp2BuildAllowlist creates a new, empty Bp2BuildConversionAllowlist
@@ -258,7 +248,6 @@
 		map[string]bool{},
 		map[string]bool{},
 		map[string]bool{},
-		map[string]bool{},
 	}
 }
 
@@ -322,18 +311,6 @@
 	return a
 }
 
-// SetCcLibraryStaticOnlyList copies the entries from ccLibraryStaticOnly into the allowlist
-func (a Bp2BuildConversionAllowlist) SetCcLibraryStaticOnlyList(ccLibraryStaticOnly []string) Bp2BuildConversionAllowlist {
-	if a.ccLibraryStaticOnly == nil {
-		a.ccLibraryStaticOnly = map[string]bool{}
-	}
-	for _, m := range ccLibraryStaticOnly {
-		a.ccLibraryStaticOnly[m] = true
-	}
-
-	return a
-}
-
 // ShouldKeepExistingBuildFileForDir returns whether an existing BUILD file should be
 // added to the build symlink forest based on the current global configuration.
 func (a Bp2BuildConversionAllowlist) ShouldKeepExistingBuildFileForDir(dir string) bool {
@@ -365,8 +342,7 @@
 			SetKeepExistingBuildFile(allowlists.Bp2buildKeepExistingBuildFile).
 			SetModuleAlwaysConvertList(allowlists.Bp2buildModuleAlwaysConvertList).
 			SetModuleTypeAlwaysConvertList(allowlists.Bp2buildModuleTypeAlwaysConvertList).
-			SetModuleDoNotConvertList(allowlists.Bp2buildModuleDoNotConvertList).
-			SetCcLibraryStaticOnlyList(allowlists.Bp2buildCcLibraryStaticOnlyList)
+			SetModuleDoNotConvertList(allowlists.Bp2buildModuleDoNotConvertList)
 	}).(Bp2BuildConversionAllowlist)
 }
 
@@ -375,30 +351,16 @@
 // method will also log whether this module is mixed build enabled for
 // metrics reporting.
 func MixedBuildsEnabled(ctx BaseModuleContext) bool {
-	mixedBuildEnabled := mixedBuildPossible(ctx)
+	module := ctx.Module()
+	mixedBuildEnabled := ctx.Config().IsMixedBuildsEnabled() &&
+		ctx.Os() != Windows && // Windows toolchains are not currently supported.
+		module.Enabled() &&
+		convertedToBazel(ctx, module) &&
+		ctx.Config().BazelContext.IsModuleNameAllowed(module.Name())
 	ctx.Config().LogMixedBuild(ctx, mixedBuildEnabled)
 	return mixedBuildEnabled
 }
 
-// mixedBuildPossible returns true if a module is ready to be replaced by a
-// converted or handcrafted Bazel target.
-func mixedBuildPossible(ctx BaseModuleContext) bool {
-	if !ctx.Config().IsMixedBuildsEnabled() {
-		return false
-	}
-	if ctx.Os() == Windows {
-		// Windows toolchains are not currently supported.
-		return false
-	}
-	if !ctx.Module().Enabled() {
-		return false
-	}
-	if !convertedToBazel(ctx, ctx.Module()) {
-		return false
-	}
-	return ctx.Config().BazelContext.BazelAllowlisted(ctx.Module().Name())
-}
-
 // ConvertedToBazel returns whether this module has been converted (with bp2build or manually) to Bazel.
 func convertedToBazel(ctx BazelConversionContext, module blueprint.Module) bool {
 	b, ok := module.(Bazelable)
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 40cc6a2..8d45041 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -152,7 +152,7 @@
 	// Note that this only implies "bazel mixed build" allowlisting. The caller
 	// should independently verify the module is eligible for Bazel handling
 	// (for example, that it is MixedBuildBuildable).
-	BazelAllowlisted(moduleName string) bool
+	IsModuleNameAllowed(moduleName string) bool
 
 	// Returns the bazel output base (the root directory for all bazel intermediate outputs).
 	OutputBase() string
@@ -181,7 +181,7 @@
 
 // A context object which tracks queued requests that need to be made to Bazel,
 // and their results after the requests have been made.
-type bazelContext struct {
+type mixedBuildBazelContext struct {
 	bazelRunner
 	paths        *bazelPaths
 	requests     map[cqueryKey]bool // cquery requests that have not yet been issued to Bazel
@@ -210,7 +210,7 @@
 	targetBuildVariant string
 }
 
-var _ BazelContext = &bazelContext{}
+var _ BazelContext = &mixedBuildBazelContext{}
 
 // A bazel context to use when Bazel is disabled.
 type noopBazelContext struct{}
@@ -261,7 +261,7 @@
 	panic("unimplemented")
 }
 
-func (m MockBazelContext) BazelAllowlisted(_ string) bool {
+func (m MockBazelContext) IsModuleNameAllowed(_ string) bool {
 	return true
 }
 
@@ -277,14 +277,14 @@
 
 var _ BazelContext = MockBazelContext{}
 
-func (bazelCtx *bazelContext) QueueBazelRequest(label string, requestType cqueryRequest, cfgKey configKey) {
+func (bazelCtx *mixedBuildBazelContext) QueueBazelRequest(label string, requestType cqueryRequest, cfgKey configKey) {
 	key := makeCqueryKey(label, requestType, cfgKey)
 	bazelCtx.requestMutex.Lock()
 	defer bazelCtx.requestMutex.Unlock()
 	bazelCtx.requests[key] = true
 }
 
-func (bazelCtx *bazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, error) {
+func (bazelCtx *mixedBuildBazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, error) {
 	key := makeCqueryKey(label, cquery.GetOutputFiles, cfgKey)
 	if rawString, ok := bazelCtx.results[key]; ok {
 		bazelOutput := strings.TrimSpace(rawString)
@@ -294,7 +294,7 @@
 	return nil, fmt.Errorf("no bazel response found for %v", key)
 }
 
-func (bazelCtx *bazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, error) {
+func (bazelCtx *mixedBuildBazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, error) {
 	key := makeCqueryKey(label, cquery.GetCcInfo, cfgKey)
 	if rawString, ok := bazelCtx.results[key]; ok {
 		bazelOutput := strings.TrimSpace(rawString)
@@ -303,7 +303,7 @@
 	return cquery.CcInfo{}, fmt.Errorf("no bazel response found for %v", key)
 }
 
-func (bazelCtx *bazelContext) GetPythonBinary(label string, cfgKey configKey) (string, error) {
+func (bazelCtx *mixedBuildBazelContext) GetPythonBinary(label string, cfgKey configKey) (string, error) {
 	key := makeCqueryKey(label, cquery.GetPythonBinary, cfgKey)
 	if rawString, ok := bazelCtx.results[key]; ok {
 		bazelOutput := strings.TrimSpace(rawString)
@@ -312,7 +312,7 @@
 	return "", fmt.Errorf("no bazel response found for %v", key)
 }
 
-func (bazelCtx *bazelContext) GetApexInfo(label string, cfgKey configKey) (cquery.ApexInfo, error) {
+func (bazelCtx *mixedBuildBazelContext) GetApexInfo(label string, cfgKey configKey) (cquery.ApexInfo, error) {
 	key := makeCqueryKey(label, cquery.GetApexInfo, cfgKey)
 	if rawString, ok := bazelCtx.results[key]; ok {
 		return cquery.GetApexInfo.ParseResult(strings.TrimSpace(rawString))
@@ -320,7 +320,7 @@
 	return cquery.ApexInfo{}, fmt.Errorf("no bazel response found for %v", key)
 }
 
-func (bazelCtx *bazelContext) GetCcUnstrippedInfo(label string, cfgKey configKey) (cquery.CcUnstrippedInfo, error) {
+func (bazelCtx *mixedBuildBazelContext) GetCcUnstrippedInfo(label string, cfgKey configKey) (cquery.CcUnstrippedInfo, error) {
 	key := makeCqueryKey(label, cquery.GetCcUnstrippedInfo, cfgKey)
 	if rawString, ok := bazelCtx.results[key]; ok {
 		return cquery.GetCcUnstrippedInfo.ParseResult(strings.TrimSpace(rawString))
@@ -361,7 +361,7 @@
 	return ""
 }
 
-func (n noopBazelContext) BazelAllowlisted(_ string) bool {
+func (n noopBazelContext) IsModuleNameAllowed(_ string) bool {
 	return false
 }
 
@@ -396,12 +396,6 @@
 			enabledModules[enabledAdHocModule] = true
 		}
 	case BazelDevMode:
-		// Don't use partially-converted cc_library targets in mixed builds,
-		// since mixed builds would generally rely on both static and shared
-		// variants of a cc_library.
-		for staticOnlyModule := range GetBp2BuildAllowList().ccLibraryStaticOnly {
-			disabledModules[staticOnlyModule] = true
-		}
 		addToStringSet(disabledModules, allowlists.MixedBuildsDisabledList)
 	default:
 		panic("Expected BazelProdMode, BazelStagingMode, or BazelDevMode")
@@ -475,7 +469,7 @@
 		targetProduct = c.DeviceProduct()
 	}
 
-	return &bazelContext{
+	return &mixedBuildBazelContext{
 		bazelRunner:           &builtinBazelRunner{},
 		paths:                 &paths,
 		requests:              make(map[cqueryKey]bool),
@@ -491,7 +485,7 @@
 	return p.metricsDir
 }
 
-func (context *bazelContext) BazelAllowlisted(moduleName string) bool {
+func (context *mixedBuildBazelContext) IsModuleNameAllowed(moduleName string) bool {
 	if context.bazelDisabledModules[moduleName] {
 		return false
 	}
@@ -618,7 +612,7 @@
 
 }
 
-func (context *bazelContext) mainBzlFileContents() []byte {
+func (context *mixedBuildBazelContext) mainBzlFileContents() []byte {
 	// TODO(cparsons): Define configuration transitions programmatically based
 	// on available archs.
 	contents := `
@@ -687,7 +681,7 @@
 	return []byte(productReplacer.Replace(contents))
 }
 
-func (context *bazelContext) mainBuildFileContents() []byte {
+func (context *mixedBuildBazelContext) mainBuildFileContents() []byte {
 	// TODO(cparsons): Map label to attribute programmatically; don't use hard-coded
 	// architecture mapping.
 	formatString := `
@@ -751,10 +745,10 @@
 
 // Returns the file contents of the buildroot.cquery file that should be used for the cquery
 // expression in order to obtain information about buildroot and its dependencies.
-// The contents of this file depend on the bazelContext's requests; requests are enumerated
+// The contents of this file depend on the mixedBuildBazelContext's requests; requests are enumerated
 // and grouped by their request type. The data retrieved for each label depends on its
 // request type.
-func (context *bazelContext) cqueryStarlarkFileContents() []byte {
+func (context *mixedBuildBazelContext) cqueryStarlarkFileContents() []byte {
 	requestTypeToCqueryIdEntries := map[cqueryRequest][]string{}
 	for val := range context.requests {
 		cqueryId := getCqueryId(val)
@@ -912,7 +906,7 @@
 
 // Issues commands to Bazel to receive results for all cquery requests
 // queued in the BazelContext.
-func (context *bazelContext) InvokeBazel(config Config, ctx *Context) error {
+func (context *mixedBuildBazelContext) InvokeBazel(config Config, ctx *Context) error {
 	if ctx != nil {
 		ctx.EventHandler.Begin("bazel")
 		defer ctx.EventHandler.End("bazel")
@@ -939,7 +933,7 @@
 	return nil
 }
 
-func (context *bazelContext) runCquery(ctx *Context) error {
+func (context *mixedBuildBazelContext) runCquery(ctx *Context) error {
 	if ctx != nil {
 		ctx.EventHandler.Begin("cquery")
 		defer ctx.EventHandler.End("cquery")
@@ -994,7 +988,7 @@
 	return nil
 }
 
-func (context *bazelContext) runAquery(config Config, ctx *Context) error {
+func (context *mixedBuildBazelContext) runAquery(config Config, ctx *Context) error {
 	if ctx != nil {
 		ctx.EventHandler.Begin("aquery")
 		defer ctx.EventHandler.End("aquery")
@@ -1032,7 +1026,7 @@
 	return err
 }
 
-func (context *bazelContext) generateBazelSymlinks(ctx *Context) error {
+func (context *mixedBuildBazelContext) generateBazelSymlinks(ctx *Context) error {
 	if ctx != nil {
 		ctx.EventHandler.Begin("symlinks")
 		defer ctx.EventHandler.End("symlinks")
@@ -1044,15 +1038,15 @@
 	return err
 }
 
-func (context *bazelContext) BuildStatementsToRegister() []bazel.BuildStatement {
+func (context *mixedBuildBazelContext) BuildStatementsToRegister() []bazel.BuildStatement {
 	return context.buildStatements
 }
 
-func (context *bazelContext) AqueryDepsets() []bazel.AqueryDepset {
+func (context *mixedBuildBazelContext) AqueryDepsets() []bazel.AqueryDepset {
 	return context.depsets
 }
 
-func (context *bazelContext) OutputBase() string {
+func (context *mixedBuildBazelContext) OutputBase() string {
 	return context.paths.outputBase
 }
 
diff --git a/android/bazel_handler_test.go b/android/bazel_handler_test.go
index 10bbf31..013e19c 100644
--- a/android/bazel_handler_test.go
+++ b/android/bazel_handler_test.go
@@ -189,7 +189,7 @@
 	return actual
 }
 
-func testBazelContext(t *testing.T, bazelCommandResults map[bazelCommand]string) (*bazelContext, string) {
+func testBazelContext(t *testing.T, bazelCommandResults map[bazelCommand]string) (*mixedBuildBazelContext, string) {
 	t.Helper()
 	p := bazelPaths{
 		soongOutDir:  t.TempDir(),
@@ -201,7 +201,7 @@
 		bazelCommandResults[aqueryCommand] = ""
 	}
 	runner := &mockBazelRunner{bazelCommandResults: bazelCommandResults}
-	return &bazelContext{
+	return &mixedBuildBazelContext{
 		bazelRunner: runner,
 		paths:       &p,
 		requests:    map[cqueryKey]bool{},
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 1ecb0af..e151521 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -496,13 +496,15 @@
 	if err != nil {
 		reportPathError(ctx, err)
 	}
-	relativeRootPath := filepath.Join("execroot", "__main__", relativeRoot)
-	if pathComponents := strings.Split(path, "/"); len(pathComponents) >= 3 &&
+	var relativeRootPath string
+	if pathComponents := strings.SplitN(path, "/", 4); len(pathComponents) >= 3 &&
 		pathComponents[0] == "bazel-out" && pathComponents[2] == "bin" {
 		// If the path starts with something like: bazel-out/linux_x86_64-fastbuild-ST-b4ef1c4402f9/bin/
 		// make it relative to that folder. bazel-out/volatile-status.txt is an example
 		// of something that starts with bazel-out but is not relative to the bin folder
 		relativeRootPath = filepath.Join("execroot", "__main__", pathComponents[0], pathComponents[1], pathComponents[2], relativeRoot)
+	} else {
+		relativeRootPath = filepath.Join("execroot", "__main__", relativeRoot)
 	}
 
 	var relPath string
diff --git a/android/bazel_test.go b/android/bazel_test.go
index 7b38b6a..87b2c8f 100644
--- a/android/bazel_test.go
+++ b/android/bazel_test.go
@@ -417,11 +417,6 @@
 			t.Errorf("bp2build module do not convert of %s: expected: true, got: %v", k, allowlist.moduleDoNotConvert[k])
 		}
 	}
-	for _, k := range allowlists.Bp2buildCcLibraryStaticOnlyList {
-		if !allowlist.ccLibraryStaticOnly[k] {
-			t.Errorf("bp2build cc library static only of %s: expected: true, got: %v", k, allowlist.ccLibraryStaticOnly[k])
-		}
-	}
 }
 
 func TestShouldKeepExistingBuildFileForDir(t *testing.T) {
diff --git a/android/config.go b/android/config.go
index d5ed883..a8b0a40 100644
--- a/android/config.go
+++ b/android/config.go
@@ -583,32 +583,28 @@
 	c.mockBpList = blueprint.MockModuleListFile
 }
 
+// TODO(b/265062549): Add a field to our collected (and uploaded) metrics which
+// describes a reason that we fell back to non-mixed builds.
 // Returns true if "Bazel builds" is enabled. In this mode, part of build
 // analysis is handled by Bazel.
 func (c *config) IsMixedBuildsEnabled() bool {
 	globalMixedBuildsSupport := c.Once(OnceKey{"globalMixedBuildsSupport"}, func() interface{} {
 		if c.productVariables.DeviceArch != nil && *c.productVariables.DeviceArch == "riscv64" {
-			fmt.Fprintln(os.Stderr, "unsupported device arch 'riscv64' for Bazel: falling back to non-mixed build")
 			return false
 		}
 		if c.IsEnvTrue("GLOBAL_THINLTO") {
-			fmt.Fprintln(os.Stderr, "unsupported env var GLOBAL_THINLTO for Bazel: falling back to non-mixed build")
 			return false
 		}
 		if len(c.productVariables.SanitizeHost) > 0 {
-			fmt.Fprintln(os.Stderr, "unsupported product var SanitizeHost for Bazel: falling back to non-mixed build")
 			return false
 		}
 		if len(c.productVariables.SanitizeDevice) > 0 {
-			fmt.Fprintln(os.Stderr, "unsupported product var SanitizeDevice for Bazel: falling back to non-mixed build")
 			return false
 		}
 		if len(c.productVariables.SanitizeDeviceDiag) > 0 {
-			fmt.Fprintln(os.Stderr, "unsupported product var SanitizeDeviceDiag for Bazel: falling back to non-mixed build")
 			return false
 		}
 		if len(c.productVariables.SanitizeDeviceArch) > 0 {
-			fmt.Fprintln(os.Stderr, "unsupported product var SanitizeDeviceArch for Bazel: falling back to non-mixed build")
 			return false
 		}
 		return true
diff --git a/android/mutator.go b/android/mutator.go
index d92b87c..4e55609 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -409,7 +409,7 @@
 
 	return &bottomUpMutatorContext{
 		bp:                ctx,
-		baseModuleContext: a.base().baseModuleContextFactory(ctx),
+		baseModuleContext: moduleContext,
 		finalPhase:        finalPhase,
 	}
 }
diff --git a/android/paths.go b/android/paths.go
index a6a54fa..0fc39df 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -1033,9 +1033,6 @@
 // SourcePath is a Path representing a file path rooted from SrcDir
 type SourcePath struct {
 	basePath
-
-	// The sources root, i.e. Config.SrcDir()
-	srcDir string
 }
 
 func (p SourcePath) RelativeToTop() Path {
@@ -1054,7 +1051,7 @@
 // code that is embedding ninja variables in paths
 func safePathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
 	p, err := validateSafePath(pathComponents...)
-	ret := SourcePath{basePath{p, ""}, "."}
+	ret := SourcePath{basePath{p, ""}}
 	if err != nil {
 		return ret, err
 	}
@@ -1071,7 +1068,7 @@
 // pathForSource creates a SourcePath from pathComponents, but does not check that it exists.
 func pathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
 	p, err := validatePath(pathComponents...)
-	ret := SourcePath{basePath{p, ""}, "."}
+	ret := SourcePath{basePath{p, ""}}
 	if err != nil {
 		return ret, err
 	}
@@ -1174,7 +1171,10 @@
 }
 
 func (p SourcePath) String() string {
-	return filepath.Join(p.srcDir, p.path)
+	if p.path == "" {
+		return "."
+	}
+	return p.path
 }
 
 // Join creates a new SourcePath with paths... joined with the current path. The
@@ -1207,7 +1207,7 @@
 		// No need to put the error message into the returned path since it has been reported already.
 		return OptionalPath{}
 	}
-	dir := filepath.Join(p.srcDir, p.path, relDir)
+	dir := filepath.Join(p.path, relDir)
 	// Use Glob so that we are run again if the directory is added.
 	if pathtools.IsGlob(dir) {
 		ReportPathErrorf(ctx, "Path may not contain a glob: %s", dir)
@@ -1220,8 +1220,7 @@
 	if len(paths) == 0 {
 		return InvalidOptionalPath(dir + " does not exist")
 	}
-	relPath := Rel(ctx, p.srcDir, paths[0])
-	return OptionalPathForPath(PathForSource(ctx, relPath))
+	return OptionalPathForPath(PathForSource(ctx, paths[0]))
 }
 
 // OutputPath is a Path representing an intermediates file path rooted from the build directory
diff --git a/android/sdk_version.go b/android/sdk_version.go
index d73c912..8953eae 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -51,6 +51,7 @@
 	SdkModule
 	SdkSystemServer
 	SdkPrivate
+	SdkToolchain // API surface provided by ART to compile other API domains
 )
 
 // String returns the string representation of this SdkKind
@@ -76,6 +77,8 @@
 		return "module-lib"
 	case SdkSystemServer:
 		return "system-server"
+	case SdkToolchain:
+		return "toolchain"
 	default:
 		return "invalid"
 	}
diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go
index c1e92b8..9f5440d 100644
--- a/android/soong_config_modules.go
+++ b/android/soong_config_modules.go
@@ -20,7 +20,9 @@
 import (
 	"fmt"
 	"path/filepath"
+	"reflect"
 	"strings"
+	"sync"
 	"text/scanner"
 
 	"github.com/google/blueprint"
@@ -31,12 +33,18 @@
 )
 
 func init() {
-	RegisterModuleType("soong_config_module_type_import", SoongConfigModuleTypeImportFactory)
-	RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
-	RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
-	RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
+	RegisterSoongConfigModuleBuildComponents(InitRegistrationContext)
 }
 
+func RegisterSoongConfigModuleBuildComponents(ctx RegistrationContext) {
+	ctx.RegisterModuleType("soong_config_module_type_import", SoongConfigModuleTypeImportFactory)
+	ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
+	ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
+	ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
+}
+
+var PrepareForTestWithSoongConfigModuleBuildComponents = FixtureRegisterWithContext(RegisterSoongConfigModuleBuildComponents)
+
 type soongConfigModuleTypeImport struct {
 	ModuleBase
 	properties soongConfigModuleTypeImportProperties
@@ -416,13 +424,43 @@
 // configModuleFactory takes an existing soongConfigModuleFactory and a
 // ModuleType to create a new ModuleFactory that uses a custom loadhook.
 func configModuleFactory(factory blueprint.ModuleFactory, moduleType *soongconfig.ModuleType, bp2build bool) blueprint.ModuleFactory {
-	conditionalFactoryProps := soongconfig.CreateProperties(factory, moduleType)
-	if !conditionalFactoryProps.IsValid() {
-		return factory
+	// Defer creation of conditional properties struct until the first call from the factory
+	// method. That avoids having to make a special call to the factory to create the properties
+	// structs from which the conditional properties struct is created. This is needed in order to
+	// allow singleton modules to be customized by soong_config_module_type as the
+	// SingletonModuleFactoryAdaptor factory registers a load hook for the singleton module
+	// everytime that it is called. Calling the factory twice causes a build failure as the load
+	// hook is called twice, the first time it updates the singleton module to indicate that it has
+	// been registered as a module, and the second time it fails because it thinks it has been
+	// registered again and a singleton module can only be registered once.
+	//
+	// This is an issue for singleton modules because:
+	// * Load hooks are registered on the module object and are only called when the module object
+	//   is created by Blueprint while processing the Android.bp file.
+	// * The module factory for a singleton module returns the same module object each time it is
+	//   called, and registers its load hook on that same module object.
+	// * When the module factory is called by Blueprint it then calls all the load hooks that have
+	//   been registered for every call to that module factory.
+	//
+	// It is not an issue for normal modules because they return a new module object each time the
+	// factory is called and so any load hooks registered on module objects which are discarded will
+	// not be run.
+	once := &sync.Once{}
+	conditionalFactoryProps := reflect.Value{}
+	getConditionalFactoryProps := func(props []interface{}) reflect.Value {
+		once.Do(func() {
+			conditionalFactoryProps = soongconfig.CreateProperties(props, moduleType)
+		})
+		return conditionalFactoryProps
 	}
 
 	return func() (blueprint.Module, []interface{}) {
 		module, props := factory()
+		conditionalFactoryProps := getConditionalFactoryProps(props)
+		if !conditionalFactoryProps.IsValid() {
+			return module, props
+		}
+
 		conditionalProps := proptools.CloneEmptyProperties(conditionalFactoryProps)
 		props = append(props, conditionalProps.Interface())
 
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index ceb8e45..cab3e2d 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -15,12 +15,10 @@
 package android
 
 import (
+	"fmt"
 	"testing"
 )
 
-type soongConfigTestDefaultsModuleProperties struct {
-}
-
 type soongConfigTestDefaultsModule struct {
 	ModuleBase
 	DefaultsModuleBase
@@ -53,6 +51,11 @@
 
 func (t soongConfigTestModule) GenerateAndroidBuildActions(ModuleContext) {}
 
+var prepareForSoongConfigTestModule = FixtureRegisterWithContext(func(ctx RegistrationContext) {
+	ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
+	ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
+})
+
 func TestSoongConfigModule(t *testing.T) {
 	configBp := `
 		soong_config_module_type {
@@ -309,14 +312,8 @@
 				result := GroupFixturePreparers(
 					tc.preparer,
 					PrepareForTestWithDefaults,
-					FixtureRegisterWithContext(func(ctx RegistrationContext) {
-						ctx.RegisterModuleType("soong_config_module_type_import", SoongConfigModuleTypeImportFactory)
-						ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
-						ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
-						ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
-						ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
-						ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
-					}),
+					PrepareForTestWithSoongConfigModuleBuildComponents,
+					prepareForSoongConfigTestModule,
 					fs.AddToFixture(),
 					FixtureWithRootAndroidBp(bp),
 				).RunTest(t)
@@ -371,14 +368,8 @@
 	GroupFixturePreparers(
 		fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
 		PrepareForTestWithDefaults,
-		FixtureRegisterWithContext(func(ctx RegistrationContext) {
-			ctx.RegisterModuleType("soong_config_module_type_import", SoongConfigModuleTypeImportFactory)
-			ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
-			ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
-			ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
-			ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
-			ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
-		}),
+		PrepareForTestWithSoongConfigModuleBuildComponents,
+		prepareForSoongConfigTestModule,
 		FixtureWithRootAndroidBp(bp),
 	).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
 		// TODO(b/171232169): improve the error message for non-existent properties
@@ -411,14 +402,8 @@
 	GroupFixturePreparers(
 		fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
 		PrepareForTestWithDefaults,
-		FixtureRegisterWithContext(func(ctx RegistrationContext) {
-			ctx.RegisterModuleType("soong_config_module_type_import", SoongConfigModuleTypeImportFactory)
-			ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
-			ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
-			ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
-			ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
-			ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
-		}),
+		PrepareForTestWithSoongConfigModuleBuildComponents,
+		prepareForSoongConfigTestModule,
 		FixtureWithRootAndroidBp(bp),
 	).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
 		// TODO(b/171232169): improve the error message for non-existent properties
@@ -426,10 +411,95 @@
 	})).RunTest(t)
 }
 
-func testConfigWithVendorVars(buildDir, bp string, fs map[string][]byte, vendorVars map[string]map[string]string) Config {
-	config := TestConfig(buildDir, nil, bp, fs)
+type soongConfigTestSingletonModule struct {
+	SingletonModuleBase
+	props soongConfigTestSingletonModuleProperties
+}
 
-	config.TestProductVariables.VendorVars = vendorVars
+type soongConfigTestSingletonModuleProperties struct {
+	Fragments []struct {
+		Apex   string
+		Module string
+	}
+}
 
-	return config
+func soongConfigTestSingletonModuleFactory() SingletonModule {
+	m := &soongConfigTestSingletonModule{}
+	m.AddProperties(&m.props)
+	InitAndroidModule(m)
+	return m
+}
+
+func (t *soongConfigTestSingletonModule) GenerateAndroidBuildActions(ModuleContext) {}
+
+func (t *soongConfigTestSingletonModule) GenerateSingletonBuildActions(SingletonContext) {}
+
+var prepareForSoongConfigTestSingletonModule = FixtureRegisterWithContext(func(ctx RegistrationContext) {
+	ctx.RegisterSingletonModuleType("test_singleton", soongConfigTestSingletonModuleFactory)
+})
+
+func TestSoongConfigModuleSingletonModule(t *testing.T) {
+	bp := `
+		soong_config_module_type {
+			name: "acme_test_singleton",
+			module_type: "test_singleton",
+			config_namespace: "acme",
+			bool_variables: ["coyote"],
+			properties: ["fragments"],
+		}
+
+		acme_test_singleton {
+			name: "wiley",
+			fragments: [
+				{
+					apex: "com.android.acme",
+					module: "road-runner",
+				},
+			],
+			soong_config_variables: {
+				coyote: {
+					fragments: [
+						{
+							apex: "com.android.acme",
+							module: "wiley",
+						},
+					],
+				},
+			},
+		}
+	`
+
+	for _, test := range []struct {
+		coyote            bool
+		expectedFragments string
+	}{
+		{
+			coyote:            false,
+			expectedFragments: "[{Apex:com.android.acme Module:road-runner}]",
+		},
+		{
+			coyote:            true,
+			expectedFragments: "[{Apex:com.android.acme Module:road-runner} {Apex:com.android.acme Module:wiley}]",
+		},
+	} {
+		t.Run(fmt.Sprintf("coyote:%t", test.coyote), func(t *testing.T) {
+			result := GroupFixturePreparers(
+				PrepareForTestWithSoongConfigModuleBuildComponents,
+				prepareForSoongConfigTestSingletonModule,
+				FixtureWithRootAndroidBp(bp),
+				FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+					variables.VendorVars = map[string]map[string]string{
+						"acme": {
+							"coyote": fmt.Sprintf("%t", test.coyote),
+						},
+					}
+				}),
+			).RunTest(t)
+
+			// Make sure that the singleton was created.
+			result.SingletonForTests("test_singleton")
+			m := result.ModuleForTests("wiley", "").module.(*soongConfigTestSingletonModule)
+			AssertStringEquals(t, "fragments", test.expectedFragments, fmt.Sprintf("%+v", m.props.Fragments))
+		})
+	}
 }
diff --git a/android/soongconfig/modules.go b/android/soongconfig/modules.go
index 1519f60..ed4888d 100644
--- a/android/soongconfig/modules.go
+++ b/android/soongconfig/modules.go
@@ -22,7 +22,6 @@
 	"strings"
 	"sync"
 
-	"github.com/google/blueprint"
 	"github.com/google/blueprint/parser"
 	"github.com/google/blueprint/proptools"
 
@@ -363,10 +362,9 @@
 //	        },
 //	    },
 //	}
-func CreateProperties(factory blueprint.ModuleFactory, moduleType *ModuleType) reflect.Value {
+func CreateProperties(factoryProps []interface{}, moduleType *ModuleType) reflect.Value {
 	var fields []reflect.StructField
 
-	_, factoryProps := factory()
 	affectablePropertiesType := createAffectablePropertiesType(moduleType.affectableProperties, factoryProps)
 	if affectablePropertiesType == nil {
 		return reflect.Value{}
diff --git a/apex/apex.go b/apex/apex.go
index b9a3c8f..e99823b 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1905,9 +1905,15 @@
 		return
 	}
 	a.installDir = android.PathForModuleInstall(ctx, "apex")
-	a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
-	a.outputFile = a.outputApexFile
+
+	// Set the output file to .apex or .capex depending on the compression configuration.
 	a.setCompression(ctx)
+	if a.isCompressed {
+		a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedCompressedOutput)
+	} else {
+		a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput)
+	}
+	a.outputFile = a.outputApexFile
 
 	// TODO(b/257829940): These are used by the apex_keys_text singleton; would probably be a clearer
 	// interface if these were set in a provider rather than the module itself
diff --git a/apex/bp2build_test.go b/apex/bp2build_test.go
index 58f30bd..01afa52 100644
--- a/apex/bp2build_test.go
+++ b/apex/bp2build_test.go
@@ -42,15 +42,16 @@
 				OutputBaseDir: outputBaseDir,
 				LabelToApexInfo: map[string]cquery.ApexInfo{
 					"//:foo": cquery.ApexInfo{
-						SignedOutput:          "signed_out.apex",
-						UnsignedOutput:        "unsigned_out.apex",
-						BundleKeyInfo:         []string{"public_key", "private_key"},
-						ContainerKeyInfo:      []string{"container_cert", "container_private"},
-						SymbolsUsedByApex:     "foo_using.txt",
-						JavaSymbolsUsedByApex: "foo_using.xml",
-						BundleFile:            "apex_bundle.zip",
-						InstalledFiles:        "installed-files.txt",
-						RequiresLibs:          []string{"//path/c:c", "//path/d:d"},
+						SignedOutput:           "signed_out.apex",
+						SignedCompressedOutput: "signed_out.capex",
+						UnsignedOutput:         "unsigned_out.apex",
+						BundleKeyInfo:          []string{"public_key", "private_key"},
+						ContainerKeyInfo:       []string{"container_cert", "container_private"},
+						SymbolsUsedByApex:      "foo_using.txt",
+						JavaSymbolsUsedByApex:  "foo_using.xml",
+						BundleFile:             "apex_bundle.zip",
+						InstalledFiles:         "installed-files.txt",
+						RequiresLibs:           []string{"//path/c:c", "//path/d:d"},
 
 						// unused
 						PackageName:  "pkg_name",
@@ -115,6 +116,68 @@
 	}
 }
 
+func TestCompressedApexImageInMixedBuilds(t *testing.T) {
+	bp := `
+apex_key{
+	name: "foo_key",
+}
+apex {
+	name: "foo",
+	key: "foo_key",
+	updatable: true,
+	min_sdk_version: "31",
+	file_contexts: ":myapex-file_contexts",
+	bazel_module: { label: "//:foo" },
+	test_only_force_compression: true, // force compression
+}`
+
+	outputBaseDir := "out/bazel"
+	result := android.GroupFixturePreparers(
+		prepareForApexTest,
+		android.FixtureModifyConfig(func(config android.Config) {
+			config.BazelContext = android.MockBazelContext{
+				OutputBaseDir: outputBaseDir,
+				LabelToApexInfo: map[string]cquery.ApexInfo{
+					"//:foo": cquery.ApexInfo{
+						SignedOutput:           "signed_out.apex",
+						SignedCompressedOutput: "signed_out.capex",
+						BundleKeyInfo:          []string{"public_key", "private_key"},
+						ContainerKeyInfo:       []string{"container_cert", "container_private"},
+					},
+				},
+			}
+		}),
+	).RunTestWithBp(t, bp)
+
+	m := result.ModuleForTests("foo", "android_common_foo_image").Module()
+	ab, ok := m.(*apexBundle)
+	if !ok {
+		t.Fatalf("Expected module to be an apexBundle, was not")
+	}
+
+	if w, g := "out/bazel/execroot/__main__/signed_out.capex", ab.outputFile.String(); w != g {
+		t.Errorf("Expected output file to be compressed apex %q, got %q", w, g)
+	}
+
+	mkData := android.AndroidMkDataForTest(t, result.TestContext, m)
+	var builder strings.Builder
+	mkData.Custom(&builder, "foo", "BAZEL_TARGET_", "", mkData)
+
+	data := builder.String()
+
+	expectedAndroidMk := []string{
+		"LOCAL_PREBUILT_MODULE_FILE := out/bazel/execroot/__main__/signed_out.capex",
+
+		// Check that the source install file is the capex. The dest is not important.
+		"LOCAL_SOONG_INSTALL_PAIRS := out/bazel/execroot/__main__/signed_out.capex:",
+	}
+	for _, androidMk := range expectedAndroidMk {
+		if !strings.Contains(data, androidMk) {
+			t.Errorf("Expected %q in androidmk data, but did not find %q", androidMk, data)
+		}
+	}
+}
+
 func TestOverrideApexImageInMixedBuilds(t *testing.T) {
 	bp := `
 apex_key{
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index 7c9ae3b..81c60d9 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -232,8 +232,14 @@
   fail("%s did not provide ApexInfo" % id_string)
 bundle_key_info = info.bundle_key_info
 container_key_info = info.container_key_info
+
+signed_compressed_output = "" # no .capex if the apex is not compressible, cannot be None as it needs to be json encoded.
+if info.signed_compressed_output:
+    signed_compressed_output = info.signed_compressed_output.path
+
 return json_encode({
     "signed_output": info.signed_output.path,
+    "signed_compressed_output": signed_compressed_output,
     "unsigned_output": info.unsigned_output.path,
     "provides_native_libs": [str(lib) for lib in info.provides_native_libs],
     "requires_native_libs": [str(lib) for lib in info.requires_native_libs],
@@ -249,18 +255,19 @@
 }
 
 type ApexInfo struct {
-	SignedOutput          string   `json:"signed_output"`
-	UnsignedOutput        string   `json:"unsigned_output"`
-	ProvidesLibs          []string `json:"provides_native_libs"`
-	RequiresLibs          []string `json:"requires_native_libs"`
-	BundleKeyInfo         []string `json:"bundle_key_info"`
-	ContainerKeyInfo      []string `json:"container_key_info"`
-	PackageName           string   `json:"package_name"`
-	SymbolsUsedByApex     string   `json:"symbols_used_by_apex"`
-	JavaSymbolsUsedByApex string   `json:"java_symbols_used_by_apex"`
-	BackingLibs           string   `json:"backing_libs"`
-	BundleFile            string   `json:"bundle_file"`
-	InstalledFiles        string   `json:"installed_files"`
+	SignedOutput           string   `json:"signed_output"`
+	SignedCompressedOutput string   `json:"signed_compressed_output"`
+	UnsignedOutput         string   `json:"unsigned_output"`
+	ProvidesLibs           []string `json:"provides_native_libs"`
+	RequiresLibs           []string `json:"requires_native_libs"`
+	BundleKeyInfo          []string `json:"bundle_key_info"`
+	ContainerKeyInfo       []string `json:"container_key_info"`
+	PackageName            string   `json:"package_name"`
+	SymbolsUsedByApex      string   `json:"symbols_used_by_apex"`
+	JavaSymbolsUsedByApex  string   `json:"java_symbols_used_by_apex"`
+	BackingLibs            string   `json:"backing_libs"`
+	BundleFile             string   `json:"bundle_file"`
+	InstalledFiles         string   `json:"installed_files"`
 }
 
 // ParseResult returns a value obtained by parsing the result of the request's Starlark function.
diff --git a/bazel/properties.go b/bazel/properties.go
index f9cabf2..76450dc 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -674,6 +674,11 @@
 	// specific select statements where an empty list for a non-default select
 	// key has a meaning.
 	EmitEmptyList bool
+
+	// If a property has struct tag "variant_prepend", this value should
+	// be set to True, so that when bp2build generates BUILD.bazel, variant
+	// properties(select ...) come before general properties.
+	Prepend bool
 }
 
 type configurableLabelLists map[ConfigurationAxis]labelListSelectValues
diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go
index 714b848..1c0e563 100644
--- a/bp2build/apex_conversion_test.go
+++ b/bp2build/apex_conversion_test.go
@@ -1146,6 +1146,76 @@
 		}})
 }
 
+func TestApexWithStubLib(t *testing.T) {
+	runApexTestCase(t, Bp2buildTestCase{
+		Description:                "apex - static variant of stub lib should not have apex_available tag",
+		ModuleTypeUnderTest:        "apex",
+		ModuleTypeUnderTestFactory: apex.BundleFactory,
+		Filesystem:                 map[string]string{},
+		Blueprint: `
+cc_library{
+	name: "foo",
+	stubs: { symbol_file: "foo.map.txt", versions: ["28", "29", "current"] },
+	apex_available: ["myapex"],
+}
+
+cc_binary{
+	name: "bar",
+	static_libs: ["foo"],
+	apex_available: ["myapex"],
+}
+
+apex {
+	name: "myapex",
+	manifest: "myapex_manifest.json",
+	file_contexts: ":myapex-file_contexts",
+	binaries: ["bar"],
+	native_shared_libs: ["foo"],
+}
+` + simpleModuleDoNotConvertBp2build("filegroup", "myapex-file_contexts"),
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_binary", "bar", AttrNameToString{
+				"local_includes": `["."]`,
+				"deps":           `[":foo_bp2build_cc_library_static"]`,
+				"tags":           `["apex_available=myapex"]`,
+			}),
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+				"local_includes": `["."]`,
+			}),
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+				"local_includes":    `["."]`,
+				"stubs_symbol_file": `"foo.map.txt"`,
+				"tags":              `["apex_available=myapex"]`,
+			}),
+			MakeBazelTarget("cc_stub_suite", "foo_stub_libs", AttrNameToString{
+				"soname":         `"foo.so"`,
+				"source_library": `":foo"`,
+				"symbol_file":    `"foo.map.txt"`,
+				"versions": `[
+        "28",
+        "29",
+        "current",
+    ]`,
+			}),
+			MakeBazelTarget("apex", "myapex", AttrNameToString{
+				"file_contexts": `":myapex-file_contexts"`,
+				"manifest":      `"myapex_manifest.json"`,
+				"binaries":      `[":bar"]`,
+				"native_shared_libs_32": `select({
+        "//build/bazel/platforms/arch:arm": [":foo"],
+        "//build/bazel/platforms/arch:x86": [":foo"],
+        "//conditions:default": [],
+    })`,
+				"native_shared_libs_64": `select({
+        "//build/bazel/platforms/arch:arm64": [":foo"],
+        "//build/bazel/platforms/arch:x86_64": [":foo"],
+        "//conditions:default": [],
+    })`,
+			}),
+		},
+	})
+}
+
 func TestApexCertificateIsSrc(t *testing.T) {
 	runApexTestCase(t, Bp2buildTestCase{
 		Description:                "apex - certificate is src",
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
index 5dc9612..86b9b27 100644
--- a/bp2build/bp2build.go
+++ b/bp2build/bp2build.go
@@ -45,17 +45,27 @@
 	bp2buildFiles := CreateBazelFiles(ctx.Config(), nil, res.buildFileToTargets, ctx.mode)
 	writeFiles(ctx, bp2buildDir, bp2buildFiles)
 
+	soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName)
+	writeFiles(ctx, soongInjectionDir, CreateSoongInjectionDirFiles(ctx, res.metrics))
+
+	return &res.metrics
+}
+
+// Wrapper function that will be responsible for all files in soong_injection directory
+// This includes
+// 1. config value(s) that are hardcoded in Soong
+// 2. product_config variables
+func CreateSoongInjectionDirFiles(ctx *CodegenContext, metrics CodegenMetrics) []BazelFile {
+	var ret []BazelFile
+
 	productConfigFiles, err := CreateProductConfigFiles(ctx)
 	if err != nil {
 		fmt.Printf("ERROR: %s", err.Error())
 		os.Exit(1)
 	}
-
-	soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName)
-	writeFiles(ctx, soongInjectionDir, productConfigFiles)
-	writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(ctx.Config(), res.metrics))
-
-	return &res.metrics
+	ret = append(ret, productConfigFiles...)
+	ret = append(ret, soongInjectionFiles(ctx.Config(), metrics)...)
+	return ret
 }
 
 // Get the output directory and create it if it doesn't exist.
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 32500a0..072f5b3 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -186,6 +186,8 @@
 	})
 }
 
+// header_libs has "variant_prepend" tag. In bp2build output,
+// variant info(select) should go before general info.
 func TestCcLibraryHeadersOsSpecificHeader(t *testing.T) {
 	runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
 		Description:                "cc_library_headers test with os-specific header_libs props",
@@ -247,14 +249,14 @@
 }`,
 		ExpectedBazelTargets: []string{
 			MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
-				"deps": `[":base-lib"] + select({
+				"deps": `select({
         "//build/bazel/platforms/os:android": [":android-lib"],
         "//build/bazel/platforms/os:darwin": [":darwin-lib"],
         "//build/bazel/platforms/os:linux_bionic": [":linux_bionic-lib"],
         "//build/bazel/platforms/os:linux_glibc": [":linux-lib"],
         "//build/bazel/platforms/os:windows": [":windows-lib"],
         "//conditions:default": [],
-    })`,
+    }) + [":base-lib"]`,
 			}),
 		},
 	})
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 5a1260f..767f4ad 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1003,6 +1003,8 @@
 	})
 }
 
+// generated_headers has "variant_prepend" tag. In bp2build output,
+// variant info(select) should go before general info.
 func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) {
 	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
 		Description: "cc_library_static arch srcs/exclude_srcs with generated files",
@@ -1066,13 +1068,13 @@
         "//build/bazel/platforms/os:android": [":generated_src_android"],
         "//conditions:default": [],
     })`,
-				"hdrs": `["//dep:generated_hdr_other_pkg"] + select({
-        "//build/bazel/platforms/arch:x86": ["//dep:generated_hdr_other_pkg_x86"],
-        "//conditions:default": [],
-    }) + select({
+				"hdrs": `select({
         "//build/bazel/platforms/os:android": ["//dep:generated_hdr_other_pkg_android"],
         "//conditions:default": [],
-    })`,
+    }) + select({
+        "//build/bazel/platforms/arch:x86": ["//dep:generated_hdr_other_pkg_x86"],
+        "//conditions:default": [],
+    }) + ["//dep:generated_hdr_other_pkg"]`,
 				"local_includes":           `["."]`,
 				"export_absolute_includes": `["dep"]`,
 			}),
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index c630965..987c903 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -106,8 +106,9 @@
 
 	return value, []selects{ret}
 }
-func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) {
+func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects, bool) {
 	value := reflect.ValueOf(list.Value.Includes)
+	prepend := list.Prepend
 	var ret []selects
 	for _, axis := range list.SortedConfigurationAxes() {
 		configToLabels := list.ConfigurableValues[axis]
@@ -133,7 +134,7 @@
 		}
 	}
 
-	return value, ret
+	return value, ret, prepend
 }
 
 func labelListSelectValue(selectKey string, list bazel.LabelList, emitEmptyList bool) (bool, reflect.Value) {
@@ -173,7 +174,7 @@
 		value, configurableAttrs, prepend = getStringListValues(list)
 		defaultSelectValue = &emptyBazelList
 	case bazel.LabelListAttribute:
-		value, configurableAttrs = getLabelListValues(list)
+		value, configurableAttrs, prepend = getLabelListValues(list)
 		emitZeroValues = list.EmitEmptyList
 		defaultSelectValue = &emptyBazelList
 		if list.ForceSpecifyEmptyList && (!value.IsNil() || list.HasConfigurableValues()) {
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index e15dd59..e53f29e 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -20,7 +20,8 @@
 	Contents string
 }
 
-func CreateSoongInjectionFiles(cfg android.Config, metrics CodegenMetrics) []BazelFile {
+// PRIVATE: Use CreateSoongInjectionDirFiles instead
+func soongInjectionFiles(cfg android.Config, metrics CodegenMetrics) []BazelFile {
 	var files []BazelFile
 
 	files = append(files, newFile("android", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index dfc7f0b..43daddc 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -84,7 +84,7 @@
 
 func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
 	testConfig := android.TestConfig("", make(map[string]string), "", make(map[string][]byte))
-	files := CreateSoongInjectionFiles(testConfig, CreateCodegenMetrics())
+	files := soongInjectionFiles(testConfig, CreateCodegenMetrics())
 
 	expectedFilePaths := []bazelFilepath{
 		{
diff --git a/bp2build/soong_config_module_type_conversion_test.go b/bp2build/soong_config_module_type_conversion_test.go
index 7029b93..dcd1f85 100644
--- a/bp2build/soong_config_module_type_conversion_test.go
+++ b/bp2build/soong_config_module_type_conversion_test.go
@@ -29,10 +29,7 @@
 func registerSoongConfigModuleTypes(ctx android.RegistrationContext) {
 	cc.RegisterCCBuildComponents(ctx)
 
-	ctx.RegisterModuleType("soong_config_module_type_import", android.SoongConfigModuleTypeImportFactory)
-	ctx.RegisterModuleType("soong_config_module_type", android.SoongConfigModuleTypeFactory)
-	ctx.RegisterModuleType("soong_config_string_variable", android.SoongConfigStringVariableDummyFactory)
-	ctx.RegisterModuleType("soong_config_bool_variable", android.SoongConfigBoolVariableDummyFactory)
+	android.RegisterSoongConfigModuleBuildComponents(ctx)
 
 	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
 }
diff --git a/cc/bp2build.go b/cc/bp2build.go
index a7ee5d1..6f97260 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -91,12 +91,12 @@
 	}
 	archVariantProps := m.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
 	for axis, configToProps := range archVariantProps {
-		for config, _props := range configToProps {
+		for cfg, _props := range configToProps {
 			if archProps, ok := _props.(*BaseCompilerProperties); ok {
 				archDisabledSrcs := android.BazelLabelForModuleSrc(ctx, archProps.Tidy_disabled_srcs)
-				moduleAttrs.Tidy_disabled_srcs.SetSelectValue(axis, config, archDisabledSrcs)
+				moduleAttrs.Tidy_disabled_srcs.SetSelectValue(axis, cfg, archDisabledSrcs)
 				archTimeoutSrcs := android.BazelLabelForModuleSrc(ctx, archProps.Tidy_timeout_srcs)
-				moduleAttrs.Tidy_timeout_srcs.SetSelectValue(axis, config, archTimeoutSrcs)
+				moduleAttrs.Tidy_timeout_srcs.SetSelectValue(axis, cfg, archTimeoutSrcs)
 			}
 		}
 	}
@@ -205,14 +205,14 @@
 
 func bp2BuildPropParseHelper(ctx android.ArchVariantContext, module *Module, propsType interface{}, parseFunc func(axis bazel.ConfigurationAxis, config string, props interface{})) {
 	for axis, configToProps := range module.GetArchVariantProperties(ctx, propsType) {
-		for config, props := range configToProps {
-			parseFunc(axis, config, props)
+		for cfg, props := range configToProps {
+			parseFunc(axis, cfg, props)
 		}
 	}
 }
 
 // Parses properties common to static and shared libraries. Also used for prebuilt libraries.
-func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
+func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, module *Module, _ *libraryDecorator, isStatic bool) staticOrSharedAttributes {
 	attrs := staticOrSharedAttributes{}
 
 	setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
@@ -669,8 +669,8 @@
 
 	ret := &bazel.LabelAttribute{}
 	for _, axis := range ca.asmSrcs.SortedConfigurationAxes() {
-		for config := range ca.asmSrcs.ConfigurableValues[axis] {
-			ret.SetSelectValue(axis, config, bazel.Label{Label: ":" + m.Name() + "_yasm"})
+		for cfg := range ca.asmSrcs.ConfigurableValues[axis] {
+			ret.SetSelectValue(axis, cfg, bazel.Label{Label: ":" + m.Name() + "_yasm"})
 		}
 	}
 	return ret
@@ -690,8 +690,8 @@
 			if _, ok := axisToConfigs[axis]; !ok {
 				axisToConfigs[axis] = map[string]bool{}
 			}
-			for config, _ := range configMap {
-				axisToConfigs[axis][config] = true
+			for cfg := range configMap {
+				axisToConfigs[axis][cfg] = true
 			}
 		}
 	}
@@ -703,49 +703,49 @@
 	linkerAttrs := linkerAttributes{}
 
 	for axis, configs := range axisToConfigs {
-		for config, _ := range configs {
+		for cfg := range configs {
 			var allHdrs []string
-			if baseCompilerProps, ok := archVariantCompilerProps[axis][config].(*BaseCompilerProperties); ok {
+			if baseCompilerProps, ok := archVariantCompilerProps[axis][cfg].(*BaseCompilerProperties); ok {
 				allHdrs = baseCompilerProps.Generated_headers
 				if baseCompilerProps.Lex != nil {
-					compilerAttrs.lexopts.SetSelectValue(axis, config, baseCompilerProps.Lex.Flags)
+					compilerAttrs.lexopts.SetSelectValue(axis, cfg, baseCompilerProps.Lex.Flags)
 				}
-				(&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, config, baseCompilerProps)
+				(&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, cfg, baseCompilerProps)
 			}
 
 			var exportHdrs []string
 
-			if baseLinkerProps, ok := archVariantLinkerProps[axis][config].(*BaseLinkerProperties); ok {
+			if baseLinkerProps, ok := archVariantLinkerProps[axis][cfg].(*BaseLinkerProperties); ok {
 				exportHdrs = baseLinkerProps.Export_generated_headers
 
-				(&linkerAttrs).bp2buildForAxisAndConfig(ctx, module.Binary(), axis, config, baseLinkerProps)
+				(&linkerAttrs).bp2buildForAxisAndConfig(ctx, module.Binary(), axis, cfg, baseLinkerProps)
 			}
 			headers := maybePartitionExportedAndImplementationsDeps(ctx, !module.Binary(), allHdrs, exportHdrs, android.BazelLabelForModuleDeps)
-			implementationHdrs.SetSelectValue(axis, config, headers.implementation)
-			compilerAttrs.hdrs.SetSelectValue(axis, config, headers.export)
+			implementationHdrs.SetSelectValue(axis, cfg, headers.implementation)
+			compilerAttrs.hdrs.SetSelectValue(axis, cfg, headers.export)
 
 			exportIncludes, exportAbsoluteIncludes := includesFromLabelList(headers.export)
-			compilerAttrs.includes.Includes.SetSelectValue(axis, config, exportIncludes)
-			compilerAttrs.includes.AbsoluteIncludes.SetSelectValue(axis, config, exportAbsoluteIncludes)
+			compilerAttrs.includes.Includes.SetSelectValue(axis, cfg, exportIncludes)
+			compilerAttrs.includes.AbsoluteIncludes.SetSelectValue(axis, cfg, exportAbsoluteIncludes)
 
 			includes, absoluteIncludes := includesFromLabelList(headers.implementation)
-			currAbsoluteIncludes := compilerAttrs.absoluteIncludes.SelectValue(axis, config)
+			currAbsoluteIncludes := compilerAttrs.absoluteIncludes.SelectValue(axis, cfg)
 			currAbsoluteIncludes = android.FirstUniqueStrings(append(currAbsoluteIncludes, absoluteIncludes...))
 
-			compilerAttrs.absoluteIncludes.SetSelectValue(axis, config, currAbsoluteIncludes)
+			compilerAttrs.absoluteIncludes.SetSelectValue(axis, cfg, currAbsoluteIncludes)
 
-			currIncludes := compilerAttrs.localIncludes.SelectValue(axis, config)
+			currIncludes := compilerAttrs.localIncludes.SelectValue(axis, cfg)
 			currIncludes = android.FirstUniqueStrings(append(currIncludes, includes...))
 
-			compilerAttrs.localIncludes.SetSelectValue(axis, config, currIncludes)
+			compilerAttrs.localIncludes.SetSelectValue(axis, cfg, currIncludes)
 
-			if libraryProps, ok := archVariantLibraryProperties[axis][config].(*LibraryProperties); ok {
+			if libraryProps, ok := archVariantLibraryProperties[axis][cfg].(*LibraryProperties); ok {
 				if axis == bazel.NoConfigAxis {
 					compilerAttrs.stubsSymbolFile = libraryProps.Stubs.Symbol_file
-					compilerAttrs.stubsVersions.SetSelectValue(axis, config, libraryProps.Stubs.Versions)
+					compilerAttrs.stubsVersions.SetSelectValue(axis, cfg, libraryProps.Stubs.Versions)
 				}
 				if suffix := libraryProps.Suffix; suffix != nil {
-					compilerAttrs.suffix.SetSelectValue(axis, config, suffix)
+					compilerAttrs.suffix.SetSelectValue(axis, cfg, suffix)
 				}
 			}
 		}
@@ -804,6 +804,12 @@
 		(&linkerAttrs).wholeArchiveDeps.Add(bp2buildCcSysprop(ctx, module.Name(), module.Properties.Min_sdk_version, compilerAttrs.syspropSrcs))
 	}
 
+	linkerAttrs.wholeArchiveDeps.Prepend = true
+	linkerAttrs.deps.Prepend = true
+	compilerAttrs.localIncludes.Prepend = true
+	compilerAttrs.absoluteIncludes.Prepend = true
+	compilerAttrs.hdrs.Prepend = true
+
 	features := compilerAttrs.features.Clone().Append(linkerAttrs.features).Append(bp2buildSanitizerFeatures(ctx, module))
 	features.DeduplicateAxesFromBase()
 
@@ -1207,7 +1213,7 @@
 	for name, dep := range productVarToDepFields {
 		props, exists := productVariableProps[name]
 		excludeProps, excludesExists := productVariableProps[dep.excludesField]
-		// if neither an include or excludes property exists, then skip it
+		// if neither an include nor excludes property exists, then skip it
 		if !exists && !excludesExists {
 			continue
 		}
@@ -1346,7 +1352,7 @@
 
 func bazelLabelForStaticModule(ctx android.BazelConversionPathContext, m blueprint.Module) string {
 	label := android.BazelModuleLabel(ctx, m)
-	if ccModule, ok := m.(*Module); ok && ccModule.typ() == fullLibrary && !android.GetBp2BuildAllowList().GenerateCcLibraryStaticOnly(m.Name()) {
+	if ccModule, ok := m.(*Module); ok && ccModule.typ() == fullLibrary {
 		return BazelLabelNameForStaticModule(label)
 	}
 	return label
diff --git a/cc/library.go b/cc/library.go
index 4b47515..8fd0019 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -292,14 +292,6 @@
 }
 
 func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) {
-	// For some cc_library modules, their static variants are ready to be
-	// converted, but not their shared variants. For these modules, delegate to
-	// the cc_library_static bp2build converter temporarily instead.
-	if android.GetBp2BuildAllowList().GenerateCcLibraryStaticOnly(ctx.Module().Name()) {
-		sharedOrStaticLibraryBp2Build(ctx, m, true)
-		return
-	}
-
 	sharedAttrs := bp2BuildParseSharedProps(ctx, m)
 	staticAttrs := bp2BuildParseStaticProps(ctx, m)
 	baseAttributes := bp2BuildParseBaseProps(ctx, m)
@@ -413,12 +405,12 @@
 	sharedTargetAttrs.Suffix = compilerAttrs.suffix
 
 	for axis, configToProps := range m.GetArchVariantProperties(ctx, &LibraryProperties{}) {
-		for config, props := range configToProps {
+		for cfg, props := range configToProps {
 			if props, ok := props.(*LibraryProperties); ok {
 				if props.Inject_bssl_hash != nil {
 					// This is an edge case applies only to libcrypto
 					if m.Name() == "libcrypto" || m.Name() == "libcrypto_for_testing" {
-						sharedTargetAttrs.Inject_bssl_hash.SetSelectValue(axis, config, props.Inject_bssl_hash)
+						sharedTargetAttrs.Inject_bssl_hash.SetSelectValue(axis, cfg, props.Inject_bssl_hash)
 					} else {
 						ctx.PropertyErrorf("inject_bssl_hash", "only applies to libcrypto")
 					}
@@ -436,17 +428,23 @@
 		Bzl_load_location: "//build/bazel/rules/cc:cc_library_shared.bzl",
 	}
 
-	tags := android.ApexAvailableTags(m)
+	var tagsForStaticVariant bazel.StringListAttribute
+	if compilerAttrs.stubsSymbolFile == nil && len(compilerAttrs.stubsVersions.Value) == 0 {
+		tagsForStaticVariant = android.ApexAvailableTags(m)
+	}
+
+	tagsForSharedVariant := android.ApexAvailableTags(m)
+
 	ctx.CreateBazelTargetModuleWithRestrictions(staticProps,
 		android.CommonAttributes{
 			Name: m.Name() + "_bp2build_cc_library_static",
-			Tags: tags,
+			Tags: tagsForStaticVariant,
 		},
 		staticTargetAttrs, staticAttrs.Enabled)
 	ctx.CreateBazelTargetModuleWithRestrictions(sharedProps,
 		android.CommonAttributes{
 			Name: m.Name(),
-			Tags: tags,
+			Tags: tagsForSharedVariant,
 		},
 		sharedTargetAttrs, sharedAttrs.Enabled)
 
@@ -1028,7 +1026,7 @@
 	return ret
 }
 
-func GlobGeneratedHeadersForSnapshot(ctx android.ModuleContext, paths android.Paths) android.Paths {
+func GlobGeneratedHeadersForSnapshot(_ android.ModuleContext, paths android.Paths) android.Paths {
 	ret := android.Paths{}
 	for _, header := range paths {
 		// TODO(b/148123511): remove exportedDeps after cleaning up genrule
@@ -1894,7 +1892,7 @@
 	errorMessage := "error: Please follow https://android.googlesource.com/platform/development/+/master/vndk/tools/header-checker/README.md#configure-cross_version-abi-check to resolve the ABI difference between your source code and version " + prevVersion + "."
 
 	library.sourceAbiDiff(ctx, referenceDump, baseName, prevVersion,
-		isLlndkOrNdk, /* allowExtensions */ true, sourceVersion, errorMessage)
+		isLlndkOrNdk, true /* allowExtensions */, sourceVersion, errorMessage)
 }
 
 func (library *libraryDecorator) sameVersionAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
@@ -1903,7 +1901,7 @@
 	libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
 	errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName
 
-	library.sourceAbiDiff(ctx, referenceDump, baseName, /* nameExt */ "",
+	library.sourceAbiDiff(ctx, referenceDump, baseName, "",
 		isLlndkOrNdk, allowExtensions, "current", errorMessage)
 }
 
@@ -1914,7 +1912,7 @@
 	errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName + " -ref-dump-dir $$ANDROID_BUILD_TOP/" + refDumpDir
 
 	library.sourceAbiDiff(ctx, referenceDump, baseName, nameExt,
-		isLlndkOrNdk, /* allowExtensions */ false, "current", errorMessage)
+		isLlndkOrNdk, false /* allowExtensions */, "current", errorMessage)
 }
 
 func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
diff --git a/cc/object.go b/cc/object.go
index c3a198d..6cb1a30 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -78,7 +78,7 @@
 	Static_libs []string `android:"arch_variant,variant_prepend"`
 
 	// list of shared library modules should only provide headers for this module.
-	Shared_libs []string `android:"arch_variant"`
+	Shared_libs []string `android:"arch_variant,variant_prepend"`
 
 	// list of modules that should only provide headers for this module.
 	Header_libs []string `android:"arch_variant,variant_prepend"`
@@ -178,6 +178,8 @@
 				deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Static_libs))
 				deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Shared_libs))
 				deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Header_libs))
+				// static_libs, shared_libs, and header_libs have variant_prepend tag
+				deps.Prepend = true
 			}
 		}
 	}
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index baa7380..803ab0d 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -145,8 +145,10 @@
 func runApiBp2build(ctx *android.Context, extraNinjaDeps []string) string {
 	ctx.EventHandler.Begin("api_bp2build")
 	defer ctx.EventHandler.End("api_bp2build")
-	// Do not allow missing dependencies.
-	ctx.SetAllowMissingDependencies(false)
+	// api_bp2build does not run the typical pipeline of soong mutators.
+	// Hoevever, it still runs the defaults mutator which can create dependencies.
+	// These dependencies might not always exist (e.g. in tests)
+	ctx.SetAllowMissingDependencies(ctx.Config().AllowMissingDependencies())
 	ctx.RegisterForApiBazelConversion()
 
 	// Register the Android.bp files in the tree
@@ -176,7 +178,7 @@
 	ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...)
 
 	// Create soong_injection repository
-	soongInjectionFiles := bp2build.CreateSoongInjectionFiles(ctx.Config(), bp2build.CreateCodegenMetrics())
+	soongInjectionFiles := bp2build.CreateSoongInjectionDirFiles(codegenContext, bp2build.CreateCodegenMetrics())
 	absoluteSoongInjectionDir := shared.JoinPath(topDir, ctx.Config().SoongOutDir(), bazel.SoongInjectionDirName)
 	for _, file := range soongInjectionFiles {
 		// The API targets in api_bp2build workspace do not have any dependency on api_bp2build.
diff --git a/filesystem/Android.bp b/filesystem/Android.bp
index dfcd405..07d57c9 100644
--- a/filesystem/Android.bp
+++ b/filesystem/Android.bp
@@ -13,6 +13,7 @@
     ],
     srcs: [
         "avb_add_hash_footer.go",
+        "avb_gen_vbmeta_image.go",
         "bootimg.go",
         "filesystem.go",
         "logical_partition.go",
diff --git a/filesystem/avb_add_hash_footer.go b/filesystem/avb_add_hash_footer.go
index 2ee420c..f3fecd0 100644
--- a/filesystem/avb_add_hash_footer.go
+++ b/filesystem/avb_add_hash_footer.go
@@ -67,6 +67,9 @@
 
 	// List of properties to add to the footer
 	Props []avbProp
+
+	// Include descriptors from images
+	Include_descriptors_from_images []string `android:"path,arch_variant"`
 }
 
 // The AVB footer adds verification information to the image.
@@ -116,6 +119,11 @@
 	}
 	cmd.FlagWithArg("--salt ", proptools.String(a.properties.Salt))
 
+	imagePaths := android.PathsForModuleSrc(ctx, a.properties.Include_descriptors_from_images)
+	for _, imagePath := range imagePaths {
+		cmd.FlagWithInput("--include_descriptors_from_image ", imagePath)
+	}
+
 	for _, prop := range a.properties.Props {
 		addAvbProp(ctx, cmd, prop)
 	}
diff --git a/filesystem/avb_gen_vbmeta_image.go b/filesystem/avb_gen_vbmeta_image.go
new file mode 100644
index 0000000..0f331f9
--- /dev/null
+++ b/filesystem/avb_gen_vbmeta_image.go
@@ -0,0 +1,108 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// 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 filesystem
+
+import (
+	"fmt"
+
+	"github.com/google/blueprint/proptools"
+
+	"android/soong/android"
+)
+
+type avbGenVbmetaImage struct {
+	android.ModuleBase
+
+	properties avbGenVbmetaImageProperties
+
+	output     android.OutputPath
+	installDir android.InstallPath
+}
+
+type avbGenVbmetaImageProperties struct {
+	// Source file of this image. Can reference a genrule type module with the ":module" syntax.
+	Src *string `android:"path,arch_variant"`
+
+	// Name of the image partition. Defaults to the name of this module.
+	Partition_name *string
+
+	// The salt in hex. Required for reproducible builds.
+	Salt *string
+}
+
+// The avbGenVbmetaImage generates an unsigned VBMeta image output for the given image.
+func avbGenVbmetaImageFactory() android.Module {
+	module := &avbGenVbmetaImage{}
+	module.AddProperties(&module.properties)
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+	return module
+}
+
+func (a *avbGenVbmetaImage) installFileName() string {
+	return a.Name() + ".img"
+}
+
+func (a *avbGenVbmetaImage) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	builder := android.NewRuleBuilder(pctx, ctx)
+	cmd := builder.Command().BuiltTool("avbtool").Text("add_hash_footer")
+	cmd.Flag("--dynamic_partition_size")
+	cmd.Flag("--do_not_append_vbmeta_image")
+
+	partition_name := proptools.StringDefault(a.properties.Partition_name, a.Name())
+	cmd.FlagWithArg("--partition_name ", partition_name)
+
+	if a.properties.Src == nil {
+		ctx.PropertyErrorf("src", "missing source file")
+		return
+	}
+	input := android.PathForModuleSrc(ctx, proptools.String(a.properties.Src))
+	cmd.FlagWithInput("--image ", input)
+
+	if a.properties.Salt == nil {
+		ctx.PropertyErrorf("salt", "missing salt value")
+		return
+	}
+	cmd.FlagWithArg("--salt ", proptools.String(a.properties.Salt))
+
+	a.output = android.PathForModuleOut(ctx, a.installFileName()).OutputPath
+	cmd.FlagWithOutput("--output_vbmeta_image ", a.output)
+	builder.Build("avbGenVbmetaImage", fmt.Sprintf("avbGenVbmetaImage %s", ctx.ModuleName()))
+}
+
+var _ android.AndroidMkEntriesProvider = (*avbGenVbmetaImage)(nil)
+
+// Implements android.AndroidMkEntriesProvider
+func (a *avbGenVbmetaImage) AndroidMkEntries() []android.AndroidMkEntries {
+	return []android.AndroidMkEntries{android.AndroidMkEntries{
+		Class:      "ETC",
+		OutputFile: android.OptionalPathForPath(a.output),
+		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+				entries.SetString("LOCAL_MODULE_PATH", a.installDir.String())
+				entries.SetString("LOCAL_INSTALLED_MODULE_STEM", a.installFileName())
+			},
+		},
+	}}
+}
+
+var _ android.OutputFileProducer = (*avbGenVbmetaImage)(nil)
+
+// Implements android.OutputFileProducer
+func (a *avbGenVbmetaImage) OutputFiles(tag string) (android.Paths, error) {
+	if tag == "" {
+		return []android.Path{a.output}, nil
+	}
+	return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index d01608f..25b8fe8 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -35,6 +35,7 @@
 	ctx.RegisterModuleType("android_filesystem", filesystemFactory)
 	ctx.RegisterModuleType("android_system_image", systemImageFactory)
 	ctx.RegisterModuleType("avb_add_hash_footer", avbAddHashFooterFactory)
+	ctx.RegisterModuleType("avb_gen_vbmeta_image", avbGenVbmetaImageFactory)
 }
 
 type filesystem struct {
@@ -69,10 +70,11 @@
 	// TODO(jiyong): allow apex_key to be specified here
 	Avb_private_key *string `android:"path"`
 
-	// Hash and signing algorithm for avbtool. Default is SHA256_RSA4096.
+	// Signing algorithm for avbtool. Default is SHA256_RSA4096.
 	Avb_algorithm *string
 
-	// Hash and signing algorithm for avbtool. Default is SHA256_RSA4096.
+	// Hash algorithm used for avbtool (for descriptors). This is passed as hash_algorithm to
+	// avbtool. Default used by avbtool is sha1.
 	Avb_hash_algorithm *string
 
 	// Name of the partition stored in vbmeta desc. Defaults to the name of this module.
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 9bfcc3d..444ffd0 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -126,8 +126,34 @@
 	android.AssertDeepEquals(t, "entries should have foo only", []string{"components/foo"}, module.entries)
 }
 
+func TestAvbGenVbmetaImage(t *testing.T) {
+	result := fixture.RunTestWithBp(t, `
+		avb_gen_vbmeta_image {
+			name: "input_hashdesc",
+			src: "input.img",
+			partition_name: "input_partition_name",
+			salt: "2222",
+		}`)
+	cmd := result.ModuleForTests("input_hashdesc", "android_arm64_armv8-a").Rule("avbGenVbmetaImage").RuleParams.Command
+	android.AssertStringDoesContain(t, "Can't find correct --partition_name argument",
+		cmd, "--partition_name input_partition_name")
+	android.AssertStringDoesContain(t, "Can't find --do_not_append_vbmeta_image",
+		cmd, "--do_not_append_vbmeta_image")
+	android.AssertStringDoesContain(t, "Can't find --output_vbmeta_image",
+		cmd, "--output_vbmeta_image ")
+	android.AssertStringDoesContain(t, "Can't find --salt argument",
+		cmd, "--salt 2222")
+}
+
 func TestAvbAddHashFooter(t *testing.T) {
 	result := fixture.RunTestWithBp(t, `
+		avb_gen_vbmeta_image {
+			name: "input_hashdesc",
+			src: "input.img",
+			partition_name: "input",
+			salt: "2222",
+		}
+
 		avb_add_hash_footer {
 			name: "myfooter",
 			src: "input.img",
@@ -145,6 +171,7 @@
 					file: "value_file",
 				},
 			],
+			include_descriptors_from_images: ["input_hashdesc"],
 		}
 	`)
 	cmd := result.ModuleForTests("myfooter", "android_arm64_armv8-a").Rule("avbAddHashFooter").RuleParams.Command
@@ -158,4 +185,6 @@
 		cmd, "--prop 'prop1:value1'")
 	android.AssertStringDoesContain(t, "Can't find --prop_from_file argument",
 		cmd, "--prop_from_file 'prop2:value_file'")
+	android.AssertStringDoesContain(t, "Can't find --include_descriptors_from_image",
+		cmd, "--include_descriptors_from_image ")
 }
diff --git a/go.mod b/go.mod
index 7239f6d..a5d9dd5 100644
--- a/go.mod
+++ b/go.mod
@@ -1,21 +1,9 @@
 module android/soong
 
+go 1.19
+
 require (
-  google.golang.org/protobuf v0.0.0
-  github.com/google/blueprint v0.0.0
-  prebuilts/bazel/common/proto/analysis_v2 v0.0.0
-  prebuilts/bazel/common/proto/build v0.0.0 // indirect
+	github.com/google/blueprint v0.0.0
+	google.golang.org/protobuf v0.0.0
+	prebuilts/bazel/common/proto/analysis_v2 v0.0.0
 )
-
-replace (
-  google.golang.org/protobuf v0.0.0 => ../../external/golang-protobuf
-  github.com/google/blueprint v0.0.0 => ../blueprint
-  github.com/google/go-cmp v0.5.5 => ../../external/go-cmp
-  prebuilts/bazel/common/proto/analysis_v2 => ../../prebuilts/bazel/common/proto/analysis_v2
-  prebuilts/bazel/common/proto/build => ../../prebuilts/bazel/common/proto/build
-)
-
-// Indirect deps from golang-protobuf
-exclude github.com/golang/protobuf v1.5.0
-
-go 2.0
diff --git a/go.work b/go.work
new file mode 100644
index 0000000..737a9df
--- /dev/null
+++ b/go.work
@@ -0,0 +1,19 @@
+go 1.19
+
+use (
+	.
+	../../external/go-cmp
+	../../external/golang-protobuf
+	../../prebuilts/bazel/common/proto/analysis_v2
+	../../prebuilts/bazel/common/proto/build
+	../blueprint
+)
+
+replace (
+	github.com/golang/protobuf v0.0.0 => ../../external/golang-protobuf
+	github.com/google/blueprint v0.0.0 => ../blueprint
+	github.com/google/go-cmp v0.0.0 => ../../external/go-cmp
+	google.golang.org/protobuf v0.0.0 => ../../external/golang-protobuf
+	prebuilts/bazel/common/proto/analysis_v2 v0.0.0 => ../../prebuilts/bazel/common/proto/analysis_v2
+	prebuilts/bazel/common/proto/build v0.0.0 => ../../prebuilts/bazel/common/proto/build
+)
diff --git a/java/app.go b/java/app.go
index df6698d..845f850 100755
--- a/java/app.go
+++ b/java/app.go
@@ -315,10 +315,6 @@
 		}
 	}
 
-	if Bool(a.appProperties.Enforce_default_target_sdk_version) {
-		a.SetEnforceDefaultTargetSdkVersion(true)
-	}
-
 	a.checkPlatformAPI(ctx)
 	a.checkSdkVersions(ctx)
 }
@@ -639,6 +635,11 @@
 		a.aapt.noticeFile = android.OptionalPathForPath(noticeAssetPath)
 	}
 
+	// For apps targeting latest target_sdk_version
+	if Bool(a.appProperties.Enforce_default_target_sdk_version) {
+		a.SetEnforceDefaultTargetSdkVersion(true)
+	}
+
 	// Process all building blocks, from AAPT to certificates.
 	a.aaptBuildActions(ctx)
 
@@ -800,6 +801,8 @@
 						unstrippedFile: dep.UnstrippedOutputFile(),
 						partition:      dep.Partition(),
 					})
+				} else if ctx.Config().AllowMissingDependencies() {
+					ctx.AddMissingDependencies([]string{otherName})
 				} else {
 					ctx.ModuleErrorf("dependency %q missing output file", otherName)
 				}
diff --git a/java/app_test.go b/java/app_test.go
index bc971e3..3fb67c1 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -3163,6 +3163,7 @@
 				variables.Platform_sdk_version = &platform_sdk_version
 				variables.Platform_sdk_codename = &platform_sdk_codename
 				variables.Platform_version_active_codenames = []string{platform_sdk_codename}
+				variables.Unbundled_build = proptools.BoolPtr(true)
 				variables.Unbundled_build_apps = []string{"sampleModule"}
 			}),
 		)
@@ -3203,7 +3204,7 @@
 			updatable:                      true,
 		},
 		{
-			name:                           "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
+			name:                           "Enforce Target SDK Version: Android.bp has current targetSdkVersion",
 			enforceDefaultTargetSdkVersion: true,
 			platform_sdk_final:             false,
 			targetSdkVersionInBp:           "current",
@@ -3241,6 +3242,78 @@
 				variables.Platform_sdk_final = &testCase.platform_sdk_final
 				variables.Platform_sdk_version = &platform_sdk_version
 				variables.Platform_sdk_codename = &platform_sdk_codename
+				variables.Unbundled_build = proptools.BoolPtr(true)
+				variables.Unbundled_build_apps = []string{"sampleModule"}
+			}),
+		)
+
+		errorHandler := android.FixtureExpectsNoErrors
+		if errExpected {
+			errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
+		}
+		result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
+
+		if !errExpected {
+			foo := result.ModuleForTests("foo", "android_common")
+			manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
+			android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion  "+testCase.targetSdkVersionExpected)
+		}
+	}
+}
+
+func TestEnforceDefaultAppTargetSdkVersionFlagForTests(t *testing.T) {
+	platform_sdk_codename := "Tiramisu"
+	platform_sdk_version := 33
+	testCases := []struct {
+		name                           string
+		enforceDefaultTargetSdkVersion bool
+		expectedError                  string
+		platform_sdk_final             bool
+		targetSdkVersionInBp           string
+		targetSdkVersionExpected       string
+	}{
+		{
+			name:                           "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
+			enforceDefaultTargetSdkVersion: false,
+			targetSdkVersionInBp:           "29",
+			targetSdkVersionExpected:       "29",
+		},
+		{
+			name:                           "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
+			enforceDefaultTargetSdkVersion: true,
+			platform_sdk_final:             true,
+			targetSdkVersionInBp:           "current",
+			targetSdkVersionExpected:       "33",
+		},
+		{
+			name:                           "Enforce Target SDK Version: Android.bp has current targetSdkVersion",
+			enforceDefaultTargetSdkVersion: true,
+			platform_sdk_final:             false,
+			targetSdkVersionInBp:           "current",
+			targetSdkVersionExpected:       "10000",
+		},
+	}
+	for _, testCase := range testCases {
+		errExpected := testCase.expectedError != ""
+		bp := fmt.Sprintf(`
+			android_test {
+				name: "foo",
+				enforce_default_target_sdk_version: %t,
+				min_sdk_version: "29",
+				target_sdk_version: "%v",
+			}
+		`, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp)
+
+		fixture := android.GroupFixturePreparers(
+			PrepareForTestWithJavaDefaultModules,
+			android.PrepareForTestWithAllowMissingDependencies,
+			android.PrepareForTestWithAndroidMk,
+			android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+				// explicitly set following platform variables to make the test deterministic
+				variables.Platform_sdk_final = &testCase.platform_sdk_final
+				variables.Platform_sdk_version = &platform_sdk_version
+				variables.Platform_sdk_codename = &platform_sdk_codename
+				variables.Unbundled_build = proptools.BoolPtr(true)
 				variables.Unbundled_build_apps = []string{"sampleModule"}
 			}),
 		)
diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp
index bfd5cf8..4fb1d76 100644
--- a/java/core-libraries/Android.bp
+++ b/java/core-libraries/Android.bp
@@ -301,3 +301,76 @@
         "core-generated-annotation-stubs",
     ],
 }
+
+// Used when compiling higher-level code against art.module.public.api.stubs.
+// This abstraction should come from the inner tree linking against the stubs
+// and not from an "sdk", since parts of this abstraction do not belong to an
+// official API (e.g. stub-annotations).
+//
+// This is only intended for use within core libraries and must not be used
+// from outside.
+java_system_modules {
+    name: "art-module-public-api-stubs-system-modules",
+    visibility: [
+        "//art/build/sdk",
+        "//external/conscrypt",
+        "//external/icu/android_icu4j",
+        "//external/wycheproof",
+    ],
+    libs: [
+        "art.module.public.api.stubs",
+        // This one is not on device but it's needed when javac compiles code
+        // containing lambdas.
+        "core-lambda-stubs-for-system-modules",
+        // This one is not on device but it's needed when javac compiles code
+        // containing @Generated annotations produced by some code generation
+        // tools.
+        // See http://b/123891440.
+        "core-generated-annotation-stubs",
+
+        // Ensure that core libraries that depend on the public API can access
+        // the UnsupportedAppUsage, CorePlatformApi and IntraCoreApi
+        // annotations.
+        "art.module.api.annotations.for.system.modules",
+
+        // Make nullability annotations available when compiling public stubs.
+        // They are provided as a separate library because while the
+        // annotations are not themselves part of the public API provided by
+        // this module they are used in the stubs.
+        "stub-annotations",
+    ],
+}
+
+// Used when compiling higher-level code against art.module.public.api.stubs.module_lib.
+//
+// This is only intended for use within core libraries and must not be used
+// from outside.
+java_system_modules {
+    name: "art-module-lib-api-stubs-system-modules",
+    visibility: [
+        "//art/build/sdk",
+        "//external/conscrypt",
+        "//external/icu/android_icu4j",
+    ],
+    libs: [
+        "art.module.public.api.stubs.module_lib",
+    ],
+}
+
+// Used when compiling against art.module.intra.core.api.stubs.
+java_system_modules {
+    name: "art-module-intra-core-api-stubs-system-modules",
+    visibility: [
+        "//art/build/sdk",
+        "//external/bouncycastle",
+        "//external/conscrypt",
+        "//external/icu/android_icu4j",
+    ],
+    libs: [
+        // The intra core API stubs library.
+        "art.module.intra.core.api.stubs",
+
+        // Additional classes needed by javac but which are not present in the stubs.
+        "art-module-intra-core-api-stubs-system-modules-lib",
+    ],
+}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 066f0d6..4bbe70a 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -877,6 +877,7 @@
 		"module_lib":    android.SdkModule,
 		"module-lib":    android.SdkModule,
 		"test":          android.SdkTest,
+		"toolchain":     android.SdkToolchain,
 	}
 )
 
diff --git a/java/jdeps.go b/java/jdeps.go
index 3734335..a52b867 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -52,6 +52,11 @@
 			return
 		}
 
+		// Prevent including both prebuilts and matching source modules when one replaces the other.
+		if !android.IsModulePreferred(module) {
+			return
+		}
+
 		ideInfoProvider, ok := module.(android.IDEInfo)
 		if !ok {
 			return
diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt
index 519a702..061f4d0 100644
--- a/java/lint_defaults.txt
+++ b/java/lint_defaults.txt
@@ -1,5 +1,10 @@
 # Treat LintError as fatal to catch invocation errors
 --fatal_check LintError
+# ObsoleteLintCustomCheck is a warning by default, but lint ignores the
+# checks from the subject jar if this issue is raised.
+# This should be an error for AOSP. If we create a check, we expect it
+# to run, otherwise we want an error.
+--fatal_check ObsoleteLintCustomCheck
 
 # Checks which do not apply to the platform (implementation
 # in lint assumes that it's running on app code)
diff --git a/scripts/conv_linker_config.py b/scripts/conv_linker_config.py
index e46efe4..3d7c0fa 100644
--- a/scripts/conv_linker_config.py
+++ b/scripts/conv_linker_config.py
@@ -27,13 +27,15 @@
 
 
 def Proto(args):
-    json_content = ''
-    with open(args.source) as f:
-        for line in f:
-            if not line.lstrip().startswith('//'):
-                json_content += line
-    obj = json.loads(json_content, object_pairs_hook=collections.OrderedDict)
-    pb = ParseDict(obj, linker_config_pb2.LinkerConfig())
+    pb = linker_config_pb2.LinkerConfig()
+    for input in args.source.split(':'):
+        json_content = ''
+        with open(input) as f:
+            for line in f:
+                if not line.lstrip().startswith('//'):
+                    json_content += line
+        obj = json.loads(json_content, object_pairs_hook=collections.OrderedDict)
+        ParseDict(obj, pb)
     with open(args.output, 'wb') as f:
         f.write(pb.SerializeToString())
 
@@ -104,7 +106,7 @@
         '--source',
         required=True,
         type=str,
-        help='Source linker configuration file in JSON.')
+        help='Colon-separated list of linker configuration files in JSON.')
     parser_proto.add_argument(
         '-o',
         '--output',
diff --git a/tests/androidmk_test.sh b/tests/androidmk_test.sh
index d0d382b..b81828b 100755
--- a/tests/androidmk_test.sh
+++ b/tests/androidmk_test.sh
@@ -133,6 +133,4 @@
   echo "Succeeded"
 }
 
-test_rewrite_license_property_inside_current_directory
-
-test_rewrite_license_property_outside_current_directory
+scan_and_run_tests
diff --git a/tests/apex_cc_module_arch_variant_tests.sh b/tests/apex_cc_module_arch_variant_tests.sh
index a514762..97e6576 100755
--- a/tests/apex_cc_module_arch_variant_tests.sh
+++ b/tests/apex_cc_module_arch_variant_tests.sh
@@ -62,7 +62,7 @@
 all_cppcompile_actions_num=0
 aquery_summary=$(call_bazel aquery --config=bp2build --config=ci --config=android --output=summary \
   'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal.apex))' \
-  | egrep -o '.*android_target.*: ([0-9]+)$' \
+  | egrep -o '.*opt-ST.*: ([0-9]+)$' \
   | cut -d: -f2 -)
 
 while read -r num;
@@ -74,7 +74,7 @@
 then
   echo "Pass: arch variant is set."
 else
-  echo "Error: number of CppCompile actions with arch variant set: actual=actions_with_arch_variant_num, expected=$all_cppcompile_actions_num"
+  echo "Error: number of CppCompile actions with arch variant set: actual=$actions_with_arch_variant_num, expected=$all_cppcompile_actions_num"
   exit 1
 fi
 
diff --git a/tests/apex_comparison_tests.sh b/tests/apex_comparison_tests.sh
index 412f84a..5007078 100755
--- a/tests/apex_comparison_tests.sh
+++ b/tests/apex_comparison_tests.sh
@@ -74,7 +74,7 @@
 # # Build debugfs separately, as it's not a dep of apexer, but needs to be an explicit arg.
 call_bazel build --config=bp2build --config=linux_x86_64 //external/e2fsprogs/debugfs //system/apex/tools:deapexer
 DEBUGFS_PATH="$(realpath $(call_bazel cquery --config=bp2build --config=linux_x86_64 --config=ci --output=files //external/e2fsprogs/debugfs))"
-DEAPEXER="$(realpath $(call_bazel cquery --config=bp2build --config=linux_x86_64 --config=ci --output=files //system/apex/tools:deapexer))"
+DEAPEXER="bazel-bin/system/apex/tools/deapexer"
 DEAPEXER="$DEAPEXER --debugfs_path=$DEBUGFS_PATH"
 
 #######
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
index 8c2ce48..6477dac 100755
--- a/tests/bp2build_bazel_test.sh
+++ b/tests/bp2build_bazel_test.sh
@@ -231,4 +231,11 @@
   fi
 }
 
+# Smoke test to verify api_bp2build worksapce does not contain any errors
+function test_api_bp2build_empty_build() {
+  setup
+  run_soong api_bp2build
+  run_bazel build --config=android --config=api_bp2build //:empty
+}
+
 scan_and_run_tests
diff --git a/tests/mixed_mode_test.sh b/tests/mixed_mode_test.sh
index 8949b42..7b3151b 100755
--- a/tests/mixed_mode_test.sh
+++ b/tests/mixed_mode_test.sh
@@ -63,5 +63,4 @@
   fi
 }
 
-test_add_irrelevant_file
-test_bazel_smoke
+scan_and_run_tests
\ No newline at end of file
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index d0eb4f9..eb76a46 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -17,4 +17,4 @@
 
 "$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh"
 "$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_arm" "armv7-a"
-"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_cf_arm64_phone" "armv8-a" "cortex-a53"
+"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_cf_arm64_phone" "armv8-a" "cortex-a53"
\ No newline at end of file
diff --git a/tests/soong_test.sh b/tests/soong_test.sh
index 905d708..f7bee40 100755
--- a/tests/soong_test.sh
+++ b/tests/soong_test.sh
@@ -19,4 +19,4 @@
   run_soong clean
 }
 
-test_m_clean_works
+scan_and_run_tests
\ No newline at end of file
diff --git a/ui/build/config.go b/ui/build/config.go
index 61f6b1c..b928faa 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -204,16 +204,11 @@
 	return nil
 }
 
-func loadEnvConfig(ctx Context, config *configImpl) error {
-	bc := os.Getenv("ANDROID_BUILD_ENVIRONMENT_CONFIG")
+func loadEnvConfig(ctx Context, config *configImpl, bc string) error {
 	if bc == "" {
 		return nil
 	}
 
-	if err := fetchEnvConfig(ctx, config, bc); err != nil {
-		ctx.Verbosef("Failed to fetch config file: %v\n", err)
-	}
-
 	configDirs := []string{
 		config.OutDir(),
 		os.Getenv("ANDROID_BUILD_ENVIRONMENT_CONFIG_DIR"),
@@ -262,6 +257,12 @@
 		environ:       OsEnvironment(),
 		sandboxConfig: &SandboxConfig{},
 	}
+	srcDir := absPath(ctx, ".")
+	bc := os.Getenv("ANDROID_BUILD_ENVIRONMENT_CONFIG")
+	if err := loadEnvConfig(ctx, ret, bc); err != nil {
+		ctx.Fatalln("Failed to parse env config files: %v", err)
+	}
+	ret.metricsUploader = GetMetricsUploader(srcDir, ret.environ)
 	return Config{ret}
 }
 
@@ -294,8 +295,15 @@
 
 	// loadEnvConfig needs to know what the OUT_DIR is, so it should
 	// be called after we determine the appropriate out directory.
-	if err := loadEnvConfig(ctx, ret); err != nil {
-		ctx.Fatalln("Failed to parse env config files: %v", err)
+	bc := os.Getenv("ANDROID_BUILD_ENVIRONMENT_CONFIG")
+
+	if bc != "" {
+		if err := fetchEnvConfig(ctx, ret, bc); err != nil {
+			ctx.Verbosef("Failed to fetch config file: %v\n", err)
+
+		} else if err := loadEnvConfig(ctx, ret, bc); err != nil {
+			ctx.Fatalln("Failed to parse env config files: %v", err)
+		}
 	}
 
 	if distDir, ok := ret.environ.Get("DIST_DIR"); ok {
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 370b1bc..e6543ec 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -15,16 +15,13 @@
 package build
 
 import (
-	"errors"
 	"fmt"
-	"io/fs"
 	"os"
 	"path/filepath"
 	"strconv"
 	"strings"
 
 	"android/soong/ui/metrics"
-	soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
 	"android/soong/ui/status"
 
 	"android/soong/shared"
@@ -32,8 +29,6 @@
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/microfactory"
-
-	"google.golang.org/protobuf/proto"
 )
 
 const (
@@ -566,22 +561,6 @@
 		targets = append(targets, config.SoongNinjaFile())
 	}
 
-	// TODO(juu): Stop embedding soong_build_metrics in soong_metrics.
-	soongBuildMetricsFile := filepath.Join(config.LogsDir(), "soong_build_metrics.pb")
-	if err := os.Remove(soongBuildMetricsFile); err != nil && !os.IsNotExist(err) {
-		ctx.Verbosef("Failed to remove %s", soongBuildMetricsFile)
-	}
-	if shouldCollectBuildSoongMetrics(config) {
-		defer func() {
-			soongBuildMetrics := loadSoongBuildMetrics(ctx, soongBuildMetricsFile)
-			if soongBuildMetrics != nil {
-				logSoongBuildMetrics(ctx, soongBuildMetrics)
-				if ctx.Metrics != nil {
-					ctx.Metrics.SetSoongBuildMetrics(soongBuildMetrics)
-				}
-			}
-		}()
-	}
 	ninja("bootstrap", "bootstrap.ninja", targets...)
 
 	distGzipFile(ctx, config, config.SoongNinjaFile(), "soong")
@@ -614,36 +593,3 @@
 		ctx.Fatalf("failed to build %s: %s", name, err)
 	}
 }
-
-func shouldCollectBuildSoongMetrics(config Config) bool {
-	// Do not collect metrics protobuf if the soong_build binary ran as the
-	// bp2build converter or the JSON graph dump.
-	return config.SoongBuildInvocationNeeded()
-}
-
-func loadSoongBuildMetrics(ctx Context, soongBuildMetricsFile string) *soong_metrics_proto.SoongBuildMetrics {
-	buf, err := os.ReadFile(soongBuildMetricsFile)
-	if errors.Is(err, fs.ErrNotExist) {
-		// Soong may not have run during this invocation
-		ctx.Verbosef("Failed to read metrics file, %s: %s", soongBuildMetricsFile, err)
-		return nil
-	} else if err != nil {
-		ctx.Fatalf("Failed to load %s: %s", soongBuildMetricsFile, err)
-	}
-	soongBuildMetrics := &soong_metrics_proto.SoongBuildMetrics{}
-	err = proto.Unmarshal(buf, soongBuildMetrics)
-	if err != nil {
-		ctx.Fatalf("Failed to unmarshal %s: %s", soongBuildMetricsFile, err)
-	}
-	return soongBuildMetrics
-}
-
-func logSoongBuildMetrics(ctx Context, metrics *soong_metrics_proto.SoongBuildMetrics) {
-	ctx.Verbosef("soong_build metrics:")
-	ctx.Verbosef(" modules: %v", metrics.GetModules())
-	ctx.Verbosef(" variants: %v", metrics.GetVariants())
-	ctx.Verbosef(" max heap size: %v MB", metrics.GetMaxHeapSize()/1e6)
-	ctx.Verbosef(" total allocation count: %v", metrics.GetTotalAllocCount())
-	ctx.Verbosef(" total allocation size: %v MB", metrics.GetTotalAllocSize()/1e6)
-
-}
diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go
index 90d124b..eb8fdc4 100644
--- a/ui/metrics/metrics_proto/metrics.pb.go
+++ b/ui/metrics/metrics_proto/metrics.pb.go
@@ -15,7 +15,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.28.0
-// 	protoc        v3.9.1
+// 	protoc        v3.21.7
 // source: metrics.proto
 
 package metrics_proto
@@ -325,7 +325,11 @@
 	// The metrics for calling Ninja.
 	NinjaRuns []*PerfInfo `protobuf:"bytes,20,rep,name=ninja_runs,json=ninjaRuns" json:"ninja_runs,omitempty"`
 	// The metrics for the whole build
-	Total             *PerfInfo          `protobuf:"bytes,21,opt,name=total" json:"total,omitempty"`
+	Total *PerfInfo `protobuf:"bytes,21,opt,name=total" json:"total,omitempty"`
+	// Deprecated because instead of embedding in a MetricsBase, we keep
+	// SoongBuildMetrics in its own file
+	//
+	// Deprecated: Do not use.
 	SoongBuildMetrics *SoongBuildMetrics `protobuf:"bytes,22,opt,name=soong_build_metrics,json=soongBuildMetrics" json:"soong_build_metrics,omitempty"`
 	BuildConfig       *BuildConfig       `protobuf:"bytes,23,opt,name=build_config,json=buildConfig" json:"build_config,omitempty"`
 	// The hostname of the machine.
@@ -533,6 +537,7 @@
 	return nil
 }
 
+// Deprecated: Do not use.
 func (x *MetricsBase) GetSoongBuildMetrics() *SoongBuildMetrics {
 	if x != nil {
 		return x.SoongBuildMetrics
@@ -1409,7 +1414,7 @@
 var file_metrics_proto_rawDesc = []byte{
 	0x0a, 0x0d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
 	0x13, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x73, 0x22, 0xf6, 0x0d, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+	0x72, 0x69, 0x63, 0x73, 0x22, 0xfa, 0x0d, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
 	0x42, 0x61, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x61,
 	0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01,
 	0x28, 0x03, 0x52, 0x12, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d,
@@ -1480,195 +1485,195 @@
 	0x75, 0x6e, 0x73, 0x12, 0x33, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x15, 0x20, 0x01,
 	0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64,
 	0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66,
-	0x6f, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x56, 0x0a, 0x13, 0x73, 0x6f, 0x6f, 0x6e,
+	0x6f, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x5a, 0x0a, 0x13, 0x73, 0x6f, 0x6f, 0x6e,
 	0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18,
 	0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
 	0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x6f, 0x6f, 0x6e,
-	0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x11, 0x73,
-	0x6f, 0x6f, 0x6e, 0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
-	0x12, 0x43, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62,
-	0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x42, 0x75, 0x69,
-	0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d,
-	0x65, 0x12, 0x59, 0x0a, 0x14, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x6f,
-	0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x27, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65,
-	0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x6f,
-	0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
-	0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x0a, 0x0d,
-	0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x1a, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
-	0x64, 0x12, 0x3c, 0x0a, 0x0a, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x72, 0x75, 0x6e, 0x73, 0x18,
-	0x1b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
-	0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66,
-	0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x52, 0x75, 0x6e, 0x73, 0x12,
-	0x53, 0x0a, 0x12, 0x65, 0x78, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x66, 0x65,
-	0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x6f,
-	0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
-	0x73, 0x2e, 0x45, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65, 0x74, 0x63, 0x68,
-	0x65, 0x72, 0x52, 0x10, 0x65, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65, 0x74,
-	0x63, 0x68, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x6f, 0x6e, 0x5f, 0x7a, 0x65, 0x72, 0x6f,
-	0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6e, 0x6f, 0x6e,
-	0x5a, 0x65, 0x72, 0x6f, 0x45, 0x78, 0x69, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f,
-	0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x30, 0x0a,
-	0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x08, 0x0a,
-	0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x53, 0x45, 0x52, 0x44,
-	0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x45, 0x4e, 0x47, 0x10, 0x02, 0x22,
-	0x3c, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f,
-	0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x52, 0x4d, 0x10, 0x01, 0x12, 0x09, 0x0a,
-	0x05, 0x41, 0x52, 0x4d, 0x36, 0x34, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x58, 0x38, 0x36, 0x10,
-	0x03, 0x12, 0x0a, 0x0a, 0x06, 0x58, 0x38, 0x36, 0x5f, 0x36, 0x34, 0x10, 0x04, 0x22, 0x99, 0x02,
-	0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a,
-	0x08, 0x75, 0x73, 0x65, 0x5f, 0x67, 0x6f, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
-	0x07, 0x75, 0x73, 0x65, 0x47, 0x6f, 0x6d, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x5f,
-	0x72, 0x62, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x75, 0x73, 0x65, 0x52, 0x62,
-	0x65, 0x12, 0x24, 0x0a, 0x0e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x5f, 0x67,
-	0x6f, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x6f, 0x72, 0x63, 0x65,
-	0x55, 0x73, 0x65, 0x47, 0x6f, 0x6d, 0x61, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x61, 0x7a, 0x65, 0x6c,
-	0x5f, 0x61, 0x73, 0x5f, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
-	0x0c, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x41, 0x73, 0x4e, 0x69, 0x6e, 0x6a, 0x61, 0x12, 0x2a, 0x0a,
-	0x11, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69,
-	0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x4d,
-	0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x72,
-	0x67, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x72, 0x67,
-	0x65, 0x74, 0x73, 0x12, 0x44, 0x0a, 0x1f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x69, 0x73,
-	0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d, 0x69, 0x78, 0x65, 0x64,
-	0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x66, 0x6f,
-	0x72, 0x63, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x61, 0x7a, 0x65, 0x6c, 0x4d,
-	0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x22, 0x6f, 0x0a, 0x12, 0x53, 0x79, 0x73,
-	0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12,
-	0x32, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61,
-	0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13,
-	0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x4d, 0x65, 0x6d,
-	0x6f, 0x72, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65,
-	0x5f, 0x63, 0x70, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x76, 0x61,
-	0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x70, 0x75, 0x73, 0x22, 0xca, 0x02, 0x0a, 0x08, 0x50,
-	0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
-	0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,
-	0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a,
-	0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x04, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09,
-	0x72, 0x65, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52,
-	0x08, 0x72, 0x65, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0a, 0x6d, 0x65, 0x6d,
-	0x6f, 0x72, 0x79, 0x5f, 0x75, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x18,
-	0x01, 0x52, 0x09, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x17,
-	0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
-	0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e,
-	0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72,
-	0x69, 0x63, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75,
-	0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x15, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
-	0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22,
-	0x0a, 0x0d, 0x6e, 0x6f, 0x6e, 0x5f, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18,
-	0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6e, 0x6f, 0x6e, 0x5a, 0x65, 0x72, 0x6f, 0x45, 0x78,
-	0x69, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72,
-	0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb9, 0x03, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x63,
-	0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12,
-	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
-	0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65,
-	0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x75,
-	0x73, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x2c, 0x0a,
-	0x12, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63,
-	0x72, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x73, 0x79, 0x73, 0x74, 0x65,
-	0x6d, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x1c, 0x0a, 0x0a, 0x6d,
-	0x61, 0x78, 0x5f, 0x72, 0x73, 0x73, 0x5f, 0x6b, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52,
-	0x08, 0x6d, 0x61, 0x78, 0x52, 0x73, 0x73, 0x4b, 0x62, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x69, 0x6e,
-	0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x05,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46,
-	0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x70,
-	0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04,
-	0x52, 0x0f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74,
-	0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x69, 0x6f, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62,
-	0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4b,
-	0x62, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x6f, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6b,
-	0x62, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x69, 0x6f, 0x4f, 0x75, 0x74, 0x70, 0x75,
-	0x74, 0x4b, 0x62, 0x12, 0x3c, 0x0a, 0x1a, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79,
-	0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65,
-	0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61,
-	0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65,
-	0x73, 0x12, 0x40, 0x0a, 0x1c, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79,
-	0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65,
-	0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e,
-	0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63,
-	0x68, 0x65, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79,
-	0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x5b, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
-	0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x73,
-	0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69,
-	0x63, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e, 0x66,
-	0x6f, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x3a, 0x07, 0x55,
-	0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73,
-	0x74, 0x65, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79,
-	0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
-	0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x75, 0x6d, 0x5f, 0x6f, 0x66, 0x5f, 0x6d,
-	0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6e, 0x75,
-	0x6d, 0x4f, 0x66, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x2f, 0x0a, 0x0b, 0x42, 0x75,
-	0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b,
-	0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x4f, 0x4f, 0x4e, 0x47, 0x10,
-	0x01, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x41, 0x4b, 0x45, 0x10, 0x02, 0x22, 0x6c, 0x0a, 0x1a, 0x43,
-	0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e,
-	0x65, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a,
-	0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20,
-	0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x61, 0x73, 0x65,
-	0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x62, 0x0a, 0x1b, 0x43, 0x72, 0x69,
-	0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79,
-	0x73, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x43, 0x0a, 0x04, 0x63, 0x75, 0x6a, 0x73,
-	0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62,
-	0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x43, 0x72, 0x69,
-	0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79,
-	0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x04, 0x63, 0x75, 0x6a, 0x73, 0x22, 0xcc, 0x02,
-	0x0a, 0x11, 0x53, 0x6f, 0x6f, 0x6e, 0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72,
-	0x69, 0x63, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a,
-	0x08, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
-	0x08, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x6f, 0x74,
-	0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63,
-	0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61,
-	0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52,
-	0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x53, 0x69, 0x7a, 0x65, 0x12,
-	0x22, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65,
-	0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x48, 0x65, 0x61, 0x70, 0x53,
-	0x69, 0x7a, 0x65, 0x12, 0x35, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c,
-	0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e,
-	0x66, 0x6f, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x50, 0x0a, 0x11, 0x6d, 0x69,
-	0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18,
-	0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
-	0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x69, 0x78, 0x65,
-	0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x6d, 0x69, 0x78,
-	0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xdb, 0x01, 0x0a,
-	0x10, 0x45, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65,
-	0x72, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0e, 0x32, 0x32, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
-	0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x45, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a,
-	0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x63,
-	0x72, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x69, 0x63, 0x72, 0x6f,
-	0x73, 0x22, 0x47, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x00,
-	0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05,
-	0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x49, 0x53, 0x53, 0x49,
-	0x4e, 0x47, 0x5f, 0x47, 0x43, 0x45, 0x52, 0x54, 0x10, 0x03, 0x22, 0x91, 0x01, 0x0a, 0x0f, 0x4d,
-	0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3d,
-	0x0a, 0x1b, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x65, 0x6e,
-	0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20,
-	0x03, 0x28, 0x09, 0x52, 0x18, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x45,
-	0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x3f, 0x0a,
-	0x1c, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x69, 0x73,
-	0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20,
-	0x03, 0x28, 0x09, 0x52, 0x19, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44,
-	0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x42, 0x28,
-	0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f,
-	0x75, 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,
-	0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x02, 0x18,
+	0x01, 0x52, 0x11, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74,
+	0x72, 0x69, 0x63, 0x73, 0x12, 0x43, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x6f, 0x6f,
+	0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+	0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x62, 0x75,
+	0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73,
+	0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73,
+	0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x59, 0x0a, 0x14, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f,
+	0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x19, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c,
+	0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
+	0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x73, 0x79,
+	0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f,
+	0x12, 0x23, 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+	0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f,
+	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x3c, 0x0a, 0x0a, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x72,
+	0x75, 0x6e, 0x73, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
+	0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
+	0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x52,
+	0x75, 0x6e, 0x73, 0x12, 0x53, 0x0a, 0x12, 0x65, 0x78, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x25, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65,
+	0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x45, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46,
+	0x65, 0x74, 0x63, 0x68, 0x65, 0x72, 0x52, 0x10, 0x65, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x6f, 0x6e, 0x5f,
+	0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52,
+	0x0b, 0x6e, 0x6f, 0x6e, 0x5a, 0x65, 0x72, 0x6f, 0x45, 0x78, 0x69, 0x74, 0x12, 0x23, 0x0a, 0x0d,
+	0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x1e, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x22, 0x30, 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e,
+	0x74, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x55,
+	0x53, 0x45, 0x52, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x45, 0x4e,
+	0x47, 0x10, 0x02, 0x22, 0x3c, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x0b, 0x0a, 0x07, 0x55,
+	0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x52, 0x4d, 0x10,
+	0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x52, 0x4d, 0x36, 0x34, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03,
+	0x58, 0x38, 0x36, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x58, 0x38, 0x36, 0x5f, 0x36, 0x34, 0x10,
+	0x04, 0x22, 0x99, 0x02, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x12, 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x5f, 0x67, 0x6f, 0x6d, 0x61, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x07, 0x75, 0x73, 0x65, 0x47, 0x6f, 0x6d, 0x61, 0x12, 0x17, 0x0a, 0x07,
+	0x75, 0x73, 0x65, 0x5f, 0x72, 0x62, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x75,
+	0x73, 0x65, 0x52, 0x62, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x75,
+	0x73, 0x65, 0x5f, 0x67, 0x6f, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66,
+	0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x47, 0x6f, 0x6d, 0x61, 0x12, 0x24, 0x0a, 0x0e, 0x62,
+	0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x61, 0x73, 0x5f, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x0c, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x41, 0x73, 0x4e, 0x69, 0x6e, 0x6a,
+	0x61, 0x12, 0x2a, 0x0a, 0x11, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d, 0x69, 0x78, 0x65, 0x64,
+	0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x62, 0x61,
+	0x7a, 0x65, 0x6c, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x18, 0x0a,
+	0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07,
+	0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0x44, 0x0a, 0x1f, 0x66, 0x6f, 0x72, 0x63, 0x65,
+	0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d,
+	0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08,
+	0x52, 0x1b, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x61,
+	0x7a, 0x65, 0x6c, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x22, 0x6f, 0x0a,
+	0x12, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49,
+	0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x68, 0x79,
+	0x73, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x04, 0x52, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61,
+	0x6c, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c,
+	0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x70, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x0d, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x70, 0x75, 0x73, 0x22, 0xca,
+	0x02, 0x0a, 0x08, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x64,
+	0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65,
+	0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x04, 0x52, 0x08, 0x72, 0x65, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a,
+	0x0a, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x75, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
+	0x04, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x65,
+	0x12, 0x60, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x72, 0x65,
+	0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x28, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
+	0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52,
+	0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x15, 0x70, 0x72, 0x6f,
+	0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e,
+	0x66, 0x6f, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x6f, 0x6e, 0x5f, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x65,
+	0x78, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6e, 0x6f, 0x6e, 0x5a, 0x65,
+	0x72, 0x6f, 0x45, 0x78, 0x69, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f,
+	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65,
+	0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb9, 0x03, 0x0a, 0x13,
+	0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49,
+	0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x5f,
+	0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x04, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f,
+	0x73, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+	0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x73,
+	0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12,
+	0x1c, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x73, 0x73, 0x5f, 0x6b, 0x62, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x52, 0x73, 0x73, 0x4b, 0x62, 0x12, 0x2a, 0x0a,
+	0x11, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c,
+	0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x50,
+	0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x61, 0x6a,
+	0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x06,
+	0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46,
+	0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x69, 0x6f, 0x5f, 0x69, 0x6e, 0x70, 0x75,
+	0x74, 0x5f, 0x6b, 0x62, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6f, 0x49, 0x6e,
+	0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x6f, 0x5f, 0x6f, 0x75, 0x74, 0x70,
+	0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x69, 0x6f, 0x4f,
+	0x75, 0x74, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x3c, 0x0a, 0x1a, 0x76, 0x6f, 0x6c, 0x75, 0x6e,
+	0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69,
+	0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18, 0x76, 0x6f, 0x6c,
+	0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69,
+	0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x1c, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e,
+	0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69,
+	0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x69, 0x6e, 0x76,
+	0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53,
+	0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x75,
+	0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x5b, 0x0a, 0x0c, 0x62, 0x75,
+	0x69, 0x6c, 0x64, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
+	0x32, 0x2f, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d,
+	0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70,
+	0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65,
+	0x6d, 0x3a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c,
+	0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c,
+	0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f,
+	0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x75, 0x6d, 0x5f,
+	0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,
+	0x52, 0x0c, 0x6e, 0x75, 0x6d, 0x4f, 0x66, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x2f,
+	0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x0b, 0x0a,
+	0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x4f,
+	0x4f, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x41, 0x4b, 0x45, 0x10, 0x02, 0x22,
+	0x6c, 0x0a, 0x1a, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a,
+	0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x12, 0x3a, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64,
+	0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+	0x42, 0x61, 0x73, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x62, 0x0a,
+	0x1b, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75,
+	0x72, 0x6e, 0x65, 0x79, 0x73, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x43, 0x0a, 0x04,
+	0x63, 0x75, 0x6a, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x6f, 0x6f,
+	0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+	0x2e, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75,
+	0x72, 0x6e, 0x65, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x04, 0x63, 0x75, 0x6a,
+	0x73, 0x22, 0xcc, 0x02, 0x0a, 0x11, 0x53, 0x6f, 0x6f, 0x6e, 0x67, 0x42, 0x75, 0x69, 0x6c, 0x64,
+	0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c,
+	0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
+	0x73, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0d, 0x52, 0x08, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x0a,
+	0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x63, 0x6f, 0x75,
+	0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41,
+	0x6c, 0x6c, 0x6f, 0x63, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f, 0x74,
+	0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x53,
+	0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f,
+	0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x48,
+	0x65, 0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x35, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74,
+	0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f,
+	0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65,
+	0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x50,
+	0x0a, 0x11, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x5f, 0x69,
+	0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
+	0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
+	0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52,
+	0x0f, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f,
+	0x22, 0xdb, 0x01, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65,
+	0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
+	0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x45, 0x78, 0x70, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a,
+	0x06, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d,
+	0x69, 0x63, 0x72, 0x6f, 0x73, 0x22, 0x47, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x46,
+	0x49, 0x47, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x01,
+	0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4d,
+	0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x47, 0x43, 0x45, 0x52, 0x54, 0x10, 0x03, 0x22, 0x91,
+	0x01, 0x0a, 0x0f, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e,
+	0x66, 0x6f, 0x12, 0x3d, 0x0a, 0x1b, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c,
+	0x64, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
+	0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x18, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75,
+	0x69, 0x6c, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
+	0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64,
+	0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
+	0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75,
+	0x69, 0x6c, 0x64, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c,
+	0x65, 0x73, 0x42, 0x28, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f,
+	0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x6d,
+	0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 }
 
 var (
diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto
index 07a7df1..5ad13fc 100644
--- a/ui/metrics/metrics_proto/metrics.proto
+++ b/ui/metrics/metrics_proto/metrics.proto
@@ -93,7 +93,9 @@
   // The metrics for the whole build
   optional PerfInfo total = 21;
 
-  optional SoongBuildMetrics soong_build_metrics = 22;
+  // Deprecated because instead of embedding in a MetricsBase, we keep
+  // SoongBuildMetrics in its own file
+  optional SoongBuildMetrics soong_build_metrics = 22 [deprecated=true];
 
   optional BuildConfig build_config = 23;